config.gcc (i[34567]86-*-*): Add tmmintrin.h to extra_headers.
[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
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 2, 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 COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;; operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
66 (UNSPEC_STACK_ALLOC 11)
67 (UNSPEC_SET_GOT 12)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_REG_SAVE 14)
70 (UNSPEC_DEF_CFA 15)
71
72 ; TLS support
73 (UNSPEC_TP 16)
74 (UNSPEC_TLS_GD 17)
75 (UNSPEC_TLS_LD_BASE 18)
76 (UNSPEC_TLSDESC 19)
77
78 ; Other random patterns
79 (UNSPEC_SCAS 20)
80 (UNSPEC_FNSTSW 21)
81 (UNSPEC_SAHF 22)
82 (UNSPEC_FSTCW 23)
83 (UNSPEC_ADD_CARRY 24)
84 (UNSPEC_FLDCW 25)
85 (UNSPEC_REP 26)
86 (UNSPEC_EH_RETURN 27)
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 30)
91 (UNSPEC_MASKMOV 31)
92 (UNSPEC_MOVMSK 32)
93 (UNSPEC_MOVNT 33)
94 (UNSPEC_MOVU 34)
95 (UNSPEC_RCP 35)
96 (UNSPEC_RSQRT 36)
97 (UNSPEC_SFENCE 37)
98 (UNSPEC_NOP 38) ; prevents combiner cleverness
99 (UNSPEC_PFRCP 39)
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
124 ; x87 Rounding
125 (UNSPEC_FRNDINT_FLOOR 70)
126 (UNSPEC_FRNDINT_CEIL 71)
127 (UNSPEC_FRNDINT_TRUNC 72)
128 (UNSPEC_FRNDINT_MASK_PM 73)
129 (UNSPEC_FIST_FLOOR 74)
130 (UNSPEC_FIST_CEIL 75)
131
132 ; x87 Double output FP
133 (UNSPEC_SINCOS_COS 80)
134 (UNSPEC_SINCOS_SIN 81)
135 (UNSPEC_TAN_ONE 82)
136 (UNSPEC_TAN_TAN 83)
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 ; SSP patterns
147 (UNSPEC_SP_SET 100)
148 (UNSPEC_SP_TEST 101)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
151
152 ; SSSE3
153 (UNSPEC_PSHUFB 120)
154 (UNSPEC_PSIGN 121)
155 (UNSPEC_PALIGNR 122)
156 ])
157
158 (define_constants
159 [(UNSPECV_BLOCKAGE 0)
160 (UNSPECV_STACK_PROBE 1)
161 (UNSPECV_EMMS 2)
162 (UNSPECV_LDMXCSR 3)
163 (UNSPECV_STMXCSR 4)
164 (UNSPECV_FEMMS 5)
165 (UNSPECV_CLFLUSH 6)
166 (UNSPECV_ALIGN 7)
167 (UNSPECV_MONITOR 8)
168 (UNSPECV_MWAIT 9)
169 (UNSPECV_CMPXCHG_1 10)
170 (UNSPECV_CMPXCHG_2 11)
171 (UNSPECV_XCHG 12)
172 (UNSPECV_LOCK 13)
173 ])
174
175 ;; Registers by name.
176 (define_constants
177 [(BP_REG 6)
178 (SP_REG 7)
179 (FLAGS_REG 17)
180 (FPSR_REG 18)
181 (DIRFLAG_REG 19)
182 ])
183
184 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
185 ;; from i386.c.
186
187 ;; In C guard expressions, put expressions which may be compile-time
188 ;; constants first. This allows for better optimization. For
189 ;; example, write "TARGET_64BIT && reload_completed", not
190 ;; "reload_completed && TARGET_64BIT".
191
192 \f
193 ;; Processor type. This attribute must exactly match the processor_type
194 ;; enumeration in i386.h.
195 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
196 (const (symbol_ref "ix86_tune")))
197
198 ;; A basic instruction type. Refinements due to arguments to be
199 ;; provided in other attributes.
200 (define_attr "type"
201 "other,multi,
202 alu,alu1,negnot,imov,imovx,lea,
203 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
204 icmp,test,ibr,setcc,icmov,
205 push,pop,call,callv,leave,
206 str,cld,
207 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
208 sselog,sselog1,sseiadd,sseishft,sseimul,
209 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
210 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
211 (const_string "other"))
212
213 ;; Main data type used by the insn
214 (define_attr "mode"
215 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
216 (const_string "unknown"))
217
218 ;; The CPU unit operations uses.
219 (define_attr "unit" "integer,i387,sse,mmx,unknown"
220 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
221 (const_string "i387")
222 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
223 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
224 (const_string "sse")
225 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
226 (const_string "mmx")
227 (eq_attr "type" "other")
228 (const_string "unknown")]
229 (const_string "integer")))
230
231 ;; The (bounding maximum) length of an instruction immediate.
232 (define_attr "length_immediate" ""
233 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
234 (const_int 0)
235 (eq_attr "unit" "i387,sse,mmx")
236 (const_int 0)
237 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
238 imul,icmp,push,pop")
239 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
240 (eq_attr "type" "imov,test")
241 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
242 (eq_attr "type" "call")
243 (if_then_else (match_operand 0 "constant_call_address_operand" "")
244 (const_int 4)
245 (const_int 0))
246 (eq_attr "type" "callv")
247 (if_then_else (match_operand 1 "constant_call_address_operand" "")
248 (const_int 4)
249 (const_int 0))
250 ;; We don't know the size before shorten_branches. Expect
251 ;; the instruction to fit for better scheduling.
252 (eq_attr "type" "ibr")
253 (const_int 1)
254 ]
255 (symbol_ref "/* Update immediate_length and other attributes! */
256 gcc_unreachable (),1")))
257
258 ;; The (bounding maximum) length of an instruction address.
259 (define_attr "length_address" ""
260 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
261 (const_int 0)
262 (and (eq_attr "type" "call")
263 (match_operand 0 "constant_call_address_operand" ""))
264 (const_int 0)
265 (and (eq_attr "type" "callv")
266 (match_operand 1 "constant_call_address_operand" ""))
267 (const_int 0)
268 ]
269 (symbol_ref "ix86_attr_length_address_default (insn)")))
270
271 ;; Set when length prefix is used.
272 (define_attr "prefix_data16" ""
273 (if_then_else (ior (eq_attr "mode" "HI")
274 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
275 (const_int 1)
276 (const_int 0)))
277
278 ;; Set when string REP prefix is used.
279 (define_attr "prefix_rep" ""
280 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
281 (const_int 1)
282 (const_int 0)))
283
284 ;; Set when 0f opcode prefix is used.
285 (define_attr "prefix_0f" ""
286 (if_then_else
287 (ior (eq_attr "type" "imovx,setcc,icmov")
288 (eq_attr "unit" "sse,mmx"))
289 (const_int 1)
290 (const_int 0)))
291
292 ;; Set when REX opcode prefix is used.
293 (define_attr "prefix_rex" ""
294 (cond [(and (eq_attr "mode" "DI")
295 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
296 (const_int 1)
297 (and (eq_attr "mode" "QI")
298 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
299 (const_int 0)))
300 (const_int 1)
301 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
302 (const_int 0))
303 (const_int 1)
304 ]
305 (const_int 0)))
306
307 ;; Set when modrm byte is used.
308 (define_attr "modrm" ""
309 (cond [(eq_attr "type" "str,cld,leave")
310 (const_int 0)
311 (eq_attr "unit" "i387")
312 (const_int 0)
313 (and (eq_attr "type" "incdec")
314 (ior (match_operand:SI 1 "register_operand" "")
315 (match_operand:HI 1 "register_operand" "")))
316 (const_int 0)
317 (and (eq_attr "type" "push")
318 (not (match_operand 1 "memory_operand" "")))
319 (const_int 0)
320 (and (eq_attr "type" "pop")
321 (not (match_operand 0 "memory_operand" "")))
322 (const_int 0)
323 (and (eq_attr "type" "imov")
324 (ior (and (match_operand 0 "register_operand" "")
325 (match_operand 1 "immediate_operand" ""))
326 (ior (and (match_operand 0 "ax_reg_operand" "")
327 (match_operand 1 "memory_displacement_only_operand" ""))
328 (and (match_operand 0 "memory_displacement_only_operand" "")
329 (match_operand 1 "ax_reg_operand" "")))))
330 (const_int 0)
331 (and (eq_attr "type" "call")
332 (match_operand 0 "constant_call_address_operand" ""))
333 (const_int 0)
334 (and (eq_attr "type" "callv")
335 (match_operand 1 "constant_call_address_operand" ""))
336 (const_int 0)
337 ]
338 (const_int 1)))
339
340 ;; The (bounding maximum) length of an instruction in bytes.
341 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
342 ;; Later we may want to split them and compute proper length as for
343 ;; other insns.
344 (define_attr "length" ""
345 (cond [(eq_attr "type" "other,multi,fistp,frndint")
346 (const_int 16)
347 (eq_attr "type" "fcmp")
348 (const_int 4)
349 (eq_attr "unit" "i387")
350 (plus (const_int 2)
351 (plus (attr "prefix_data16")
352 (attr "length_address")))]
353 (plus (plus (attr "modrm")
354 (plus (attr "prefix_0f")
355 (plus (attr "prefix_rex")
356 (const_int 1))))
357 (plus (attr "prefix_rep")
358 (plus (attr "prefix_data16")
359 (plus (attr "length_immediate")
360 (attr "length_address")))))))
361
362 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
363 ;; `store' if there is a simple memory reference therein, or `unknown'
364 ;; if the instruction is complex.
365
366 (define_attr "memory" "none,load,store,both,unknown"
367 (cond [(eq_attr "type" "other,multi,str")
368 (const_string "unknown")
369 (eq_attr "type" "lea,fcmov,fpspc,cld")
370 (const_string "none")
371 (eq_attr "type" "fistp,leave")
372 (const_string "both")
373 (eq_attr "type" "frndint")
374 (const_string "load")
375 (eq_attr "type" "push")
376 (if_then_else (match_operand 1 "memory_operand" "")
377 (const_string "both")
378 (const_string "store"))
379 (eq_attr "type" "pop")
380 (if_then_else (match_operand 0 "memory_operand" "")
381 (const_string "both")
382 (const_string "load"))
383 (eq_attr "type" "setcc")
384 (if_then_else (match_operand 0 "memory_operand" "")
385 (const_string "store")
386 (const_string "none"))
387 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
388 (if_then_else (ior (match_operand 0 "memory_operand" "")
389 (match_operand 1 "memory_operand" ""))
390 (const_string "load")
391 (const_string "none"))
392 (eq_attr "type" "ibr")
393 (if_then_else (match_operand 0 "memory_operand" "")
394 (const_string "load")
395 (const_string "none"))
396 (eq_attr "type" "call")
397 (if_then_else (match_operand 0 "constant_call_address_operand" "")
398 (const_string "none")
399 (const_string "load"))
400 (eq_attr "type" "callv")
401 (if_then_else (match_operand 1 "constant_call_address_operand" "")
402 (const_string "none")
403 (const_string "load"))
404 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
405 (match_operand 1 "memory_operand" ""))
406 (const_string "both")
407 (and (match_operand 0 "memory_operand" "")
408 (match_operand 1 "memory_operand" ""))
409 (const_string "both")
410 (match_operand 0 "memory_operand" "")
411 (const_string "store")
412 (match_operand 1 "memory_operand" "")
413 (const_string "load")
414 (and (eq_attr "type"
415 "!alu1,negnot,ishift1,
416 imov,imovx,icmp,test,
417 fmov,fcmp,fsgn,
418 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
419 mmx,mmxmov,mmxcmp,mmxcvt")
420 (match_operand 2 "memory_operand" ""))
421 (const_string "load")
422 (and (eq_attr "type" "icmov")
423 (match_operand 3 "memory_operand" ""))
424 (const_string "load")
425 ]
426 (const_string "none")))
427
428 ;; Indicates if an instruction has both an immediate and a displacement.
429
430 (define_attr "imm_disp" "false,true,unknown"
431 (cond [(eq_attr "type" "other,multi")
432 (const_string "unknown")
433 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
434 (and (match_operand 0 "memory_displacement_operand" "")
435 (match_operand 1 "immediate_operand" "")))
436 (const_string "true")
437 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
438 (and (match_operand 0 "memory_displacement_operand" "")
439 (match_operand 2 "immediate_operand" "")))
440 (const_string "true")
441 ]
442 (const_string "false")))
443
444 ;; Indicates if an FP operation has an integer source.
445
446 (define_attr "fp_int_src" "false,true"
447 (const_string "false"))
448
449 ;; Defines rounding mode of an FP operation.
450
451 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
452 (const_string "any"))
453
454 ;; Describe a user's asm statement.
455 (define_asm_attributes
456 [(set_attr "length" "128")
457 (set_attr "type" "multi")])
458
459 ;; All x87 floating point modes
460 (define_mode_macro X87MODEF [SF DF XF])
461
462 ;; All integer modes handled by x87 fisttp operator.
463 (define_mode_macro X87MODEI [HI SI DI])
464
465 ;; All integer modes handled by integer x87 operators.
466 (define_mode_macro X87MODEI12 [HI SI])
467
468 ;; All SSE floating point modes
469 (define_mode_macro SSEMODEF [SF DF])
470
471 ;; All integer modes handled by SSE cvtts?2si* operators.
472 (define_mode_macro SSEMODEI24 [SI DI])
473
474 \f
475 ;; Scheduling descriptions
476
477 (include "pentium.md")
478 (include "ppro.md")
479 (include "k6.md")
480 (include "athlon.md")
481
482 \f
483 ;; Operand and operator predicates and constraints
484
485 (include "predicates.md")
486 (include "constraints.md")
487
488 \f
489 ;; Compare instructions.
490
491 ;; All compare insns have expanders that save the operands away without
492 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
493 ;; after the cmp) will actually emit the cmpM.
494
495 (define_expand "cmpti"
496 [(set (reg:CC FLAGS_REG)
497 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
498 (match_operand:TI 1 "x86_64_general_operand" "")))]
499 "TARGET_64BIT"
500 {
501 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
502 operands[0] = force_reg (TImode, operands[0]);
503 ix86_compare_op0 = operands[0];
504 ix86_compare_op1 = operands[1];
505 DONE;
506 })
507
508 (define_expand "cmpdi"
509 [(set (reg:CC FLAGS_REG)
510 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
511 (match_operand:DI 1 "x86_64_general_operand" "")))]
512 ""
513 {
514 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
515 operands[0] = force_reg (DImode, operands[0]);
516 ix86_compare_op0 = operands[0];
517 ix86_compare_op1 = operands[1];
518 DONE;
519 })
520
521 (define_expand "cmpsi"
522 [(set (reg:CC FLAGS_REG)
523 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
524 (match_operand:SI 1 "general_operand" "")))]
525 ""
526 {
527 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
528 operands[0] = force_reg (SImode, operands[0]);
529 ix86_compare_op0 = operands[0];
530 ix86_compare_op1 = operands[1];
531 DONE;
532 })
533
534 (define_expand "cmphi"
535 [(set (reg:CC FLAGS_REG)
536 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
537 (match_operand:HI 1 "general_operand" "")))]
538 ""
539 {
540 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
541 operands[0] = force_reg (HImode, operands[0]);
542 ix86_compare_op0 = operands[0];
543 ix86_compare_op1 = operands[1];
544 DONE;
545 })
546
547 (define_expand "cmpqi"
548 [(set (reg:CC FLAGS_REG)
549 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
550 (match_operand:QI 1 "general_operand" "")))]
551 "TARGET_QIMODE_MATH"
552 {
553 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
554 operands[0] = force_reg (QImode, operands[0]);
555 ix86_compare_op0 = operands[0];
556 ix86_compare_op1 = operands[1];
557 DONE;
558 })
559
560 (define_insn "cmpdi_ccno_1_rex64"
561 [(set (reg FLAGS_REG)
562 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
563 (match_operand:DI 1 "const0_operand" "n,n")))]
564 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
565 "@
566 test{q}\t{%0, %0|%0, %0}
567 cmp{q}\t{%1, %0|%0, %1}"
568 [(set_attr "type" "test,icmp")
569 (set_attr "length_immediate" "0,1")
570 (set_attr "mode" "DI")])
571
572 (define_insn "*cmpdi_minus_1_rex64"
573 [(set (reg FLAGS_REG)
574 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
575 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
576 (const_int 0)))]
577 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
578 "cmp{q}\t{%1, %0|%0, %1}"
579 [(set_attr "type" "icmp")
580 (set_attr "mode" "DI")])
581
582 (define_expand "cmpdi_1_rex64"
583 [(set (reg:CC FLAGS_REG)
584 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
585 (match_operand:DI 1 "general_operand" "")))]
586 "TARGET_64BIT"
587 "")
588
589 (define_insn "cmpdi_1_insn_rex64"
590 [(set (reg FLAGS_REG)
591 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
592 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
593 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
594 "cmp{q}\t{%1, %0|%0, %1}"
595 [(set_attr "type" "icmp")
596 (set_attr "mode" "DI")])
597
598
599 (define_insn "*cmpsi_ccno_1"
600 [(set (reg FLAGS_REG)
601 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
602 (match_operand:SI 1 "const0_operand" "n,n")))]
603 "ix86_match_ccmode (insn, CCNOmode)"
604 "@
605 test{l}\t{%0, %0|%0, %0}
606 cmp{l}\t{%1, %0|%0, %1}"
607 [(set_attr "type" "test,icmp")
608 (set_attr "length_immediate" "0,1")
609 (set_attr "mode" "SI")])
610
611 (define_insn "*cmpsi_minus_1"
612 [(set (reg FLAGS_REG)
613 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
614 (match_operand:SI 1 "general_operand" "ri,mr"))
615 (const_int 0)))]
616 "ix86_match_ccmode (insn, CCGOCmode)"
617 "cmp{l}\t{%1, %0|%0, %1}"
618 [(set_attr "type" "icmp")
619 (set_attr "mode" "SI")])
620
621 (define_expand "cmpsi_1"
622 [(set (reg:CC FLAGS_REG)
623 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
624 (match_operand:SI 1 "general_operand" "ri,mr")))]
625 ""
626 "")
627
628 (define_insn "*cmpsi_1_insn"
629 [(set (reg FLAGS_REG)
630 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
631 (match_operand:SI 1 "general_operand" "ri,mr")))]
632 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
633 && ix86_match_ccmode (insn, CCmode)"
634 "cmp{l}\t{%1, %0|%0, %1}"
635 [(set_attr "type" "icmp")
636 (set_attr "mode" "SI")])
637
638 (define_insn "*cmphi_ccno_1"
639 [(set (reg FLAGS_REG)
640 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
641 (match_operand:HI 1 "const0_operand" "n,n")))]
642 "ix86_match_ccmode (insn, CCNOmode)"
643 "@
644 test{w}\t{%0, %0|%0, %0}
645 cmp{w}\t{%1, %0|%0, %1}"
646 [(set_attr "type" "test,icmp")
647 (set_attr "length_immediate" "0,1")
648 (set_attr "mode" "HI")])
649
650 (define_insn "*cmphi_minus_1"
651 [(set (reg FLAGS_REG)
652 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
653 (match_operand:HI 1 "general_operand" "ri,mr"))
654 (const_int 0)))]
655 "ix86_match_ccmode (insn, CCGOCmode)"
656 "cmp{w}\t{%1, %0|%0, %1}"
657 [(set_attr "type" "icmp")
658 (set_attr "mode" "HI")])
659
660 (define_insn "*cmphi_1"
661 [(set (reg FLAGS_REG)
662 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
663 (match_operand:HI 1 "general_operand" "ri,mr")))]
664 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
665 && ix86_match_ccmode (insn, CCmode)"
666 "cmp{w}\t{%1, %0|%0, %1}"
667 [(set_attr "type" "icmp")
668 (set_attr "mode" "HI")])
669
670 (define_insn "*cmpqi_ccno_1"
671 [(set (reg FLAGS_REG)
672 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
673 (match_operand:QI 1 "const0_operand" "n,n")))]
674 "ix86_match_ccmode (insn, CCNOmode)"
675 "@
676 test{b}\t{%0, %0|%0, %0}
677 cmp{b}\t{$0, %0|%0, 0}"
678 [(set_attr "type" "test,icmp")
679 (set_attr "length_immediate" "0,1")
680 (set_attr "mode" "QI")])
681
682 (define_insn "*cmpqi_1"
683 [(set (reg FLAGS_REG)
684 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
685 (match_operand:QI 1 "general_operand" "qi,mq")))]
686 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
687 && ix86_match_ccmode (insn, CCmode)"
688 "cmp{b}\t{%1, %0|%0, %1}"
689 [(set_attr "type" "icmp")
690 (set_attr "mode" "QI")])
691
692 (define_insn "*cmpqi_minus_1"
693 [(set (reg FLAGS_REG)
694 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
695 (match_operand:QI 1 "general_operand" "qi,mq"))
696 (const_int 0)))]
697 "ix86_match_ccmode (insn, CCGOCmode)"
698 "cmp{b}\t{%1, %0|%0, %1}"
699 [(set_attr "type" "icmp")
700 (set_attr "mode" "QI")])
701
702 (define_insn "*cmpqi_ext_1"
703 [(set (reg FLAGS_REG)
704 (compare
705 (match_operand:QI 0 "general_operand" "Qm")
706 (subreg:QI
707 (zero_extract:SI
708 (match_operand 1 "ext_register_operand" "Q")
709 (const_int 8)
710 (const_int 8)) 0)))]
711 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
712 "cmp{b}\t{%h1, %0|%0, %h1}"
713 [(set_attr "type" "icmp")
714 (set_attr "mode" "QI")])
715
716 (define_insn "*cmpqi_ext_1_rex64"
717 [(set (reg FLAGS_REG)
718 (compare
719 (match_operand:QI 0 "register_operand" "Q")
720 (subreg:QI
721 (zero_extract:SI
722 (match_operand 1 "ext_register_operand" "Q")
723 (const_int 8)
724 (const_int 8)) 0)))]
725 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
726 "cmp{b}\t{%h1, %0|%0, %h1}"
727 [(set_attr "type" "icmp")
728 (set_attr "mode" "QI")])
729
730 (define_insn "*cmpqi_ext_2"
731 [(set (reg FLAGS_REG)
732 (compare
733 (subreg:QI
734 (zero_extract:SI
735 (match_operand 0 "ext_register_operand" "Q")
736 (const_int 8)
737 (const_int 8)) 0)
738 (match_operand:QI 1 "const0_operand" "n")))]
739 "ix86_match_ccmode (insn, CCNOmode)"
740 "test{b}\t%h0, %h0"
741 [(set_attr "type" "test")
742 (set_attr "length_immediate" "0")
743 (set_attr "mode" "QI")])
744
745 (define_expand "cmpqi_ext_3"
746 [(set (reg:CC FLAGS_REG)
747 (compare:CC
748 (subreg:QI
749 (zero_extract:SI
750 (match_operand 0 "ext_register_operand" "")
751 (const_int 8)
752 (const_int 8)) 0)
753 (match_operand:QI 1 "general_operand" "")))]
754 ""
755 "")
756
757 (define_insn "cmpqi_ext_3_insn"
758 [(set (reg FLAGS_REG)
759 (compare
760 (subreg:QI
761 (zero_extract:SI
762 (match_operand 0 "ext_register_operand" "Q")
763 (const_int 8)
764 (const_int 8)) 0)
765 (match_operand:QI 1 "general_operand" "Qmn")))]
766 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
767 "cmp{b}\t{%1, %h0|%h0, %1}"
768 [(set_attr "type" "icmp")
769 (set_attr "mode" "QI")])
770
771 (define_insn "cmpqi_ext_3_insn_rex64"
772 [(set (reg FLAGS_REG)
773 (compare
774 (subreg:QI
775 (zero_extract:SI
776 (match_operand 0 "ext_register_operand" "Q")
777 (const_int 8)
778 (const_int 8)) 0)
779 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
780 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
781 "cmp{b}\t{%1, %h0|%h0, %1}"
782 [(set_attr "type" "icmp")
783 (set_attr "mode" "QI")])
784
785 (define_insn "*cmpqi_ext_4"
786 [(set (reg FLAGS_REG)
787 (compare
788 (subreg:QI
789 (zero_extract:SI
790 (match_operand 0 "ext_register_operand" "Q")
791 (const_int 8)
792 (const_int 8)) 0)
793 (subreg:QI
794 (zero_extract:SI
795 (match_operand 1 "ext_register_operand" "Q")
796 (const_int 8)
797 (const_int 8)) 0)))]
798 "ix86_match_ccmode (insn, CCmode)"
799 "cmp{b}\t{%h1, %h0|%h0, %h1}"
800 [(set_attr "type" "icmp")
801 (set_attr "mode" "QI")])
802
803 ;; These implement float point compares.
804 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
805 ;; which would allow mix and match FP modes on the compares. Which is what
806 ;; the old patterns did, but with many more of them.
807
808 (define_expand "cmpxf"
809 [(set (reg:CC FLAGS_REG)
810 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
811 (match_operand:XF 1 "nonmemory_operand" "")))]
812 "TARGET_80387"
813 {
814 ix86_compare_op0 = operands[0];
815 ix86_compare_op1 = operands[1];
816 DONE;
817 })
818
819 (define_expand "cmpdf"
820 [(set (reg:CC FLAGS_REG)
821 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
822 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
823 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
824 {
825 ix86_compare_op0 = operands[0];
826 ix86_compare_op1 = operands[1];
827 DONE;
828 })
829
830 (define_expand "cmpsf"
831 [(set (reg:CC FLAGS_REG)
832 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
833 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
834 "TARGET_80387 || TARGET_SSE_MATH"
835 {
836 ix86_compare_op0 = operands[0];
837 ix86_compare_op1 = operands[1];
838 DONE;
839 })
840
841 ;; FP compares, step 1:
842 ;; Set the FP condition codes.
843 ;;
844 ;; CCFPmode compare with exceptions
845 ;; CCFPUmode compare with no exceptions
846
847 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
848 ;; used to manage the reg stack popping would not be preserved.
849
850 (define_insn "*cmpfp_0"
851 [(set (match_operand:HI 0 "register_operand" "=a")
852 (unspec:HI
853 [(compare:CCFP
854 (match_operand 1 "register_operand" "f")
855 (match_operand 2 "const0_operand" "X"))]
856 UNSPEC_FNSTSW))]
857 "TARGET_80387
858 && FLOAT_MODE_P (GET_MODE (operands[1]))
859 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
860 "* return output_fp_compare (insn, operands, 0, 0);"
861 [(set_attr "type" "multi")
862 (set_attr "unit" "i387")
863 (set (attr "mode")
864 (cond [(match_operand:SF 1 "" "")
865 (const_string "SF")
866 (match_operand:DF 1 "" "")
867 (const_string "DF")
868 ]
869 (const_string "XF")))])
870
871 (define_insn "*cmpfp_sf"
872 [(set (match_operand:HI 0 "register_operand" "=a")
873 (unspec:HI
874 [(compare:CCFP
875 (match_operand:SF 1 "register_operand" "f")
876 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
877 UNSPEC_FNSTSW))]
878 "TARGET_80387"
879 "* return output_fp_compare (insn, operands, 0, 0);"
880 [(set_attr "type" "multi")
881 (set_attr "unit" "i387")
882 (set_attr "mode" "SF")])
883
884 (define_insn "*cmpfp_df"
885 [(set (match_operand:HI 0 "register_operand" "=a")
886 (unspec:HI
887 [(compare:CCFP
888 (match_operand:DF 1 "register_operand" "f")
889 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
890 UNSPEC_FNSTSW))]
891 "TARGET_80387"
892 "* return output_fp_compare (insn, operands, 0, 0);"
893 [(set_attr "type" "multi")
894 (set_attr "unit" "i387")
895 (set_attr "mode" "DF")])
896
897 (define_insn "*cmpfp_xf"
898 [(set (match_operand:HI 0 "register_operand" "=a")
899 (unspec:HI
900 [(compare:CCFP
901 (match_operand:XF 1 "register_operand" "f")
902 (match_operand:XF 2 "register_operand" "f"))]
903 UNSPEC_FNSTSW))]
904 "TARGET_80387"
905 "* return output_fp_compare (insn, operands, 0, 0);"
906 [(set_attr "type" "multi")
907 (set_attr "unit" "i387")
908 (set_attr "mode" "XF")])
909
910 (define_insn "*cmpfp_u"
911 [(set (match_operand:HI 0 "register_operand" "=a")
912 (unspec:HI
913 [(compare:CCFPU
914 (match_operand 1 "register_operand" "f")
915 (match_operand 2 "register_operand" "f"))]
916 UNSPEC_FNSTSW))]
917 "TARGET_80387
918 && FLOAT_MODE_P (GET_MODE (operands[1]))
919 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
920 "* return output_fp_compare (insn, operands, 0, 1);"
921 [(set_attr "type" "multi")
922 (set_attr "unit" "i387")
923 (set (attr "mode")
924 (cond [(match_operand:SF 1 "" "")
925 (const_string "SF")
926 (match_operand:DF 1 "" "")
927 (const_string "DF")
928 ]
929 (const_string "XF")))])
930
931 (define_insn "*cmpfp_<mode>"
932 [(set (match_operand:HI 0 "register_operand" "=a")
933 (unspec:HI
934 [(compare:CCFP
935 (match_operand 1 "register_operand" "f")
936 (match_operator 3 "float_operator"
937 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
938 UNSPEC_FNSTSW))]
939 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
940 && FLOAT_MODE_P (GET_MODE (operands[1]))
941 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
942 "* return output_fp_compare (insn, operands, 0, 0);"
943 [(set_attr "type" "multi")
944 (set_attr "unit" "i387")
945 (set_attr "fp_int_src" "true")
946 (set_attr "mode" "<MODE>")])
947
948 ;; FP compares, step 2
949 ;; Move the fpsw to ax.
950
951 (define_insn "x86_fnstsw_1"
952 [(set (match_operand:HI 0 "register_operand" "=a")
953 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
954 "TARGET_80387"
955 "fnstsw\t%0"
956 [(set_attr "length" "2")
957 (set_attr "mode" "SI")
958 (set_attr "unit" "i387")])
959
960 ;; FP compares, step 3
961 ;; Get ax into flags, general case.
962
963 (define_insn "x86_sahf_1"
964 [(set (reg:CC FLAGS_REG)
965 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
966 "!TARGET_64BIT"
967 "sahf"
968 [(set_attr "length" "1")
969 (set_attr "athlon_decode" "vector")
970 (set_attr "mode" "SI")])
971
972 ;; Pentium Pro can do steps 1 through 3 in one go.
973
974 (define_insn "*cmpfp_i_mixed"
975 [(set (reg:CCFP FLAGS_REG)
976 (compare:CCFP (match_operand 0 "register_operand" "f,x")
977 (match_operand 1 "nonimmediate_operand" "f,xm")))]
978 "TARGET_MIX_SSE_I387
979 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
980 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
981 "* return output_fp_compare (insn, operands, 1, 0);"
982 [(set_attr "type" "fcmp,ssecomi")
983 (set (attr "mode")
984 (if_then_else (match_operand:SF 1 "" "")
985 (const_string "SF")
986 (const_string "DF")))
987 (set_attr "athlon_decode" "vector")])
988
989 (define_insn "*cmpfp_i_sse"
990 [(set (reg:CCFP FLAGS_REG)
991 (compare:CCFP (match_operand 0 "register_operand" "x")
992 (match_operand 1 "nonimmediate_operand" "xm")))]
993 "TARGET_SSE_MATH
994 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
995 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
996 "* return output_fp_compare (insn, operands, 1, 0);"
997 [(set_attr "type" "ssecomi")
998 (set (attr "mode")
999 (if_then_else (match_operand:SF 1 "" "")
1000 (const_string "SF")
1001 (const_string "DF")))
1002 (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_i_i387"
1005 [(set (reg:CCFP FLAGS_REG)
1006 (compare:CCFP (match_operand 0 "register_operand" "f")
1007 (match_operand 1 "register_operand" "f")))]
1008 "TARGET_80387 && TARGET_CMOVE
1009 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1010 && FLOAT_MODE_P (GET_MODE (operands[0]))
1011 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1012 "* return output_fp_compare (insn, operands, 1, 0);"
1013 [(set_attr "type" "fcmp")
1014 (set (attr "mode")
1015 (cond [(match_operand:SF 1 "" "")
1016 (const_string "SF")
1017 (match_operand:DF 1 "" "")
1018 (const_string "DF")
1019 ]
1020 (const_string "XF")))
1021 (set_attr "athlon_decode" "vector")])
1022
1023 (define_insn "*cmpfp_iu_mixed"
1024 [(set (reg:CCFPU FLAGS_REG)
1025 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1026 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1027 "TARGET_MIX_SSE_I387
1028 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1029 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1030 "* return output_fp_compare (insn, operands, 1, 1);"
1031 [(set_attr "type" "fcmp,ssecomi")
1032 (set (attr "mode")
1033 (if_then_else (match_operand:SF 1 "" "")
1034 (const_string "SF")
1035 (const_string "DF")))
1036 (set_attr "athlon_decode" "vector")])
1037
1038 (define_insn "*cmpfp_iu_sse"
1039 [(set (reg:CCFPU FLAGS_REG)
1040 (compare:CCFPU (match_operand 0 "register_operand" "x")
1041 (match_operand 1 "nonimmediate_operand" "xm")))]
1042 "TARGET_SSE_MATH
1043 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1044 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1045 "* return output_fp_compare (insn, operands, 1, 1);"
1046 [(set_attr "type" "ssecomi")
1047 (set (attr "mode")
1048 (if_then_else (match_operand:SF 1 "" "")
1049 (const_string "SF")
1050 (const_string "DF")))
1051 (set_attr "athlon_decode" "vector")])
1052
1053 (define_insn "*cmpfp_iu_387"
1054 [(set (reg:CCFPU FLAGS_REG)
1055 (compare:CCFPU (match_operand 0 "register_operand" "f")
1056 (match_operand 1 "register_operand" "f")))]
1057 "TARGET_80387 && TARGET_CMOVE
1058 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1059 && FLOAT_MODE_P (GET_MODE (operands[0]))
1060 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1061 "* return output_fp_compare (insn, operands, 1, 1);"
1062 [(set_attr "type" "fcmp")
1063 (set (attr "mode")
1064 (cond [(match_operand:SF 1 "" "")
1065 (const_string "SF")
1066 (match_operand:DF 1 "" "")
1067 (const_string "DF")
1068 ]
1069 (const_string "XF")))
1070 (set_attr "athlon_decode" "vector")])
1071 \f
1072 ;; Move instructions.
1073
1074 ;; General case of fullword move.
1075
1076 (define_expand "movsi"
1077 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1078 (match_operand:SI 1 "general_operand" ""))]
1079 ""
1080 "ix86_expand_move (SImode, operands); DONE;")
1081
1082 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1083 ;; general_operand.
1084 ;;
1085 ;; %%% We don't use a post-inc memory reference because x86 is not a
1086 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1087 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1088 ;; targets without our curiosities, and it is just as easy to represent
1089 ;; this differently.
1090
1091 (define_insn "*pushsi2"
1092 [(set (match_operand:SI 0 "push_operand" "=<")
1093 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1094 "!TARGET_64BIT"
1095 "push{l}\t%1"
1096 [(set_attr "type" "push")
1097 (set_attr "mode" "SI")])
1098
1099 ;; For 64BIT abi we always round up to 8 bytes.
1100 (define_insn "*pushsi2_rex64"
1101 [(set (match_operand:SI 0 "push_operand" "=X")
1102 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1103 "TARGET_64BIT"
1104 "push{q}\t%q1"
1105 [(set_attr "type" "push")
1106 (set_attr "mode" "SI")])
1107
1108 (define_insn "*pushsi2_prologue"
1109 [(set (match_operand:SI 0 "push_operand" "=<")
1110 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1111 (clobber (mem:BLK (scratch)))]
1112 "!TARGET_64BIT"
1113 "push{l}\t%1"
1114 [(set_attr "type" "push")
1115 (set_attr "mode" "SI")])
1116
1117 (define_insn "*popsi1_epilogue"
1118 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1119 (mem:SI (reg:SI SP_REG)))
1120 (set (reg:SI SP_REG)
1121 (plus:SI (reg:SI SP_REG) (const_int 4)))
1122 (clobber (mem:BLK (scratch)))]
1123 "!TARGET_64BIT"
1124 "pop{l}\t%0"
1125 [(set_attr "type" "pop")
1126 (set_attr "mode" "SI")])
1127
1128 (define_insn "popsi1"
1129 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1130 (mem:SI (reg:SI SP_REG)))
1131 (set (reg:SI SP_REG)
1132 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1133 "!TARGET_64BIT"
1134 "pop{l}\t%0"
1135 [(set_attr "type" "pop")
1136 (set_attr "mode" "SI")])
1137
1138 (define_insn "*movsi_xor"
1139 [(set (match_operand:SI 0 "register_operand" "=r")
1140 (match_operand:SI 1 "const0_operand" "i"))
1141 (clobber (reg:CC FLAGS_REG))]
1142 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1143 "xor{l}\t{%0, %0|%0, %0}"
1144 [(set_attr "type" "alu1")
1145 (set_attr "mode" "SI")
1146 (set_attr "length_immediate" "0")])
1147
1148 (define_insn "*movsi_or"
1149 [(set (match_operand:SI 0 "register_operand" "=r")
1150 (match_operand:SI 1 "immediate_operand" "i"))
1151 (clobber (reg:CC FLAGS_REG))]
1152 "reload_completed
1153 && operands[1] == constm1_rtx
1154 && (TARGET_PENTIUM || optimize_size)"
1155 {
1156 operands[1] = constm1_rtx;
1157 return "or{l}\t{%1, %0|%0, %1}";
1158 }
1159 [(set_attr "type" "alu1")
1160 (set_attr "mode" "SI")
1161 (set_attr "length_immediate" "1")])
1162
1163 (define_insn "*movsi_1"
1164 [(set (match_operand:SI 0 "nonimmediate_operand"
1165 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1166 (match_operand:SI 1 "general_operand"
1167 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1168 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1169 {
1170 switch (get_attr_type (insn))
1171 {
1172 case TYPE_SSELOG1:
1173 if (get_attr_mode (insn) == MODE_TI)
1174 return "pxor\t%0, %0";
1175 return "xorps\t%0, %0";
1176
1177 case TYPE_SSEMOV:
1178 switch (get_attr_mode (insn))
1179 {
1180 case MODE_TI:
1181 return "movdqa\t{%1, %0|%0, %1}";
1182 case MODE_V4SF:
1183 return "movaps\t{%1, %0|%0, %1}";
1184 case MODE_SI:
1185 return "movd\t{%1, %0|%0, %1}";
1186 case MODE_SF:
1187 return "movss\t{%1, %0|%0, %1}";
1188 default:
1189 gcc_unreachable ();
1190 }
1191
1192 case TYPE_MMXADD:
1193 return "pxor\t%0, %0";
1194
1195 case TYPE_MMXMOV:
1196 if (get_attr_mode (insn) == MODE_DI)
1197 return "movq\t{%1, %0|%0, %1}";
1198 return "movd\t{%1, %0|%0, %1}";
1199
1200 case TYPE_LEA:
1201 return "lea{l}\t{%1, %0|%0, %1}";
1202
1203 default:
1204 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1205 return "mov{l}\t{%1, %0|%0, %1}";
1206 }
1207 }
1208 [(set (attr "type")
1209 (cond [(eq_attr "alternative" "2")
1210 (const_string "mmxadd")
1211 (eq_attr "alternative" "3,4,5")
1212 (const_string "mmxmov")
1213 (eq_attr "alternative" "6")
1214 (const_string "sselog1")
1215 (eq_attr "alternative" "7,8,9,10,11")
1216 (const_string "ssemov")
1217 (match_operand:DI 1 "pic_32bit_operand" "")
1218 (const_string "lea")
1219 ]
1220 (const_string "imov")))
1221 (set (attr "mode")
1222 (cond [(eq_attr "alternative" "2,3")
1223 (const_string "DI")
1224 (eq_attr "alternative" "6,7")
1225 (if_then_else
1226 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1227 (const_string "V4SF")
1228 (const_string "TI"))
1229 (and (eq_attr "alternative" "8,9,10,11")
1230 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1231 (const_string "SF")
1232 ]
1233 (const_string "SI")))])
1234
1235 ;; Stores and loads of ax to arbitrary constant address.
1236 ;; We fake an second form of instruction to force reload to load address
1237 ;; into register when rax is not available
1238 (define_insn "*movabssi_1_rex64"
1239 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1240 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1241 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1242 "@
1243 movabs{l}\t{%1, %P0|%P0, %1}
1244 mov{l}\t{%1, %a0|%a0, %1}"
1245 [(set_attr "type" "imov")
1246 (set_attr "modrm" "0,*")
1247 (set_attr "length_address" "8,0")
1248 (set_attr "length_immediate" "0,*")
1249 (set_attr "memory" "store")
1250 (set_attr "mode" "SI")])
1251
1252 (define_insn "*movabssi_2_rex64"
1253 [(set (match_operand:SI 0 "register_operand" "=a,r")
1254 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1255 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1256 "@
1257 movabs{l}\t{%P1, %0|%0, %P1}
1258 mov{l}\t{%a1, %0|%0, %a1}"
1259 [(set_attr "type" "imov")
1260 (set_attr "modrm" "0,*")
1261 (set_attr "length_address" "8,0")
1262 (set_attr "length_immediate" "0")
1263 (set_attr "memory" "load")
1264 (set_attr "mode" "SI")])
1265
1266 (define_insn "*swapsi"
1267 [(set (match_operand:SI 0 "register_operand" "+r")
1268 (match_operand:SI 1 "register_operand" "+r"))
1269 (set (match_dup 1)
1270 (match_dup 0))]
1271 ""
1272 "xchg{l}\t%1, %0"
1273 [(set_attr "type" "imov")
1274 (set_attr "mode" "SI")
1275 (set_attr "pent_pair" "np")
1276 (set_attr "athlon_decode" "vector")])
1277
1278 (define_expand "movhi"
1279 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1280 (match_operand:HI 1 "general_operand" ""))]
1281 ""
1282 "ix86_expand_move (HImode, operands); DONE;")
1283
1284 (define_insn "*pushhi2"
1285 [(set (match_operand:HI 0 "push_operand" "=X")
1286 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1287 "!TARGET_64BIT"
1288 "push{l}\t%k1"
1289 [(set_attr "type" "push")
1290 (set_attr "mode" "SI")])
1291
1292 ;; For 64BIT abi we always round up to 8 bytes.
1293 (define_insn "*pushhi2_rex64"
1294 [(set (match_operand:HI 0 "push_operand" "=X")
1295 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1296 "TARGET_64BIT"
1297 "push{q}\t%q1"
1298 [(set_attr "type" "push")
1299 (set_attr "mode" "DI")])
1300
1301 (define_insn "*movhi_1"
1302 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1303 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1304 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1305 {
1306 switch (get_attr_type (insn))
1307 {
1308 case TYPE_IMOVX:
1309 /* movzwl is faster than movw on p2 due to partial word stalls,
1310 though not as fast as an aligned movl. */
1311 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1312 default:
1313 if (get_attr_mode (insn) == MODE_SI)
1314 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1315 else
1316 return "mov{w}\t{%1, %0|%0, %1}";
1317 }
1318 }
1319 [(set (attr "type")
1320 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1321 (const_string "imov")
1322 (and (eq_attr "alternative" "0")
1323 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1324 (const_int 0))
1325 (eq (symbol_ref "TARGET_HIMODE_MATH")
1326 (const_int 0))))
1327 (const_string "imov")
1328 (and (eq_attr "alternative" "1,2")
1329 (match_operand:HI 1 "aligned_operand" ""))
1330 (const_string "imov")
1331 (and (ne (symbol_ref "TARGET_MOVX")
1332 (const_int 0))
1333 (eq_attr "alternative" "0,2"))
1334 (const_string "imovx")
1335 ]
1336 (const_string "imov")))
1337 (set (attr "mode")
1338 (cond [(eq_attr "type" "imovx")
1339 (const_string "SI")
1340 (and (eq_attr "alternative" "1,2")
1341 (match_operand:HI 1 "aligned_operand" ""))
1342 (const_string "SI")
1343 (and (eq_attr "alternative" "0")
1344 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1345 (const_int 0))
1346 (eq (symbol_ref "TARGET_HIMODE_MATH")
1347 (const_int 0))))
1348 (const_string "SI")
1349 ]
1350 (const_string "HI")))])
1351
1352 ;; Stores and loads of ax to arbitrary constant address.
1353 ;; We fake an second form of instruction to force reload to load address
1354 ;; into register when rax is not available
1355 (define_insn "*movabshi_1_rex64"
1356 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1357 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1358 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1359 "@
1360 movabs{w}\t{%1, %P0|%P0, %1}
1361 mov{w}\t{%1, %a0|%a0, %1}"
1362 [(set_attr "type" "imov")
1363 (set_attr "modrm" "0,*")
1364 (set_attr "length_address" "8,0")
1365 (set_attr "length_immediate" "0,*")
1366 (set_attr "memory" "store")
1367 (set_attr "mode" "HI")])
1368
1369 (define_insn "*movabshi_2_rex64"
1370 [(set (match_operand:HI 0 "register_operand" "=a,r")
1371 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1372 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1373 "@
1374 movabs{w}\t{%P1, %0|%0, %P1}
1375 mov{w}\t{%a1, %0|%0, %a1}"
1376 [(set_attr "type" "imov")
1377 (set_attr "modrm" "0,*")
1378 (set_attr "length_address" "8,0")
1379 (set_attr "length_immediate" "0")
1380 (set_attr "memory" "load")
1381 (set_attr "mode" "HI")])
1382
1383 (define_insn "*swaphi_1"
1384 [(set (match_operand:HI 0 "register_operand" "+r")
1385 (match_operand:HI 1 "register_operand" "+r"))
1386 (set (match_dup 1)
1387 (match_dup 0))]
1388 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1389 "xchg{l}\t%k1, %k0"
1390 [(set_attr "type" "imov")
1391 (set_attr "mode" "SI")
1392 (set_attr "pent_pair" "np")
1393 (set_attr "athlon_decode" "vector")])
1394
1395 (define_insn "*swaphi_2"
1396 [(set (match_operand:HI 0 "register_operand" "+r")
1397 (match_operand:HI 1 "register_operand" "+r"))
1398 (set (match_dup 1)
1399 (match_dup 0))]
1400 "TARGET_PARTIAL_REG_STALL"
1401 "xchg{w}\t%1, %0"
1402 [(set_attr "type" "imov")
1403 (set_attr "mode" "HI")
1404 (set_attr "pent_pair" "np")
1405 (set_attr "athlon_decode" "vector")])
1406
1407 (define_expand "movstricthi"
1408 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1409 (match_operand:HI 1 "general_operand" ""))]
1410 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1411 {
1412 /* Don't generate memory->memory moves, go through a register */
1413 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1414 operands[1] = force_reg (HImode, operands[1]);
1415 })
1416
1417 (define_insn "*movstricthi_1"
1418 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1419 (match_operand:HI 1 "general_operand" "rn,m"))]
1420 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1421 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1422 "mov{w}\t{%1, %0|%0, %1}"
1423 [(set_attr "type" "imov")
1424 (set_attr "mode" "HI")])
1425
1426 (define_insn "*movstricthi_xor"
1427 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1428 (match_operand:HI 1 "const0_operand" "i"))
1429 (clobber (reg:CC FLAGS_REG))]
1430 "reload_completed
1431 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1432 "xor{w}\t{%0, %0|%0, %0}"
1433 [(set_attr "type" "alu1")
1434 (set_attr "mode" "HI")
1435 (set_attr "length_immediate" "0")])
1436
1437 (define_expand "movqi"
1438 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1439 (match_operand:QI 1 "general_operand" ""))]
1440 ""
1441 "ix86_expand_move (QImode, operands); DONE;")
1442
1443 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1444 ;; "push a byte". But actually we use pushl, which has the effect
1445 ;; of rounding the amount pushed up to a word.
1446
1447 (define_insn "*pushqi2"
1448 [(set (match_operand:QI 0 "push_operand" "=X")
1449 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1450 "!TARGET_64BIT"
1451 "push{l}\t%k1"
1452 [(set_attr "type" "push")
1453 (set_attr "mode" "SI")])
1454
1455 ;; For 64BIT abi we always round up to 8 bytes.
1456 (define_insn "*pushqi2_rex64"
1457 [(set (match_operand:QI 0 "push_operand" "=X")
1458 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1459 "TARGET_64BIT"
1460 "push{q}\t%q1"
1461 [(set_attr "type" "push")
1462 (set_attr "mode" "DI")])
1463
1464 ;; Situation is quite tricky about when to choose full sized (SImode) move
1465 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1466 ;; partial register dependency machines (such as AMD Athlon), where QImode
1467 ;; moves issue extra dependency and for partial register stalls machines
1468 ;; that don't use QImode patterns (and QImode move cause stall on the next
1469 ;; instruction).
1470 ;;
1471 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1472 ;; register stall machines with, where we use QImode instructions, since
1473 ;; partial register stall can be caused there. Then we use movzx.
1474 (define_insn "*movqi_1"
1475 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1476 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1477 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1478 {
1479 switch (get_attr_type (insn))
1480 {
1481 case TYPE_IMOVX:
1482 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1483 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1484 default:
1485 if (get_attr_mode (insn) == MODE_SI)
1486 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1487 else
1488 return "mov{b}\t{%1, %0|%0, %1}";
1489 }
1490 }
1491 [(set (attr "type")
1492 (cond [(and (eq_attr "alternative" "5")
1493 (not (match_operand:QI 1 "aligned_operand" "")))
1494 (const_string "imovx")
1495 (ne (symbol_ref "optimize_size") (const_int 0))
1496 (const_string "imov")
1497 (and (eq_attr "alternative" "3")
1498 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1499 (const_int 0))
1500 (eq (symbol_ref "TARGET_QIMODE_MATH")
1501 (const_int 0))))
1502 (const_string "imov")
1503 (eq_attr "alternative" "3,5")
1504 (const_string "imovx")
1505 (and (ne (symbol_ref "TARGET_MOVX")
1506 (const_int 0))
1507 (eq_attr "alternative" "2"))
1508 (const_string "imovx")
1509 ]
1510 (const_string "imov")))
1511 (set (attr "mode")
1512 (cond [(eq_attr "alternative" "3,4,5")
1513 (const_string "SI")
1514 (eq_attr "alternative" "6")
1515 (const_string "QI")
1516 (eq_attr "type" "imovx")
1517 (const_string "SI")
1518 (and (eq_attr "type" "imov")
1519 (and (eq_attr "alternative" "0,1")
1520 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1521 (const_int 0))
1522 (and (eq (symbol_ref "optimize_size")
1523 (const_int 0))
1524 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1525 (const_int 0))))))
1526 (const_string "SI")
1527 ;; Avoid partial register stalls when not using QImode arithmetic
1528 (and (eq_attr "type" "imov")
1529 (and (eq_attr "alternative" "0,1")
1530 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1531 (const_int 0))
1532 (eq (symbol_ref "TARGET_QIMODE_MATH")
1533 (const_int 0)))))
1534 (const_string "SI")
1535 ]
1536 (const_string "QI")))])
1537
1538 (define_expand "reload_outqi"
1539 [(parallel [(match_operand:QI 0 "" "=m")
1540 (match_operand:QI 1 "register_operand" "r")
1541 (match_operand:QI 2 "register_operand" "=&q")])]
1542 ""
1543 {
1544 rtx op0, op1, op2;
1545 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1546
1547 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1548 if (! q_regs_operand (op1, QImode))
1549 {
1550 emit_insn (gen_movqi (op2, op1));
1551 op1 = op2;
1552 }
1553 emit_insn (gen_movqi (op0, op1));
1554 DONE;
1555 })
1556
1557 (define_insn "*swapqi_1"
1558 [(set (match_operand:QI 0 "register_operand" "+r")
1559 (match_operand:QI 1 "register_operand" "+r"))
1560 (set (match_dup 1)
1561 (match_dup 0))]
1562 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1563 "xchg{l}\t%k1, %k0"
1564 [(set_attr "type" "imov")
1565 (set_attr "mode" "SI")
1566 (set_attr "pent_pair" "np")
1567 (set_attr "athlon_decode" "vector")])
1568
1569 (define_insn "*swapqi_2"
1570 [(set (match_operand:QI 0 "register_operand" "+q")
1571 (match_operand:QI 1 "register_operand" "+q"))
1572 (set (match_dup 1)
1573 (match_dup 0))]
1574 "TARGET_PARTIAL_REG_STALL"
1575 "xchg{b}\t%1, %0"
1576 [(set_attr "type" "imov")
1577 (set_attr "mode" "QI")
1578 (set_attr "pent_pair" "np")
1579 (set_attr "athlon_decode" "vector")])
1580
1581 (define_expand "movstrictqi"
1582 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1583 (match_operand:QI 1 "general_operand" ""))]
1584 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1585 {
1586 /* Don't generate memory->memory moves, go through a register. */
1587 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1588 operands[1] = force_reg (QImode, operands[1]);
1589 })
1590
1591 (define_insn "*movstrictqi_1"
1592 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1593 (match_operand:QI 1 "general_operand" "*qn,m"))]
1594 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1595 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1596 "mov{b}\t{%1, %0|%0, %1}"
1597 [(set_attr "type" "imov")
1598 (set_attr "mode" "QI")])
1599
1600 (define_insn "*movstrictqi_xor"
1601 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1602 (match_operand:QI 1 "const0_operand" "i"))
1603 (clobber (reg:CC FLAGS_REG))]
1604 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1605 "xor{b}\t{%0, %0|%0, %0}"
1606 [(set_attr "type" "alu1")
1607 (set_attr "mode" "QI")
1608 (set_attr "length_immediate" "0")])
1609
1610 (define_insn "*movsi_extv_1"
1611 [(set (match_operand:SI 0 "register_operand" "=R")
1612 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1613 (const_int 8)
1614 (const_int 8)))]
1615 ""
1616 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1617 [(set_attr "type" "imovx")
1618 (set_attr "mode" "SI")])
1619
1620 (define_insn "*movhi_extv_1"
1621 [(set (match_operand:HI 0 "register_operand" "=R")
1622 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1623 (const_int 8)
1624 (const_int 8)))]
1625 ""
1626 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1627 [(set_attr "type" "imovx")
1628 (set_attr "mode" "SI")])
1629
1630 (define_insn "*movqi_extv_1"
1631 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1632 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1633 (const_int 8)
1634 (const_int 8)))]
1635 "!TARGET_64BIT"
1636 {
1637 switch (get_attr_type (insn))
1638 {
1639 case TYPE_IMOVX:
1640 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1641 default:
1642 return "mov{b}\t{%h1, %0|%0, %h1}";
1643 }
1644 }
1645 [(set (attr "type")
1646 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1647 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1648 (ne (symbol_ref "TARGET_MOVX")
1649 (const_int 0))))
1650 (const_string "imovx")
1651 (const_string "imov")))
1652 (set (attr "mode")
1653 (if_then_else (eq_attr "type" "imovx")
1654 (const_string "SI")
1655 (const_string "QI")))])
1656
1657 (define_insn "*movqi_extv_1_rex64"
1658 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1659 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1660 (const_int 8)
1661 (const_int 8)))]
1662 "TARGET_64BIT"
1663 {
1664 switch (get_attr_type (insn))
1665 {
1666 case TYPE_IMOVX:
1667 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1668 default:
1669 return "mov{b}\t{%h1, %0|%0, %h1}";
1670 }
1671 }
1672 [(set (attr "type")
1673 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1674 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1675 (ne (symbol_ref "TARGET_MOVX")
1676 (const_int 0))))
1677 (const_string "imovx")
1678 (const_string "imov")))
1679 (set (attr "mode")
1680 (if_then_else (eq_attr "type" "imovx")
1681 (const_string "SI")
1682 (const_string "QI")))])
1683
1684 ;; Stores and loads of ax to arbitrary constant address.
1685 ;; We fake an second form of instruction to force reload to load address
1686 ;; into register when rax is not available
1687 (define_insn "*movabsqi_1_rex64"
1688 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1689 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1690 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1691 "@
1692 movabs{b}\t{%1, %P0|%P0, %1}
1693 mov{b}\t{%1, %a0|%a0, %1}"
1694 [(set_attr "type" "imov")
1695 (set_attr "modrm" "0,*")
1696 (set_attr "length_address" "8,0")
1697 (set_attr "length_immediate" "0,*")
1698 (set_attr "memory" "store")
1699 (set_attr "mode" "QI")])
1700
1701 (define_insn "*movabsqi_2_rex64"
1702 [(set (match_operand:QI 0 "register_operand" "=a,r")
1703 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1704 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1705 "@
1706 movabs{b}\t{%P1, %0|%0, %P1}
1707 mov{b}\t{%a1, %0|%0, %a1}"
1708 [(set_attr "type" "imov")
1709 (set_attr "modrm" "0,*")
1710 (set_attr "length_address" "8,0")
1711 (set_attr "length_immediate" "0")
1712 (set_attr "memory" "load")
1713 (set_attr "mode" "QI")])
1714
1715 (define_insn "*movdi_extzv_1"
1716 [(set (match_operand:DI 0 "register_operand" "=R")
1717 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1718 (const_int 8)
1719 (const_int 8)))]
1720 "TARGET_64BIT"
1721 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1722 [(set_attr "type" "imovx")
1723 (set_attr "mode" "DI")])
1724
1725 (define_insn "*movsi_extzv_1"
1726 [(set (match_operand:SI 0 "register_operand" "=R")
1727 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1728 (const_int 8)
1729 (const_int 8)))]
1730 ""
1731 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1732 [(set_attr "type" "imovx")
1733 (set_attr "mode" "SI")])
1734
1735 (define_insn "*movqi_extzv_2"
1736 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1737 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1738 (const_int 8)
1739 (const_int 8)) 0))]
1740 "!TARGET_64BIT"
1741 {
1742 switch (get_attr_type (insn))
1743 {
1744 case TYPE_IMOVX:
1745 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1746 default:
1747 return "mov{b}\t{%h1, %0|%0, %h1}";
1748 }
1749 }
1750 [(set (attr "type")
1751 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1752 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1753 (ne (symbol_ref "TARGET_MOVX")
1754 (const_int 0))))
1755 (const_string "imovx")
1756 (const_string "imov")))
1757 (set (attr "mode")
1758 (if_then_else (eq_attr "type" "imovx")
1759 (const_string "SI")
1760 (const_string "QI")))])
1761
1762 (define_insn "*movqi_extzv_2_rex64"
1763 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1764 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1765 (const_int 8)
1766 (const_int 8)) 0))]
1767 "TARGET_64BIT"
1768 {
1769 switch (get_attr_type (insn))
1770 {
1771 case TYPE_IMOVX:
1772 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1773 default:
1774 return "mov{b}\t{%h1, %0|%0, %h1}";
1775 }
1776 }
1777 [(set (attr "type")
1778 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1779 (ne (symbol_ref "TARGET_MOVX")
1780 (const_int 0)))
1781 (const_string "imovx")
1782 (const_string "imov")))
1783 (set (attr "mode")
1784 (if_then_else (eq_attr "type" "imovx")
1785 (const_string "SI")
1786 (const_string "QI")))])
1787
1788 (define_insn "movsi_insv_1"
1789 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1790 (const_int 8)
1791 (const_int 8))
1792 (match_operand:SI 1 "general_operand" "Qmn"))]
1793 "!TARGET_64BIT"
1794 "mov{b}\t{%b1, %h0|%h0, %b1}"
1795 [(set_attr "type" "imov")
1796 (set_attr "mode" "QI")])
1797
1798 (define_insn "movdi_insv_1_rex64"
1799 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1800 (const_int 8)
1801 (const_int 8))
1802 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1803 "TARGET_64BIT"
1804 "mov{b}\t{%b1, %h0|%h0, %b1}"
1805 [(set_attr "type" "imov")
1806 (set_attr "mode" "QI")])
1807
1808 (define_insn "*movqi_insv_2"
1809 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1810 (const_int 8)
1811 (const_int 8))
1812 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1813 (const_int 8)))]
1814 ""
1815 "mov{b}\t{%h1, %h0|%h0, %h1}"
1816 [(set_attr "type" "imov")
1817 (set_attr "mode" "QI")])
1818
1819 (define_expand "movdi"
1820 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1821 (match_operand:DI 1 "general_operand" ""))]
1822 ""
1823 "ix86_expand_move (DImode, operands); DONE;")
1824
1825 (define_insn "*pushdi"
1826 [(set (match_operand:DI 0 "push_operand" "=<")
1827 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1828 "!TARGET_64BIT"
1829 "#")
1830
1831 (define_insn "*pushdi2_rex64"
1832 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1833 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1834 "TARGET_64BIT"
1835 "@
1836 push{q}\t%1
1837 #"
1838 [(set_attr "type" "push,multi")
1839 (set_attr "mode" "DI")])
1840
1841 ;; Convert impossible pushes of immediate to existing instructions.
1842 ;; First try to get scratch register and go through it. In case this
1843 ;; fails, push sign extended lower part first and then overwrite
1844 ;; upper part by 32bit move.
1845 (define_peephole2
1846 [(match_scratch:DI 2 "r")
1847 (set (match_operand:DI 0 "push_operand" "")
1848 (match_operand:DI 1 "immediate_operand" ""))]
1849 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1850 && !x86_64_immediate_operand (operands[1], DImode)"
1851 [(set (match_dup 2) (match_dup 1))
1852 (set (match_dup 0) (match_dup 2))]
1853 "")
1854
1855 ;; We need to define this as both peepholer and splitter for case
1856 ;; peephole2 pass is not run.
1857 ;; "&& 1" is needed to keep it from matching the previous pattern.
1858 (define_peephole2
1859 [(set (match_operand:DI 0 "push_operand" "")
1860 (match_operand:DI 1 "immediate_operand" ""))]
1861 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1862 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1863 [(set (match_dup 0) (match_dup 1))
1864 (set (match_dup 2) (match_dup 3))]
1865 "split_di (operands + 1, 1, operands + 2, operands + 3);
1866 operands[1] = gen_lowpart (DImode, operands[2]);
1867 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1868 GEN_INT (4)));
1869 ")
1870
1871 (define_split
1872 [(set (match_operand:DI 0 "push_operand" "")
1873 (match_operand:DI 1 "immediate_operand" ""))]
1874 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1875 ? flow2_completed : reload_completed)
1876 && !symbolic_operand (operands[1], DImode)
1877 && !x86_64_immediate_operand (operands[1], DImode)"
1878 [(set (match_dup 0) (match_dup 1))
1879 (set (match_dup 2) (match_dup 3))]
1880 "split_di (operands + 1, 1, operands + 2, operands + 3);
1881 operands[1] = gen_lowpart (DImode, operands[2]);
1882 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1883 GEN_INT (4)));
1884 ")
1885
1886 (define_insn "*pushdi2_prologue_rex64"
1887 [(set (match_operand:DI 0 "push_operand" "=<")
1888 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1889 (clobber (mem:BLK (scratch)))]
1890 "TARGET_64BIT"
1891 "push{q}\t%1"
1892 [(set_attr "type" "push")
1893 (set_attr "mode" "DI")])
1894
1895 (define_insn "*popdi1_epilogue_rex64"
1896 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1897 (mem:DI (reg:DI SP_REG)))
1898 (set (reg:DI SP_REG)
1899 (plus:DI (reg:DI SP_REG) (const_int 8)))
1900 (clobber (mem:BLK (scratch)))]
1901 "TARGET_64BIT"
1902 "pop{q}\t%0"
1903 [(set_attr "type" "pop")
1904 (set_attr "mode" "DI")])
1905
1906 (define_insn "popdi1"
1907 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1908 (mem:DI (reg:DI SP_REG)))
1909 (set (reg:DI SP_REG)
1910 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1911 "TARGET_64BIT"
1912 "pop{q}\t%0"
1913 [(set_attr "type" "pop")
1914 (set_attr "mode" "DI")])
1915
1916 (define_insn "*movdi_xor_rex64"
1917 [(set (match_operand:DI 0 "register_operand" "=r")
1918 (match_operand:DI 1 "const0_operand" "i"))
1919 (clobber (reg:CC FLAGS_REG))]
1920 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1921 && reload_completed"
1922 "xor{l}\t{%k0, %k0|%k0, %k0}"
1923 [(set_attr "type" "alu1")
1924 (set_attr "mode" "SI")
1925 (set_attr "length_immediate" "0")])
1926
1927 (define_insn "*movdi_or_rex64"
1928 [(set (match_operand:DI 0 "register_operand" "=r")
1929 (match_operand:DI 1 "const_int_operand" "i"))
1930 (clobber (reg:CC FLAGS_REG))]
1931 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1932 && reload_completed
1933 && operands[1] == constm1_rtx"
1934 {
1935 operands[1] = constm1_rtx;
1936 return "or{q}\t{%1, %0|%0, %1}";
1937 }
1938 [(set_attr "type" "alu1")
1939 (set_attr "mode" "DI")
1940 (set_attr "length_immediate" "1")])
1941
1942 (define_insn "*movdi_2"
1943 [(set (match_operand:DI 0 "nonimmediate_operand"
1944 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1945 (match_operand:DI 1 "general_operand"
1946 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1947 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1948 "@
1949 #
1950 #
1951 pxor\t%0, %0
1952 movq\t{%1, %0|%0, %1}
1953 movq\t{%1, %0|%0, %1}
1954 pxor\t%0, %0
1955 movq\t{%1, %0|%0, %1}
1956 movdqa\t{%1, %0|%0, %1}
1957 movq\t{%1, %0|%0, %1}
1958 xorps\t%0, %0
1959 movlps\t{%1, %0|%0, %1}
1960 movaps\t{%1, %0|%0, %1}
1961 movlps\t{%1, %0|%0, %1}"
1962 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1963 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1964
1965 (define_split
1966 [(set (match_operand:DI 0 "push_operand" "")
1967 (match_operand:DI 1 "general_operand" ""))]
1968 "!TARGET_64BIT && reload_completed
1969 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1970 [(const_int 0)]
1971 "ix86_split_long_move (operands); DONE;")
1972
1973 ;; %%% This multiword shite has got to go.
1974 (define_split
1975 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1976 (match_operand:DI 1 "general_operand" ""))]
1977 "!TARGET_64BIT && reload_completed
1978 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1979 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1980 [(const_int 0)]
1981 "ix86_split_long_move (operands); DONE;")
1982
1983 (define_insn "*movdi_1_rex64"
1984 [(set (match_operand:DI 0 "nonimmediate_operand"
1985 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1986 (match_operand:DI 1 "general_operand"
1987 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1988 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1989 {
1990 switch (get_attr_type (insn))
1991 {
1992 case TYPE_SSECVT:
1993 if (which_alternative == 13)
1994 return "movq2dq\t{%1, %0|%0, %1}";
1995 else
1996 return "movdq2q\t{%1, %0|%0, %1}";
1997 case TYPE_SSEMOV:
1998 if (get_attr_mode (insn) == MODE_TI)
1999 return "movdqa\t{%1, %0|%0, %1}";
2000 /* FALLTHRU */
2001 case TYPE_MMXMOV:
2002 /* Moves from and into integer register is done using movd opcode with
2003 REX prefix. */
2004 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2005 return "movd\t{%1, %0|%0, %1}";
2006 return "movq\t{%1, %0|%0, %1}";
2007 case TYPE_SSELOG1:
2008 case TYPE_MMXADD:
2009 return "pxor\t%0, %0";
2010 case TYPE_MULTI:
2011 return "#";
2012 case TYPE_LEA:
2013 return "lea{q}\t{%a1, %0|%0, %a1}";
2014 default:
2015 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2016 if (get_attr_mode (insn) == MODE_SI)
2017 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2018 else if (which_alternative == 2)
2019 return "movabs{q}\t{%1, %0|%0, %1}";
2020 else
2021 return "mov{q}\t{%1, %0|%0, %1}";
2022 }
2023 }
2024 [(set (attr "type")
2025 (cond [(eq_attr "alternative" "5")
2026 (const_string "mmxadd")
2027 (eq_attr "alternative" "6,7,8")
2028 (const_string "mmxmov")
2029 (eq_attr "alternative" "9")
2030 (const_string "sselog1")
2031 (eq_attr "alternative" "10,11,12")
2032 (const_string "ssemov")
2033 (eq_attr "alternative" "13,14")
2034 (const_string "ssecvt")
2035 (eq_attr "alternative" "4")
2036 (const_string "multi")
2037 (match_operand:DI 1 "pic_32bit_operand" "")
2038 (const_string "lea")
2039 ]
2040 (const_string "imov")))
2041 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2042 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2043 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2044
2045 ;; Stores and loads of ax to arbitrary constant address.
2046 ;; We fake an second form of instruction to force reload to load address
2047 ;; into register when rax is not available
2048 (define_insn "*movabsdi_1_rex64"
2049 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2050 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2051 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2052 "@
2053 movabs{q}\t{%1, %P0|%P0, %1}
2054 mov{q}\t{%1, %a0|%a0, %1}"
2055 [(set_attr "type" "imov")
2056 (set_attr "modrm" "0,*")
2057 (set_attr "length_address" "8,0")
2058 (set_attr "length_immediate" "0,*")
2059 (set_attr "memory" "store")
2060 (set_attr "mode" "DI")])
2061
2062 (define_insn "*movabsdi_2_rex64"
2063 [(set (match_operand:DI 0 "register_operand" "=a,r")
2064 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2065 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2066 "@
2067 movabs{q}\t{%P1, %0|%0, %P1}
2068 mov{q}\t{%a1, %0|%0, %a1}"
2069 [(set_attr "type" "imov")
2070 (set_attr "modrm" "0,*")
2071 (set_attr "length_address" "8,0")
2072 (set_attr "length_immediate" "0")
2073 (set_attr "memory" "load")
2074 (set_attr "mode" "DI")])
2075
2076 ;; Convert impossible stores of immediate to existing instructions.
2077 ;; First try to get scratch register and go through it. In case this
2078 ;; fails, move by 32bit parts.
2079 (define_peephole2
2080 [(match_scratch:DI 2 "r")
2081 (set (match_operand:DI 0 "memory_operand" "")
2082 (match_operand:DI 1 "immediate_operand" ""))]
2083 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084 && !x86_64_immediate_operand (operands[1], DImode)"
2085 [(set (match_dup 2) (match_dup 1))
2086 (set (match_dup 0) (match_dup 2))]
2087 "")
2088
2089 ;; We need to define this as both peepholer and splitter for case
2090 ;; peephole2 pass is not run.
2091 ;; "&& 1" is needed to keep it from matching the previous pattern.
2092 (define_peephole2
2093 [(set (match_operand:DI 0 "memory_operand" "")
2094 (match_operand:DI 1 "immediate_operand" ""))]
2095 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2096 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2097 [(set (match_dup 2) (match_dup 3))
2098 (set (match_dup 4) (match_dup 5))]
2099 "split_di (operands, 2, operands + 2, operands + 4);")
2100
2101 (define_split
2102 [(set (match_operand:DI 0 "memory_operand" "")
2103 (match_operand:DI 1 "immediate_operand" ""))]
2104 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2105 ? flow2_completed : reload_completed)
2106 && !symbolic_operand (operands[1], DImode)
2107 && !x86_64_immediate_operand (operands[1], DImode)"
2108 [(set (match_dup 2) (match_dup 3))
2109 (set (match_dup 4) (match_dup 5))]
2110 "split_di (operands, 2, operands + 2, operands + 4);")
2111
2112 (define_insn "*swapdi_rex64"
2113 [(set (match_operand:DI 0 "register_operand" "+r")
2114 (match_operand:DI 1 "register_operand" "+r"))
2115 (set (match_dup 1)
2116 (match_dup 0))]
2117 "TARGET_64BIT"
2118 "xchg{q}\t%1, %0"
2119 [(set_attr "type" "imov")
2120 (set_attr "mode" "DI")
2121 (set_attr "pent_pair" "np")
2122 (set_attr "athlon_decode" "vector")])
2123
2124 (define_expand "movti"
2125 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2126 (match_operand:TI 1 "nonimmediate_operand" ""))]
2127 "TARGET_SSE || TARGET_64BIT"
2128 {
2129 if (TARGET_64BIT)
2130 ix86_expand_move (TImode, operands);
2131 else
2132 ix86_expand_vector_move (TImode, operands);
2133 DONE;
2134 })
2135
2136 (define_insn "*movti_internal"
2137 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2138 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2139 "TARGET_SSE && !TARGET_64BIT
2140 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2141 {
2142 switch (which_alternative)
2143 {
2144 case 0:
2145 if (get_attr_mode (insn) == MODE_V4SF)
2146 return "xorps\t%0, %0";
2147 else
2148 return "pxor\t%0, %0";
2149 case 1:
2150 case 2:
2151 if (get_attr_mode (insn) == MODE_V4SF)
2152 return "movaps\t{%1, %0|%0, %1}";
2153 else
2154 return "movdqa\t{%1, %0|%0, %1}";
2155 default:
2156 gcc_unreachable ();
2157 }
2158 }
2159 [(set_attr "type" "sselog1,ssemov,ssemov")
2160 (set (attr "mode")
2161 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2162 (ne (symbol_ref "optimize_size") (const_int 0)))
2163 (const_string "V4SF")
2164 (and (eq_attr "alternative" "2")
2165 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2166 (const_int 0)))
2167 (const_string "V4SF")]
2168 (const_string "TI")))])
2169
2170 (define_insn "*movti_rex64"
2171 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2172 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2173 "TARGET_64BIT
2174 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2175 {
2176 switch (which_alternative)
2177 {
2178 case 0:
2179 case 1:
2180 return "#";
2181 case 2:
2182 if (get_attr_mode (insn) == MODE_V4SF)
2183 return "xorps\t%0, %0";
2184 else
2185 return "pxor\t%0, %0";
2186 case 3:
2187 case 4:
2188 if (get_attr_mode (insn) == MODE_V4SF)
2189 return "movaps\t{%1, %0|%0, %1}";
2190 else
2191 return "movdqa\t{%1, %0|%0, %1}";
2192 default:
2193 gcc_unreachable ();
2194 }
2195 }
2196 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2197 (set (attr "mode")
2198 (cond [(eq_attr "alternative" "2,3")
2199 (if_then_else
2200 (ne (symbol_ref "optimize_size")
2201 (const_int 0))
2202 (const_string "V4SF")
2203 (const_string "TI"))
2204 (eq_attr "alternative" "4")
2205 (if_then_else
2206 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2207 (const_int 0))
2208 (ne (symbol_ref "optimize_size")
2209 (const_int 0)))
2210 (const_string "V4SF")
2211 (const_string "TI"))]
2212 (const_string "DI")))])
2213
2214 (define_split
2215 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2216 (match_operand:TI 1 "general_operand" ""))]
2217 "reload_completed && !SSE_REG_P (operands[0])
2218 && !SSE_REG_P (operands[1])"
2219 [(const_int 0)]
2220 "ix86_split_long_move (operands); DONE;")
2221
2222 (define_expand "movsf"
2223 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2224 (match_operand:SF 1 "general_operand" ""))]
2225 ""
2226 "ix86_expand_move (SFmode, operands); DONE;")
2227
2228 (define_insn "*pushsf"
2229 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2230 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2231 "!TARGET_64BIT"
2232 {
2233 /* Anything else should be already split before reg-stack. */
2234 gcc_assert (which_alternative == 1);
2235 return "push{l}\t%1";
2236 }
2237 [(set_attr "type" "multi,push,multi")
2238 (set_attr "unit" "i387,*,*")
2239 (set_attr "mode" "SF,SI,SF")])
2240
2241 (define_insn "*pushsf_rex64"
2242 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2243 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2244 "TARGET_64BIT"
2245 {
2246 /* Anything else should be already split before reg-stack. */
2247 gcc_assert (which_alternative == 1);
2248 return "push{q}\t%q1";
2249 }
2250 [(set_attr "type" "multi,push,multi")
2251 (set_attr "unit" "i387,*,*")
2252 (set_attr "mode" "SF,DI,SF")])
2253
2254 (define_split
2255 [(set (match_operand:SF 0 "push_operand" "")
2256 (match_operand:SF 1 "memory_operand" ""))]
2257 "reload_completed
2258 && GET_CODE (operands[1]) == MEM
2259 && constant_pool_reference_p (operands[1])"
2260 [(set (match_dup 0)
2261 (match_dup 1))]
2262 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2263
2264
2265 ;; %%% Kill this when call knows how to work this out.
2266 (define_split
2267 [(set (match_operand:SF 0 "push_operand" "")
2268 (match_operand:SF 1 "any_fp_register_operand" ""))]
2269 "!TARGET_64BIT"
2270 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2271 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2272
2273 (define_split
2274 [(set (match_operand:SF 0 "push_operand" "")
2275 (match_operand:SF 1 "any_fp_register_operand" ""))]
2276 "TARGET_64BIT"
2277 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2278 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2279
2280 (define_insn "*movsf_1"
2281 [(set (match_operand:SF 0 "nonimmediate_operand"
2282 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2283 (match_operand:SF 1 "general_operand"
2284 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2285 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2286 && (reload_in_progress || reload_completed
2287 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288 || GET_CODE (operands[1]) != CONST_DOUBLE
2289 || memory_operand (operands[0], SFmode))"
2290 {
2291 switch (which_alternative)
2292 {
2293 case 0:
2294 return output_387_reg_move (insn, operands);
2295
2296 case 1:
2297 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298 return "fstp%z0\t%y0";
2299 else
2300 return "fst%z0\t%y0";
2301
2302 case 2:
2303 return standard_80387_constant_opcode (operands[1]);
2304
2305 case 3:
2306 case 4:
2307 return "mov{l}\t{%1, %0|%0, %1}";
2308 case 5:
2309 if (get_attr_mode (insn) == MODE_TI)
2310 return "pxor\t%0, %0";
2311 else
2312 return "xorps\t%0, %0";
2313 case 6:
2314 if (get_attr_mode (insn) == MODE_V4SF)
2315 return "movaps\t{%1, %0|%0, %1}";
2316 else
2317 return "movss\t{%1, %0|%0, %1}";
2318 case 7:
2319 case 8:
2320 return "movss\t{%1, %0|%0, %1}";
2321
2322 case 9:
2323 case 10:
2324 return "movd\t{%1, %0|%0, %1}";
2325
2326 case 11:
2327 return "movq\t{%1, %0|%0, %1}";
2328
2329 default:
2330 gcc_unreachable ();
2331 }
2332 }
2333 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2334 (set (attr "mode")
2335 (cond [(eq_attr "alternative" "3,4,9,10")
2336 (const_string "SI")
2337 (eq_attr "alternative" "5")
2338 (if_then_else
2339 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2340 (const_int 0))
2341 (ne (symbol_ref "TARGET_SSE2")
2342 (const_int 0)))
2343 (eq (symbol_ref "optimize_size")
2344 (const_int 0)))
2345 (const_string "TI")
2346 (const_string "V4SF"))
2347 /* For architectures resolving dependencies on
2348 whole SSE registers use APS move to break dependency
2349 chains, otherwise use short move to avoid extra work.
2350
2351 Do the same for architectures resolving dependencies on
2352 the parts. While in DF mode it is better to always handle
2353 just register parts, the SF mode is different due to lack
2354 of instructions to load just part of the register. It is
2355 better to maintain the whole registers in single format
2356 to avoid problems on using packed logical operations. */
2357 (eq_attr "alternative" "6")
2358 (if_then_else
2359 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2360 (const_int 0))
2361 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2362 (const_int 0)))
2363 (const_string "V4SF")
2364 (const_string "SF"))
2365 (eq_attr "alternative" "11")
2366 (const_string "DI")]
2367 (const_string "SF")))])
2368
2369 (define_insn "*swapsf"
2370 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2371 (match_operand:SF 1 "fp_register_operand" "+f"))
2372 (set (match_dup 1)
2373 (match_dup 0))]
2374 "reload_completed || TARGET_80387"
2375 {
2376 if (STACK_TOP_P (operands[0]))
2377 return "fxch\t%1";
2378 else
2379 return "fxch\t%0";
2380 }
2381 [(set_attr "type" "fxch")
2382 (set_attr "mode" "SF")])
2383
2384 (define_expand "movdf"
2385 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2386 (match_operand:DF 1 "general_operand" ""))]
2387 ""
2388 "ix86_expand_move (DFmode, operands); DONE;")
2389
2390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2391 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2392 ;; On the average, pushdf using integers can be still shorter. Allow this
2393 ;; pattern for optimize_size too.
2394
2395 (define_insn "*pushdf_nointeger"
2396 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2397 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2398 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2399 {
2400 /* This insn should be already split before reg-stack. */
2401 gcc_unreachable ();
2402 }
2403 [(set_attr "type" "multi")
2404 (set_attr "unit" "i387,*,*,*")
2405 (set_attr "mode" "DF,SI,SI,DF")])
2406
2407 (define_insn "*pushdf_integer"
2408 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2409 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2410 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2411 {
2412 /* This insn should be already split before reg-stack. */
2413 gcc_unreachable ();
2414 }
2415 [(set_attr "type" "multi")
2416 (set_attr "unit" "i387,*,*")
2417 (set_attr "mode" "DF,SI,DF")])
2418
2419 ;; %%% Kill this when call knows how to work this out.
2420 (define_split
2421 [(set (match_operand:DF 0 "push_operand" "")
2422 (match_operand:DF 1 "any_fp_register_operand" ""))]
2423 "!TARGET_64BIT && reload_completed"
2424 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2425 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2426 "")
2427
2428 (define_split
2429 [(set (match_operand:DF 0 "push_operand" "")
2430 (match_operand:DF 1 "any_fp_register_operand" ""))]
2431 "TARGET_64BIT && reload_completed"
2432 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2433 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2434 "")
2435
2436 (define_split
2437 [(set (match_operand:DF 0 "push_operand" "")
2438 (match_operand:DF 1 "general_operand" ""))]
2439 "reload_completed"
2440 [(const_int 0)]
2441 "ix86_split_long_move (operands); DONE;")
2442
2443 ;; Moving is usually shorter when only FP registers are used. This separate
2444 ;; movdf pattern avoids the use of integer registers for FP operations
2445 ;; when optimizing for size.
2446
2447 (define_insn "*movdf_nointeger"
2448 [(set (match_operand:DF 0 "nonimmediate_operand"
2449 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2450 (match_operand:DF 1 "general_operand"
2451 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2452 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2453 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2454 && (reload_in_progress || reload_completed
2455 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2456 || GET_CODE (operands[1]) != CONST_DOUBLE
2457 || memory_operand (operands[0], DFmode))"
2458 {
2459 switch (which_alternative)
2460 {
2461 case 0:
2462 return output_387_reg_move (insn, operands);
2463
2464 case 1:
2465 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2466 return "fstp%z0\t%y0";
2467 else
2468 return "fst%z0\t%y0";
2469
2470 case 2:
2471 return standard_80387_constant_opcode (operands[1]);
2472
2473 case 3:
2474 case 4:
2475 return "#";
2476 case 5:
2477 switch (get_attr_mode (insn))
2478 {
2479 case MODE_V4SF:
2480 return "xorps\t%0, %0";
2481 case MODE_V2DF:
2482 return "xorpd\t%0, %0";
2483 case MODE_TI:
2484 return "pxor\t%0, %0";
2485 default:
2486 gcc_unreachable ();
2487 }
2488 case 6:
2489 case 7:
2490 case 8:
2491 switch (get_attr_mode (insn))
2492 {
2493 case MODE_V4SF:
2494 return "movaps\t{%1, %0|%0, %1}";
2495 case MODE_V2DF:
2496 return "movapd\t{%1, %0|%0, %1}";
2497 case MODE_TI:
2498 return "movdqa\t{%1, %0|%0, %1}";
2499 case MODE_DI:
2500 return "movq\t{%1, %0|%0, %1}";
2501 case MODE_DF:
2502 return "movsd\t{%1, %0|%0, %1}";
2503 case MODE_V1DF:
2504 return "movlpd\t{%1, %0|%0, %1}";
2505 case MODE_V2SF:
2506 return "movlps\t{%1, %0|%0, %1}";
2507 default:
2508 gcc_unreachable ();
2509 }
2510
2511 default:
2512 gcc_unreachable ();
2513 }
2514 }
2515 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2516 (set (attr "mode")
2517 (cond [(eq_attr "alternative" "0,1,2")
2518 (const_string "DF")
2519 (eq_attr "alternative" "3,4")
2520 (const_string "SI")
2521
2522 /* For SSE1, we have many fewer alternatives. */
2523 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2524 (cond [(eq_attr "alternative" "5,6")
2525 (const_string "V4SF")
2526 ]
2527 (const_string "V2SF"))
2528
2529 /* xorps is one byte shorter. */
2530 (eq_attr "alternative" "5")
2531 (cond [(ne (symbol_ref "optimize_size")
2532 (const_int 0))
2533 (const_string "V4SF")
2534 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2535 (const_int 0))
2536 (const_string "TI")
2537 ]
2538 (const_string "V2DF"))
2539
2540 /* For architectures resolving dependencies on
2541 whole SSE registers use APD move to break dependency
2542 chains, otherwise use short move to avoid extra work.
2543
2544 movaps encodes one byte shorter. */
2545 (eq_attr "alternative" "6")
2546 (cond
2547 [(ne (symbol_ref "optimize_size")
2548 (const_int 0))
2549 (const_string "V4SF")
2550 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2551 (const_int 0))
2552 (const_string "V2DF")
2553 ]
2554 (const_string "DF"))
2555 /* For architectures resolving dependencies on register
2556 parts we may avoid extra work to zero out upper part
2557 of register. */
2558 (eq_attr "alternative" "7")
2559 (if_then_else
2560 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2561 (const_int 0))
2562 (const_string "V1DF")
2563 (const_string "DF"))
2564 ]
2565 (const_string "DF")))])
2566
2567 (define_insn "*movdf_integer"
2568 [(set (match_operand:DF 0 "nonimmediate_operand"
2569 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2570 (match_operand:DF 1 "general_operand"
2571 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2572 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2573 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2574 && (reload_in_progress || reload_completed
2575 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2576 || GET_CODE (operands[1]) != CONST_DOUBLE
2577 || memory_operand (operands[0], DFmode))"
2578 {
2579 switch (which_alternative)
2580 {
2581 case 0:
2582 return output_387_reg_move (insn, operands);
2583
2584 case 1:
2585 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2586 return "fstp%z0\t%y0";
2587 else
2588 return "fst%z0\t%y0";
2589
2590 case 2:
2591 return standard_80387_constant_opcode (operands[1]);
2592
2593 case 3:
2594 case 4:
2595 return "#";
2596
2597 case 5:
2598 switch (get_attr_mode (insn))
2599 {
2600 case MODE_V4SF:
2601 return "xorps\t%0, %0";
2602 case MODE_V2DF:
2603 return "xorpd\t%0, %0";
2604 case MODE_TI:
2605 return "pxor\t%0, %0";
2606 default:
2607 gcc_unreachable ();
2608 }
2609 case 6:
2610 case 7:
2611 case 8:
2612 switch (get_attr_mode (insn))
2613 {
2614 case MODE_V4SF:
2615 return "movaps\t{%1, %0|%0, %1}";
2616 case MODE_V2DF:
2617 return "movapd\t{%1, %0|%0, %1}";
2618 case MODE_TI:
2619 return "movdqa\t{%1, %0|%0, %1}";
2620 case MODE_DI:
2621 return "movq\t{%1, %0|%0, %1}";
2622 case MODE_DF:
2623 return "movsd\t{%1, %0|%0, %1}";
2624 case MODE_V1DF:
2625 return "movlpd\t{%1, %0|%0, %1}";
2626 case MODE_V2SF:
2627 return "movlps\t{%1, %0|%0, %1}";
2628 default:
2629 gcc_unreachable ();
2630 }
2631
2632 default:
2633 gcc_unreachable();
2634 }
2635 }
2636 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2637 (set (attr "mode")
2638 (cond [(eq_attr "alternative" "0,1,2")
2639 (const_string "DF")
2640 (eq_attr "alternative" "3,4")
2641 (const_string "SI")
2642
2643 /* For SSE1, we have many fewer alternatives. */
2644 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2645 (cond [(eq_attr "alternative" "5,6")
2646 (const_string "V4SF")
2647 ]
2648 (const_string "V2SF"))
2649
2650 /* xorps is one byte shorter. */
2651 (eq_attr "alternative" "5")
2652 (cond [(ne (symbol_ref "optimize_size")
2653 (const_int 0))
2654 (const_string "V4SF")
2655 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2656 (const_int 0))
2657 (const_string "TI")
2658 ]
2659 (const_string "V2DF"))
2660
2661 /* For architectures resolving dependencies on
2662 whole SSE registers use APD move to break dependency
2663 chains, otherwise use short move to avoid extra work.
2664
2665 movaps encodes one byte shorter. */
2666 (eq_attr "alternative" "6")
2667 (cond
2668 [(ne (symbol_ref "optimize_size")
2669 (const_int 0))
2670 (const_string "V4SF")
2671 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2672 (const_int 0))
2673 (const_string "V2DF")
2674 ]
2675 (const_string "DF"))
2676 /* For architectures resolving dependencies on register
2677 parts we may avoid extra work to zero out upper part
2678 of register. */
2679 (eq_attr "alternative" "7")
2680 (if_then_else
2681 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2682 (const_int 0))
2683 (const_string "V1DF")
2684 (const_string "DF"))
2685 ]
2686 (const_string "DF")))])
2687
2688 (define_split
2689 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2690 (match_operand:DF 1 "general_operand" ""))]
2691 "reload_completed
2692 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2693 && ! (ANY_FP_REG_P (operands[0]) ||
2694 (GET_CODE (operands[0]) == SUBREG
2695 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2696 && ! (ANY_FP_REG_P (operands[1]) ||
2697 (GET_CODE (operands[1]) == SUBREG
2698 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2699 [(const_int 0)]
2700 "ix86_split_long_move (operands); DONE;")
2701
2702 (define_insn "*swapdf"
2703 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2704 (match_operand:DF 1 "fp_register_operand" "+f"))
2705 (set (match_dup 1)
2706 (match_dup 0))]
2707 "reload_completed || TARGET_80387"
2708 {
2709 if (STACK_TOP_P (operands[0]))
2710 return "fxch\t%1";
2711 else
2712 return "fxch\t%0";
2713 }
2714 [(set_attr "type" "fxch")
2715 (set_attr "mode" "DF")])
2716
2717 (define_expand "movxf"
2718 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2719 (match_operand:XF 1 "general_operand" ""))]
2720 ""
2721 "ix86_expand_move (XFmode, operands); DONE;")
2722
2723 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2724 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2725 ;; Pushing using integer instructions is longer except for constants
2726 ;; and direct memory references.
2727 ;; (assuming that any given constant is pushed only once, but this ought to be
2728 ;; handled elsewhere).
2729
2730 (define_insn "*pushxf_nointeger"
2731 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2732 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2733 "optimize_size"
2734 {
2735 /* This insn should be already split before reg-stack. */
2736 gcc_unreachable ();
2737 }
2738 [(set_attr "type" "multi")
2739 (set_attr "unit" "i387,*,*")
2740 (set_attr "mode" "XF,SI,SI")])
2741
2742 (define_insn "*pushxf_integer"
2743 [(set (match_operand:XF 0 "push_operand" "=<,<")
2744 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2745 "!optimize_size"
2746 {
2747 /* This insn should be already split before reg-stack. */
2748 gcc_unreachable ();
2749 }
2750 [(set_attr "type" "multi")
2751 (set_attr "unit" "i387,*")
2752 (set_attr "mode" "XF,SI")])
2753
2754 (define_split
2755 [(set (match_operand 0 "push_operand" "")
2756 (match_operand 1 "general_operand" ""))]
2757 "reload_completed
2758 && (GET_MODE (operands[0]) == XFmode
2759 || GET_MODE (operands[0]) == DFmode)
2760 && !ANY_FP_REG_P (operands[1])"
2761 [(const_int 0)]
2762 "ix86_split_long_move (operands); DONE;")
2763
2764 (define_split
2765 [(set (match_operand:XF 0 "push_operand" "")
2766 (match_operand:XF 1 "any_fp_register_operand" ""))]
2767 "!TARGET_64BIT"
2768 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2769 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2770 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2771
2772 (define_split
2773 [(set (match_operand:XF 0 "push_operand" "")
2774 (match_operand:XF 1 "any_fp_register_operand" ""))]
2775 "TARGET_64BIT"
2776 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2777 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2778 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2779
2780 ;; Do not use integer registers when optimizing for size
2781 (define_insn "*movxf_nointeger"
2782 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2783 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2784 "optimize_size
2785 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2786 && (reload_in_progress || reload_completed
2787 || GET_CODE (operands[1]) != CONST_DOUBLE
2788 || memory_operand (operands[0], XFmode))"
2789 {
2790 switch (which_alternative)
2791 {
2792 case 0:
2793 return output_387_reg_move (insn, operands);
2794
2795 case 1:
2796 /* There is no non-popping store to memory for XFmode. So if
2797 we need one, follow the store with a load. */
2798 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2799 return "fstp%z0\t%y0\;fld%z0\t%y0";
2800 else
2801 return "fstp%z0\t%y0";
2802
2803 case 2:
2804 return standard_80387_constant_opcode (operands[1]);
2805
2806 case 3: case 4:
2807 return "#";
2808 default:
2809 gcc_unreachable ();
2810 }
2811 }
2812 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2813 (set_attr "mode" "XF,XF,XF,SI,SI")])
2814
2815 (define_insn "*movxf_integer"
2816 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2817 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2818 "!optimize_size
2819 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2820 && (reload_in_progress || reload_completed
2821 || GET_CODE (operands[1]) != CONST_DOUBLE
2822 || memory_operand (operands[0], XFmode))"
2823 {
2824 switch (which_alternative)
2825 {
2826 case 0:
2827 return output_387_reg_move (insn, operands);
2828
2829 case 1:
2830 /* There is no non-popping store to memory for XFmode. So if
2831 we need one, follow the store with a load. */
2832 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2833 return "fstp%z0\t%y0\;fld%z0\t%y0";
2834 else
2835 return "fstp%z0\t%y0";
2836
2837 case 2:
2838 return standard_80387_constant_opcode (operands[1]);
2839
2840 case 3: case 4:
2841 return "#";
2842
2843 default:
2844 gcc_unreachable ();
2845 }
2846 }
2847 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2848 (set_attr "mode" "XF,XF,XF,SI,SI")])
2849
2850 (define_split
2851 [(set (match_operand 0 "nonimmediate_operand" "")
2852 (match_operand 1 "general_operand" ""))]
2853 "reload_completed
2854 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2855 && GET_MODE (operands[0]) == XFmode
2856 && ! (ANY_FP_REG_P (operands[0]) ||
2857 (GET_CODE (operands[0]) == SUBREG
2858 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2859 && ! (ANY_FP_REG_P (operands[1]) ||
2860 (GET_CODE (operands[1]) == SUBREG
2861 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2862 [(const_int 0)]
2863 "ix86_split_long_move (operands); DONE;")
2864
2865 (define_split
2866 [(set (match_operand 0 "register_operand" "")
2867 (match_operand 1 "memory_operand" ""))]
2868 "reload_completed
2869 && GET_CODE (operands[1]) == MEM
2870 && (GET_MODE (operands[0]) == XFmode
2871 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2872 && constant_pool_reference_p (operands[1])"
2873 [(set (match_dup 0) (match_dup 1))]
2874 {
2875 rtx c = avoid_constant_pool_reference (operands[1]);
2876 rtx r = operands[0];
2877
2878 if (GET_CODE (r) == SUBREG)
2879 r = SUBREG_REG (r);
2880
2881 if (SSE_REG_P (r))
2882 {
2883 if (!standard_sse_constant_p (c))
2884 FAIL;
2885 }
2886 else if (FP_REG_P (r))
2887 {
2888 if (!standard_80387_constant_p (c))
2889 FAIL;
2890 }
2891 else if (MMX_REG_P (r))
2892 FAIL;
2893
2894 operands[1] = c;
2895 })
2896
2897 (define_insn "swapxf"
2898 [(set (match_operand:XF 0 "register_operand" "+f")
2899 (match_operand:XF 1 "register_operand" "+f"))
2900 (set (match_dup 1)
2901 (match_dup 0))]
2902 "TARGET_80387"
2903 {
2904 if (STACK_TOP_P (operands[0]))
2905 return "fxch\t%1";
2906 else
2907 return "fxch\t%0";
2908 }
2909 [(set_attr "type" "fxch")
2910 (set_attr "mode" "XF")])
2911
2912 (define_expand "movtf"
2913 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2914 (match_operand:TF 1 "nonimmediate_operand" ""))]
2915 "TARGET_64BIT"
2916 {
2917 ix86_expand_move (TFmode, operands);
2918 DONE;
2919 })
2920
2921 (define_insn "*movtf_internal"
2922 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2923 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2924 "TARGET_64BIT
2925 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2926 {
2927 switch (which_alternative)
2928 {
2929 case 0:
2930 case 1:
2931 return "#";
2932 case 2:
2933 if (get_attr_mode (insn) == MODE_V4SF)
2934 return "xorps\t%0, %0";
2935 else
2936 return "pxor\t%0, %0";
2937 case 3:
2938 case 4:
2939 if (get_attr_mode (insn) == MODE_V4SF)
2940 return "movaps\t{%1, %0|%0, %1}";
2941 else
2942 return "movdqa\t{%1, %0|%0, %1}";
2943 default:
2944 gcc_unreachable ();
2945 }
2946 }
2947 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2948 (set (attr "mode")
2949 (cond [(eq_attr "alternative" "2,3")
2950 (if_then_else
2951 (ne (symbol_ref "optimize_size")
2952 (const_int 0))
2953 (const_string "V4SF")
2954 (const_string "TI"))
2955 (eq_attr "alternative" "4")
2956 (if_then_else
2957 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2958 (const_int 0))
2959 (ne (symbol_ref "optimize_size")
2960 (const_int 0)))
2961 (const_string "V4SF")
2962 (const_string "TI"))]
2963 (const_string "DI")))])
2964
2965 (define_split
2966 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2967 (match_operand:TF 1 "general_operand" ""))]
2968 "reload_completed && !SSE_REG_P (operands[0])
2969 && !SSE_REG_P (operands[1])"
2970 [(const_int 0)]
2971 "ix86_split_long_move (operands); DONE;")
2972 \f
2973 ;; Zero extension instructions
2974
2975 (define_expand "zero_extendhisi2"
2976 [(set (match_operand:SI 0 "register_operand" "")
2977 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2978 ""
2979 {
2980 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2981 {
2982 operands[1] = force_reg (HImode, operands[1]);
2983 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2984 DONE;
2985 }
2986 })
2987
2988 (define_insn "zero_extendhisi2_and"
2989 [(set (match_operand:SI 0 "register_operand" "=r")
2990 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2991 (clobber (reg:CC FLAGS_REG))]
2992 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2993 "#"
2994 [(set_attr "type" "alu1")
2995 (set_attr "mode" "SI")])
2996
2997 (define_split
2998 [(set (match_operand:SI 0 "register_operand" "")
2999 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3000 (clobber (reg:CC FLAGS_REG))]
3001 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3002 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3003 (clobber (reg:CC FLAGS_REG))])]
3004 "")
3005
3006 (define_insn "*zero_extendhisi2_movzwl"
3007 [(set (match_operand:SI 0 "register_operand" "=r")
3008 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3009 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3010 "movz{wl|x}\t{%1, %0|%0, %1}"
3011 [(set_attr "type" "imovx")
3012 (set_attr "mode" "SI")])
3013
3014 (define_expand "zero_extendqihi2"
3015 [(parallel
3016 [(set (match_operand:HI 0 "register_operand" "")
3017 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3018 (clobber (reg:CC FLAGS_REG))])]
3019 ""
3020 "")
3021
3022 (define_insn "*zero_extendqihi2_and"
3023 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3024 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3025 (clobber (reg:CC FLAGS_REG))]
3026 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3027 "#"
3028 [(set_attr "type" "alu1")
3029 (set_attr "mode" "HI")])
3030
3031 (define_insn "*zero_extendqihi2_movzbw_and"
3032 [(set (match_operand:HI 0 "register_operand" "=r,r")
3033 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3034 (clobber (reg:CC FLAGS_REG))]
3035 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3036 "#"
3037 [(set_attr "type" "imovx,alu1")
3038 (set_attr "mode" "HI")])
3039
3040 ; zero extend to SImode here to avoid partial register stalls
3041 (define_insn "*zero_extendqihi2_movzbl"
3042 [(set (match_operand:HI 0 "register_operand" "=r")
3043 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3044 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3045 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3046 [(set_attr "type" "imovx")
3047 (set_attr "mode" "SI")])
3048
3049 ;; For the movzbw case strip only the clobber
3050 (define_split
3051 [(set (match_operand:HI 0 "register_operand" "")
3052 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3053 (clobber (reg:CC FLAGS_REG))]
3054 "reload_completed
3055 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3056 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3057 [(set (match_operand:HI 0 "register_operand" "")
3058 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3059
3060 ;; When source and destination does not overlap, clear destination
3061 ;; first and then do the movb
3062 (define_split
3063 [(set (match_operand:HI 0 "register_operand" "")
3064 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3065 (clobber (reg:CC FLAGS_REG))]
3066 "reload_completed
3067 && ANY_QI_REG_P (operands[0])
3068 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3069 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3070 [(set (match_dup 0) (const_int 0))
3071 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3072 "operands[2] = gen_lowpart (QImode, operands[0]);")
3073
3074 ;; Rest is handled by single and.
3075 (define_split
3076 [(set (match_operand:HI 0 "register_operand" "")
3077 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3078 (clobber (reg:CC FLAGS_REG))]
3079 "reload_completed
3080 && true_regnum (operands[0]) == true_regnum (operands[1])"
3081 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3082 (clobber (reg:CC FLAGS_REG))])]
3083 "")
3084
3085 (define_expand "zero_extendqisi2"
3086 [(parallel
3087 [(set (match_operand:SI 0 "register_operand" "")
3088 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3089 (clobber (reg:CC FLAGS_REG))])]
3090 ""
3091 "")
3092
3093 (define_insn "*zero_extendqisi2_and"
3094 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3095 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3096 (clobber (reg:CC FLAGS_REG))]
3097 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3098 "#"
3099 [(set_attr "type" "alu1")
3100 (set_attr "mode" "SI")])
3101
3102 (define_insn "*zero_extendqisi2_movzbw_and"
3103 [(set (match_operand:SI 0 "register_operand" "=r,r")
3104 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3105 (clobber (reg:CC FLAGS_REG))]
3106 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3107 "#"
3108 [(set_attr "type" "imovx,alu1")
3109 (set_attr "mode" "SI")])
3110
3111 (define_insn "*zero_extendqisi2_movzbw"
3112 [(set (match_operand:SI 0 "register_operand" "=r")
3113 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3114 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3115 "movz{bl|x}\t{%1, %0|%0, %1}"
3116 [(set_attr "type" "imovx")
3117 (set_attr "mode" "SI")])
3118
3119 ;; For the movzbl case strip only the clobber
3120 (define_split
3121 [(set (match_operand:SI 0 "register_operand" "")
3122 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3123 (clobber (reg:CC FLAGS_REG))]
3124 "reload_completed
3125 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3126 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3127 [(set (match_dup 0)
3128 (zero_extend:SI (match_dup 1)))])
3129
3130 ;; When source and destination does not overlap, clear destination
3131 ;; first and then do the movb
3132 (define_split
3133 [(set (match_operand:SI 0 "register_operand" "")
3134 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3135 (clobber (reg:CC FLAGS_REG))]
3136 "reload_completed
3137 && ANY_QI_REG_P (operands[0])
3138 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3139 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3140 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3141 [(set (match_dup 0) (const_int 0))
3142 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3143 "operands[2] = gen_lowpart (QImode, operands[0]);")
3144
3145 ;; Rest is handled by single and.
3146 (define_split
3147 [(set (match_operand:SI 0 "register_operand" "")
3148 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3149 (clobber (reg:CC FLAGS_REG))]
3150 "reload_completed
3151 && true_regnum (operands[0]) == true_regnum (operands[1])"
3152 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3153 (clobber (reg:CC FLAGS_REG))])]
3154 "")
3155
3156 ;; %%% Kill me once multi-word ops are sane.
3157 (define_expand "zero_extendsidi2"
3158 [(set (match_operand:DI 0 "register_operand" "=r")
3159 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3160 ""
3161 "if (!TARGET_64BIT)
3162 {
3163 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3164 DONE;
3165 }
3166 ")
3167
3168 (define_insn "zero_extendsidi2_32"
3169 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3170 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3171 (clobber (reg:CC FLAGS_REG))]
3172 "!TARGET_64BIT"
3173 "@
3174 #
3175 #
3176 #
3177 movd\t{%1, %0|%0, %1}
3178 movd\t{%1, %0|%0, %1}"
3179 [(set_attr "mode" "SI,SI,SI,DI,TI")
3180 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3181
3182 (define_insn "zero_extendsidi2_rex64"
3183 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3184 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3185 "TARGET_64BIT"
3186 "@
3187 mov\t{%k1, %k0|%k0, %k1}
3188 #
3189 movd\t{%1, %0|%0, %1}
3190 movd\t{%1, %0|%0, %1}"
3191 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3192 (set_attr "mode" "SI,DI,SI,SI")])
3193
3194 (define_split
3195 [(set (match_operand:DI 0 "memory_operand" "")
3196 (zero_extend:DI (match_dup 0)))]
3197 "TARGET_64BIT"
3198 [(set (match_dup 4) (const_int 0))]
3199 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3200
3201 (define_split
3202 [(set (match_operand:DI 0 "register_operand" "")
3203 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3204 (clobber (reg:CC FLAGS_REG))]
3205 "!TARGET_64BIT && reload_completed
3206 && true_regnum (operands[0]) == true_regnum (operands[1])"
3207 [(set (match_dup 4) (const_int 0))]
3208 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3209
3210 (define_split
3211 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3212 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3213 (clobber (reg:CC FLAGS_REG))]
3214 "!TARGET_64BIT && reload_completed
3215 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3216 [(set (match_dup 3) (match_dup 1))
3217 (set (match_dup 4) (const_int 0))]
3218 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3219
3220 (define_insn "zero_extendhidi2"
3221 [(set (match_operand:DI 0 "register_operand" "=r")
3222 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3223 "TARGET_64BIT"
3224 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3225 [(set_attr "type" "imovx")
3226 (set_attr "mode" "DI")])
3227
3228 (define_insn "zero_extendqidi2"
3229 [(set (match_operand:DI 0 "register_operand" "=r")
3230 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3231 "TARGET_64BIT"
3232 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3233 [(set_attr "type" "imovx")
3234 (set_attr "mode" "DI")])
3235 \f
3236 ;; Sign extension instructions
3237
3238 (define_expand "extendsidi2"
3239 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3240 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3241 (clobber (reg:CC FLAGS_REG))
3242 (clobber (match_scratch:SI 2 ""))])]
3243 ""
3244 {
3245 if (TARGET_64BIT)
3246 {
3247 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3248 DONE;
3249 }
3250 })
3251
3252 (define_insn "*extendsidi2_1"
3253 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3254 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3255 (clobber (reg:CC FLAGS_REG))
3256 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3257 "!TARGET_64BIT"
3258 "#")
3259
3260 (define_insn "extendsidi2_rex64"
3261 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3262 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3263 "TARGET_64BIT"
3264 "@
3265 {cltq|cdqe}
3266 movs{lq|x}\t{%1,%0|%0, %1}"
3267 [(set_attr "type" "imovx")
3268 (set_attr "mode" "DI")
3269 (set_attr "prefix_0f" "0")
3270 (set_attr "modrm" "0,1")])
3271
3272 (define_insn "extendhidi2"
3273 [(set (match_operand:DI 0 "register_operand" "=r")
3274 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3275 "TARGET_64BIT"
3276 "movs{wq|x}\t{%1,%0|%0, %1}"
3277 [(set_attr "type" "imovx")
3278 (set_attr "mode" "DI")])
3279
3280 (define_insn "extendqidi2"
3281 [(set (match_operand:DI 0 "register_operand" "=r")
3282 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3283 "TARGET_64BIT"
3284 "movs{bq|x}\t{%1,%0|%0, %1}"
3285 [(set_attr "type" "imovx")
3286 (set_attr "mode" "DI")])
3287
3288 ;; Extend to memory case when source register does die.
3289 (define_split
3290 [(set (match_operand:DI 0 "memory_operand" "")
3291 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3292 (clobber (reg:CC FLAGS_REG))
3293 (clobber (match_operand:SI 2 "register_operand" ""))]
3294 "(reload_completed
3295 && dead_or_set_p (insn, operands[1])
3296 && !reg_mentioned_p (operands[1], operands[0]))"
3297 [(set (match_dup 3) (match_dup 1))
3298 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3299 (clobber (reg:CC FLAGS_REG))])
3300 (set (match_dup 4) (match_dup 1))]
3301 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3302
3303 ;; Extend to memory case when source register does not die.
3304 (define_split
3305 [(set (match_operand:DI 0 "memory_operand" "")
3306 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3307 (clobber (reg:CC FLAGS_REG))
3308 (clobber (match_operand:SI 2 "register_operand" ""))]
3309 "reload_completed"
3310 [(const_int 0)]
3311 {
3312 split_di (&operands[0], 1, &operands[3], &operands[4]);
3313
3314 emit_move_insn (operands[3], operands[1]);
3315
3316 /* Generate a cltd if possible and doing so it profitable. */
3317 if (true_regnum (operands[1]) == 0
3318 && true_regnum (operands[2]) == 1
3319 && (optimize_size || TARGET_USE_CLTD))
3320 {
3321 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3322 }
3323 else
3324 {
3325 emit_move_insn (operands[2], operands[1]);
3326 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3327 }
3328 emit_move_insn (operands[4], operands[2]);
3329 DONE;
3330 })
3331
3332 ;; Extend to register case. Optimize case where source and destination
3333 ;; registers match and cases where we can use cltd.
3334 (define_split
3335 [(set (match_operand:DI 0 "register_operand" "")
3336 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3337 (clobber (reg:CC FLAGS_REG))
3338 (clobber (match_scratch:SI 2 ""))]
3339 "reload_completed"
3340 [(const_int 0)]
3341 {
3342 split_di (&operands[0], 1, &operands[3], &operands[4]);
3343
3344 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3345 emit_move_insn (operands[3], operands[1]);
3346
3347 /* Generate a cltd if possible and doing so it profitable. */
3348 if (true_regnum (operands[3]) == 0
3349 && (optimize_size || TARGET_USE_CLTD))
3350 {
3351 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3352 DONE;
3353 }
3354
3355 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3356 emit_move_insn (operands[4], operands[1]);
3357
3358 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3359 DONE;
3360 })
3361
3362 (define_insn "extendhisi2"
3363 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3364 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3365 ""
3366 {
3367 switch (get_attr_prefix_0f (insn))
3368 {
3369 case 0:
3370 return "{cwtl|cwde}";
3371 default:
3372 return "movs{wl|x}\t{%1,%0|%0, %1}";
3373 }
3374 }
3375 [(set_attr "type" "imovx")
3376 (set_attr "mode" "SI")
3377 (set (attr "prefix_0f")
3378 ;; movsx is short decodable while cwtl is vector decoded.
3379 (if_then_else (and (eq_attr "cpu" "!k6")
3380 (eq_attr "alternative" "0"))
3381 (const_string "0")
3382 (const_string "1")))
3383 (set (attr "modrm")
3384 (if_then_else (eq_attr "prefix_0f" "0")
3385 (const_string "0")
3386 (const_string "1")))])
3387
3388 (define_insn "*extendhisi2_zext"
3389 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3390 (zero_extend:DI
3391 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3392 "TARGET_64BIT"
3393 {
3394 switch (get_attr_prefix_0f (insn))
3395 {
3396 case 0:
3397 return "{cwtl|cwde}";
3398 default:
3399 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3400 }
3401 }
3402 [(set_attr "type" "imovx")
3403 (set_attr "mode" "SI")
3404 (set (attr "prefix_0f")
3405 ;; movsx is short decodable while cwtl is vector decoded.
3406 (if_then_else (and (eq_attr "cpu" "!k6")
3407 (eq_attr "alternative" "0"))
3408 (const_string "0")
3409 (const_string "1")))
3410 (set (attr "modrm")
3411 (if_then_else (eq_attr "prefix_0f" "0")
3412 (const_string "0")
3413 (const_string "1")))])
3414
3415 (define_insn "extendqihi2"
3416 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3417 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3418 ""
3419 {
3420 switch (get_attr_prefix_0f (insn))
3421 {
3422 case 0:
3423 return "{cbtw|cbw}";
3424 default:
3425 return "movs{bw|x}\t{%1,%0|%0, %1}";
3426 }
3427 }
3428 [(set_attr "type" "imovx")
3429 (set_attr "mode" "HI")
3430 (set (attr "prefix_0f")
3431 ;; movsx is short decodable while cwtl is vector decoded.
3432 (if_then_else (and (eq_attr "cpu" "!k6")
3433 (eq_attr "alternative" "0"))
3434 (const_string "0")
3435 (const_string "1")))
3436 (set (attr "modrm")
3437 (if_then_else (eq_attr "prefix_0f" "0")
3438 (const_string "0")
3439 (const_string "1")))])
3440
3441 (define_insn "extendqisi2"
3442 [(set (match_operand:SI 0 "register_operand" "=r")
3443 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3444 ""
3445 "movs{bl|x}\t{%1,%0|%0, %1}"
3446 [(set_attr "type" "imovx")
3447 (set_attr "mode" "SI")])
3448
3449 (define_insn "*extendqisi2_zext"
3450 [(set (match_operand:DI 0 "register_operand" "=r")
3451 (zero_extend:DI
3452 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3453 "TARGET_64BIT"
3454 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3455 [(set_attr "type" "imovx")
3456 (set_attr "mode" "SI")])
3457 \f
3458 ;; Conversions between float and double.
3459
3460 ;; These are all no-ops in the model used for the 80387. So just
3461 ;; emit moves.
3462
3463 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3464 (define_insn "*dummy_extendsfdf2"
3465 [(set (match_operand:DF 0 "push_operand" "=<")
3466 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3467 "0"
3468 "#")
3469
3470 (define_split
3471 [(set (match_operand:DF 0 "push_operand" "")
3472 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3473 "!TARGET_64BIT"
3474 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3475 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3476
3477 (define_split
3478 [(set (match_operand:DF 0 "push_operand" "")
3479 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3480 "TARGET_64BIT"
3481 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3482 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3483
3484 (define_insn "*dummy_extendsfxf2"
3485 [(set (match_operand:XF 0 "push_operand" "=<")
3486 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3487 "0"
3488 "#")
3489
3490 (define_split
3491 [(set (match_operand:XF 0 "push_operand" "")
3492 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3493 ""
3494 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3495 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3496 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3497
3498 (define_split
3499 [(set (match_operand:XF 0 "push_operand" "")
3500 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3501 "TARGET_64BIT"
3502 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3503 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3504 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3505
3506 (define_split
3507 [(set (match_operand:XF 0 "push_operand" "")
3508 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3509 ""
3510 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3511 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3512 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3513
3514 (define_split
3515 [(set (match_operand:XF 0 "push_operand" "")
3516 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3517 "TARGET_64BIT"
3518 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3519 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3520 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3521
3522 (define_expand "extendsfdf2"
3523 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3524 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3525 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3526 {
3527 /* ??? Needed for compress_float_constant since all fp constants
3528 are LEGITIMATE_CONSTANT_P. */
3529 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3530 {
3531 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3532 && standard_80387_constant_p (operands[1]) > 0)
3533 {
3534 operands[1] = simplify_const_unary_operation
3535 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3536 emit_move_insn_1 (operands[0], operands[1]);
3537 DONE;
3538 }
3539 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3540 }
3541 })
3542
3543 (define_insn "*extendsfdf2_mixed"
3544 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3545 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3546 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3547 {
3548 switch (which_alternative)
3549 {
3550 case 0:
3551 return output_387_reg_move (insn, operands);
3552
3553 case 1:
3554 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3555 return "fstp%z0\t%y0";
3556 else
3557 return "fst%z0\t%y0";
3558
3559 case 2:
3560 return "cvtss2sd\t{%1, %0|%0, %1}";
3561
3562 default:
3563 gcc_unreachable ();
3564 }
3565 }
3566 [(set_attr "type" "fmov,fmov,ssecvt")
3567 (set_attr "mode" "SF,XF,DF")])
3568
3569 (define_insn "*extendsfdf2_sse"
3570 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3571 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3572 "TARGET_SSE2 && TARGET_SSE_MATH"
3573 "cvtss2sd\t{%1, %0|%0, %1}"
3574 [(set_attr "type" "ssecvt")
3575 (set_attr "mode" "DF")])
3576
3577 (define_insn "*extendsfdf2_i387"
3578 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3579 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3580 "TARGET_80387"
3581 {
3582 switch (which_alternative)
3583 {
3584 case 0:
3585 return output_387_reg_move (insn, operands);
3586
3587 case 1:
3588 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3589 return "fstp%z0\t%y0";
3590 else
3591 return "fst%z0\t%y0";
3592
3593 default:
3594 gcc_unreachable ();
3595 }
3596 }
3597 [(set_attr "type" "fmov")
3598 (set_attr "mode" "SF,XF")])
3599
3600 (define_expand "extendsfxf2"
3601 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3602 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3603 "TARGET_80387"
3604 {
3605 /* ??? Needed for compress_float_constant since all fp constants
3606 are LEGITIMATE_CONSTANT_P. */
3607 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3608 {
3609 if (standard_80387_constant_p (operands[1]) > 0)
3610 {
3611 operands[1] = simplify_const_unary_operation
3612 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3613 emit_move_insn_1 (operands[0], operands[1]);
3614 DONE;
3615 }
3616 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3617 }
3618 })
3619
3620 (define_insn "*extendsfxf2_i387"
3621 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3622 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3623 "TARGET_80387"
3624 {
3625 switch (which_alternative)
3626 {
3627 case 0:
3628 return output_387_reg_move (insn, operands);
3629
3630 case 1:
3631 /* There is no non-popping store to memory for XFmode. So if
3632 we need one, follow the store with a load. */
3633 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3634 return "fstp%z0\t%y0";
3635 else
3636 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3637
3638 default:
3639 gcc_unreachable ();
3640 }
3641 }
3642 [(set_attr "type" "fmov")
3643 (set_attr "mode" "SF,XF")])
3644
3645 (define_expand "extenddfxf2"
3646 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3647 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3648 "TARGET_80387"
3649 {
3650 /* ??? Needed for compress_float_constant since all fp constants
3651 are LEGITIMATE_CONSTANT_P. */
3652 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3653 {
3654 if (standard_80387_constant_p (operands[1]) > 0)
3655 {
3656 operands[1] = simplify_const_unary_operation
3657 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3658 emit_move_insn_1 (operands[0], operands[1]);
3659 DONE;
3660 }
3661 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3662 }
3663 })
3664
3665 (define_insn "*extenddfxf2_i387"
3666 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3667 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3668 "TARGET_80387"
3669 {
3670 switch (which_alternative)
3671 {
3672 case 0:
3673 return output_387_reg_move (insn, operands);
3674
3675 case 1:
3676 /* There is no non-popping store to memory for XFmode. So if
3677 we need one, follow the store with a load. */
3678 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3679 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3680 else
3681 return "fstp%z0\t%y0";
3682
3683 default:
3684 gcc_unreachable ();
3685 }
3686 }
3687 [(set_attr "type" "fmov")
3688 (set_attr "mode" "DF,XF")])
3689
3690 ;; %%% This seems bad bad news.
3691 ;; This cannot output into an f-reg because there is no way to be sure
3692 ;; of truncating in that case. Otherwise this is just like a simple move
3693 ;; insn. So we pretend we can output to a reg in order to get better
3694 ;; register preferencing, but we really use a stack slot.
3695
3696 ;; Conversion from DFmode to SFmode.
3697
3698 (define_expand "truncdfsf2"
3699 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3700 (float_truncate:SF
3701 (match_operand:DF 1 "nonimmediate_operand" "")))]
3702 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3703 {
3704 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3705 ;
3706 else if (flag_unsafe_math_optimizations)
3707 ;
3708 else
3709 {
3710 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3711 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3712 DONE;
3713 }
3714 })
3715
3716 (define_expand "truncdfsf2_with_temp"
3717 [(parallel [(set (match_operand:SF 0 "" "")
3718 (float_truncate:SF (match_operand:DF 1 "" "")))
3719 (clobber (match_operand:SF 2 "" ""))])]
3720 "")
3721
3722 (define_insn "*truncdfsf_fast_mixed"
3723 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3724 (float_truncate:SF
3725 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3726 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3727 {
3728 switch (which_alternative)
3729 {
3730 case 0:
3731 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3732 return "fstp%z0\t%y0";
3733 else
3734 return "fst%z0\t%y0";
3735 case 1:
3736 return output_387_reg_move (insn, operands);
3737 case 2:
3738 return "cvtsd2ss\t{%1, %0|%0, %1}";
3739 default:
3740 gcc_unreachable ();
3741 }
3742 }
3743 [(set_attr "type" "fmov,fmov,ssecvt")
3744 (set_attr "mode" "SF")])
3745
3746 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3747 ;; because nothing we do here is unsafe.
3748 (define_insn "*truncdfsf_fast_sse"
3749 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3750 (float_truncate:SF
3751 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3752 "TARGET_SSE2 && TARGET_SSE_MATH"
3753 "cvtsd2ss\t{%1, %0|%0, %1}"
3754 [(set_attr "type" "ssecvt")
3755 (set_attr "mode" "SF")])
3756
3757 (define_insn "*truncdfsf_fast_i387"
3758 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3759 (float_truncate:SF
3760 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3761 "TARGET_80387 && flag_unsafe_math_optimizations"
3762 "* return output_387_reg_move (insn, operands);"
3763 [(set_attr "type" "fmov")
3764 (set_attr "mode" "SF")])
3765
3766 (define_insn "*truncdfsf_mixed"
3767 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3768 (float_truncate:SF
3769 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3770 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3771 "TARGET_MIX_SSE_I387"
3772 {
3773 switch (which_alternative)
3774 {
3775 case 0:
3776 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3777 return "fstp%z0\t%y0";
3778 else
3779 return "fst%z0\t%y0";
3780 case 1:
3781 return "#";
3782 case 2:
3783 return "cvtsd2ss\t{%1, %0|%0, %1}";
3784 default:
3785 gcc_unreachable ();
3786 }
3787 }
3788 [(set_attr "type" "fmov,multi,ssecvt")
3789 (set_attr "unit" "*,i387,*")
3790 (set_attr "mode" "SF")])
3791
3792 (define_insn "*truncdfsf_i387"
3793 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3794 (float_truncate:SF
3795 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3796 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3797 "TARGET_80387"
3798 {
3799 switch (which_alternative)
3800 {
3801 case 0:
3802 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3803 return "fstp%z0\t%y0";
3804 else
3805 return "fst%z0\t%y0";
3806 case 1:
3807 return "#";
3808 default:
3809 gcc_unreachable ();
3810 }
3811 }
3812 [(set_attr "type" "fmov,multi")
3813 (set_attr "unit" "*,i387")
3814 (set_attr "mode" "SF")])
3815
3816 (define_insn "*truncdfsf2_i387_1"
3817 [(set (match_operand:SF 0 "memory_operand" "=m")
3818 (float_truncate:SF
3819 (match_operand:DF 1 "register_operand" "f")))]
3820 "TARGET_80387
3821 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3822 && !TARGET_MIX_SSE_I387"
3823 {
3824 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3825 return "fstp%z0\t%y0";
3826 else
3827 return "fst%z0\t%y0";
3828 }
3829 [(set_attr "type" "fmov")
3830 (set_attr "mode" "SF")])
3831
3832 (define_split
3833 [(set (match_operand:SF 0 "register_operand" "")
3834 (float_truncate:SF
3835 (match_operand:DF 1 "fp_register_operand" "")))
3836 (clobber (match_operand 2 "" ""))]
3837 "reload_completed"
3838 [(set (match_dup 2) (match_dup 1))
3839 (set (match_dup 0) (match_dup 2))]
3840 {
3841 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3842 })
3843
3844 ;; Conversion from XFmode to SFmode.
3845
3846 (define_expand "truncxfsf2"
3847 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3848 (float_truncate:SF
3849 (match_operand:XF 1 "register_operand" "")))
3850 (clobber (match_dup 2))])]
3851 "TARGET_80387"
3852 {
3853 if (flag_unsafe_math_optimizations)
3854 {
3855 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3856 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3857 if (reg != operands[0])
3858 emit_move_insn (operands[0], reg);
3859 DONE;
3860 }
3861 else
3862 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3863 })
3864
3865 (define_insn "*truncxfsf2_mixed"
3866 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3867 (float_truncate:SF
3868 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3869 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3870 "TARGET_MIX_SSE_I387"
3871 {
3872 gcc_assert (!which_alternative);
3873 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3874 return "fstp%z0\t%y0";
3875 else
3876 return "fst%z0\t%y0";
3877 }
3878 [(set_attr "type" "fmov,multi,multi,multi")
3879 (set_attr "unit" "*,i387,i387,i387")
3880 (set_attr "mode" "SF")])
3881
3882 (define_insn "truncxfsf2_i387_noop"
3883 [(set (match_operand:SF 0 "register_operand" "=f")
3884 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3885 "TARGET_80387 && flag_unsafe_math_optimizations"
3886 {
3887 return output_387_reg_move (insn, operands);
3888 }
3889 [(set_attr "type" "fmov")
3890 (set_attr "mode" "SF")])
3891
3892 (define_insn "*truncxfsf2_i387"
3893 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3894 (float_truncate:SF
3895 (match_operand:XF 1 "register_operand" "f,f,f")))
3896 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3897 "TARGET_80387"
3898 {
3899 gcc_assert (!which_alternative);
3900 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3901 return "fstp%z0\t%y0";
3902 else
3903 return "fst%z0\t%y0";
3904 }
3905 [(set_attr "type" "fmov,multi,multi")
3906 (set_attr "unit" "*,i387,i387")
3907 (set_attr "mode" "SF")])
3908
3909 (define_insn "*truncxfsf2_i387_1"
3910 [(set (match_operand:SF 0 "memory_operand" "=m")
3911 (float_truncate:SF
3912 (match_operand:XF 1 "register_operand" "f")))]
3913 "TARGET_80387"
3914 {
3915 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3916 return "fstp%z0\t%y0";
3917 else
3918 return "fst%z0\t%y0";
3919 }
3920 [(set_attr "type" "fmov")
3921 (set_attr "mode" "SF")])
3922
3923 (define_split
3924 [(set (match_operand:SF 0 "register_operand" "")
3925 (float_truncate:SF
3926 (match_operand:XF 1 "register_operand" "")))
3927 (clobber (match_operand:SF 2 "memory_operand" ""))]
3928 "TARGET_80387 && reload_completed"
3929 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3930 (set (match_dup 0) (match_dup 2))]
3931 "")
3932
3933 (define_split
3934 [(set (match_operand:SF 0 "memory_operand" "")
3935 (float_truncate:SF
3936 (match_operand:XF 1 "register_operand" "")))
3937 (clobber (match_operand:SF 2 "memory_operand" ""))]
3938 "TARGET_80387"
3939 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3940 "")
3941
3942 ;; Conversion from XFmode to DFmode.
3943
3944 (define_expand "truncxfdf2"
3945 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3946 (float_truncate:DF
3947 (match_operand:XF 1 "register_operand" "")))
3948 (clobber (match_dup 2))])]
3949 "TARGET_80387"
3950 {
3951 if (flag_unsafe_math_optimizations)
3952 {
3953 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3954 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3955 if (reg != operands[0])
3956 emit_move_insn (operands[0], reg);
3957 DONE;
3958 }
3959 else
3960 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3961 })
3962
3963 (define_insn "*truncxfdf2_mixed"
3964 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3965 (float_truncate:DF
3966 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3967 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3968 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3969 {
3970 gcc_assert (!which_alternative);
3971 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3972 return "fstp%z0\t%y0";
3973 else
3974 return "fst%z0\t%y0";
3975 }
3976 [(set_attr "type" "fmov,multi,multi,multi")
3977 (set_attr "unit" "*,i387,i387,i387")
3978 (set_attr "mode" "DF")])
3979
3980 (define_insn "truncxfdf2_i387_noop"
3981 [(set (match_operand:DF 0 "register_operand" "=f")
3982 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3983 "TARGET_80387 && flag_unsafe_math_optimizations"
3984 {
3985 return output_387_reg_move (insn, operands);
3986 }
3987 [(set_attr "type" "fmov")
3988 (set_attr "mode" "DF")])
3989
3990 (define_insn "*truncxfdf2_i387"
3991 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
3992 (float_truncate:DF
3993 (match_operand:XF 1 "register_operand" "f,f,f")))
3994 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3995 "TARGET_80387"
3996 {
3997 gcc_assert (!which_alternative);
3998 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3999 return "fstp%z0\t%y0";
4000 else
4001 return "fst%z0\t%y0";
4002 }
4003 [(set_attr "type" "fmov,multi,multi")
4004 (set_attr "unit" "*,i387,i387")
4005 (set_attr "mode" "DF")])
4006
4007 (define_insn "*truncxfdf2_i387_1"
4008 [(set (match_operand:DF 0 "memory_operand" "=m")
4009 (float_truncate:DF
4010 (match_operand:XF 1 "register_operand" "f")))]
4011 "TARGET_80387"
4012 {
4013 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4014 return "fstp%z0\t%y0";
4015 else
4016 return "fst%z0\t%y0";
4017 }
4018 [(set_attr "type" "fmov")
4019 (set_attr "mode" "DF")])
4020
4021 (define_split
4022 [(set (match_operand:DF 0 "register_operand" "")
4023 (float_truncate:DF
4024 (match_operand:XF 1 "register_operand" "")))
4025 (clobber (match_operand:DF 2 "memory_operand" ""))]
4026 "TARGET_80387 && reload_completed"
4027 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4028 (set (match_dup 0) (match_dup 2))]
4029 "")
4030
4031 (define_split
4032 [(set (match_operand:DF 0 "memory_operand" "")
4033 (float_truncate:DF
4034 (match_operand:XF 1 "register_operand" "")))
4035 (clobber (match_operand:DF 2 "memory_operand" ""))]
4036 "TARGET_80387"
4037 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4038 "")
4039 \f
4040 ;; Signed conversion to DImode.
4041
4042 (define_expand "fix_truncxfdi2"
4043 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4044 (fix:DI (match_operand:XF 1 "register_operand" "")))
4045 (clobber (reg:CC FLAGS_REG))])]
4046 "TARGET_80387"
4047 {
4048 if (TARGET_FISTTP)
4049 {
4050 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4051 DONE;
4052 }
4053 })
4054
4055 (define_expand "fix_trunc<mode>di2"
4056 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4057 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4058 (clobber (reg:CC FLAGS_REG))])]
4059 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4060 {
4061 if (TARGET_FISTTP
4062 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4063 {
4064 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4065 DONE;
4066 }
4067 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4068 {
4069 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4070 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4071 if (out != operands[0])
4072 emit_move_insn (operands[0], out);
4073 DONE;
4074 }
4075 })
4076
4077 ;; Signed conversion to SImode.
4078
4079 (define_expand "fix_truncxfsi2"
4080 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4081 (fix:SI (match_operand:XF 1 "register_operand" "")))
4082 (clobber (reg:CC FLAGS_REG))])]
4083 "TARGET_80387"
4084 {
4085 if (TARGET_FISTTP)
4086 {
4087 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4088 DONE;
4089 }
4090 })
4091
4092 (define_expand "fix_trunc<mode>si2"
4093 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4094 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4095 (clobber (reg:CC FLAGS_REG))])]
4096 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4097 {
4098 if (TARGET_FISTTP
4099 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4100 {
4101 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4102 DONE;
4103 }
4104 if (SSE_FLOAT_MODE_P (<MODE>mode))
4105 {
4106 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4107 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4108 if (out != operands[0])
4109 emit_move_insn (operands[0], out);
4110 DONE;
4111 }
4112 })
4113
4114 ;; Signed conversion to HImode.
4115
4116 (define_expand "fix_trunc<mode>hi2"
4117 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4118 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4119 (clobber (reg:CC FLAGS_REG))])]
4120 "TARGET_80387
4121 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4122 {
4123 if (TARGET_FISTTP)
4124 {
4125 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4126 DONE;
4127 }
4128 })
4129
4130 ;; When SSE is available, it is always faster to use it!
4131 (define_insn "fix_truncsfdi_sse"
4132 [(set (match_operand:DI 0 "register_operand" "=r,r")
4133 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4134 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4135 "cvttss2si{q}\t{%1, %0|%0, %1}"
4136 [(set_attr "type" "sseicvt")
4137 (set_attr "mode" "SF")
4138 (set_attr "athlon_decode" "double,vector")])
4139
4140 (define_insn "fix_truncdfdi_sse"
4141 [(set (match_operand:DI 0 "register_operand" "=r,r")
4142 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4143 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4144 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4145 [(set_attr "type" "sseicvt")
4146 (set_attr "mode" "DF")
4147 (set_attr "athlon_decode" "double,vector")])
4148
4149 (define_insn "fix_truncsfsi_sse"
4150 [(set (match_operand:SI 0 "register_operand" "=r,r")
4151 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4152 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4153 "cvttss2si\t{%1, %0|%0, %1}"
4154 [(set_attr "type" "sseicvt")
4155 (set_attr "mode" "DF")
4156 (set_attr "athlon_decode" "double,vector")])
4157
4158 (define_insn "fix_truncdfsi_sse"
4159 [(set (match_operand:SI 0 "register_operand" "=r,r")
4160 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4161 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4162 "cvttsd2si\t{%1, %0|%0, %1}"
4163 [(set_attr "type" "sseicvt")
4164 (set_attr "mode" "DF")
4165 (set_attr "athlon_decode" "double,vector")])
4166
4167 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4168 (define_peephole2
4169 [(set (match_operand:DF 0 "register_operand" "")
4170 (match_operand:DF 1 "memory_operand" ""))
4171 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4172 (fix:SSEMODEI24 (match_dup 0)))]
4173 "!TARGET_K8
4174 && peep2_reg_dead_p (2, operands[0])"
4175 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4176 "")
4177
4178 (define_peephole2
4179 [(set (match_operand:SF 0 "register_operand" "")
4180 (match_operand:SF 1 "memory_operand" ""))
4181 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4182 (fix:SSEMODEI24 (match_dup 0)))]
4183 "!TARGET_K8
4184 && peep2_reg_dead_p (2, operands[0])"
4185 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4186 "")
4187
4188 ;; Avoid vector decoded forms of the instruction.
4189 (define_peephole2
4190 [(match_scratch:DF 2 "Y")
4191 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4192 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4193 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4194 [(set (match_dup 2) (match_dup 1))
4195 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4196 "")
4197
4198 (define_peephole2
4199 [(match_scratch:SF 2 "x")
4200 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4201 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4202 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4203 [(set (match_dup 2) (match_dup 1))
4204 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4205 "")
4206
4207 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4208 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4209 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4210 "TARGET_FISTTP
4211 && FLOAT_MODE_P (GET_MODE (operands[1]))
4212 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4213 && (TARGET_64BIT || <MODE>mode != DImode))
4214 && TARGET_SSE_MATH)
4215 && !(reload_completed || reload_in_progress)"
4216 "#"
4217 "&& 1"
4218 [(const_int 0)]
4219 {
4220 if (memory_operand (operands[0], VOIDmode))
4221 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4222 else
4223 {
4224 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4225 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4226 operands[1],
4227 operands[2]));
4228 }
4229 DONE;
4230 }
4231 [(set_attr "type" "fisttp")
4232 (set_attr "mode" "<MODE>")])
4233
4234 (define_insn "fix_trunc<mode>_i387_fisttp"
4235 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4236 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4237 (clobber (match_scratch:XF 2 "=&1f"))]
4238 "TARGET_FISTTP
4239 && FLOAT_MODE_P (GET_MODE (operands[1]))
4240 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4241 && (TARGET_64BIT || <MODE>mode != DImode))
4242 && TARGET_SSE_MATH)"
4243 "* return output_fix_trunc (insn, operands, 1);"
4244 [(set_attr "type" "fisttp")
4245 (set_attr "mode" "<MODE>")])
4246
4247 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4248 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4249 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4250 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4251 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4252 "TARGET_FISTTP
4253 && FLOAT_MODE_P (GET_MODE (operands[1]))
4254 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4255 && (TARGET_64BIT || <MODE>mode != DImode))
4256 && TARGET_SSE_MATH)"
4257 "#"
4258 [(set_attr "type" "fisttp")
4259 (set_attr "mode" "<MODE>")])
4260
4261 (define_split
4262 [(set (match_operand:X87MODEI 0 "register_operand" "")
4263 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4264 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4265 (clobber (match_scratch 3 ""))]
4266 "reload_completed"
4267 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4268 (clobber (match_dup 3))])
4269 (set (match_dup 0) (match_dup 2))]
4270 "")
4271
4272 (define_split
4273 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4274 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4275 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4276 (clobber (match_scratch 3 ""))]
4277 "reload_completed"
4278 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4279 (clobber (match_dup 3))])]
4280 "")
4281
4282 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4283 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4284 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4285 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4286 ;; function in i386.c.
4287 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4288 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4289 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4290 (clobber (reg:CC FLAGS_REG))]
4291 "TARGET_80387 && !TARGET_FISTTP
4292 && FLOAT_MODE_P (GET_MODE (operands[1]))
4293 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4294 && (TARGET_64BIT || <MODE>mode != DImode))
4295 && !(reload_completed || reload_in_progress)"
4296 "#"
4297 "&& 1"
4298 [(const_int 0)]
4299 {
4300 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4301
4302 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4303 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4304 if (memory_operand (operands[0], VOIDmode))
4305 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4306 operands[2], operands[3]));
4307 else
4308 {
4309 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4310 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4311 operands[2], operands[3],
4312 operands[4]));
4313 }
4314 DONE;
4315 }
4316 [(set_attr "type" "fistp")
4317 (set_attr "i387_cw" "trunc")
4318 (set_attr "mode" "<MODE>")])
4319
4320 (define_insn "fix_truncdi_i387"
4321 [(set (match_operand:DI 0 "memory_operand" "=m")
4322 (fix:DI (match_operand 1 "register_operand" "f")))
4323 (use (match_operand:HI 2 "memory_operand" "m"))
4324 (use (match_operand:HI 3 "memory_operand" "m"))
4325 (clobber (match_scratch:XF 4 "=&1f"))]
4326 "TARGET_80387 && !TARGET_FISTTP
4327 && FLOAT_MODE_P (GET_MODE (operands[1]))
4328 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4329 "* return output_fix_trunc (insn, operands, 0);"
4330 [(set_attr "type" "fistp")
4331 (set_attr "i387_cw" "trunc")
4332 (set_attr "mode" "DI")])
4333
4334 (define_insn "fix_truncdi_i387_with_temp"
4335 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4336 (fix:DI (match_operand 1 "register_operand" "f,f")))
4337 (use (match_operand:HI 2 "memory_operand" "m,m"))
4338 (use (match_operand:HI 3 "memory_operand" "m,m"))
4339 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4340 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4341 "TARGET_80387 && !TARGET_FISTTP
4342 && FLOAT_MODE_P (GET_MODE (operands[1]))
4343 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4344 "#"
4345 [(set_attr "type" "fistp")
4346 (set_attr "i387_cw" "trunc")
4347 (set_attr "mode" "DI")])
4348
4349 (define_split
4350 [(set (match_operand:DI 0 "register_operand" "")
4351 (fix:DI (match_operand 1 "register_operand" "")))
4352 (use (match_operand:HI 2 "memory_operand" ""))
4353 (use (match_operand:HI 3 "memory_operand" ""))
4354 (clobber (match_operand:DI 4 "memory_operand" ""))
4355 (clobber (match_scratch 5 ""))]
4356 "reload_completed"
4357 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4358 (use (match_dup 2))
4359 (use (match_dup 3))
4360 (clobber (match_dup 5))])
4361 (set (match_dup 0) (match_dup 4))]
4362 "")
4363
4364 (define_split
4365 [(set (match_operand:DI 0 "memory_operand" "")
4366 (fix:DI (match_operand 1 "register_operand" "")))
4367 (use (match_operand:HI 2 "memory_operand" ""))
4368 (use (match_operand:HI 3 "memory_operand" ""))
4369 (clobber (match_operand:DI 4 "memory_operand" ""))
4370 (clobber (match_scratch 5 ""))]
4371 "reload_completed"
4372 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4373 (use (match_dup 2))
4374 (use (match_dup 3))
4375 (clobber (match_dup 5))])]
4376 "")
4377
4378 (define_insn "fix_trunc<mode>_i387"
4379 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4380 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4381 (use (match_operand:HI 2 "memory_operand" "m"))
4382 (use (match_operand:HI 3 "memory_operand" "m"))]
4383 "TARGET_80387 && !TARGET_FISTTP
4384 && FLOAT_MODE_P (GET_MODE (operands[1]))
4385 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4386 "* return output_fix_trunc (insn, operands, 0);"
4387 [(set_attr "type" "fistp")
4388 (set_attr "i387_cw" "trunc")
4389 (set_attr "mode" "<MODE>")])
4390
4391 (define_insn "fix_trunc<mode>_i387_with_temp"
4392 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4393 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4394 (use (match_operand:HI 2 "memory_operand" "m,m"))
4395 (use (match_operand:HI 3 "memory_operand" "m,m"))
4396 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4397 "TARGET_80387 && !TARGET_FISTTP
4398 && FLOAT_MODE_P (GET_MODE (operands[1]))
4399 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4400 "#"
4401 [(set_attr "type" "fistp")
4402 (set_attr "i387_cw" "trunc")
4403 (set_attr "mode" "<MODE>")])
4404
4405 (define_split
4406 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4407 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4408 (use (match_operand:HI 2 "memory_operand" ""))
4409 (use (match_operand:HI 3 "memory_operand" ""))
4410 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4411 "reload_completed"
4412 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4413 (use (match_dup 2))
4414 (use (match_dup 3))])
4415 (set (match_dup 0) (match_dup 4))]
4416 "")
4417
4418 (define_split
4419 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4420 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4421 (use (match_operand:HI 2 "memory_operand" ""))
4422 (use (match_operand:HI 3 "memory_operand" ""))
4423 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4424 "reload_completed"
4425 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4426 (use (match_dup 2))
4427 (use (match_dup 3))])]
4428 "")
4429
4430 (define_insn "x86_fnstcw_1"
4431 [(set (match_operand:HI 0 "memory_operand" "=m")
4432 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4433 "TARGET_80387"
4434 "fnstcw\t%0"
4435 [(set_attr "length" "2")
4436 (set_attr "mode" "HI")
4437 (set_attr "unit" "i387")])
4438
4439 (define_insn "x86_fldcw_1"
4440 [(set (reg:HI FPSR_REG)
4441 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4442 "TARGET_80387"
4443 "fldcw\t%0"
4444 [(set_attr "length" "2")
4445 (set_attr "mode" "HI")
4446 (set_attr "unit" "i387")
4447 (set_attr "athlon_decode" "vector")])
4448 \f
4449 ;; Conversion between fixed point and floating point.
4450
4451 ;; Even though we only accept memory inputs, the backend _really_
4452 ;; wants to be able to do this between registers.
4453
4454 (define_expand "floathisf2"
4455 [(set (match_operand:SF 0 "register_operand" "")
4456 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4457 "TARGET_80387 || TARGET_SSE_MATH"
4458 {
4459 if (TARGET_SSE_MATH)
4460 {
4461 emit_insn (gen_floatsisf2 (operands[0],
4462 convert_to_mode (SImode, operands[1], 0)));
4463 DONE;
4464 }
4465 })
4466
4467 (define_insn "*floathisf2_i387"
4468 [(set (match_operand:SF 0 "register_operand" "=f,f")
4469 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4470 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4471 "@
4472 fild%z1\t%1
4473 #"
4474 [(set_attr "type" "fmov,multi")
4475 (set_attr "mode" "SF")
4476 (set_attr "unit" "*,i387")
4477 (set_attr "fp_int_src" "true")])
4478
4479 (define_expand "floatsisf2"
4480 [(set (match_operand:SF 0 "register_operand" "")
4481 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4482 "TARGET_80387 || TARGET_SSE_MATH"
4483 "")
4484
4485 (define_insn "*floatsisf2_mixed"
4486 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4487 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4488 "TARGET_MIX_SSE_I387"
4489 "@
4490 fild%z1\t%1
4491 #
4492 cvtsi2ss\t{%1, %0|%0, %1}
4493 cvtsi2ss\t{%1, %0|%0, %1}"
4494 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4495 (set_attr "mode" "SF")
4496 (set_attr "unit" "*,i387,*,*")
4497 (set_attr "athlon_decode" "*,*,vector,double")
4498 (set_attr "fp_int_src" "true")])
4499
4500 (define_insn "*floatsisf2_sse"
4501 [(set (match_operand:SF 0 "register_operand" "=x,x")
4502 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4503 "TARGET_SSE_MATH"
4504 "cvtsi2ss\t{%1, %0|%0, %1}"
4505 [(set_attr "type" "sseicvt")
4506 (set_attr "mode" "SF")
4507 (set_attr "athlon_decode" "vector,double")
4508 (set_attr "fp_int_src" "true")])
4509
4510 (define_insn "*floatsisf2_i387"
4511 [(set (match_operand:SF 0 "register_operand" "=f,f")
4512 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4513 "TARGET_80387"
4514 "@
4515 fild%z1\t%1
4516 #"
4517 [(set_attr "type" "fmov,multi")
4518 (set_attr "mode" "SF")
4519 (set_attr "unit" "*,i387")
4520 (set_attr "fp_int_src" "true")])
4521
4522 (define_expand "floatdisf2"
4523 [(set (match_operand:SF 0 "register_operand" "")
4524 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4525 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4526 "")
4527
4528 (define_insn "*floatdisf2_mixed"
4529 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4530 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4531 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4532 "@
4533 fild%z1\t%1
4534 #
4535 cvtsi2ss{q}\t{%1, %0|%0, %1}
4536 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4537 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4538 (set_attr "mode" "SF")
4539 (set_attr "unit" "*,i387,*,*")
4540 (set_attr "athlon_decode" "*,*,vector,double")
4541 (set_attr "fp_int_src" "true")])
4542
4543 (define_insn "*floatdisf2_sse"
4544 [(set (match_operand:SF 0 "register_operand" "=x,x")
4545 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4546 "TARGET_64BIT && TARGET_SSE_MATH"
4547 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4548 [(set_attr "type" "sseicvt")
4549 (set_attr "mode" "SF")
4550 (set_attr "athlon_decode" "vector,double")
4551 (set_attr "fp_int_src" "true")])
4552
4553 (define_insn "*floatdisf2_i387"
4554 [(set (match_operand:SF 0 "register_operand" "=f,f")
4555 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4556 "TARGET_80387"
4557 "@
4558 fild%z1\t%1
4559 #"
4560 [(set_attr "type" "fmov,multi")
4561 (set_attr "mode" "SF")
4562 (set_attr "unit" "*,i387")
4563 (set_attr "fp_int_src" "true")])
4564
4565 (define_expand "floathidf2"
4566 [(set (match_operand:DF 0 "register_operand" "")
4567 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4568 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4569 {
4570 if (TARGET_SSE2 && TARGET_SSE_MATH)
4571 {
4572 emit_insn (gen_floatsidf2 (operands[0],
4573 convert_to_mode (SImode, operands[1], 0)));
4574 DONE;
4575 }
4576 })
4577
4578 (define_insn "*floathidf2_i387"
4579 [(set (match_operand:DF 0 "register_operand" "=f,f")
4580 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4581 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4582 "@
4583 fild%z1\t%1
4584 #"
4585 [(set_attr "type" "fmov,multi")
4586 (set_attr "mode" "DF")
4587 (set_attr "unit" "*,i387")
4588 (set_attr "fp_int_src" "true")])
4589
4590 (define_expand "floatsidf2"
4591 [(set (match_operand:DF 0 "register_operand" "")
4592 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4593 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4594 "")
4595
4596 (define_insn "*floatsidf2_mixed"
4597 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4598 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4599 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4600 "@
4601 fild%z1\t%1
4602 #
4603 cvtsi2sd\t{%1, %0|%0, %1}
4604 cvtsi2sd\t{%1, %0|%0, %1}"
4605 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4606 (set_attr "mode" "DF")
4607 (set_attr "unit" "*,i387,*,*")
4608 (set_attr "athlon_decode" "*,*,double,direct")
4609 (set_attr "fp_int_src" "true")])
4610
4611 (define_insn "*floatsidf2_sse"
4612 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4613 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4614 "TARGET_SSE2 && TARGET_SSE_MATH"
4615 "cvtsi2sd\t{%1, %0|%0, %1}"
4616 [(set_attr "type" "sseicvt")
4617 (set_attr "mode" "DF")
4618 (set_attr "athlon_decode" "double,direct")
4619 (set_attr "fp_int_src" "true")])
4620
4621 (define_insn "*floatsidf2_i387"
4622 [(set (match_operand:DF 0 "register_operand" "=f,f")
4623 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4624 "TARGET_80387"
4625 "@
4626 fild%z1\t%1
4627 #"
4628 [(set_attr "type" "fmov,multi")
4629 (set_attr "mode" "DF")
4630 (set_attr "unit" "*,i387")
4631 (set_attr "fp_int_src" "true")])
4632
4633 (define_expand "floatdidf2"
4634 [(set (match_operand:DF 0 "register_operand" "")
4635 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4636 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4637 "")
4638
4639 (define_insn "*floatdidf2_mixed"
4640 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4641 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4642 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4643 "@
4644 fild%z1\t%1
4645 #
4646 cvtsi2sd{q}\t{%1, %0|%0, %1}
4647 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4648 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4649 (set_attr "mode" "DF")
4650 (set_attr "unit" "*,i387,*,*")
4651 (set_attr "athlon_decode" "*,*,double,direct")
4652 (set_attr "fp_int_src" "true")])
4653
4654 (define_insn "*floatdidf2_sse"
4655 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4656 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4657 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4658 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4659 [(set_attr "type" "sseicvt")
4660 (set_attr "mode" "DF")
4661 (set_attr "athlon_decode" "double,direct")
4662 (set_attr "fp_int_src" "true")])
4663
4664 (define_insn "*floatdidf2_i387"
4665 [(set (match_operand:DF 0 "register_operand" "=f,f")
4666 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4667 "TARGET_80387"
4668 "@
4669 fild%z1\t%1
4670 #"
4671 [(set_attr "type" "fmov,multi")
4672 (set_attr "mode" "DF")
4673 (set_attr "unit" "*,i387")
4674 (set_attr "fp_int_src" "true")])
4675
4676 (define_insn "floathixf2"
4677 [(set (match_operand:XF 0 "register_operand" "=f,f")
4678 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4679 "TARGET_80387"
4680 "@
4681 fild%z1\t%1
4682 #"
4683 [(set_attr "type" "fmov,multi")
4684 (set_attr "mode" "XF")
4685 (set_attr "unit" "*,i387")
4686 (set_attr "fp_int_src" "true")])
4687
4688 (define_insn "floatsixf2"
4689 [(set (match_operand:XF 0 "register_operand" "=f,f")
4690 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4691 "TARGET_80387"
4692 "@
4693 fild%z1\t%1
4694 #"
4695 [(set_attr "type" "fmov,multi")
4696 (set_attr "mode" "XF")
4697 (set_attr "unit" "*,i387")
4698 (set_attr "fp_int_src" "true")])
4699
4700 (define_insn "floatdixf2"
4701 [(set (match_operand:XF 0 "register_operand" "=f,f")
4702 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4703 "TARGET_80387"
4704 "@
4705 fild%z1\t%1
4706 #"
4707 [(set_attr "type" "fmov,multi")
4708 (set_attr "mode" "XF")
4709 (set_attr "unit" "*,i387")
4710 (set_attr "fp_int_src" "true")])
4711
4712 ;; %%% Kill these when reload knows how to do it.
4713 (define_split
4714 [(set (match_operand 0 "fp_register_operand" "")
4715 (float (match_operand 1 "register_operand" "")))]
4716 "reload_completed
4717 && TARGET_80387
4718 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4719 [(const_int 0)]
4720 {
4721 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4722 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4723 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4724 ix86_free_from_memory (GET_MODE (operands[1]));
4725 DONE;
4726 })
4727
4728 (define_expand "floatunssisf2"
4729 [(use (match_operand:SF 0 "register_operand" ""))
4730 (use (match_operand:SI 1 "register_operand" ""))]
4731 "!TARGET_64BIT && TARGET_SSE_MATH"
4732 "x86_emit_floatuns (operands); DONE;")
4733
4734 (define_expand "floatunsdisf2"
4735 [(use (match_operand:SF 0 "register_operand" ""))
4736 (use (match_operand:DI 1 "register_operand" ""))]
4737 "TARGET_64BIT && TARGET_SSE_MATH"
4738 "x86_emit_floatuns (operands); DONE;")
4739
4740 (define_expand "floatunsdidf2"
4741 [(use (match_operand:DF 0 "register_operand" ""))
4742 (use (match_operand:DI 1 "register_operand" ""))]
4743 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4744 "x86_emit_floatuns (operands); DONE;")
4745 \f
4746 ;; SSE extract/set expanders
4747
4748 \f
4749 ;; Add instructions
4750
4751 ;; %%% splits for addditi3
4752
4753 (define_expand "addti3"
4754 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4755 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4756 (match_operand:TI 2 "x86_64_general_operand" "")))
4757 (clobber (reg:CC FLAGS_REG))]
4758 "TARGET_64BIT"
4759 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4760
4761 (define_insn "*addti3_1"
4762 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4763 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4764 (match_operand:TI 2 "general_operand" "roiF,riF")))
4765 (clobber (reg:CC FLAGS_REG))]
4766 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4767 "#")
4768
4769 (define_split
4770 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4771 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4772 (match_operand:TI 2 "general_operand" "")))
4773 (clobber (reg:CC FLAGS_REG))]
4774 "TARGET_64BIT && reload_completed"
4775 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4776 UNSPEC_ADD_CARRY))
4777 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4778 (parallel [(set (match_dup 3)
4779 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4780 (match_dup 4))
4781 (match_dup 5)))
4782 (clobber (reg:CC FLAGS_REG))])]
4783 "split_ti (operands+0, 1, operands+0, operands+3);
4784 split_ti (operands+1, 1, operands+1, operands+4);
4785 split_ti (operands+2, 1, operands+2, operands+5);")
4786
4787 ;; %%% splits for addsidi3
4788 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4789 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4790 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4791
4792 (define_expand "adddi3"
4793 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4794 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4795 (match_operand:DI 2 "x86_64_general_operand" "")))
4796 (clobber (reg:CC FLAGS_REG))]
4797 ""
4798 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4799
4800 (define_insn "*adddi3_1"
4801 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4802 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4803 (match_operand:DI 2 "general_operand" "roiF,riF")))
4804 (clobber (reg:CC FLAGS_REG))]
4805 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4806 "#")
4807
4808 (define_split
4809 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4810 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4811 (match_operand:DI 2 "general_operand" "")))
4812 (clobber (reg:CC FLAGS_REG))]
4813 "!TARGET_64BIT && reload_completed"
4814 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4815 UNSPEC_ADD_CARRY))
4816 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4817 (parallel [(set (match_dup 3)
4818 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4819 (match_dup 4))
4820 (match_dup 5)))
4821 (clobber (reg:CC FLAGS_REG))])]
4822 "split_di (operands+0, 1, operands+0, operands+3);
4823 split_di (operands+1, 1, operands+1, operands+4);
4824 split_di (operands+2, 1, operands+2, operands+5);")
4825
4826 (define_insn "adddi3_carry_rex64"
4827 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4828 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4829 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4830 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4831 (clobber (reg:CC FLAGS_REG))]
4832 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4833 "adc{q}\t{%2, %0|%0, %2}"
4834 [(set_attr "type" "alu")
4835 (set_attr "pent_pair" "pu")
4836 (set_attr "mode" "DI")])
4837
4838 (define_insn "*adddi3_cc_rex64"
4839 [(set (reg:CC FLAGS_REG)
4840 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4841 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4842 UNSPEC_ADD_CARRY))
4843 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4844 (plus:DI (match_dup 1) (match_dup 2)))]
4845 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4846 "add{q}\t{%2, %0|%0, %2}"
4847 [(set_attr "type" "alu")
4848 (set_attr "mode" "DI")])
4849
4850 (define_insn "addqi3_carry"
4851 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4852 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4853 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4854 (match_operand:QI 2 "general_operand" "qi,qm")))
4855 (clobber (reg:CC FLAGS_REG))]
4856 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4857 "adc{b}\t{%2, %0|%0, %2}"
4858 [(set_attr "type" "alu")
4859 (set_attr "pent_pair" "pu")
4860 (set_attr "mode" "QI")])
4861
4862 (define_insn "addhi3_carry"
4863 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4864 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4865 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4866 (match_operand:HI 2 "general_operand" "ri,rm")))
4867 (clobber (reg:CC FLAGS_REG))]
4868 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4869 "adc{w}\t{%2, %0|%0, %2}"
4870 [(set_attr "type" "alu")
4871 (set_attr "pent_pair" "pu")
4872 (set_attr "mode" "HI")])
4873
4874 (define_insn "addsi3_carry"
4875 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4876 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4877 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4878 (match_operand:SI 2 "general_operand" "ri,rm")))
4879 (clobber (reg:CC FLAGS_REG))]
4880 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4881 "adc{l}\t{%2, %0|%0, %2}"
4882 [(set_attr "type" "alu")
4883 (set_attr "pent_pair" "pu")
4884 (set_attr "mode" "SI")])
4885
4886 (define_insn "*addsi3_carry_zext"
4887 [(set (match_operand:DI 0 "register_operand" "=r")
4888 (zero_extend:DI
4889 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4890 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4891 (match_operand:SI 2 "general_operand" "rim"))))
4892 (clobber (reg:CC FLAGS_REG))]
4893 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4894 "adc{l}\t{%2, %k0|%k0, %2}"
4895 [(set_attr "type" "alu")
4896 (set_attr "pent_pair" "pu")
4897 (set_attr "mode" "SI")])
4898
4899 (define_insn "*addsi3_cc"
4900 [(set (reg:CC FLAGS_REG)
4901 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4902 (match_operand:SI 2 "general_operand" "ri,rm")]
4903 UNSPEC_ADD_CARRY))
4904 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4905 (plus:SI (match_dup 1) (match_dup 2)))]
4906 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4907 "add{l}\t{%2, %0|%0, %2}"
4908 [(set_attr "type" "alu")
4909 (set_attr "mode" "SI")])
4910
4911 (define_insn "addqi3_cc"
4912 [(set (reg:CC FLAGS_REG)
4913 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4914 (match_operand:QI 2 "general_operand" "qi,qm")]
4915 UNSPEC_ADD_CARRY))
4916 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4917 (plus:QI (match_dup 1) (match_dup 2)))]
4918 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4919 "add{b}\t{%2, %0|%0, %2}"
4920 [(set_attr "type" "alu")
4921 (set_attr "mode" "QI")])
4922
4923 (define_expand "addsi3"
4924 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4925 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4926 (match_operand:SI 2 "general_operand" "")))
4927 (clobber (reg:CC FLAGS_REG))])]
4928 ""
4929 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4930
4931 (define_insn "*lea_1"
4932 [(set (match_operand:SI 0 "register_operand" "=r")
4933 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4934 "!TARGET_64BIT"
4935 "lea{l}\t{%a1, %0|%0, %a1}"
4936 [(set_attr "type" "lea")
4937 (set_attr "mode" "SI")])
4938
4939 (define_insn "*lea_1_rex64"
4940 [(set (match_operand:SI 0 "register_operand" "=r")
4941 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4942 "TARGET_64BIT"
4943 "lea{l}\t{%a1, %0|%0, %a1}"
4944 [(set_attr "type" "lea")
4945 (set_attr "mode" "SI")])
4946
4947 (define_insn "*lea_1_zext"
4948 [(set (match_operand:DI 0 "register_operand" "=r")
4949 (zero_extend:DI
4950 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4951 "TARGET_64BIT"
4952 "lea{l}\t{%a1, %k0|%k0, %a1}"
4953 [(set_attr "type" "lea")
4954 (set_attr "mode" "SI")])
4955
4956 (define_insn "*lea_2_rex64"
4957 [(set (match_operand:DI 0 "register_operand" "=r")
4958 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4959 "TARGET_64BIT"
4960 "lea{q}\t{%a1, %0|%0, %a1}"
4961 [(set_attr "type" "lea")
4962 (set_attr "mode" "DI")])
4963
4964 ;; The lea patterns for non-Pmodes needs to be matched by several
4965 ;; insns converted to real lea by splitters.
4966
4967 (define_insn_and_split "*lea_general_1"
4968 [(set (match_operand 0 "register_operand" "=r")
4969 (plus (plus (match_operand 1 "index_register_operand" "l")
4970 (match_operand 2 "register_operand" "r"))
4971 (match_operand 3 "immediate_operand" "i")))]
4972 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4973 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4974 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4975 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4976 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4977 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4978 || GET_MODE (operands[3]) == VOIDmode)"
4979 "#"
4980 "&& reload_completed"
4981 [(const_int 0)]
4982 {
4983 rtx pat;
4984 operands[0] = gen_lowpart (SImode, operands[0]);
4985 operands[1] = gen_lowpart (Pmode, operands[1]);
4986 operands[2] = gen_lowpart (Pmode, operands[2]);
4987 operands[3] = gen_lowpart (Pmode, operands[3]);
4988 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4989 operands[3]);
4990 if (Pmode != SImode)
4991 pat = gen_rtx_SUBREG (SImode, pat, 0);
4992 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4993 DONE;
4994 }
4995 [(set_attr "type" "lea")
4996 (set_attr "mode" "SI")])
4997
4998 (define_insn_and_split "*lea_general_1_zext"
4999 [(set (match_operand:DI 0 "register_operand" "=r")
5000 (zero_extend:DI
5001 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5002 (match_operand:SI 2 "register_operand" "r"))
5003 (match_operand:SI 3 "immediate_operand" "i"))))]
5004 "TARGET_64BIT"
5005 "#"
5006 "&& reload_completed"
5007 [(set (match_dup 0)
5008 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5009 (match_dup 2))
5010 (match_dup 3)) 0)))]
5011 {
5012 operands[1] = gen_lowpart (Pmode, operands[1]);
5013 operands[2] = gen_lowpart (Pmode, operands[2]);
5014 operands[3] = gen_lowpart (Pmode, operands[3]);
5015 }
5016 [(set_attr "type" "lea")
5017 (set_attr "mode" "SI")])
5018
5019 (define_insn_and_split "*lea_general_2"
5020 [(set (match_operand 0 "register_operand" "=r")
5021 (plus (mult (match_operand 1 "index_register_operand" "l")
5022 (match_operand 2 "const248_operand" "i"))
5023 (match_operand 3 "nonmemory_operand" "ri")))]
5024 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5025 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5026 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5027 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5028 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5029 || GET_MODE (operands[3]) == VOIDmode)"
5030 "#"
5031 "&& reload_completed"
5032 [(const_int 0)]
5033 {
5034 rtx pat;
5035 operands[0] = gen_lowpart (SImode, operands[0]);
5036 operands[1] = gen_lowpart (Pmode, operands[1]);
5037 operands[3] = gen_lowpart (Pmode, operands[3]);
5038 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5039 operands[3]);
5040 if (Pmode != SImode)
5041 pat = gen_rtx_SUBREG (SImode, pat, 0);
5042 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5043 DONE;
5044 }
5045 [(set_attr "type" "lea")
5046 (set_attr "mode" "SI")])
5047
5048 (define_insn_and_split "*lea_general_2_zext"
5049 [(set (match_operand:DI 0 "register_operand" "=r")
5050 (zero_extend:DI
5051 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5052 (match_operand:SI 2 "const248_operand" "n"))
5053 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5054 "TARGET_64BIT"
5055 "#"
5056 "&& reload_completed"
5057 [(set (match_dup 0)
5058 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5059 (match_dup 2))
5060 (match_dup 3)) 0)))]
5061 {
5062 operands[1] = gen_lowpart (Pmode, operands[1]);
5063 operands[3] = gen_lowpart (Pmode, operands[3]);
5064 }
5065 [(set_attr "type" "lea")
5066 (set_attr "mode" "SI")])
5067
5068 (define_insn_and_split "*lea_general_3"
5069 [(set (match_operand 0 "register_operand" "=r")
5070 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5071 (match_operand 2 "const248_operand" "i"))
5072 (match_operand 3 "register_operand" "r"))
5073 (match_operand 4 "immediate_operand" "i")))]
5074 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5075 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5076 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5077 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5078 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5079 "#"
5080 "&& reload_completed"
5081 [(const_int 0)]
5082 {
5083 rtx pat;
5084 operands[0] = gen_lowpart (SImode, operands[0]);
5085 operands[1] = gen_lowpart (Pmode, operands[1]);
5086 operands[3] = gen_lowpart (Pmode, operands[3]);
5087 operands[4] = gen_lowpart (Pmode, operands[4]);
5088 pat = gen_rtx_PLUS (Pmode,
5089 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5090 operands[2]),
5091 operands[3]),
5092 operands[4]);
5093 if (Pmode != SImode)
5094 pat = gen_rtx_SUBREG (SImode, pat, 0);
5095 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5096 DONE;
5097 }
5098 [(set_attr "type" "lea")
5099 (set_attr "mode" "SI")])
5100
5101 (define_insn_and_split "*lea_general_3_zext"
5102 [(set (match_operand:DI 0 "register_operand" "=r")
5103 (zero_extend:DI
5104 (plus:SI (plus:SI (mult:SI
5105 (match_operand:SI 1 "index_register_operand" "l")
5106 (match_operand:SI 2 "const248_operand" "n"))
5107 (match_operand:SI 3 "register_operand" "r"))
5108 (match_operand:SI 4 "immediate_operand" "i"))))]
5109 "TARGET_64BIT"
5110 "#"
5111 "&& reload_completed"
5112 [(set (match_dup 0)
5113 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5114 (match_dup 2))
5115 (match_dup 3))
5116 (match_dup 4)) 0)))]
5117 {
5118 operands[1] = gen_lowpart (Pmode, operands[1]);
5119 operands[3] = gen_lowpart (Pmode, operands[3]);
5120 operands[4] = gen_lowpart (Pmode, operands[4]);
5121 }
5122 [(set_attr "type" "lea")
5123 (set_attr "mode" "SI")])
5124
5125 (define_insn "*adddi_1_rex64"
5126 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5127 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5128 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5129 (clobber (reg:CC FLAGS_REG))]
5130 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5131 {
5132 switch (get_attr_type (insn))
5133 {
5134 case TYPE_LEA:
5135 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5136 return "lea{q}\t{%a2, %0|%0, %a2}";
5137
5138 case TYPE_INCDEC:
5139 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5140 if (operands[2] == const1_rtx)
5141 return "inc{q}\t%0";
5142 else
5143 {
5144 gcc_assert (operands[2] == constm1_rtx);
5145 return "dec{q}\t%0";
5146 }
5147
5148 default:
5149 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5150
5151 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5152 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5153 if (GET_CODE (operands[2]) == CONST_INT
5154 /* Avoid overflows. */
5155 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5156 && (INTVAL (operands[2]) == 128
5157 || (INTVAL (operands[2]) < 0
5158 && INTVAL (operands[2]) != -128)))
5159 {
5160 operands[2] = GEN_INT (-INTVAL (operands[2]));
5161 return "sub{q}\t{%2, %0|%0, %2}";
5162 }
5163 return "add{q}\t{%2, %0|%0, %2}";
5164 }
5165 }
5166 [(set (attr "type")
5167 (cond [(eq_attr "alternative" "2")
5168 (const_string "lea")
5169 ; Current assemblers are broken and do not allow @GOTOFF in
5170 ; ought but a memory context.
5171 (match_operand:DI 2 "pic_symbolic_operand" "")
5172 (const_string "lea")
5173 (match_operand:DI 2 "incdec_operand" "")
5174 (const_string "incdec")
5175 ]
5176 (const_string "alu")))
5177 (set_attr "mode" "DI")])
5178
5179 ;; Convert lea to the lea pattern to avoid flags dependency.
5180 (define_split
5181 [(set (match_operand:DI 0 "register_operand" "")
5182 (plus:DI (match_operand:DI 1 "register_operand" "")
5183 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5184 (clobber (reg:CC FLAGS_REG))]
5185 "TARGET_64BIT && reload_completed
5186 && true_regnum (operands[0]) != true_regnum (operands[1])"
5187 [(set (match_dup 0)
5188 (plus:DI (match_dup 1)
5189 (match_dup 2)))]
5190 "")
5191
5192 (define_insn "*adddi_2_rex64"
5193 [(set (reg FLAGS_REG)
5194 (compare
5195 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5196 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5197 (const_int 0)))
5198 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5199 (plus:DI (match_dup 1) (match_dup 2)))]
5200 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5201 && ix86_binary_operator_ok (PLUS, DImode, operands)
5202 /* Current assemblers are broken and do not allow @GOTOFF in
5203 ought but a memory context. */
5204 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5205 {
5206 switch (get_attr_type (insn))
5207 {
5208 case TYPE_INCDEC:
5209 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5210 if (operands[2] == const1_rtx)
5211 return "inc{q}\t%0";
5212 else
5213 {
5214 gcc_assert (operands[2] == constm1_rtx);
5215 return "dec{q}\t%0";
5216 }
5217
5218 default:
5219 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5220 /* ???? We ought to handle there the 32bit case too
5221 - do we need new constraint? */
5222 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5223 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5224 if (GET_CODE (operands[2]) == CONST_INT
5225 /* Avoid overflows. */
5226 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5227 && (INTVAL (operands[2]) == 128
5228 || (INTVAL (operands[2]) < 0
5229 && INTVAL (operands[2]) != -128)))
5230 {
5231 operands[2] = GEN_INT (-INTVAL (operands[2]));
5232 return "sub{q}\t{%2, %0|%0, %2}";
5233 }
5234 return "add{q}\t{%2, %0|%0, %2}";
5235 }
5236 }
5237 [(set (attr "type")
5238 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5239 (const_string "incdec")
5240 (const_string "alu")))
5241 (set_attr "mode" "DI")])
5242
5243 (define_insn "*adddi_3_rex64"
5244 [(set (reg FLAGS_REG)
5245 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5246 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5247 (clobber (match_scratch:DI 0 "=r"))]
5248 "TARGET_64BIT
5249 && ix86_match_ccmode (insn, CCZmode)
5250 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5251 /* Current assemblers are broken and do not allow @GOTOFF in
5252 ought but a memory context. */
5253 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5254 {
5255 switch (get_attr_type (insn))
5256 {
5257 case TYPE_INCDEC:
5258 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5259 if (operands[2] == const1_rtx)
5260 return "inc{q}\t%0";
5261 else
5262 {
5263 gcc_assert (operands[2] == constm1_rtx);
5264 return "dec{q}\t%0";
5265 }
5266
5267 default:
5268 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5269 /* ???? We ought to handle there the 32bit case too
5270 - do we need new constraint? */
5271 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5272 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5273 if (GET_CODE (operands[2]) == CONST_INT
5274 /* Avoid overflows. */
5275 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5276 && (INTVAL (operands[2]) == 128
5277 || (INTVAL (operands[2]) < 0
5278 && INTVAL (operands[2]) != -128)))
5279 {
5280 operands[2] = GEN_INT (-INTVAL (operands[2]));
5281 return "sub{q}\t{%2, %0|%0, %2}";
5282 }
5283 return "add{q}\t{%2, %0|%0, %2}";
5284 }
5285 }
5286 [(set (attr "type")
5287 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5288 (const_string "incdec")
5289 (const_string "alu")))
5290 (set_attr "mode" "DI")])
5291
5292 ; For comparisons against 1, -1 and 128, we may generate better code
5293 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5294 ; is matched then. We can't accept general immediate, because for
5295 ; case of overflows, the result is messed up.
5296 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5297 ; when negated.
5298 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5299 ; only for comparisons not depending on it.
5300 (define_insn "*adddi_4_rex64"
5301 [(set (reg FLAGS_REG)
5302 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5303 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5304 (clobber (match_scratch:DI 0 "=rm"))]
5305 "TARGET_64BIT
5306 && ix86_match_ccmode (insn, CCGCmode)"
5307 {
5308 switch (get_attr_type (insn))
5309 {
5310 case TYPE_INCDEC:
5311 if (operands[2] == constm1_rtx)
5312 return "inc{q}\t%0";
5313 else
5314 {
5315 gcc_assert (operands[2] == const1_rtx);
5316 return "dec{q}\t%0";
5317 }
5318
5319 default:
5320 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5321 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5322 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5323 if ((INTVAL (operands[2]) == -128
5324 || (INTVAL (operands[2]) > 0
5325 && INTVAL (operands[2]) != 128))
5326 /* Avoid overflows. */
5327 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5328 return "sub{q}\t{%2, %0|%0, %2}";
5329 operands[2] = GEN_INT (-INTVAL (operands[2]));
5330 return "add{q}\t{%2, %0|%0, %2}";
5331 }
5332 }
5333 [(set (attr "type")
5334 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5335 (const_string "incdec")
5336 (const_string "alu")))
5337 (set_attr "mode" "DI")])
5338
5339 (define_insn "*adddi_5_rex64"
5340 [(set (reg FLAGS_REG)
5341 (compare
5342 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5343 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5344 (const_int 0)))
5345 (clobber (match_scratch:DI 0 "=r"))]
5346 "TARGET_64BIT
5347 && ix86_match_ccmode (insn, CCGOCmode)
5348 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5349 /* Current assemblers are broken and do not allow @GOTOFF in
5350 ought but a memory context. */
5351 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5352 {
5353 switch (get_attr_type (insn))
5354 {
5355 case TYPE_INCDEC:
5356 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5357 if (operands[2] == const1_rtx)
5358 return "inc{q}\t%0";
5359 else
5360 {
5361 gcc_assert (operands[2] == constm1_rtx);
5362 return "dec{q}\t%0";
5363 }
5364
5365 default:
5366 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5367 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5368 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5369 if (GET_CODE (operands[2]) == CONST_INT
5370 /* Avoid overflows. */
5371 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5372 && (INTVAL (operands[2]) == 128
5373 || (INTVAL (operands[2]) < 0
5374 && INTVAL (operands[2]) != -128)))
5375 {
5376 operands[2] = GEN_INT (-INTVAL (operands[2]));
5377 return "sub{q}\t{%2, %0|%0, %2}";
5378 }
5379 return "add{q}\t{%2, %0|%0, %2}";
5380 }
5381 }
5382 [(set (attr "type")
5383 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5384 (const_string "incdec")
5385 (const_string "alu")))
5386 (set_attr "mode" "DI")])
5387
5388
5389 (define_insn "*addsi_1"
5390 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5391 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5392 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5393 (clobber (reg:CC FLAGS_REG))]
5394 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5395 {
5396 switch (get_attr_type (insn))
5397 {
5398 case TYPE_LEA:
5399 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5400 return "lea{l}\t{%a2, %0|%0, %a2}";
5401
5402 case TYPE_INCDEC:
5403 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5404 if (operands[2] == const1_rtx)
5405 return "inc{l}\t%0";
5406 else
5407 {
5408 gcc_assert (operands[2] == constm1_rtx);
5409 return "dec{l}\t%0";
5410 }
5411
5412 default:
5413 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5414
5415 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5416 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5417 if (GET_CODE (operands[2]) == CONST_INT
5418 && (INTVAL (operands[2]) == 128
5419 || (INTVAL (operands[2]) < 0
5420 && INTVAL (operands[2]) != -128)))
5421 {
5422 operands[2] = GEN_INT (-INTVAL (operands[2]));
5423 return "sub{l}\t{%2, %0|%0, %2}";
5424 }
5425 return "add{l}\t{%2, %0|%0, %2}";
5426 }
5427 }
5428 [(set (attr "type")
5429 (cond [(eq_attr "alternative" "2")
5430 (const_string "lea")
5431 ; Current assemblers are broken and do not allow @GOTOFF in
5432 ; ought but a memory context.
5433 (match_operand:SI 2 "pic_symbolic_operand" "")
5434 (const_string "lea")
5435 (match_operand:SI 2 "incdec_operand" "")
5436 (const_string "incdec")
5437 ]
5438 (const_string "alu")))
5439 (set_attr "mode" "SI")])
5440
5441 ;; Convert lea to the lea pattern to avoid flags dependency.
5442 (define_split
5443 [(set (match_operand 0 "register_operand" "")
5444 (plus (match_operand 1 "register_operand" "")
5445 (match_operand 2 "nonmemory_operand" "")))
5446 (clobber (reg:CC FLAGS_REG))]
5447 "reload_completed
5448 && true_regnum (operands[0]) != true_regnum (operands[1])"
5449 [(const_int 0)]
5450 {
5451 rtx pat;
5452 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5453 may confuse gen_lowpart. */
5454 if (GET_MODE (operands[0]) != Pmode)
5455 {
5456 operands[1] = gen_lowpart (Pmode, operands[1]);
5457 operands[2] = gen_lowpart (Pmode, operands[2]);
5458 }
5459 operands[0] = gen_lowpart (SImode, operands[0]);
5460 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5461 if (Pmode != SImode)
5462 pat = gen_rtx_SUBREG (SImode, pat, 0);
5463 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5464 DONE;
5465 })
5466
5467 ;; It may seem that nonimmediate operand is proper one for operand 1.
5468 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5469 ;; we take care in ix86_binary_operator_ok to not allow two memory
5470 ;; operands so proper swapping will be done in reload. This allow
5471 ;; patterns constructed from addsi_1 to match.
5472 (define_insn "addsi_1_zext"
5473 [(set (match_operand:DI 0 "register_operand" "=r,r")
5474 (zero_extend:DI
5475 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5476 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5477 (clobber (reg:CC FLAGS_REG))]
5478 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5479 {
5480 switch (get_attr_type (insn))
5481 {
5482 case TYPE_LEA:
5483 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5484 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5485
5486 case TYPE_INCDEC:
5487 if (operands[2] == const1_rtx)
5488 return "inc{l}\t%k0";
5489 else
5490 {
5491 gcc_assert (operands[2] == constm1_rtx);
5492 return "dec{l}\t%k0";
5493 }
5494
5495 default:
5496 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5497 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5498 if (GET_CODE (operands[2]) == CONST_INT
5499 && (INTVAL (operands[2]) == 128
5500 || (INTVAL (operands[2]) < 0
5501 && INTVAL (operands[2]) != -128)))
5502 {
5503 operands[2] = GEN_INT (-INTVAL (operands[2]));
5504 return "sub{l}\t{%2, %k0|%k0, %2}";
5505 }
5506 return "add{l}\t{%2, %k0|%k0, %2}";
5507 }
5508 }
5509 [(set (attr "type")
5510 (cond [(eq_attr "alternative" "1")
5511 (const_string "lea")
5512 ; Current assemblers are broken and do not allow @GOTOFF in
5513 ; ought but a memory context.
5514 (match_operand:SI 2 "pic_symbolic_operand" "")
5515 (const_string "lea")
5516 (match_operand:SI 2 "incdec_operand" "")
5517 (const_string "incdec")
5518 ]
5519 (const_string "alu")))
5520 (set_attr "mode" "SI")])
5521
5522 ;; Convert lea to the lea pattern to avoid flags dependency.
5523 (define_split
5524 [(set (match_operand:DI 0 "register_operand" "")
5525 (zero_extend:DI
5526 (plus:SI (match_operand:SI 1 "register_operand" "")
5527 (match_operand:SI 2 "nonmemory_operand" ""))))
5528 (clobber (reg:CC FLAGS_REG))]
5529 "TARGET_64BIT && reload_completed
5530 && true_regnum (operands[0]) != true_regnum (operands[1])"
5531 [(set (match_dup 0)
5532 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5533 {
5534 operands[1] = gen_lowpart (Pmode, operands[1]);
5535 operands[2] = gen_lowpart (Pmode, operands[2]);
5536 })
5537
5538 (define_insn "*addsi_2"
5539 [(set (reg FLAGS_REG)
5540 (compare
5541 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5542 (match_operand:SI 2 "general_operand" "rmni,rni"))
5543 (const_int 0)))
5544 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5545 (plus:SI (match_dup 1) (match_dup 2)))]
5546 "ix86_match_ccmode (insn, CCGOCmode)
5547 && ix86_binary_operator_ok (PLUS, SImode, operands)
5548 /* Current assemblers are broken and do not allow @GOTOFF in
5549 ought but a memory context. */
5550 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5551 {
5552 switch (get_attr_type (insn))
5553 {
5554 case TYPE_INCDEC:
5555 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5556 if (operands[2] == const1_rtx)
5557 return "inc{l}\t%0";
5558 else
5559 {
5560 gcc_assert (operands[2] == constm1_rtx);
5561 return "dec{l}\t%0";
5562 }
5563
5564 default:
5565 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5566 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5567 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5568 if (GET_CODE (operands[2]) == CONST_INT
5569 && (INTVAL (operands[2]) == 128
5570 || (INTVAL (operands[2]) < 0
5571 && INTVAL (operands[2]) != -128)))
5572 {
5573 operands[2] = GEN_INT (-INTVAL (operands[2]));
5574 return "sub{l}\t{%2, %0|%0, %2}";
5575 }
5576 return "add{l}\t{%2, %0|%0, %2}";
5577 }
5578 }
5579 [(set (attr "type")
5580 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5581 (const_string "incdec")
5582 (const_string "alu")))
5583 (set_attr "mode" "SI")])
5584
5585 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5586 (define_insn "*addsi_2_zext"
5587 [(set (reg FLAGS_REG)
5588 (compare
5589 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5590 (match_operand:SI 2 "general_operand" "rmni"))
5591 (const_int 0)))
5592 (set (match_operand:DI 0 "register_operand" "=r")
5593 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5594 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5595 && ix86_binary_operator_ok (PLUS, SImode, operands)
5596 /* Current assemblers are broken and do not allow @GOTOFF in
5597 ought but a memory context. */
5598 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5599 {
5600 switch (get_attr_type (insn))
5601 {
5602 case TYPE_INCDEC:
5603 if (operands[2] == const1_rtx)
5604 return "inc{l}\t%k0";
5605 else
5606 {
5607 gcc_assert (operands[2] == constm1_rtx);
5608 return "dec{l}\t%k0";
5609 }
5610
5611 default:
5612 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5613 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5614 if (GET_CODE (operands[2]) == CONST_INT
5615 && (INTVAL (operands[2]) == 128
5616 || (INTVAL (operands[2]) < 0
5617 && INTVAL (operands[2]) != -128)))
5618 {
5619 operands[2] = GEN_INT (-INTVAL (operands[2]));
5620 return "sub{l}\t{%2, %k0|%k0, %2}";
5621 }
5622 return "add{l}\t{%2, %k0|%k0, %2}";
5623 }
5624 }
5625 [(set (attr "type")
5626 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5627 (const_string "incdec")
5628 (const_string "alu")))
5629 (set_attr "mode" "SI")])
5630
5631 (define_insn "*addsi_3"
5632 [(set (reg FLAGS_REG)
5633 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5634 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5635 (clobber (match_scratch:SI 0 "=r"))]
5636 "ix86_match_ccmode (insn, CCZmode)
5637 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5638 /* Current assemblers are broken and do not allow @GOTOFF in
5639 ought but a memory context. */
5640 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5641 {
5642 switch (get_attr_type (insn))
5643 {
5644 case TYPE_INCDEC:
5645 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5646 if (operands[2] == const1_rtx)
5647 return "inc{l}\t%0";
5648 else
5649 {
5650 gcc_assert (operands[2] == constm1_rtx);
5651 return "dec{l}\t%0";
5652 }
5653
5654 default:
5655 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5656 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5657 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5658 if (GET_CODE (operands[2]) == CONST_INT
5659 && (INTVAL (operands[2]) == 128
5660 || (INTVAL (operands[2]) < 0
5661 && INTVAL (operands[2]) != -128)))
5662 {
5663 operands[2] = GEN_INT (-INTVAL (operands[2]));
5664 return "sub{l}\t{%2, %0|%0, %2}";
5665 }
5666 return "add{l}\t{%2, %0|%0, %2}";
5667 }
5668 }
5669 [(set (attr "type")
5670 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5671 (const_string "incdec")
5672 (const_string "alu")))
5673 (set_attr "mode" "SI")])
5674
5675 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5676 (define_insn "*addsi_3_zext"
5677 [(set (reg FLAGS_REG)
5678 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5679 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5680 (set (match_operand:DI 0 "register_operand" "=r")
5681 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5682 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5683 && ix86_binary_operator_ok (PLUS, SImode, operands)
5684 /* Current assemblers are broken and do not allow @GOTOFF in
5685 ought but a memory context. */
5686 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5687 {
5688 switch (get_attr_type (insn))
5689 {
5690 case TYPE_INCDEC:
5691 if (operands[2] == const1_rtx)
5692 return "inc{l}\t%k0";
5693 else
5694 {
5695 gcc_assert (operands[2] == constm1_rtx);
5696 return "dec{l}\t%k0";
5697 }
5698
5699 default:
5700 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5701 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5702 if (GET_CODE (operands[2]) == CONST_INT
5703 && (INTVAL (operands[2]) == 128
5704 || (INTVAL (operands[2]) < 0
5705 && INTVAL (operands[2]) != -128)))
5706 {
5707 operands[2] = GEN_INT (-INTVAL (operands[2]));
5708 return "sub{l}\t{%2, %k0|%k0, %2}";
5709 }
5710 return "add{l}\t{%2, %k0|%k0, %2}";
5711 }
5712 }
5713 [(set (attr "type")
5714 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5715 (const_string "incdec")
5716 (const_string "alu")))
5717 (set_attr "mode" "SI")])
5718
5719 ; For comparisons against 1, -1 and 128, we may generate better code
5720 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5721 ; is matched then. We can't accept general immediate, because for
5722 ; case of overflows, the result is messed up.
5723 ; This pattern also don't hold of 0x80000000, since the value overflows
5724 ; when negated.
5725 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5726 ; only for comparisons not depending on it.
5727 (define_insn "*addsi_4"
5728 [(set (reg FLAGS_REG)
5729 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5730 (match_operand:SI 2 "const_int_operand" "n")))
5731 (clobber (match_scratch:SI 0 "=rm"))]
5732 "ix86_match_ccmode (insn, CCGCmode)
5733 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5734 {
5735 switch (get_attr_type (insn))
5736 {
5737 case TYPE_INCDEC:
5738 if (operands[2] == constm1_rtx)
5739 return "inc{l}\t%0";
5740 else
5741 {
5742 gcc_assert (operands[2] == const1_rtx);
5743 return "dec{l}\t%0";
5744 }
5745
5746 default:
5747 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5748 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5749 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5750 if ((INTVAL (operands[2]) == -128
5751 || (INTVAL (operands[2]) > 0
5752 && INTVAL (operands[2]) != 128)))
5753 return "sub{l}\t{%2, %0|%0, %2}";
5754 operands[2] = GEN_INT (-INTVAL (operands[2]));
5755 return "add{l}\t{%2, %0|%0, %2}";
5756 }
5757 }
5758 [(set (attr "type")
5759 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5760 (const_string "incdec")
5761 (const_string "alu")))
5762 (set_attr "mode" "SI")])
5763
5764 (define_insn "*addsi_5"
5765 [(set (reg FLAGS_REG)
5766 (compare
5767 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5768 (match_operand:SI 2 "general_operand" "rmni"))
5769 (const_int 0)))
5770 (clobber (match_scratch:SI 0 "=r"))]
5771 "ix86_match_ccmode (insn, CCGOCmode)
5772 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5773 /* Current assemblers are broken and do not allow @GOTOFF in
5774 ought but a memory context. */
5775 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5776 {
5777 switch (get_attr_type (insn))
5778 {
5779 case TYPE_INCDEC:
5780 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5781 if (operands[2] == const1_rtx)
5782 return "inc{l}\t%0";
5783 else
5784 {
5785 gcc_assert (operands[2] == constm1_rtx);
5786 return "dec{l}\t%0";
5787 }
5788
5789 default:
5790 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5791 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5792 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5793 if (GET_CODE (operands[2]) == CONST_INT
5794 && (INTVAL (operands[2]) == 128
5795 || (INTVAL (operands[2]) < 0
5796 && INTVAL (operands[2]) != -128)))
5797 {
5798 operands[2] = GEN_INT (-INTVAL (operands[2]));
5799 return "sub{l}\t{%2, %0|%0, %2}";
5800 }
5801 return "add{l}\t{%2, %0|%0, %2}";
5802 }
5803 }
5804 [(set (attr "type")
5805 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5806 (const_string "incdec")
5807 (const_string "alu")))
5808 (set_attr "mode" "SI")])
5809
5810 (define_expand "addhi3"
5811 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5812 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5813 (match_operand:HI 2 "general_operand" "")))
5814 (clobber (reg:CC FLAGS_REG))])]
5815 "TARGET_HIMODE_MATH"
5816 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5817
5818 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5819 ;; type optimizations enabled by define-splits. This is not important
5820 ;; for PII, and in fact harmful because of partial register stalls.
5821
5822 (define_insn "*addhi_1_lea"
5823 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5824 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5825 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5826 (clobber (reg:CC FLAGS_REG))]
5827 "!TARGET_PARTIAL_REG_STALL
5828 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5829 {
5830 switch (get_attr_type (insn))
5831 {
5832 case TYPE_LEA:
5833 return "#";
5834 case TYPE_INCDEC:
5835 if (operands[2] == const1_rtx)
5836 return "inc{w}\t%0";
5837 else
5838 {
5839 gcc_assert (operands[2] == constm1_rtx);
5840 return "dec{w}\t%0";
5841 }
5842
5843 default:
5844 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5845 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5846 if (GET_CODE (operands[2]) == CONST_INT
5847 && (INTVAL (operands[2]) == 128
5848 || (INTVAL (operands[2]) < 0
5849 && INTVAL (operands[2]) != -128)))
5850 {
5851 operands[2] = GEN_INT (-INTVAL (operands[2]));
5852 return "sub{w}\t{%2, %0|%0, %2}";
5853 }
5854 return "add{w}\t{%2, %0|%0, %2}";
5855 }
5856 }
5857 [(set (attr "type")
5858 (if_then_else (eq_attr "alternative" "2")
5859 (const_string "lea")
5860 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5861 (const_string "incdec")
5862 (const_string "alu"))))
5863 (set_attr "mode" "HI,HI,SI")])
5864
5865 (define_insn "*addhi_1"
5866 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5867 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5868 (match_operand:HI 2 "general_operand" "ri,rm")))
5869 (clobber (reg:CC FLAGS_REG))]
5870 "TARGET_PARTIAL_REG_STALL
5871 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5872 {
5873 switch (get_attr_type (insn))
5874 {
5875 case TYPE_INCDEC:
5876 if (operands[2] == const1_rtx)
5877 return "inc{w}\t%0";
5878 else
5879 {
5880 gcc_assert (operands[2] == constm1_rtx);
5881 return "dec{w}\t%0";
5882 }
5883
5884 default:
5885 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5886 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5887 if (GET_CODE (operands[2]) == CONST_INT
5888 && (INTVAL (operands[2]) == 128
5889 || (INTVAL (operands[2]) < 0
5890 && INTVAL (operands[2]) != -128)))
5891 {
5892 operands[2] = GEN_INT (-INTVAL (operands[2]));
5893 return "sub{w}\t{%2, %0|%0, %2}";
5894 }
5895 return "add{w}\t{%2, %0|%0, %2}";
5896 }
5897 }
5898 [(set (attr "type")
5899 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5900 (const_string "incdec")
5901 (const_string "alu")))
5902 (set_attr "mode" "HI")])
5903
5904 (define_insn "*addhi_2"
5905 [(set (reg FLAGS_REG)
5906 (compare
5907 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5908 (match_operand:HI 2 "general_operand" "rmni,rni"))
5909 (const_int 0)))
5910 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5911 (plus:HI (match_dup 1) (match_dup 2)))]
5912 "ix86_match_ccmode (insn, CCGOCmode)
5913 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5914 {
5915 switch (get_attr_type (insn))
5916 {
5917 case TYPE_INCDEC:
5918 if (operands[2] == const1_rtx)
5919 return "inc{w}\t%0";
5920 else
5921 {
5922 gcc_assert (operands[2] == constm1_rtx);
5923 return "dec{w}\t%0";
5924 }
5925
5926 default:
5927 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5928 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5929 if (GET_CODE (operands[2]) == CONST_INT
5930 && (INTVAL (operands[2]) == 128
5931 || (INTVAL (operands[2]) < 0
5932 && INTVAL (operands[2]) != -128)))
5933 {
5934 operands[2] = GEN_INT (-INTVAL (operands[2]));
5935 return "sub{w}\t{%2, %0|%0, %2}";
5936 }
5937 return "add{w}\t{%2, %0|%0, %2}";
5938 }
5939 }
5940 [(set (attr "type")
5941 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5942 (const_string "incdec")
5943 (const_string "alu")))
5944 (set_attr "mode" "HI")])
5945
5946 (define_insn "*addhi_3"
5947 [(set (reg FLAGS_REG)
5948 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5949 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5950 (clobber (match_scratch:HI 0 "=r"))]
5951 "ix86_match_ccmode (insn, CCZmode)
5952 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5953 {
5954 switch (get_attr_type (insn))
5955 {
5956 case TYPE_INCDEC:
5957 if (operands[2] == const1_rtx)
5958 return "inc{w}\t%0";
5959 else
5960 {
5961 gcc_assert (operands[2] == constm1_rtx);
5962 return "dec{w}\t%0";
5963 }
5964
5965 default:
5966 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5967 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5968 if (GET_CODE (operands[2]) == CONST_INT
5969 && (INTVAL (operands[2]) == 128
5970 || (INTVAL (operands[2]) < 0
5971 && INTVAL (operands[2]) != -128)))
5972 {
5973 operands[2] = GEN_INT (-INTVAL (operands[2]));
5974 return "sub{w}\t{%2, %0|%0, %2}";
5975 }
5976 return "add{w}\t{%2, %0|%0, %2}";
5977 }
5978 }
5979 [(set (attr "type")
5980 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5981 (const_string "incdec")
5982 (const_string "alu")))
5983 (set_attr "mode" "HI")])
5984
5985 ; See comments above addsi_4 for details.
5986 (define_insn "*addhi_4"
5987 [(set (reg FLAGS_REG)
5988 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5989 (match_operand:HI 2 "const_int_operand" "n")))
5990 (clobber (match_scratch:HI 0 "=rm"))]
5991 "ix86_match_ccmode (insn, CCGCmode)
5992 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5993 {
5994 switch (get_attr_type (insn))
5995 {
5996 case TYPE_INCDEC:
5997 if (operands[2] == constm1_rtx)
5998 return "inc{w}\t%0";
5999 else
6000 {
6001 gcc_assert (operands[2] == const1_rtx);
6002 return "dec{w}\t%0";
6003 }
6004
6005 default:
6006 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6007 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6008 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6009 if ((INTVAL (operands[2]) == -128
6010 || (INTVAL (operands[2]) > 0
6011 && INTVAL (operands[2]) != 128)))
6012 return "sub{w}\t{%2, %0|%0, %2}";
6013 operands[2] = GEN_INT (-INTVAL (operands[2]));
6014 return "add{w}\t{%2, %0|%0, %2}";
6015 }
6016 }
6017 [(set (attr "type")
6018 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6019 (const_string "incdec")
6020 (const_string "alu")))
6021 (set_attr "mode" "SI")])
6022
6023
6024 (define_insn "*addhi_5"
6025 [(set (reg FLAGS_REG)
6026 (compare
6027 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6028 (match_operand:HI 2 "general_operand" "rmni"))
6029 (const_int 0)))
6030 (clobber (match_scratch:HI 0 "=r"))]
6031 "ix86_match_ccmode (insn, CCGOCmode)
6032 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6033 {
6034 switch (get_attr_type (insn))
6035 {
6036 case TYPE_INCDEC:
6037 if (operands[2] == const1_rtx)
6038 return "inc{w}\t%0";
6039 else
6040 {
6041 gcc_assert (operands[2] == constm1_rtx);
6042 return "dec{w}\t%0";
6043 }
6044
6045 default:
6046 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6047 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6048 if (GET_CODE (operands[2]) == CONST_INT
6049 && (INTVAL (operands[2]) == 128
6050 || (INTVAL (operands[2]) < 0
6051 && INTVAL (operands[2]) != -128)))
6052 {
6053 operands[2] = GEN_INT (-INTVAL (operands[2]));
6054 return "sub{w}\t{%2, %0|%0, %2}";
6055 }
6056 return "add{w}\t{%2, %0|%0, %2}";
6057 }
6058 }
6059 [(set (attr "type")
6060 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6061 (const_string "incdec")
6062 (const_string "alu")))
6063 (set_attr "mode" "HI")])
6064
6065 (define_expand "addqi3"
6066 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6067 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6068 (match_operand:QI 2 "general_operand" "")))
6069 (clobber (reg:CC FLAGS_REG))])]
6070 "TARGET_QIMODE_MATH"
6071 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6072
6073 ;; %%% Potential partial reg stall on alternative 2. What to do?
6074 (define_insn "*addqi_1_lea"
6075 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6076 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6077 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6078 (clobber (reg:CC FLAGS_REG))]
6079 "!TARGET_PARTIAL_REG_STALL
6080 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6081 {
6082 int widen = (which_alternative == 2);
6083 switch (get_attr_type (insn))
6084 {
6085 case TYPE_LEA:
6086 return "#";
6087 case TYPE_INCDEC:
6088 if (operands[2] == const1_rtx)
6089 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6090 else
6091 {
6092 gcc_assert (operands[2] == constm1_rtx);
6093 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6094 }
6095
6096 default:
6097 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6098 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6099 if (GET_CODE (operands[2]) == CONST_INT
6100 && (INTVAL (operands[2]) == 128
6101 || (INTVAL (operands[2]) < 0
6102 && INTVAL (operands[2]) != -128)))
6103 {
6104 operands[2] = GEN_INT (-INTVAL (operands[2]));
6105 if (widen)
6106 return "sub{l}\t{%2, %k0|%k0, %2}";
6107 else
6108 return "sub{b}\t{%2, %0|%0, %2}";
6109 }
6110 if (widen)
6111 return "add{l}\t{%k2, %k0|%k0, %k2}";
6112 else
6113 return "add{b}\t{%2, %0|%0, %2}";
6114 }
6115 }
6116 [(set (attr "type")
6117 (if_then_else (eq_attr "alternative" "3")
6118 (const_string "lea")
6119 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6120 (const_string "incdec")
6121 (const_string "alu"))))
6122 (set_attr "mode" "QI,QI,SI,SI")])
6123
6124 (define_insn "*addqi_1"
6125 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6126 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6127 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6128 (clobber (reg:CC FLAGS_REG))]
6129 "TARGET_PARTIAL_REG_STALL
6130 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6131 {
6132 int widen = (which_alternative == 2);
6133 switch (get_attr_type (insn))
6134 {
6135 case TYPE_INCDEC:
6136 if (operands[2] == const1_rtx)
6137 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6138 else
6139 {
6140 gcc_assert (operands[2] == constm1_rtx);
6141 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6142 }
6143
6144 default:
6145 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6146 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6147 if (GET_CODE (operands[2]) == CONST_INT
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 if (widen)
6154 return "sub{l}\t{%2, %k0|%k0, %2}";
6155 else
6156 return "sub{b}\t{%2, %0|%0, %2}";
6157 }
6158 if (widen)
6159 return "add{l}\t{%k2, %k0|%k0, %k2}";
6160 else
6161 return "add{b}\t{%2, %0|%0, %2}";
6162 }
6163 }
6164 [(set (attr "type")
6165 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6166 (const_string "incdec")
6167 (const_string "alu")))
6168 (set_attr "mode" "QI,QI,SI")])
6169
6170 (define_insn "*addqi_1_slp"
6171 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6172 (plus:QI (match_dup 0)
6173 (match_operand:QI 1 "general_operand" "qn,qnm")))
6174 (clobber (reg:CC FLAGS_REG))]
6175 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6176 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6177 {
6178 switch (get_attr_type (insn))
6179 {
6180 case TYPE_INCDEC:
6181 if (operands[1] == const1_rtx)
6182 return "inc{b}\t%0";
6183 else
6184 {
6185 gcc_assert (operands[1] == constm1_rtx);
6186 return "dec{b}\t%0";
6187 }
6188
6189 default:
6190 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6191 if (GET_CODE (operands[1]) == CONST_INT
6192 && INTVAL (operands[1]) < 0)
6193 {
6194 operands[1] = GEN_INT (-INTVAL (operands[1]));
6195 return "sub{b}\t{%1, %0|%0, %1}";
6196 }
6197 return "add{b}\t{%1, %0|%0, %1}";
6198 }
6199 }
6200 [(set (attr "type")
6201 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6202 (const_string "incdec")
6203 (const_string "alu1")))
6204 (set (attr "memory")
6205 (if_then_else (match_operand 1 "memory_operand" "")
6206 (const_string "load")
6207 (const_string "none")))
6208 (set_attr "mode" "QI")])
6209
6210 (define_insn "*addqi_2"
6211 [(set (reg FLAGS_REG)
6212 (compare
6213 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6214 (match_operand:QI 2 "general_operand" "qmni,qni"))
6215 (const_int 0)))
6216 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6217 (plus:QI (match_dup 1) (match_dup 2)))]
6218 "ix86_match_ccmode (insn, CCGOCmode)
6219 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6220 {
6221 switch (get_attr_type (insn))
6222 {
6223 case TYPE_INCDEC:
6224 if (operands[2] == const1_rtx)
6225 return "inc{b}\t%0";
6226 else
6227 {
6228 gcc_assert (operands[2] == constm1_rtx
6229 || (GET_CODE (operands[2]) == CONST_INT
6230 && INTVAL (operands[2]) == 255));
6231 return "dec{b}\t%0";
6232 }
6233
6234 default:
6235 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6236 if (GET_CODE (operands[2]) == CONST_INT
6237 && INTVAL (operands[2]) < 0)
6238 {
6239 operands[2] = GEN_INT (-INTVAL (operands[2]));
6240 return "sub{b}\t{%2, %0|%0, %2}";
6241 }
6242 return "add{b}\t{%2, %0|%0, %2}";
6243 }
6244 }
6245 [(set (attr "type")
6246 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6247 (const_string "incdec")
6248 (const_string "alu")))
6249 (set_attr "mode" "QI")])
6250
6251 (define_insn "*addqi_3"
6252 [(set (reg FLAGS_REG)
6253 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6254 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6255 (clobber (match_scratch:QI 0 "=q"))]
6256 "ix86_match_ccmode (insn, CCZmode)
6257 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6258 {
6259 switch (get_attr_type (insn))
6260 {
6261 case TYPE_INCDEC:
6262 if (operands[2] == const1_rtx)
6263 return "inc{b}\t%0";
6264 else
6265 {
6266 gcc_assert (operands[2] == constm1_rtx
6267 || (GET_CODE (operands[2]) == CONST_INT
6268 && INTVAL (operands[2]) == 255));
6269 return "dec{b}\t%0";
6270 }
6271
6272 default:
6273 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6274 if (GET_CODE (operands[2]) == CONST_INT
6275 && INTVAL (operands[2]) < 0)
6276 {
6277 operands[2] = GEN_INT (-INTVAL (operands[2]));
6278 return "sub{b}\t{%2, %0|%0, %2}";
6279 }
6280 return "add{b}\t{%2, %0|%0, %2}";
6281 }
6282 }
6283 [(set (attr "type")
6284 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6285 (const_string "incdec")
6286 (const_string "alu")))
6287 (set_attr "mode" "QI")])
6288
6289 ; See comments above addsi_4 for details.
6290 (define_insn "*addqi_4"
6291 [(set (reg FLAGS_REG)
6292 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6293 (match_operand:QI 2 "const_int_operand" "n")))
6294 (clobber (match_scratch:QI 0 "=qm"))]
6295 "ix86_match_ccmode (insn, CCGCmode)
6296 && (INTVAL (operands[2]) & 0xff) != 0x80"
6297 {
6298 switch (get_attr_type (insn))
6299 {
6300 case TYPE_INCDEC:
6301 if (operands[2] == constm1_rtx
6302 || (GET_CODE (operands[2]) == CONST_INT
6303 && INTVAL (operands[2]) == 255))
6304 return "inc{b}\t%0";
6305 else
6306 {
6307 gcc_assert (operands[2] == const1_rtx);
6308 return "dec{b}\t%0";
6309 }
6310
6311 default:
6312 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6313 if (INTVAL (operands[2]) < 0)
6314 {
6315 operands[2] = GEN_INT (-INTVAL (operands[2]));
6316 return "add{b}\t{%2, %0|%0, %2}";
6317 }
6318 return "sub{b}\t{%2, %0|%0, %2}";
6319 }
6320 }
6321 [(set (attr "type")
6322 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6323 (const_string "incdec")
6324 (const_string "alu")))
6325 (set_attr "mode" "QI")])
6326
6327
6328 (define_insn "*addqi_5"
6329 [(set (reg FLAGS_REG)
6330 (compare
6331 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6332 (match_operand:QI 2 "general_operand" "qmni"))
6333 (const_int 0)))
6334 (clobber (match_scratch:QI 0 "=q"))]
6335 "ix86_match_ccmode (insn, CCGOCmode)
6336 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6337 {
6338 switch (get_attr_type (insn))
6339 {
6340 case TYPE_INCDEC:
6341 if (operands[2] == const1_rtx)
6342 return "inc{b}\t%0";
6343 else
6344 {
6345 gcc_assert (operands[2] == constm1_rtx
6346 || (GET_CODE (operands[2]) == CONST_INT
6347 && INTVAL (operands[2]) == 255));
6348 return "dec{b}\t%0";
6349 }
6350
6351 default:
6352 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6353 if (GET_CODE (operands[2]) == CONST_INT
6354 && INTVAL (operands[2]) < 0)
6355 {
6356 operands[2] = GEN_INT (-INTVAL (operands[2]));
6357 return "sub{b}\t{%2, %0|%0, %2}";
6358 }
6359 return "add{b}\t{%2, %0|%0, %2}";
6360 }
6361 }
6362 [(set (attr "type")
6363 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6364 (const_string "incdec")
6365 (const_string "alu")))
6366 (set_attr "mode" "QI")])
6367
6368
6369 (define_insn "addqi_ext_1"
6370 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6371 (const_int 8)
6372 (const_int 8))
6373 (plus:SI
6374 (zero_extract:SI
6375 (match_operand 1 "ext_register_operand" "0")
6376 (const_int 8)
6377 (const_int 8))
6378 (match_operand:QI 2 "general_operand" "Qmn")))
6379 (clobber (reg:CC FLAGS_REG))]
6380 "!TARGET_64BIT"
6381 {
6382 switch (get_attr_type (insn))
6383 {
6384 case TYPE_INCDEC:
6385 if (operands[2] == const1_rtx)
6386 return "inc{b}\t%h0";
6387 else
6388 {
6389 gcc_assert (operands[2] == constm1_rtx
6390 || (GET_CODE (operands[2]) == CONST_INT
6391 && INTVAL (operands[2]) == 255));
6392 return "dec{b}\t%h0";
6393 }
6394
6395 default:
6396 return "add{b}\t{%2, %h0|%h0, %2}";
6397 }
6398 }
6399 [(set (attr "type")
6400 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6401 (const_string "incdec")
6402 (const_string "alu")))
6403 (set_attr "mode" "QI")])
6404
6405 (define_insn "*addqi_ext_1_rex64"
6406 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6407 (const_int 8)
6408 (const_int 8))
6409 (plus:SI
6410 (zero_extract:SI
6411 (match_operand 1 "ext_register_operand" "0")
6412 (const_int 8)
6413 (const_int 8))
6414 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6415 (clobber (reg:CC FLAGS_REG))]
6416 "TARGET_64BIT"
6417 {
6418 switch (get_attr_type (insn))
6419 {
6420 case TYPE_INCDEC:
6421 if (operands[2] == const1_rtx)
6422 return "inc{b}\t%h0";
6423 else
6424 {
6425 gcc_assert (operands[2] == constm1_rtx
6426 || (GET_CODE (operands[2]) == CONST_INT
6427 && INTVAL (operands[2]) == 255));
6428 return "dec{b}\t%h0";
6429 }
6430
6431 default:
6432 return "add{b}\t{%2, %h0|%h0, %2}";
6433 }
6434 }
6435 [(set (attr "type")
6436 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6437 (const_string "incdec")
6438 (const_string "alu")))
6439 (set_attr "mode" "QI")])
6440
6441 (define_insn "*addqi_ext_2"
6442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6443 (const_int 8)
6444 (const_int 8))
6445 (plus:SI
6446 (zero_extract:SI
6447 (match_operand 1 "ext_register_operand" "%0")
6448 (const_int 8)
6449 (const_int 8))
6450 (zero_extract:SI
6451 (match_operand 2 "ext_register_operand" "Q")
6452 (const_int 8)
6453 (const_int 8))))
6454 (clobber (reg:CC FLAGS_REG))]
6455 ""
6456 "add{b}\t{%h2, %h0|%h0, %h2}"
6457 [(set_attr "type" "alu")
6458 (set_attr "mode" "QI")])
6459
6460 ;; The patterns that match these are at the end of this file.
6461
6462 (define_expand "addxf3"
6463 [(set (match_operand:XF 0 "register_operand" "")
6464 (plus:XF (match_operand:XF 1 "register_operand" "")
6465 (match_operand:XF 2 "register_operand" "")))]
6466 "TARGET_80387"
6467 "")
6468
6469 (define_expand "adddf3"
6470 [(set (match_operand:DF 0 "register_operand" "")
6471 (plus:DF (match_operand:DF 1 "register_operand" "")
6472 (match_operand:DF 2 "nonimmediate_operand" "")))]
6473 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6474 "")
6475
6476 (define_expand "addsf3"
6477 [(set (match_operand:SF 0 "register_operand" "")
6478 (plus:SF (match_operand:SF 1 "register_operand" "")
6479 (match_operand:SF 2 "nonimmediate_operand" "")))]
6480 "TARGET_80387 || TARGET_SSE_MATH"
6481 "")
6482 \f
6483 ;; Subtract instructions
6484
6485 ;; %%% splits for subditi3
6486
6487 (define_expand "subti3"
6488 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6489 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6490 (match_operand:TI 2 "x86_64_general_operand" "")))
6491 (clobber (reg:CC FLAGS_REG))])]
6492 "TARGET_64BIT"
6493 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6494
6495 (define_insn "*subti3_1"
6496 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6497 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6498 (match_operand:TI 2 "general_operand" "roiF,riF")))
6499 (clobber (reg:CC FLAGS_REG))]
6500 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6501 "#")
6502
6503 (define_split
6504 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6505 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6506 (match_operand:TI 2 "general_operand" "")))
6507 (clobber (reg:CC FLAGS_REG))]
6508 "TARGET_64BIT && reload_completed"
6509 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6510 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6511 (parallel [(set (match_dup 3)
6512 (minus:DI (match_dup 4)
6513 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6514 (match_dup 5))))
6515 (clobber (reg:CC FLAGS_REG))])]
6516 "split_ti (operands+0, 1, operands+0, operands+3);
6517 split_ti (operands+1, 1, operands+1, operands+4);
6518 split_ti (operands+2, 1, operands+2, operands+5);")
6519
6520 ;; %%% splits for subsidi3
6521
6522 (define_expand "subdi3"
6523 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6524 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6525 (match_operand:DI 2 "x86_64_general_operand" "")))
6526 (clobber (reg:CC FLAGS_REG))])]
6527 ""
6528 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6529
6530 (define_insn "*subdi3_1"
6531 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6532 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6533 (match_operand:DI 2 "general_operand" "roiF,riF")))
6534 (clobber (reg:CC FLAGS_REG))]
6535 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6536 "#")
6537
6538 (define_split
6539 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6540 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6541 (match_operand:DI 2 "general_operand" "")))
6542 (clobber (reg:CC FLAGS_REG))]
6543 "!TARGET_64BIT && reload_completed"
6544 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6545 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6546 (parallel [(set (match_dup 3)
6547 (minus:SI (match_dup 4)
6548 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6549 (match_dup 5))))
6550 (clobber (reg:CC FLAGS_REG))])]
6551 "split_di (operands+0, 1, operands+0, operands+3);
6552 split_di (operands+1, 1, operands+1, operands+4);
6553 split_di (operands+2, 1, operands+2, operands+5);")
6554
6555 (define_insn "subdi3_carry_rex64"
6556 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6557 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6558 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6559 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6560 (clobber (reg:CC FLAGS_REG))]
6561 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6562 "sbb{q}\t{%2, %0|%0, %2}"
6563 [(set_attr "type" "alu")
6564 (set_attr "pent_pair" "pu")
6565 (set_attr "mode" "DI")])
6566
6567 (define_insn "*subdi_1_rex64"
6568 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6569 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6570 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6571 (clobber (reg:CC FLAGS_REG))]
6572 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6573 "sub{q}\t{%2, %0|%0, %2}"
6574 [(set_attr "type" "alu")
6575 (set_attr "mode" "DI")])
6576
6577 (define_insn "*subdi_2_rex64"
6578 [(set (reg FLAGS_REG)
6579 (compare
6580 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6581 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6582 (const_int 0)))
6583 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6584 (minus:DI (match_dup 1) (match_dup 2)))]
6585 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6586 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6587 "sub{q}\t{%2, %0|%0, %2}"
6588 [(set_attr "type" "alu")
6589 (set_attr "mode" "DI")])
6590
6591 (define_insn "*subdi_3_rex63"
6592 [(set (reg FLAGS_REG)
6593 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6594 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6595 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6596 (minus:DI (match_dup 1) (match_dup 2)))]
6597 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6598 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6599 "sub{q}\t{%2, %0|%0, %2}"
6600 [(set_attr "type" "alu")
6601 (set_attr "mode" "DI")])
6602
6603 (define_insn "subqi3_carry"
6604 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6605 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6606 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6607 (match_operand:QI 2 "general_operand" "qi,qm"))))
6608 (clobber (reg:CC FLAGS_REG))]
6609 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6610 "sbb{b}\t{%2, %0|%0, %2}"
6611 [(set_attr "type" "alu")
6612 (set_attr "pent_pair" "pu")
6613 (set_attr "mode" "QI")])
6614
6615 (define_insn "subhi3_carry"
6616 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6617 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6618 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6619 (match_operand:HI 2 "general_operand" "ri,rm"))))
6620 (clobber (reg:CC FLAGS_REG))]
6621 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6622 "sbb{w}\t{%2, %0|%0, %2}"
6623 [(set_attr "type" "alu")
6624 (set_attr "pent_pair" "pu")
6625 (set_attr "mode" "HI")])
6626
6627 (define_insn "subsi3_carry"
6628 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6629 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6630 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6631 (match_operand:SI 2 "general_operand" "ri,rm"))))
6632 (clobber (reg:CC FLAGS_REG))]
6633 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6634 "sbb{l}\t{%2, %0|%0, %2}"
6635 [(set_attr "type" "alu")
6636 (set_attr "pent_pair" "pu")
6637 (set_attr "mode" "SI")])
6638
6639 (define_insn "subsi3_carry_zext"
6640 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6641 (zero_extend:DI
6642 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6643 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6644 (match_operand:SI 2 "general_operand" "ri,rm")))))
6645 (clobber (reg:CC FLAGS_REG))]
6646 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6647 "sbb{l}\t{%2, %k0|%k0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "pent_pair" "pu")
6650 (set_attr "mode" "SI")])
6651
6652 (define_expand "subsi3"
6653 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6654 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6655 (match_operand:SI 2 "general_operand" "")))
6656 (clobber (reg:CC FLAGS_REG))])]
6657 ""
6658 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6659
6660 (define_insn "*subsi_1"
6661 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6662 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6663 (match_operand:SI 2 "general_operand" "ri,rm")))
6664 (clobber (reg:CC FLAGS_REG))]
6665 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6666 "sub{l}\t{%2, %0|%0, %2}"
6667 [(set_attr "type" "alu")
6668 (set_attr "mode" "SI")])
6669
6670 (define_insn "*subsi_1_zext"
6671 [(set (match_operand:DI 0 "register_operand" "=r")
6672 (zero_extend:DI
6673 (minus:SI (match_operand:SI 1 "register_operand" "0")
6674 (match_operand:SI 2 "general_operand" "rim"))))
6675 (clobber (reg:CC FLAGS_REG))]
6676 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6677 "sub{l}\t{%2, %k0|%k0, %2}"
6678 [(set_attr "type" "alu")
6679 (set_attr "mode" "SI")])
6680
6681 (define_insn "*subsi_2"
6682 [(set (reg FLAGS_REG)
6683 (compare
6684 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6685 (match_operand:SI 2 "general_operand" "ri,rm"))
6686 (const_int 0)))
6687 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6688 (minus:SI (match_dup 1) (match_dup 2)))]
6689 "ix86_match_ccmode (insn, CCGOCmode)
6690 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6691 "sub{l}\t{%2, %0|%0, %2}"
6692 [(set_attr "type" "alu")
6693 (set_attr "mode" "SI")])
6694
6695 (define_insn "*subsi_2_zext"
6696 [(set (reg FLAGS_REG)
6697 (compare
6698 (minus:SI (match_operand:SI 1 "register_operand" "0")
6699 (match_operand:SI 2 "general_operand" "rim"))
6700 (const_int 0)))
6701 (set (match_operand:DI 0 "register_operand" "=r")
6702 (zero_extend:DI
6703 (minus:SI (match_dup 1)
6704 (match_dup 2))))]
6705 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6706 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707 "sub{l}\t{%2, %k0|%k0, %2}"
6708 [(set_attr "type" "alu")
6709 (set_attr "mode" "SI")])
6710
6711 (define_insn "*subsi_3"
6712 [(set (reg FLAGS_REG)
6713 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6714 (match_operand:SI 2 "general_operand" "ri,rm")))
6715 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6716 (minus:SI (match_dup 1) (match_dup 2)))]
6717 "ix86_match_ccmode (insn, CCmode)
6718 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6719 "sub{l}\t{%2, %0|%0, %2}"
6720 [(set_attr "type" "alu")
6721 (set_attr "mode" "SI")])
6722
6723 (define_insn "*subsi_3_zext"
6724 [(set (reg FLAGS_REG)
6725 (compare (match_operand:SI 1 "register_operand" "0")
6726 (match_operand:SI 2 "general_operand" "rim")))
6727 (set (match_operand:DI 0 "register_operand" "=r")
6728 (zero_extend:DI
6729 (minus:SI (match_dup 1)
6730 (match_dup 2))))]
6731 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6732 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6733 "sub{l}\t{%2, %1|%1, %2}"
6734 [(set_attr "type" "alu")
6735 (set_attr "mode" "DI")])
6736
6737 (define_expand "subhi3"
6738 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6739 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6740 (match_operand:HI 2 "general_operand" "")))
6741 (clobber (reg:CC FLAGS_REG))])]
6742 "TARGET_HIMODE_MATH"
6743 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6744
6745 (define_insn "*subhi_1"
6746 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6747 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6748 (match_operand:HI 2 "general_operand" "ri,rm")))
6749 (clobber (reg:CC FLAGS_REG))]
6750 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6751 "sub{w}\t{%2, %0|%0, %2}"
6752 [(set_attr "type" "alu")
6753 (set_attr "mode" "HI")])
6754
6755 (define_insn "*subhi_2"
6756 [(set (reg FLAGS_REG)
6757 (compare
6758 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6759 (match_operand:HI 2 "general_operand" "ri,rm"))
6760 (const_int 0)))
6761 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6762 (minus:HI (match_dup 1) (match_dup 2)))]
6763 "ix86_match_ccmode (insn, CCGOCmode)
6764 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6765 "sub{w}\t{%2, %0|%0, %2}"
6766 [(set_attr "type" "alu")
6767 (set_attr "mode" "HI")])
6768
6769 (define_insn "*subhi_3"
6770 [(set (reg FLAGS_REG)
6771 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6772 (match_operand:HI 2 "general_operand" "ri,rm")))
6773 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6774 (minus:HI (match_dup 1) (match_dup 2)))]
6775 "ix86_match_ccmode (insn, CCmode)
6776 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6777 "sub{w}\t{%2, %0|%0, %2}"
6778 [(set_attr "type" "alu")
6779 (set_attr "mode" "HI")])
6780
6781 (define_expand "subqi3"
6782 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6783 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6784 (match_operand:QI 2 "general_operand" "")))
6785 (clobber (reg:CC FLAGS_REG))])]
6786 "TARGET_QIMODE_MATH"
6787 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6788
6789 (define_insn "*subqi_1"
6790 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6791 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6792 (match_operand:QI 2 "general_operand" "qn,qmn")))
6793 (clobber (reg:CC FLAGS_REG))]
6794 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6795 "sub{b}\t{%2, %0|%0, %2}"
6796 [(set_attr "type" "alu")
6797 (set_attr "mode" "QI")])
6798
6799 (define_insn "*subqi_1_slp"
6800 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6801 (minus:QI (match_dup 0)
6802 (match_operand:QI 1 "general_operand" "qn,qmn")))
6803 (clobber (reg:CC FLAGS_REG))]
6804 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6805 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6806 "sub{b}\t{%1, %0|%0, %1}"
6807 [(set_attr "type" "alu1")
6808 (set_attr "mode" "QI")])
6809
6810 (define_insn "*subqi_2"
6811 [(set (reg FLAGS_REG)
6812 (compare
6813 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6814 (match_operand:QI 2 "general_operand" "qi,qm"))
6815 (const_int 0)))
6816 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6817 (minus:HI (match_dup 1) (match_dup 2)))]
6818 "ix86_match_ccmode (insn, CCGOCmode)
6819 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6820 "sub{b}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "mode" "QI")])
6823
6824 (define_insn "*subqi_3"
6825 [(set (reg FLAGS_REG)
6826 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6827 (match_operand:QI 2 "general_operand" "qi,qm")))
6828 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6829 (minus:HI (match_dup 1) (match_dup 2)))]
6830 "ix86_match_ccmode (insn, CCmode)
6831 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6832 "sub{b}\t{%2, %0|%0, %2}"
6833 [(set_attr "type" "alu")
6834 (set_attr "mode" "QI")])
6835
6836 ;; The patterns that match these are at the end of this file.
6837
6838 (define_expand "subxf3"
6839 [(set (match_operand:XF 0 "register_operand" "")
6840 (minus:XF (match_operand:XF 1 "register_operand" "")
6841 (match_operand:XF 2 "register_operand" "")))]
6842 "TARGET_80387"
6843 "")
6844
6845 (define_expand "subdf3"
6846 [(set (match_operand:DF 0 "register_operand" "")
6847 (minus:DF (match_operand:DF 1 "register_operand" "")
6848 (match_operand:DF 2 "nonimmediate_operand" "")))]
6849 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6850 "")
6851
6852 (define_expand "subsf3"
6853 [(set (match_operand:SF 0 "register_operand" "")
6854 (minus:SF (match_operand:SF 1 "register_operand" "")
6855 (match_operand:SF 2 "nonimmediate_operand" "")))]
6856 "TARGET_80387 || TARGET_SSE_MATH"
6857 "")
6858 \f
6859 ;; Multiply instructions
6860
6861 (define_expand "muldi3"
6862 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6863 (mult:DI (match_operand:DI 1 "register_operand" "")
6864 (match_operand:DI 2 "x86_64_general_operand" "")))
6865 (clobber (reg:CC FLAGS_REG))])]
6866 "TARGET_64BIT"
6867 "")
6868
6869 (define_insn "*muldi3_1_rex64"
6870 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6871 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6872 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6873 (clobber (reg:CC FLAGS_REG))]
6874 "TARGET_64BIT
6875 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6876 "@
6877 imul{q}\t{%2, %1, %0|%0, %1, %2}
6878 imul{q}\t{%2, %1, %0|%0, %1, %2}
6879 imul{q}\t{%2, %0|%0, %2}"
6880 [(set_attr "type" "imul")
6881 (set_attr "prefix_0f" "0,0,1")
6882 (set (attr "athlon_decode")
6883 (cond [(eq_attr "cpu" "athlon")
6884 (const_string "vector")
6885 (eq_attr "alternative" "1")
6886 (const_string "vector")
6887 (and (eq_attr "alternative" "2")
6888 (match_operand 1 "memory_operand" ""))
6889 (const_string "vector")]
6890 (const_string "direct")))
6891 (set_attr "mode" "DI")])
6892
6893 (define_expand "mulsi3"
6894 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6895 (mult:SI (match_operand:SI 1 "register_operand" "")
6896 (match_operand:SI 2 "general_operand" "")))
6897 (clobber (reg:CC FLAGS_REG))])]
6898 ""
6899 "")
6900
6901 (define_insn "*mulsi3_1"
6902 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6903 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6904 (match_operand:SI 2 "general_operand" "K,i,mr")))
6905 (clobber (reg:CC FLAGS_REG))]
6906 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6907 "@
6908 imul{l}\t{%2, %1, %0|%0, %1, %2}
6909 imul{l}\t{%2, %1, %0|%0, %1, %2}
6910 imul{l}\t{%2, %0|%0, %2}"
6911 [(set_attr "type" "imul")
6912 (set_attr "prefix_0f" "0,0,1")
6913 (set (attr "athlon_decode")
6914 (cond [(eq_attr "cpu" "athlon")
6915 (const_string "vector")
6916 (eq_attr "alternative" "1")
6917 (const_string "vector")
6918 (and (eq_attr "alternative" "2")
6919 (match_operand 1 "memory_operand" ""))
6920 (const_string "vector")]
6921 (const_string "direct")))
6922 (set_attr "mode" "SI")])
6923
6924 (define_insn "*mulsi3_1_zext"
6925 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6926 (zero_extend:DI
6927 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6928 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6929 (clobber (reg:CC FLAGS_REG))]
6930 "TARGET_64BIT
6931 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6932 "@
6933 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6934 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6935 imul{l}\t{%2, %k0|%k0, %2}"
6936 [(set_attr "type" "imul")
6937 (set_attr "prefix_0f" "0,0,1")
6938 (set (attr "athlon_decode")
6939 (cond [(eq_attr "cpu" "athlon")
6940 (const_string "vector")
6941 (eq_attr "alternative" "1")
6942 (const_string "vector")
6943 (and (eq_attr "alternative" "2")
6944 (match_operand 1 "memory_operand" ""))
6945 (const_string "vector")]
6946 (const_string "direct")))
6947 (set_attr "mode" "SI")])
6948
6949 (define_expand "mulhi3"
6950 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6951 (mult:HI (match_operand:HI 1 "register_operand" "")
6952 (match_operand:HI 2 "general_operand" "")))
6953 (clobber (reg:CC FLAGS_REG))])]
6954 "TARGET_HIMODE_MATH"
6955 "")
6956
6957 (define_insn "*mulhi3_1"
6958 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6959 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6960 (match_operand:HI 2 "general_operand" "K,i,mr")))
6961 (clobber (reg:CC FLAGS_REG))]
6962 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6963 "@
6964 imul{w}\t{%2, %1, %0|%0, %1, %2}
6965 imul{w}\t{%2, %1, %0|%0, %1, %2}
6966 imul{w}\t{%2, %0|%0, %2}"
6967 [(set_attr "type" "imul")
6968 (set_attr "prefix_0f" "0,0,1")
6969 (set (attr "athlon_decode")
6970 (cond [(eq_attr "cpu" "athlon")
6971 (const_string "vector")
6972 (eq_attr "alternative" "1,2")
6973 (const_string "vector")]
6974 (const_string "direct")))
6975 (set_attr "mode" "HI")])
6976
6977 (define_expand "mulqi3"
6978 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6979 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6980 (match_operand:QI 2 "register_operand" "")))
6981 (clobber (reg:CC FLAGS_REG))])]
6982 "TARGET_QIMODE_MATH"
6983 "")
6984
6985 (define_insn "*mulqi3_1"
6986 [(set (match_operand:QI 0 "register_operand" "=a")
6987 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6988 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6989 (clobber (reg:CC FLAGS_REG))]
6990 "TARGET_QIMODE_MATH
6991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6992 "mul{b}\t%2"
6993 [(set_attr "type" "imul")
6994 (set_attr "length_immediate" "0")
6995 (set (attr "athlon_decode")
6996 (if_then_else (eq_attr "cpu" "athlon")
6997 (const_string "vector")
6998 (const_string "direct")))
6999 (set_attr "mode" "QI")])
7000
7001 (define_expand "umulqihi3"
7002 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7003 (mult:HI (zero_extend:HI
7004 (match_operand:QI 1 "nonimmediate_operand" ""))
7005 (zero_extend:HI
7006 (match_operand:QI 2 "register_operand" ""))))
7007 (clobber (reg:CC FLAGS_REG))])]
7008 "TARGET_QIMODE_MATH"
7009 "")
7010
7011 (define_insn "*umulqihi3_1"
7012 [(set (match_operand:HI 0 "register_operand" "=a")
7013 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7014 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7015 (clobber (reg:CC FLAGS_REG))]
7016 "TARGET_QIMODE_MATH
7017 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7018 "mul{b}\t%2"
7019 [(set_attr "type" "imul")
7020 (set_attr "length_immediate" "0")
7021 (set (attr "athlon_decode")
7022 (if_then_else (eq_attr "cpu" "athlon")
7023 (const_string "vector")
7024 (const_string "direct")))
7025 (set_attr "mode" "QI")])
7026
7027 (define_expand "mulqihi3"
7028 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7029 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7030 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7031 (clobber (reg:CC FLAGS_REG))])]
7032 "TARGET_QIMODE_MATH"
7033 "")
7034
7035 (define_insn "*mulqihi3_insn"
7036 [(set (match_operand:HI 0 "register_operand" "=a")
7037 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7038 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7039 (clobber (reg:CC FLAGS_REG))]
7040 "TARGET_QIMODE_MATH
7041 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7042 "imul{b}\t%2"
7043 [(set_attr "type" "imul")
7044 (set_attr "length_immediate" "0")
7045 (set (attr "athlon_decode")
7046 (if_then_else (eq_attr "cpu" "athlon")
7047 (const_string "vector")
7048 (const_string "direct")))
7049 (set_attr "mode" "QI")])
7050
7051 (define_expand "umulditi3"
7052 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7053 (mult:TI (zero_extend:TI
7054 (match_operand:DI 1 "nonimmediate_operand" ""))
7055 (zero_extend:TI
7056 (match_operand:DI 2 "register_operand" ""))))
7057 (clobber (reg:CC FLAGS_REG))])]
7058 "TARGET_64BIT"
7059 "")
7060
7061 (define_insn "*umulditi3_insn"
7062 [(set (match_operand:TI 0 "register_operand" "=A")
7063 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7064 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7065 (clobber (reg:CC FLAGS_REG))]
7066 "TARGET_64BIT
7067 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7068 "mul{q}\t%2"
7069 [(set_attr "type" "imul")
7070 (set_attr "length_immediate" "0")
7071 (set (attr "athlon_decode")
7072 (if_then_else (eq_attr "cpu" "athlon")
7073 (const_string "vector")
7074 (const_string "double")))
7075 (set_attr "mode" "DI")])
7076
7077 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7078 (define_expand "umulsidi3"
7079 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7080 (mult:DI (zero_extend:DI
7081 (match_operand:SI 1 "nonimmediate_operand" ""))
7082 (zero_extend:DI
7083 (match_operand:SI 2 "register_operand" ""))))
7084 (clobber (reg:CC FLAGS_REG))])]
7085 "!TARGET_64BIT"
7086 "")
7087
7088 (define_insn "*umulsidi3_insn"
7089 [(set (match_operand:DI 0 "register_operand" "=A")
7090 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7091 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7092 (clobber (reg:CC FLAGS_REG))]
7093 "!TARGET_64BIT
7094 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7095 "mul{l}\t%2"
7096 [(set_attr "type" "imul")
7097 (set_attr "length_immediate" "0")
7098 (set (attr "athlon_decode")
7099 (if_then_else (eq_attr "cpu" "athlon")
7100 (const_string "vector")
7101 (const_string "double")))
7102 (set_attr "mode" "SI")])
7103
7104 (define_expand "mulditi3"
7105 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7106 (mult:TI (sign_extend:TI
7107 (match_operand:DI 1 "nonimmediate_operand" ""))
7108 (sign_extend:TI
7109 (match_operand:DI 2 "register_operand" ""))))
7110 (clobber (reg:CC FLAGS_REG))])]
7111 "TARGET_64BIT"
7112 "")
7113
7114 (define_insn "*mulditi3_insn"
7115 [(set (match_operand:TI 0 "register_operand" "=A")
7116 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7117 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7118 (clobber (reg:CC FLAGS_REG))]
7119 "TARGET_64BIT
7120 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7121 "imul{q}\t%2"
7122 [(set_attr "type" "imul")
7123 (set_attr "length_immediate" "0")
7124 (set (attr "athlon_decode")
7125 (if_then_else (eq_attr "cpu" "athlon")
7126 (const_string "vector")
7127 (const_string "double")))
7128 (set_attr "mode" "DI")])
7129
7130 (define_expand "mulsidi3"
7131 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7132 (mult:DI (sign_extend:DI
7133 (match_operand:SI 1 "nonimmediate_operand" ""))
7134 (sign_extend:DI
7135 (match_operand:SI 2 "register_operand" ""))))
7136 (clobber (reg:CC FLAGS_REG))])]
7137 "!TARGET_64BIT"
7138 "")
7139
7140 (define_insn "*mulsidi3_insn"
7141 [(set (match_operand:DI 0 "register_operand" "=A")
7142 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7143 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7144 (clobber (reg:CC FLAGS_REG))]
7145 "!TARGET_64BIT
7146 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7147 "imul{l}\t%2"
7148 [(set_attr "type" "imul")
7149 (set_attr "length_immediate" "0")
7150 (set (attr "athlon_decode")
7151 (if_then_else (eq_attr "cpu" "athlon")
7152 (const_string "vector")
7153 (const_string "double")))
7154 (set_attr "mode" "SI")])
7155
7156 (define_expand "umuldi3_highpart"
7157 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7158 (truncate:DI
7159 (lshiftrt:TI
7160 (mult:TI (zero_extend:TI
7161 (match_operand:DI 1 "nonimmediate_operand" ""))
7162 (zero_extend:TI
7163 (match_operand:DI 2 "register_operand" "")))
7164 (const_int 64))))
7165 (clobber (match_scratch:DI 3 ""))
7166 (clobber (reg:CC FLAGS_REG))])]
7167 "TARGET_64BIT"
7168 "")
7169
7170 (define_insn "*umuldi3_highpart_rex64"
7171 [(set (match_operand:DI 0 "register_operand" "=d")
7172 (truncate:DI
7173 (lshiftrt:TI
7174 (mult:TI (zero_extend:TI
7175 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7176 (zero_extend:TI
7177 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7178 (const_int 64))))
7179 (clobber (match_scratch:DI 3 "=1"))
7180 (clobber (reg:CC FLAGS_REG))]
7181 "TARGET_64BIT
7182 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7183 "mul{q}\t%2"
7184 [(set_attr "type" "imul")
7185 (set_attr "length_immediate" "0")
7186 (set (attr "athlon_decode")
7187 (if_then_else (eq_attr "cpu" "athlon")
7188 (const_string "vector")
7189 (const_string "double")))
7190 (set_attr "mode" "DI")])
7191
7192 (define_expand "umulsi3_highpart"
7193 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7194 (truncate:SI
7195 (lshiftrt:DI
7196 (mult:DI (zero_extend:DI
7197 (match_operand:SI 1 "nonimmediate_operand" ""))
7198 (zero_extend:DI
7199 (match_operand:SI 2 "register_operand" "")))
7200 (const_int 32))))
7201 (clobber (match_scratch:SI 3 ""))
7202 (clobber (reg:CC FLAGS_REG))])]
7203 ""
7204 "")
7205
7206 (define_insn "*umulsi3_highpart_insn"
7207 [(set (match_operand:SI 0 "register_operand" "=d")
7208 (truncate:SI
7209 (lshiftrt:DI
7210 (mult:DI (zero_extend:DI
7211 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7212 (zero_extend:DI
7213 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7214 (const_int 32))))
7215 (clobber (match_scratch:SI 3 "=1"))
7216 (clobber (reg:CC FLAGS_REG))]
7217 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7218 "mul{l}\t%2"
7219 [(set_attr "type" "imul")
7220 (set_attr "length_immediate" "0")
7221 (set (attr "athlon_decode")
7222 (if_then_else (eq_attr "cpu" "athlon")
7223 (const_string "vector")
7224 (const_string "double")))
7225 (set_attr "mode" "SI")])
7226
7227 (define_insn "*umulsi3_highpart_zext"
7228 [(set (match_operand:DI 0 "register_operand" "=d")
7229 (zero_extend:DI (truncate:SI
7230 (lshiftrt:DI
7231 (mult:DI (zero_extend:DI
7232 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7233 (zero_extend:DI
7234 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7235 (const_int 32)))))
7236 (clobber (match_scratch:SI 3 "=1"))
7237 (clobber (reg:CC FLAGS_REG))]
7238 "TARGET_64BIT
7239 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7240 "mul{l}\t%2"
7241 [(set_attr "type" "imul")
7242 (set_attr "length_immediate" "0")
7243 (set (attr "athlon_decode")
7244 (if_then_else (eq_attr "cpu" "athlon")
7245 (const_string "vector")
7246 (const_string "double")))
7247 (set_attr "mode" "SI")])
7248
7249 (define_expand "smuldi3_highpart"
7250 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7251 (truncate:DI
7252 (lshiftrt:TI
7253 (mult:TI (sign_extend:TI
7254 (match_operand:DI 1 "nonimmediate_operand" ""))
7255 (sign_extend:TI
7256 (match_operand:DI 2 "register_operand" "")))
7257 (const_int 64))))
7258 (clobber (match_scratch:DI 3 ""))
7259 (clobber (reg:CC FLAGS_REG))])]
7260 "TARGET_64BIT"
7261 "")
7262
7263 (define_insn "*smuldi3_highpart_rex64"
7264 [(set (match_operand:DI 0 "register_operand" "=d")
7265 (truncate:DI
7266 (lshiftrt:TI
7267 (mult:TI (sign_extend:TI
7268 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7269 (sign_extend:TI
7270 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7271 (const_int 64))))
7272 (clobber (match_scratch:DI 3 "=1"))
7273 (clobber (reg:CC FLAGS_REG))]
7274 "TARGET_64BIT
7275 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7276 "imul{q}\t%2"
7277 [(set_attr "type" "imul")
7278 (set (attr "athlon_decode")
7279 (if_then_else (eq_attr "cpu" "athlon")
7280 (const_string "vector")
7281 (const_string "double")))
7282 (set_attr "mode" "DI")])
7283
7284 (define_expand "smulsi3_highpart"
7285 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7286 (truncate:SI
7287 (lshiftrt:DI
7288 (mult:DI (sign_extend:DI
7289 (match_operand:SI 1 "nonimmediate_operand" ""))
7290 (sign_extend:DI
7291 (match_operand:SI 2 "register_operand" "")))
7292 (const_int 32))))
7293 (clobber (match_scratch:SI 3 ""))
7294 (clobber (reg:CC FLAGS_REG))])]
7295 ""
7296 "")
7297
7298 (define_insn "*smulsi3_highpart_insn"
7299 [(set (match_operand:SI 0 "register_operand" "=d")
7300 (truncate:SI
7301 (lshiftrt:DI
7302 (mult:DI (sign_extend:DI
7303 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7304 (sign_extend:DI
7305 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7306 (const_int 32))))
7307 (clobber (match_scratch:SI 3 "=1"))
7308 (clobber (reg:CC FLAGS_REG))]
7309 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7310 "imul{l}\t%2"
7311 [(set_attr "type" "imul")
7312 (set (attr "athlon_decode")
7313 (if_then_else (eq_attr "cpu" "athlon")
7314 (const_string "vector")
7315 (const_string "double")))
7316 (set_attr "mode" "SI")])
7317
7318 (define_insn "*smulsi3_highpart_zext"
7319 [(set (match_operand:DI 0 "register_operand" "=d")
7320 (zero_extend:DI (truncate:SI
7321 (lshiftrt:DI
7322 (mult:DI (sign_extend:DI
7323 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7324 (sign_extend:DI
7325 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7326 (const_int 32)))))
7327 (clobber (match_scratch:SI 3 "=1"))
7328 (clobber (reg:CC FLAGS_REG))]
7329 "TARGET_64BIT
7330 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7331 "imul{l}\t%2"
7332 [(set_attr "type" "imul")
7333 (set (attr "athlon_decode")
7334 (if_then_else (eq_attr "cpu" "athlon")
7335 (const_string "vector")
7336 (const_string "double")))
7337 (set_attr "mode" "SI")])
7338
7339 ;; The patterns that match these are at the end of this file.
7340
7341 (define_expand "mulxf3"
7342 [(set (match_operand:XF 0 "register_operand" "")
7343 (mult:XF (match_operand:XF 1 "register_operand" "")
7344 (match_operand:XF 2 "register_operand" "")))]
7345 "TARGET_80387"
7346 "")
7347
7348 (define_expand "muldf3"
7349 [(set (match_operand:DF 0 "register_operand" "")
7350 (mult:DF (match_operand:DF 1 "register_operand" "")
7351 (match_operand:DF 2 "nonimmediate_operand" "")))]
7352 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7353 "")
7354
7355 (define_expand "mulsf3"
7356 [(set (match_operand:SF 0 "register_operand" "")
7357 (mult:SF (match_operand:SF 1 "register_operand" "")
7358 (match_operand:SF 2 "nonimmediate_operand" "")))]
7359 "TARGET_80387 || TARGET_SSE_MATH"
7360 "")
7361 \f
7362 ;; Divide instructions
7363
7364 (define_insn "divqi3"
7365 [(set (match_operand:QI 0 "register_operand" "=a")
7366 (div:QI (match_operand:HI 1 "register_operand" "0")
7367 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7368 (clobber (reg:CC FLAGS_REG))]
7369 "TARGET_QIMODE_MATH"
7370 "idiv{b}\t%2"
7371 [(set_attr "type" "idiv")
7372 (set_attr "mode" "QI")])
7373
7374 (define_insn "udivqi3"
7375 [(set (match_operand:QI 0 "register_operand" "=a")
7376 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7377 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7378 (clobber (reg:CC FLAGS_REG))]
7379 "TARGET_QIMODE_MATH"
7380 "div{b}\t%2"
7381 [(set_attr "type" "idiv")
7382 (set_attr "mode" "QI")])
7383
7384 ;; The patterns that match these are at the end of this file.
7385
7386 (define_expand "divxf3"
7387 [(set (match_operand:XF 0 "register_operand" "")
7388 (div:XF (match_operand:XF 1 "register_operand" "")
7389 (match_operand:XF 2 "register_operand" "")))]
7390 "TARGET_80387"
7391 "")
7392
7393 (define_expand "divdf3"
7394 [(set (match_operand:DF 0 "register_operand" "")
7395 (div:DF (match_operand:DF 1 "register_operand" "")
7396 (match_operand:DF 2 "nonimmediate_operand" "")))]
7397 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7398 "")
7399
7400 (define_expand "divsf3"
7401 [(set (match_operand:SF 0 "register_operand" "")
7402 (div:SF (match_operand:SF 1 "register_operand" "")
7403 (match_operand:SF 2 "nonimmediate_operand" "")))]
7404 "TARGET_80387 || TARGET_SSE_MATH"
7405 "")
7406 \f
7407 ;; Remainder instructions.
7408
7409 (define_expand "divmoddi4"
7410 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7411 (div:DI (match_operand:DI 1 "register_operand" "")
7412 (match_operand:DI 2 "nonimmediate_operand" "")))
7413 (set (match_operand:DI 3 "register_operand" "")
7414 (mod:DI (match_dup 1) (match_dup 2)))
7415 (clobber (reg:CC FLAGS_REG))])]
7416 "TARGET_64BIT"
7417 "")
7418
7419 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7420 ;; Penalize eax case slightly because it results in worse scheduling
7421 ;; of code.
7422 (define_insn "*divmoddi4_nocltd_rex64"
7423 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7424 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7425 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7426 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7427 (mod:DI (match_dup 2) (match_dup 3)))
7428 (clobber (reg:CC FLAGS_REG))]
7429 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7430 "#"
7431 [(set_attr "type" "multi")])
7432
7433 (define_insn "*divmoddi4_cltd_rex64"
7434 [(set (match_operand:DI 0 "register_operand" "=a")
7435 (div:DI (match_operand:DI 2 "register_operand" "a")
7436 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7437 (set (match_operand:DI 1 "register_operand" "=&d")
7438 (mod:DI (match_dup 2) (match_dup 3)))
7439 (clobber (reg:CC FLAGS_REG))]
7440 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7441 "#"
7442 [(set_attr "type" "multi")])
7443
7444 (define_insn "*divmoddi_noext_rex64"
7445 [(set (match_operand:DI 0 "register_operand" "=a")
7446 (div:DI (match_operand:DI 1 "register_operand" "0")
7447 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7448 (set (match_operand:DI 3 "register_operand" "=d")
7449 (mod:DI (match_dup 1) (match_dup 2)))
7450 (use (match_operand:DI 4 "register_operand" "3"))
7451 (clobber (reg:CC FLAGS_REG))]
7452 "TARGET_64BIT"
7453 "idiv{q}\t%2"
7454 [(set_attr "type" "idiv")
7455 (set_attr "mode" "DI")])
7456
7457 (define_split
7458 [(set (match_operand:DI 0 "register_operand" "")
7459 (div:DI (match_operand:DI 1 "register_operand" "")
7460 (match_operand:DI 2 "nonimmediate_operand" "")))
7461 (set (match_operand:DI 3 "register_operand" "")
7462 (mod:DI (match_dup 1) (match_dup 2)))
7463 (clobber (reg:CC FLAGS_REG))]
7464 "TARGET_64BIT && reload_completed"
7465 [(parallel [(set (match_dup 3)
7466 (ashiftrt:DI (match_dup 4) (const_int 63)))
7467 (clobber (reg:CC FLAGS_REG))])
7468 (parallel [(set (match_dup 0)
7469 (div:DI (reg:DI 0) (match_dup 2)))
7470 (set (match_dup 3)
7471 (mod:DI (reg:DI 0) (match_dup 2)))
7472 (use (match_dup 3))
7473 (clobber (reg:CC FLAGS_REG))])]
7474 {
7475 /* Avoid use of cltd in favor of a mov+shift. */
7476 if (!TARGET_USE_CLTD && !optimize_size)
7477 {
7478 if (true_regnum (operands[1]))
7479 emit_move_insn (operands[0], operands[1]);
7480 else
7481 emit_move_insn (operands[3], operands[1]);
7482 operands[4] = operands[3];
7483 }
7484 else
7485 {
7486 gcc_assert (!true_regnum (operands[1]));
7487 operands[4] = operands[1];
7488 }
7489 })
7490
7491
7492 (define_expand "divmodsi4"
7493 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7494 (div:SI (match_operand:SI 1 "register_operand" "")
7495 (match_operand:SI 2 "nonimmediate_operand" "")))
7496 (set (match_operand:SI 3 "register_operand" "")
7497 (mod:SI (match_dup 1) (match_dup 2)))
7498 (clobber (reg:CC FLAGS_REG))])]
7499 ""
7500 "")
7501
7502 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7503 ;; Penalize eax case slightly because it results in worse scheduling
7504 ;; of code.
7505 (define_insn "*divmodsi4_nocltd"
7506 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7507 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7508 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7509 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7510 (mod:SI (match_dup 2) (match_dup 3)))
7511 (clobber (reg:CC FLAGS_REG))]
7512 "!optimize_size && !TARGET_USE_CLTD"
7513 "#"
7514 [(set_attr "type" "multi")])
7515
7516 (define_insn "*divmodsi4_cltd"
7517 [(set (match_operand:SI 0 "register_operand" "=a")
7518 (div:SI (match_operand:SI 2 "register_operand" "a")
7519 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7520 (set (match_operand:SI 1 "register_operand" "=&d")
7521 (mod:SI (match_dup 2) (match_dup 3)))
7522 (clobber (reg:CC FLAGS_REG))]
7523 "optimize_size || TARGET_USE_CLTD"
7524 "#"
7525 [(set_attr "type" "multi")])
7526
7527 (define_insn "*divmodsi_noext"
7528 [(set (match_operand:SI 0 "register_operand" "=a")
7529 (div:SI (match_operand:SI 1 "register_operand" "0")
7530 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7531 (set (match_operand:SI 3 "register_operand" "=d")
7532 (mod:SI (match_dup 1) (match_dup 2)))
7533 (use (match_operand:SI 4 "register_operand" "3"))
7534 (clobber (reg:CC FLAGS_REG))]
7535 ""
7536 "idiv{l}\t%2"
7537 [(set_attr "type" "idiv")
7538 (set_attr "mode" "SI")])
7539
7540 (define_split
7541 [(set (match_operand:SI 0 "register_operand" "")
7542 (div:SI (match_operand:SI 1 "register_operand" "")
7543 (match_operand:SI 2 "nonimmediate_operand" "")))
7544 (set (match_operand:SI 3 "register_operand" "")
7545 (mod:SI (match_dup 1) (match_dup 2)))
7546 (clobber (reg:CC FLAGS_REG))]
7547 "reload_completed"
7548 [(parallel [(set (match_dup 3)
7549 (ashiftrt:SI (match_dup 4) (const_int 31)))
7550 (clobber (reg:CC FLAGS_REG))])
7551 (parallel [(set (match_dup 0)
7552 (div:SI (reg:SI 0) (match_dup 2)))
7553 (set (match_dup 3)
7554 (mod:SI (reg:SI 0) (match_dup 2)))
7555 (use (match_dup 3))
7556 (clobber (reg:CC FLAGS_REG))])]
7557 {
7558 /* Avoid use of cltd in favor of a mov+shift. */
7559 if (!TARGET_USE_CLTD && !optimize_size)
7560 {
7561 if (true_regnum (operands[1]))
7562 emit_move_insn (operands[0], operands[1]);
7563 else
7564 emit_move_insn (operands[3], operands[1]);
7565 operands[4] = operands[3];
7566 }
7567 else
7568 {
7569 gcc_assert (!true_regnum (operands[1]));
7570 operands[4] = operands[1];
7571 }
7572 })
7573 ;; %%% Split me.
7574 (define_insn "divmodhi4"
7575 [(set (match_operand:HI 0 "register_operand" "=a")
7576 (div:HI (match_operand:HI 1 "register_operand" "0")
7577 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7578 (set (match_operand:HI 3 "register_operand" "=&d")
7579 (mod:HI (match_dup 1) (match_dup 2)))
7580 (clobber (reg:CC FLAGS_REG))]
7581 "TARGET_HIMODE_MATH"
7582 "cwtd\;idiv{w}\t%2"
7583 [(set_attr "type" "multi")
7584 (set_attr "length_immediate" "0")
7585 (set_attr "mode" "SI")])
7586
7587 (define_insn "udivmoddi4"
7588 [(set (match_operand:DI 0 "register_operand" "=a")
7589 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7590 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7591 (set (match_operand:DI 3 "register_operand" "=&d")
7592 (umod:DI (match_dup 1) (match_dup 2)))
7593 (clobber (reg:CC FLAGS_REG))]
7594 "TARGET_64BIT"
7595 "xor{q}\t%3, %3\;div{q}\t%2"
7596 [(set_attr "type" "multi")
7597 (set_attr "length_immediate" "0")
7598 (set_attr "mode" "DI")])
7599
7600 (define_insn "*udivmoddi4_noext"
7601 [(set (match_operand:DI 0 "register_operand" "=a")
7602 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7603 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7604 (set (match_operand:DI 3 "register_operand" "=d")
7605 (umod:DI (match_dup 1) (match_dup 2)))
7606 (use (match_dup 3))
7607 (clobber (reg:CC FLAGS_REG))]
7608 "TARGET_64BIT"
7609 "div{q}\t%2"
7610 [(set_attr "type" "idiv")
7611 (set_attr "mode" "DI")])
7612
7613 (define_split
7614 [(set (match_operand:DI 0 "register_operand" "")
7615 (udiv:DI (match_operand:DI 1 "register_operand" "")
7616 (match_operand:DI 2 "nonimmediate_operand" "")))
7617 (set (match_operand:DI 3 "register_operand" "")
7618 (umod:DI (match_dup 1) (match_dup 2)))
7619 (clobber (reg:CC FLAGS_REG))]
7620 "TARGET_64BIT && reload_completed"
7621 [(set (match_dup 3) (const_int 0))
7622 (parallel [(set (match_dup 0)
7623 (udiv:DI (match_dup 1) (match_dup 2)))
7624 (set (match_dup 3)
7625 (umod:DI (match_dup 1) (match_dup 2)))
7626 (use (match_dup 3))
7627 (clobber (reg:CC FLAGS_REG))])]
7628 "")
7629
7630 (define_insn "udivmodsi4"
7631 [(set (match_operand:SI 0 "register_operand" "=a")
7632 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7633 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7634 (set (match_operand:SI 3 "register_operand" "=&d")
7635 (umod:SI (match_dup 1) (match_dup 2)))
7636 (clobber (reg:CC FLAGS_REG))]
7637 ""
7638 "xor{l}\t%3, %3\;div{l}\t%2"
7639 [(set_attr "type" "multi")
7640 (set_attr "length_immediate" "0")
7641 (set_attr "mode" "SI")])
7642
7643 (define_insn "*udivmodsi4_noext"
7644 [(set (match_operand:SI 0 "register_operand" "=a")
7645 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7646 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7647 (set (match_operand:SI 3 "register_operand" "=d")
7648 (umod:SI (match_dup 1) (match_dup 2)))
7649 (use (match_dup 3))
7650 (clobber (reg:CC FLAGS_REG))]
7651 ""
7652 "div{l}\t%2"
7653 [(set_attr "type" "idiv")
7654 (set_attr "mode" "SI")])
7655
7656 (define_split
7657 [(set (match_operand:SI 0 "register_operand" "")
7658 (udiv:SI (match_operand:SI 1 "register_operand" "")
7659 (match_operand:SI 2 "nonimmediate_operand" "")))
7660 (set (match_operand:SI 3 "register_operand" "")
7661 (umod:SI (match_dup 1) (match_dup 2)))
7662 (clobber (reg:CC FLAGS_REG))]
7663 "reload_completed"
7664 [(set (match_dup 3) (const_int 0))
7665 (parallel [(set (match_dup 0)
7666 (udiv:SI (match_dup 1) (match_dup 2)))
7667 (set (match_dup 3)
7668 (umod:SI (match_dup 1) (match_dup 2)))
7669 (use (match_dup 3))
7670 (clobber (reg:CC FLAGS_REG))])]
7671 "")
7672
7673 (define_expand "udivmodhi4"
7674 [(set (match_dup 4) (const_int 0))
7675 (parallel [(set (match_operand:HI 0 "register_operand" "")
7676 (udiv:HI (match_operand:HI 1 "register_operand" "")
7677 (match_operand:HI 2 "nonimmediate_operand" "")))
7678 (set (match_operand:HI 3 "register_operand" "")
7679 (umod:HI (match_dup 1) (match_dup 2)))
7680 (use (match_dup 4))
7681 (clobber (reg:CC FLAGS_REG))])]
7682 "TARGET_HIMODE_MATH"
7683 "operands[4] = gen_reg_rtx (HImode);")
7684
7685 (define_insn "*udivmodhi_noext"
7686 [(set (match_operand:HI 0 "register_operand" "=a")
7687 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7688 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7689 (set (match_operand:HI 3 "register_operand" "=d")
7690 (umod:HI (match_dup 1) (match_dup 2)))
7691 (use (match_operand:HI 4 "register_operand" "3"))
7692 (clobber (reg:CC FLAGS_REG))]
7693 ""
7694 "div{w}\t%2"
7695 [(set_attr "type" "idiv")
7696 (set_attr "mode" "HI")])
7697
7698 ;; We cannot use div/idiv for double division, because it causes
7699 ;; "division by zero" on the overflow and that's not what we expect
7700 ;; from truncate. Because true (non truncating) double division is
7701 ;; never generated, we can't create this insn anyway.
7702 ;
7703 ;(define_insn ""
7704 ; [(set (match_operand:SI 0 "register_operand" "=a")
7705 ; (truncate:SI
7706 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7707 ; (zero_extend:DI
7708 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7709 ; (set (match_operand:SI 3 "register_operand" "=d")
7710 ; (truncate:SI
7711 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7712 ; (clobber (reg:CC FLAGS_REG))]
7713 ; ""
7714 ; "div{l}\t{%2, %0|%0, %2}"
7715 ; [(set_attr "type" "idiv")])
7716 \f
7717 ;;- Logical AND instructions
7718
7719 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7720 ;; Note that this excludes ah.
7721
7722 (define_insn "*testdi_1_rex64"
7723 [(set (reg FLAGS_REG)
7724 (compare
7725 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7726 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7727 (const_int 0)))]
7728 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7729 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7730 "@
7731 test{l}\t{%k1, %k0|%k0, %k1}
7732 test{l}\t{%k1, %k0|%k0, %k1}
7733 test{q}\t{%1, %0|%0, %1}
7734 test{q}\t{%1, %0|%0, %1}
7735 test{q}\t{%1, %0|%0, %1}"
7736 [(set_attr "type" "test")
7737 (set_attr "modrm" "0,1,0,1,1")
7738 (set_attr "mode" "SI,SI,DI,DI,DI")
7739 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7740
7741 (define_insn "testsi_1"
7742 [(set (reg FLAGS_REG)
7743 (compare
7744 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7745 (match_operand:SI 1 "general_operand" "in,in,rin"))
7746 (const_int 0)))]
7747 "ix86_match_ccmode (insn, CCNOmode)
7748 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7749 "test{l}\t{%1, %0|%0, %1}"
7750 [(set_attr "type" "test")
7751 (set_attr "modrm" "0,1,1")
7752 (set_attr "mode" "SI")
7753 (set_attr "pent_pair" "uv,np,uv")])
7754
7755 (define_expand "testsi_ccno_1"
7756 [(set (reg:CCNO FLAGS_REG)
7757 (compare:CCNO
7758 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7759 (match_operand:SI 1 "nonmemory_operand" ""))
7760 (const_int 0)))]
7761 ""
7762 "")
7763
7764 (define_insn "*testhi_1"
7765 [(set (reg FLAGS_REG)
7766 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7767 (match_operand:HI 1 "general_operand" "n,n,rn"))
7768 (const_int 0)))]
7769 "ix86_match_ccmode (insn, CCNOmode)
7770 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7771 "test{w}\t{%1, %0|%0, %1}"
7772 [(set_attr "type" "test")
7773 (set_attr "modrm" "0,1,1")
7774 (set_attr "mode" "HI")
7775 (set_attr "pent_pair" "uv,np,uv")])
7776
7777 (define_expand "testqi_ccz_1"
7778 [(set (reg:CCZ FLAGS_REG)
7779 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7780 (match_operand:QI 1 "nonmemory_operand" ""))
7781 (const_int 0)))]
7782 ""
7783 "")
7784
7785 (define_insn "*testqi_1_maybe_si"
7786 [(set (reg FLAGS_REG)
7787 (compare
7788 (and:QI
7789 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7790 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7791 (const_int 0)))]
7792 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7793 && ix86_match_ccmode (insn,
7794 GET_CODE (operands[1]) == CONST_INT
7795 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7796 {
7797 if (which_alternative == 3)
7798 {
7799 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7800 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7801 return "test{l}\t{%1, %k0|%k0, %1}";
7802 }
7803 return "test{b}\t{%1, %0|%0, %1}";
7804 }
7805 [(set_attr "type" "test")
7806 (set_attr "modrm" "0,1,1,1")
7807 (set_attr "mode" "QI,QI,QI,SI")
7808 (set_attr "pent_pair" "uv,np,uv,np")])
7809
7810 (define_insn "*testqi_1"
7811 [(set (reg FLAGS_REG)
7812 (compare
7813 (and:QI
7814 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7815 (match_operand:QI 1 "general_operand" "n,n,qn"))
7816 (const_int 0)))]
7817 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7818 && ix86_match_ccmode (insn, CCNOmode)"
7819 "test{b}\t{%1, %0|%0, %1}"
7820 [(set_attr "type" "test")
7821 (set_attr "modrm" "0,1,1")
7822 (set_attr "mode" "QI")
7823 (set_attr "pent_pair" "uv,np,uv")])
7824
7825 (define_expand "testqi_ext_ccno_0"
7826 [(set (reg:CCNO FLAGS_REG)
7827 (compare:CCNO
7828 (and:SI
7829 (zero_extract:SI
7830 (match_operand 0 "ext_register_operand" "")
7831 (const_int 8)
7832 (const_int 8))
7833 (match_operand 1 "const_int_operand" ""))
7834 (const_int 0)))]
7835 ""
7836 "")
7837
7838 (define_insn "*testqi_ext_0"
7839 [(set (reg FLAGS_REG)
7840 (compare
7841 (and:SI
7842 (zero_extract:SI
7843 (match_operand 0 "ext_register_operand" "Q")
7844 (const_int 8)
7845 (const_int 8))
7846 (match_operand 1 "const_int_operand" "n"))
7847 (const_int 0)))]
7848 "ix86_match_ccmode (insn, CCNOmode)"
7849 "test{b}\t{%1, %h0|%h0, %1}"
7850 [(set_attr "type" "test")
7851 (set_attr "mode" "QI")
7852 (set_attr "length_immediate" "1")
7853 (set_attr "pent_pair" "np")])
7854
7855 (define_insn "*testqi_ext_1"
7856 [(set (reg FLAGS_REG)
7857 (compare
7858 (and:SI
7859 (zero_extract:SI
7860 (match_operand 0 "ext_register_operand" "Q")
7861 (const_int 8)
7862 (const_int 8))
7863 (zero_extend:SI
7864 (match_operand:QI 1 "general_operand" "Qm")))
7865 (const_int 0)))]
7866 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7867 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7868 "test{b}\t{%1, %h0|%h0, %1}"
7869 [(set_attr "type" "test")
7870 (set_attr "mode" "QI")])
7871
7872 (define_insn "*testqi_ext_1_rex64"
7873 [(set (reg FLAGS_REG)
7874 (compare
7875 (and:SI
7876 (zero_extract:SI
7877 (match_operand 0 "ext_register_operand" "Q")
7878 (const_int 8)
7879 (const_int 8))
7880 (zero_extend:SI
7881 (match_operand:QI 1 "register_operand" "Q")))
7882 (const_int 0)))]
7883 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7884 "test{b}\t{%1, %h0|%h0, %1}"
7885 [(set_attr "type" "test")
7886 (set_attr "mode" "QI")])
7887
7888 (define_insn "*testqi_ext_2"
7889 [(set (reg FLAGS_REG)
7890 (compare
7891 (and:SI
7892 (zero_extract:SI
7893 (match_operand 0 "ext_register_operand" "Q")
7894 (const_int 8)
7895 (const_int 8))
7896 (zero_extract:SI
7897 (match_operand 1 "ext_register_operand" "Q")
7898 (const_int 8)
7899 (const_int 8)))
7900 (const_int 0)))]
7901 "ix86_match_ccmode (insn, CCNOmode)"
7902 "test{b}\t{%h1, %h0|%h0, %h1}"
7903 [(set_attr "type" "test")
7904 (set_attr "mode" "QI")])
7905
7906 ;; Combine likes to form bit extractions for some tests. Humor it.
7907 (define_insn "*testqi_ext_3"
7908 [(set (reg FLAGS_REG)
7909 (compare (zero_extract:SI
7910 (match_operand 0 "nonimmediate_operand" "rm")
7911 (match_operand:SI 1 "const_int_operand" "")
7912 (match_operand:SI 2 "const_int_operand" ""))
7913 (const_int 0)))]
7914 "ix86_match_ccmode (insn, CCNOmode)
7915 && INTVAL (operands[1]) > 0
7916 && INTVAL (operands[2]) >= 0
7917 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7918 && (GET_MODE (operands[0]) == SImode
7919 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7920 || GET_MODE (operands[0]) == HImode
7921 || GET_MODE (operands[0]) == QImode)"
7922 "#")
7923
7924 (define_insn "*testqi_ext_3_rex64"
7925 [(set (reg FLAGS_REG)
7926 (compare (zero_extract:DI
7927 (match_operand 0 "nonimmediate_operand" "rm")
7928 (match_operand:DI 1 "const_int_operand" "")
7929 (match_operand:DI 2 "const_int_operand" ""))
7930 (const_int 0)))]
7931 "TARGET_64BIT
7932 && ix86_match_ccmode (insn, CCNOmode)
7933 && INTVAL (operands[1]) > 0
7934 && INTVAL (operands[2]) >= 0
7935 /* Ensure that resulting mask is zero or sign extended operand. */
7936 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7937 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7938 && INTVAL (operands[1]) > 32))
7939 && (GET_MODE (operands[0]) == SImode
7940 || GET_MODE (operands[0]) == DImode
7941 || GET_MODE (operands[0]) == HImode
7942 || GET_MODE (operands[0]) == QImode)"
7943 "#")
7944
7945 (define_split
7946 [(set (match_operand 0 "flags_reg_operand" "")
7947 (match_operator 1 "compare_operator"
7948 [(zero_extract
7949 (match_operand 2 "nonimmediate_operand" "")
7950 (match_operand 3 "const_int_operand" "")
7951 (match_operand 4 "const_int_operand" ""))
7952 (const_int 0)]))]
7953 "ix86_match_ccmode (insn, CCNOmode)"
7954 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7955 {
7956 rtx val = operands[2];
7957 HOST_WIDE_INT len = INTVAL (operands[3]);
7958 HOST_WIDE_INT pos = INTVAL (operands[4]);
7959 HOST_WIDE_INT mask;
7960 enum machine_mode mode, submode;
7961
7962 mode = GET_MODE (val);
7963 if (GET_CODE (val) == MEM)
7964 {
7965 /* ??? Combine likes to put non-volatile mem extractions in QImode
7966 no matter the size of the test. So find a mode that works. */
7967 if (! MEM_VOLATILE_P (val))
7968 {
7969 mode = smallest_mode_for_size (pos + len, MODE_INT);
7970 val = adjust_address (val, mode, 0);
7971 }
7972 }
7973 else if (GET_CODE (val) == SUBREG
7974 && (submode = GET_MODE (SUBREG_REG (val)),
7975 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7976 && pos + len <= GET_MODE_BITSIZE (submode))
7977 {
7978 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7979 mode = submode;
7980 val = SUBREG_REG (val);
7981 }
7982 else if (mode == HImode && pos + len <= 8)
7983 {
7984 /* Small HImode tests can be converted to QImode. */
7985 mode = QImode;
7986 val = gen_lowpart (QImode, val);
7987 }
7988
7989 if (len == HOST_BITS_PER_WIDE_INT)
7990 mask = -1;
7991 else
7992 mask = ((HOST_WIDE_INT)1 << len) - 1;
7993 mask <<= pos;
7994
7995 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7996 })
7997
7998 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7999 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8000 ;; this is relatively important trick.
8001 ;; Do the conversion only post-reload to avoid limiting of the register class
8002 ;; to QI regs.
8003 (define_split
8004 [(set (match_operand 0 "flags_reg_operand" "")
8005 (match_operator 1 "compare_operator"
8006 [(and (match_operand 2 "register_operand" "")
8007 (match_operand 3 "const_int_operand" ""))
8008 (const_int 0)]))]
8009 "reload_completed
8010 && QI_REG_P (operands[2])
8011 && GET_MODE (operands[2]) != QImode
8012 && ((ix86_match_ccmode (insn, CCZmode)
8013 && !(INTVAL (operands[3]) & ~(255 << 8)))
8014 || (ix86_match_ccmode (insn, CCNOmode)
8015 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8016 [(set (match_dup 0)
8017 (match_op_dup 1
8018 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8019 (match_dup 3))
8020 (const_int 0)]))]
8021 "operands[2] = gen_lowpart (SImode, operands[2]);
8022 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8023
8024 (define_split
8025 [(set (match_operand 0 "flags_reg_operand" "")
8026 (match_operator 1 "compare_operator"
8027 [(and (match_operand 2 "nonimmediate_operand" "")
8028 (match_operand 3 "const_int_operand" ""))
8029 (const_int 0)]))]
8030 "reload_completed
8031 && GET_MODE (operands[2]) != QImode
8032 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8033 && ((ix86_match_ccmode (insn, CCZmode)
8034 && !(INTVAL (operands[3]) & ~255))
8035 || (ix86_match_ccmode (insn, CCNOmode)
8036 && !(INTVAL (operands[3]) & ~127)))"
8037 [(set (match_dup 0)
8038 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8039 (const_int 0)]))]
8040 "operands[2] = gen_lowpart (QImode, operands[2]);
8041 operands[3] = gen_lowpart (QImode, operands[3]);")
8042
8043
8044 ;; %%% This used to optimize known byte-wide and operations to memory,
8045 ;; and sometimes to QImode registers. If this is considered useful,
8046 ;; it should be done with splitters.
8047
8048 (define_expand "anddi3"
8049 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8050 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8051 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8052 (clobber (reg:CC FLAGS_REG))]
8053 "TARGET_64BIT"
8054 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8055
8056 (define_insn "*anddi_1_rex64"
8057 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8058 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8059 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8060 (clobber (reg:CC FLAGS_REG))]
8061 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8062 {
8063 switch (get_attr_type (insn))
8064 {
8065 case TYPE_IMOVX:
8066 {
8067 enum machine_mode mode;
8068
8069 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8070 if (INTVAL (operands[2]) == 0xff)
8071 mode = QImode;
8072 else
8073 {
8074 gcc_assert (INTVAL (operands[2]) == 0xffff);
8075 mode = HImode;
8076 }
8077
8078 operands[1] = gen_lowpart (mode, operands[1]);
8079 if (mode == QImode)
8080 return "movz{bq|x}\t{%1,%0|%0, %1}";
8081 else
8082 return "movz{wq|x}\t{%1,%0|%0, %1}";
8083 }
8084
8085 default:
8086 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8087 if (get_attr_mode (insn) == MODE_SI)
8088 return "and{l}\t{%k2, %k0|%k0, %k2}";
8089 else
8090 return "and{q}\t{%2, %0|%0, %2}";
8091 }
8092 }
8093 [(set_attr "type" "alu,alu,alu,imovx")
8094 (set_attr "length_immediate" "*,*,*,0")
8095 (set_attr "mode" "SI,DI,DI,DI")])
8096
8097 (define_insn "*anddi_2"
8098 [(set (reg FLAGS_REG)
8099 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8100 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8101 (const_int 0)))
8102 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8103 (and:DI (match_dup 1) (match_dup 2)))]
8104 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8105 && ix86_binary_operator_ok (AND, DImode, operands)"
8106 "@
8107 and{l}\t{%k2, %k0|%k0, %k2}
8108 and{q}\t{%2, %0|%0, %2}
8109 and{q}\t{%2, %0|%0, %2}"
8110 [(set_attr "type" "alu")
8111 (set_attr "mode" "SI,DI,DI")])
8112
8113 (define_expand "andsi3"
8114 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8115 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8116 (match_operand:SI 2 "general_operand" "")))
8117 (clobber (reg:CC FLAGS_REG))]
8118 ""
8119 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8120
8121 (define_insn "*andsi_1"
8122 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8123 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8124 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8125 (clobber (reg:CC FLAGS_REG))]
8126 "ix86_binary_operator_ok (AND, SImode, operands)"
8127 {
8128 switch (get_attr_type (insn))
8129 {
8130 case TYPE_IMOVX:
8131 {
8132 enum machine_mode mode;
8133
8134 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8135 if (INTVAL (operands[2]) == 0xff)
8136 mode = QImode;
8137 else
8138 {
8139 gcc_assert (INTVAL (operands[2]) == 0xffff);
8140 mode = HImode;
8141 }
8142
8143 operands[1] = gen_lowpart (mode, operands[1]);
8144 if (mode == QImode)
8145 return "movz{bl|x}\t{%1,%0|%0, %1}";
8146 else
8147 return "movz{wl|x}\t{%1,%0|%0, %1}";
8148 }
8149
8150 default:
8151 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8152 return "and{l}\t{%2, %0|%0, %2}";
8153 }
8154 }
8155 [(set_attr "type" "alu,alu,imovx")
8156 (set_attr "length_immediate" "*,*,0")
8157 (set_attr "mode" "SI")])
8158
8159 (define_split
8160 [(set (match_operand 0 "register_operand" "")
8161 (and (match_dup 0)
8162 (const_int -65536)))
8163 (clobber (reg:CC FLAGS_REG))]
8164 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8165 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8166 "operands[1] = gen_lowpart (HImode, operands[0]);")
8167
8168 (define_split
8169 [(set (match_operand 0 "ext_register_operand" "")
8170 (and (match_dup 0)
8171 (const_int -256)))
8172 (clobber (reg:CC FLAGS_REG))]
8173 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8174 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8175 "operands[1] = gen_lowpart (QImode, operands[0]);")
8176
8177 (define_split
8178 [(set (match_operand 0 "ext_register_operand" "")
8179 (and (match_dup 0)
8180 (const_int -65281)))
8181 (clobber (reg:CC FLAGS_REG))]
8182 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8183 [(parallel [(set (zero_extract:SI (match_dup 0)
8184 (const_int 8)
8185 (const_int 8))
8186 (xor:SI
8187 (zero_extract:SI (match_dup 0)
8188 (const_int 8)
8189 (const_int 8))
8190 (zero_extract:SI (match_dup 0)
8191 (const_int 8)
8192 (const_int 8))))
8193 (clobber (reg:CC FLAGS_REG))])]
8194 "operands[0] = gen_lowpart (SImode, operands[0]);")
8195
8196 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8197 (define_insn "*andsi_1_zext"
8198 [(set (match_operand:DI 0 "register_operand" "=r")
8199 (zero_extend:DI
8200 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8201 (match_operand:SI 2 "general_operand" "rim"))))
8202 (clobber (reg:CC FLAGS_REG))]
8203 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8204 "and{l}\t{%2, %k0|%k0, %2}"
8205 [(set_attr "type" "alu")
8206 (set_attr "mode" "SI")])
8207
8208 (define_insn "*andsi_2"
8209 [(set (reg FLAGS_REG)
8210 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8211 (match_operand:SI 2 "general_operand" "rim,ri"))
8212 (const_int 0)))
8213 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8214 (and:SI (match_dup 1) (match_dup 2)))]
8215 "ix86_match_ccmode (insn, CCNOmode)
8216 && ix86_binary_operator_ok (AND, SImode, operands)"
8217 "and{l}\t{%2, %0|%0, %2}"
8218 [(set_attr "type" "alu")
8219 (set_attr "mode" "SI")])
8220
8221 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8222 (define_insn "*andsi_2_zext"
8223 [(set (reg FLAGS_REG)
8224 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8225 (match_operand:SI 2 "general_operand" "rim"))
8226 (const_int 0)))
8227 (set (match_operand:DI 0 "register_operand" "=r")
8228 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8229 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8230 && ix86_binary_operator_ok (AND, SImode, operands)"
8231 "and{l}\t{%2, %k0|%k0, %2}"
8232 [(set_attr "type" "alu")
8233 (set_attr "mode" "SI")])
8234
8235 (define_expand "andhi3"
8236 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8237 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8238 (match_operand:HI 2 "general_operand" "")))
8239 (clobber (reg:CC FLAGS_REG))]
8240 "TARGET_HIMODE_MATH"
8241 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8242
8243 (define_insn "*andhi_1"
8244 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8245 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8246 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8247 (clobber (reg:CC FLAGS_REG))]
8248 "ix86_binary_operator_ok (AND, HImode, operands)"
8249 {
8250 switch (get_attr_type (insn))
8251 {
8252 case TYPE_IMOVX:
8253 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8254 gcc_assert (INTVAL (operands[2]) == 0xff);
8255 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8256
8257 default:
8258 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8259
8260 return "and{w}\t{%2, %0|%0, %2}";
8261 }
8262 }
8263 [(set_attr "type" "alu,alu,imovx")
8264 (set_attr "length_immediate" "*,*,0")
8265 (set_attr "mode" "HI,HI,SI")])
8266
8267 (define_insn "*andhi_2"
8268 [(set (reg FLAGS_REG)
8269 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8270 (match_operand:HI 2 "general_operand" "rim,ri"))
8271 (const_int 0)))
8272 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8273 (and:HI (match_dup 1) (match_dup 2)))]
8274 "ix86_match_ccmode (insn, CCNOmode)
8275 && ix86_binary_operator_ok (AND, HImode, operands)"
8276 "and{w}\t{%2, %0|%0, %2}"
8277 [(set_attr "type" "alu")
8278 (set_attr "mode" "HI")])
8279
8280 (define_expand "andqi3"
8281 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8282 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8283 (match_operand:QI 2 "general_operand" "")))
8284 (clobber (reg:CC FLAGS_REG))]
8285 "TARGET_QIMODE_MATH"
8286 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8287
8288 ;; %%% Potential partial reg stall on alternative 2. What to do?
8289 (define_insn "*andqi_1"
8290 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8291 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8292 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8293 (clobber (reg:CC FLAGS_REG))]
8294 "ix86_binary_operator_ok (AND, QImode, operands)"
8295 "@
8296 and{b}\t{%2, %0|%0, %2}
8297 and{b}\t{%2, %0|%0, %2}
8298 and{l}\t{%k2, %k0|%k0, %k2}"
8299 [(set_attr "type" "alu")
8300 (set_attr "mode" "QI,QI,SI")])
8301
8302 (define_insn "*andqi_1_slp"
8303 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8304 (and:QI (match_dup 0)
8305 (match_operand:QI 1 "general_operand" "qi,qmi")))
8306 (clobber (reg:CC FLAGS_REG))]
8307 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8308 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8309 "and{b}\t{%1, %0|%0, %1}"
8310 [(set_attr "type" "alu1")
8311 (set_attr "mode" "QI")])
8312
8313 (define_insn "*andqi_2_maybe_si"
8314 [(set (reg FLAGS_REG)
8315 (compare (and:QI
8316 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8317 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8318 (const_int 0)))
8319 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8320 (and:QI (match_dup 1) (match_dup 2)))]
8321 "ix86_binary_operator_ok (AND, QImode, operands)
8322 && ix86_match_ccmode (insn,
8323 GET_CODE (operands[2]) == CONST_INT
8324 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8325 {
8326 if (which_alternative == 2)
8327 {
8328 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8329 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8330 return "and{l}\t{%2, %k0|%k0, %2}";
8331 }
8332 return "and{b}\t{%2, %0|%0, %2}";
8333 }
8334 [(set_attr "type" "alu")
8335 (set_attr "mode" "QI,QI,SI")])
8336
8337 (define_insn "*andqi_2"
8338 [(set (reg FLAGS_REG)
8339 (compare (and:QI
8340 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8341 (match_operand:QI 2 "general_operand" "qim,qi"))
8342 (const_int 0)))
8343 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8344 (and:QI (match_dup 1) (match_dup 2)))]
8345 "ix86_match_ccmode (insn, CCNOmode)
8346 && ix86_binary_operator_ok (AND, QImode, operands)"
8347 "and{b}\t{%2, %0|%0, %2}"
8348 [(set_attr "type" "alu")
8349 (set_attr "mode" "QI")])
8350
8351 (define_insn "*andqi_2_slp"
8352 [(set (reg FLAGS_REG)
8353 (compare (and:QI
8354 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8355 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8356 (const_int 0)))
8357 (set (strict_low_part (match_dup 0))
8358 (and:QI (match_dup 0) (match_dup 1)))]
8359 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8360 && ix86_match_ccmode (insn, CCNOmode)
8361 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8362 "and{b}\t{%1, %0|%0, %1}"
8363 [(set_attr "type" "alu1")
8364 (set_attr "mode" "QI")])
8365
8366 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8367 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8368 ;; for a QImode operand, which of course failed.
8369
8370 (define_insn "andqi_ext_0"
8371 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8372 (const_int 8)
8373 (const_int 8))
8374 (and:SI
8375 (zero_extract:SI
8376 (match_operand 1 "ext_register_operand" "0")
8377 (const_int 8)
8378 (const_int 8))
8379 (match_operand 2 "const_int_operand" "n")))
8380 (clobber (reg:CC FLAGS_REG))]
8381 ""
8382 "and{b}\t{%2, %h0|%h0, %2}"
8383 [(set_attr "type" "alu")
8384 (set_attr "length_immediate" "1")
8385 (set_attr "mode" "QI")])
8386
8387 ;; Generated by peephole translating test to and. This shows up
8388 ;; often in fp comparisons.
8389
8390 (define_insn "*andqi_ext_0_cc"
8391 [(set (reg FLAGS_REG)
8392 (compare
8393 (and:SI
8394 (zero_extract:SI
8395 (match_operand 1 "ext_register_operand" "0")
8396 (const_int 8)
8397 (const_int 8))
8398 (match_operand 2 "const_int_operand" "n"))
8399 (const_int 0)))
8400 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8401 (const_int 8)
8402 (const_int 8))
8403 (and:SI
8404 (zero_extract:SI
8405 (match_dup 1)
8406 (const_int 8)
8407 (const_int 8))
8408 (match_dup 2)))]
8409 "ix86_match_ccmode (insn, CCNOmode)"
8410 "and{b}\t{%2, %h0|%h0, %2}"
8411 [(set_attr "type" "alu")
8412 (set_attr "length_immediate" "1")
8413 (set_attr "mode" "QI")])
8414
8415 (define_insn "*andqi_ext_1"
8416 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8417 (const_int 8)
8418 (const_int 8))
8419 (and:SI
8420 (zero_extract:SI
8421 (match_operand 1 "ext_register_operand" "0")
8422 (const_int 8)
8423 (const_int 8))
8424 (zero_extend:SI
8425 (match_operand:QI 2 "general_operand" "Qm"))))
8426 (clobber (reg:CC FLAGS_REG))]
8427 "!TARGET_64BIT"
8428 "and{b}\t{%2, %h0|%h0, %2}"
8429 [(set_attr "type" "alu")
8430 (set_attr "length_immediate" "0")
8431 (set_attr "mode" "QI")])
8432
8433 (define_insn "*andqi_ext_1_rex64"
8434 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8435 (const_int 8)
8436 (const_int 8))
8437 (and:SI
8438 (zero_extract:SI
8439 (match_operand 1 "ext_register_operand" "0")
8440 (const_int 8)
8441 (const_int 8))
8442 (zero_extend:SI
8443 (match_operand 2 "ext_register_operand" "Q"))))
8444 (clobber (reg:CC FLAGS_REG))]
8445 "TARGET_64BIT"
8446 "and{b}\t{%2, %h0|%h0, %2}"
8447 [(set_attr "type" "alu")
8448 (set_attr "length_immediate" "0")
8449 (set_attr "mode" "QI")])
8450
8451 (define_insn "*andqi_ext_2"
8452 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8453 (const_int 8)
8454 (const_int 8))
8455 (and:SI
8456 (zero_extract:SI
8457 (match_operand 1 "ext_register_operand" "%0")
8458 (const_int 8)
8459 (const_int 8))
8460 (zero_extract:SI
8461 (match_operand 2 "ext_register_operand" "Q")
8462 (const_int 8)
8463 (const_int 8))))
8464 (clobber (reg:CC FLAGS_REG))]
8465 ""
8466 "and{b}\t{%h2, %h0|%h0, %h2}"
8467 [(set_attr "type" "alu")
8468 (set_attr "length_immediate" "0")
8469 (set_attr "mode" "QI")])
8470
8471 ;; Convert wide AND instructions with immediate operand to shorter QImode
8472 ;; equivalents when possible.
8473 ;; Don't do the splitting with memory operands, since it introduces risk
8474 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8475 ;; for size, but that can (should?) be handled by generic code instead.
8476 (define_split
8477 [(set (match_operand 0 "register_operand" "")
8478 (and (match_operand 1 "register_operand" "")
8479 (match_operand 2 "const_int_operand" "")))
8480 (clobber (reg:CC FLAGS_REG))]
8481 "reload_completed
8482 && QI_REG_P (operands[0])
8483 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8484 && !(~INTVAL (operands[2]) & ~(255 << 8))
8485 && GET_MODE (operands[0]) != QImode"
8486 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8487 (and:SI (zero_extract:SI (match_dup 1)
8488 (const_int 8) (const_int 8))
8489 (match_dup 2)))
8490 (clobber (reg:CC FLAGS_REG))])]
8491 "operands[0] = gen_lowpart (SImode, operands[0]);
8492 operands[1] = gen_lowpart (SImode, operands[1]);
8493 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8494
8495 ;; Since AND can be encoded with sign extended immediate, this is only
8496 ;; profitable when 7th bit is not set.
8497 (define_split
8498 [(set (match_operand 0 "register_operand" "")
8499 (and (match_operand 1 "general_operand" "")
8500 (match_operand 2 "const_int_operand" "")))
8501 (clobber (reg:CC FLAGS_REG))]
8502 "reload_completed
8503 && ANY_QI_REG_P (operands[0])
8504 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8505 && !(~INTVAL (operands[2]) & ~255)
8506 && !(INTVAL (operands[2]) & 128)
8507 && GET_MODE (operands[0]) != QImode"
8508 [(parallel [(set (strict_low_part (match_dup 0))
8509 (and:QI (match_dup 1)
8510 (match_dup 2)))
8511 (clobber (reg:CC FLAGS_REG))])]
8512 "operands[0] = gen_lowpart (QImode, operands[0]);
8513 operands[1] = gen_lowpart (QImode, operands[1]);
8514 operands[2] = gen_lowpart (QImode, operands[2]);")
8515 \f
8516 ;; Logical inclusive OR instructions
8517
8518 ;; %%% This used to optimize known byte-wide and operations to memory.
8519 ;; If this is considered useful, it should be done with splitters.
8520
8521 (define_expand "iordi3"
8522 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8523 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8524 (match_operand:DI 2 "x86_64_general_operand" "")))
8525 (clobber (reg:CC FLAGS_REG))]
8526 "TARGET_64BIT"
8527 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8528
8529 (define_insn "*iordi_1_rex64"
8530 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8531 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8532 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8533 (clobber (reg:CC FLAGS_REG))]
8534 "TARGET_64BIT
8535 && ix86_binary_operator_ok (IOR, DImode, operands)"
8536 "or{q}\t{%2, %0|%0, %2}"
8537 [(set_attr "type" "alu")
8538 (set_attr "mode" "DI")])
8539
8540 (define_insn "*iordi_2_rex64"
8541 [(set (reg FLAGS_REG)
8542 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8543 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8544 (const_int 0)))
8545 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8546 (ior:DI (match_dup 1) (match_dup 2)))]
8547 "TARGET_64BIT
8548 && ix86_match_ccmode (insn, CCNOmode)
8549 && ix86_binary_operator_ok (IOR, DImode, operands)"
8550 "or{q}\t{%2, %0|%0, %2}"
8551 [(set_attr "type" "alu")
8552 (set_attr "mode" "DI")])
8553
8554 (define_insn "*iordi_3_rex64"
8555 [(set (reg FLAGS_REG)
8556 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8557 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8558 (const_int 0)))
8559 (clobber (match_scratch:DI 0 "=r"))]
8560 "TARGET_64BIT
8561 && ix86_match_ccmode (insn, CCNOmode)
8562 && ix86_binary_operator_ok (IOR, DImode, operands)"
8563 "or{q}\t{%2, %0|%0, %2}"
8564 [(set_attr "type" "alu")
8565 (set_attr "mode" "DI")])
8566
8567
8568 (define_expand "iorsi3"
8569 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8570 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8571 (match_operand:SI 2 "general_operand" "")))
8572 (clobber (reg:CC FLAGS_REG))]
8573 ""
8574 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8575
8576 (define_insn "*iorsi_1"
8577 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8578 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8579 (match_operand:SI 2 "general_operand" "ri,rmi")))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "ix86_binary_operator_ok (IOR, SImode, operands)"
8582 "or{l}\t{%2, %0|%0, %2}"
8583 [(set_attr "type" "alu")
8584 (set_attr "mode" "SI")])
8585
8586 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8587 (define_insn "*iorsi_1_zext"
8588 [(set (match_operand:DI 0 "register_operand" "=rm")
8589 (zero_extend:DI
8590 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8591 (match_operand:SI 2 "general_operand" "rim"))))
8592 (clobber (reg:CC FLAGS_REG))]
8593 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8594 "or{l}\t{%2, %k0|%k0, %2}"
8595 [(set_attr "type" "alu")
8596 (set_attr "mode" "SI")])
8597
8598 (define_insn "*iorsi_1_zext_imm"
8599 [(set (match_operand:DI 0 "register_operand" "=rm")
8600 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8601 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8602 (clobber (reg:CC FLAGS_REG))]
8603 "TARGET_64BIT"
8604 "or{l}\t{%2, %k0|%k0, %2}"
8605 [(set_attr "type" "alu")
8606 (set_attr "mode" "SI")])
8607
8608 (define_insn "*iorsi_2"
8609 [(set (reg FLAGS_REG)
8610 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8611 (match_operand:SI 2 "general_operand" "rim,ri"))
8612 (const_int 0)))
8613 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8614 (ior:SI (match_dup 1) (match_dup 2)))]
8615 "ix86_match_ccmode (insn, CCNOmode)
8616 && ix86_binary_operator_ok (IOR, SImode, operands)"
8617 "or{l}\t{%2, %0|%0, %2}"
8618 [(set_attr "type" "alu")
8619 (set_attr "mode" "SI")])
8620
8621 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8622 ;; ??? Special case for immediate operand is missing - it is tricky.
8623 (define_insn "*iorsi_2_zext"
8624 [(set (reg FLAGS_REG)
8625 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8626 (match_operand:SI 2 "general_operand" "rim"))
8627 (const_int 0)))
8628 (set (match_operand:DI 0 "register_operand" "=r")
8629 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8630 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8631 && ix86_binary_operator_ok (IOR, SImode, operands)"
8632 "or{l}\t{%2, %k0|%k0, %2}"
8633 [(set_attr "type" "alu")
8634 (set_attr "mode" "SI")])
8635
8636 (define_insn "*iorsi_2_zext_imm"
8637 [(set (reg FLAGS_REG)
8638 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8639 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8640 (const_int 0)))
8641 (set (match_operand:DI 0 "register_operand" "=r")
8642 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8643 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8644 && ix86_binary_operator_ok (IOR, SImode, operands)"
8645 "or{l}\t{%2, %k0|%k0, %2}"
8646 [(set_attr "type" "alu")
8647 (set_attr "mode" "SI")])
8648
8649 (define_insn "*iorsi_3"
8650 [(set (reg FLAGS_REG)
8651 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8652 (match_operand:SI 2 "general_operand" "rim"))
8653 (const_int 0)))
8654 (clobber (match_scratch:SI 0 "=r"))]
8655 "ix86_match_ccmode (insn, CCNOmode)
8656 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8657 "or{l}\t{%2, %0|%0, %2}"
8658 [(set_attr "type" "alu")
8659 (set_attr "mode" "SI")])
8660
8661 (define_expand "iorhi3"
8662 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8663 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8664 (match_operand:HI 2 "general_operand" "")))
8665 (clobber (reg:CC FLAGS_REG))]
8666 "TARGET_HIMODE_MATH"
8667 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8668
8669 (define_insn "*iorhi_1"
8670 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8671 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8672 (match_operand:HI 2 "general_operand" "rmi,ri")))
8673 (clobber (reg:CC FLAGS_REG))]
8674 "ix86_binary_operator_ok (IOR, HImode, operands)"
8675 "or{w}\t{%2, %0|%0, %2}"
8676 [(set_attr "type" "alu")
8677 (set_attr "mode" "HI")])
8678
8679 (define_insn "*iorhi_2"
8680 [(set (reg FLAGS_REG)
8681 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8682 (match_operand:HI 2 "general_operand" "rim,ri"))
8683 (const_int 0)))
8684 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8685 (ior:HI (match_dup 1) (match_dup 2)))]
8686 "ix86_match_ccmode (insn, CCNOmode)
8687 && ix86_binary_operator_ok (IOR, HImode, operands)"
8688 "or{w}\t{%2, %0|%0, %2}"
8689 [(set_attr "type" "alu")
8690 (set_attr "mode" "HI")])
8691
8692 (define_insn "*iorhi_3"
8693 [(set (reg FLAGS_REG)
8694 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8695 (match_operand:HI 2 "general_operand" "rim"))
8696 (const_int 0)))
8697 (clobber (match_scratch:HI 0 "=r"))]
8698 "ix86_match_ccmode (insn, CCNOmode)
8699 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8700 "or{w}\t{%2, %0|%0, %2}"
8701 [(set_attr "type" "alu")
8702 (set_attr "mode" "HI")])
8703
8704 (define_expand "iorqi3"
8705 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8706 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8707 (match_operand:QI 2 "general_operand" "")))
8708 (clobber (reg:CC FLAGS_REG))]
8709 "TARGET_QIMODE_MATH"
8710 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8711
8712 ;; %%% Potential partial reg stall on alternative 2. What to do?
8713 (define_insn "*iorqi_1"
8714 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8715 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8716 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "ix86_binary_operator_ok (IOR, QImode, operands)"
8719 "@
8720 or{b}\t{%2, %0|%0, %2}
8721 or{b}\t{%2, %0|%0, %2}
8722 or{l}\t{%k2, %k0|%k0, %k2}"
8723 [(set_attr "type" "alu")
8724 (set_attr "mode" "QI,QI,SI")])
8725
8726 (define_insn "*iorqi_1_slp"
8727 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8728 (ior:QI (match_dup 0)
8729 (match_operand:QI 1 "general_operand" "qmi,qi")))
8730 (clobber (reg:CC FLAGS_REG))]
8731 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8732 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8733 "or{b}\t{%1, %0|%0, %1}"
8734 [(set_attr "type" "alu1")
8735 (set_attr "mode" "QI")])
8736
8737 (define_insn "*iorqi_2"
8738 [(set (reg FLAGS_REG)
8739 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8740 (match_operand:QI 2 "general_operand" "qim,qi"))
8741 (const_int 0)))
8742 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8743 (ior:QI (match_dup 1) (match_dup 2)))]
8744 "ix86_match_ccmode (insn, CCNOmode)
8745 && ix86_binary_operator_ok (IOR, QImode, operands)"
8746 "or{b}\t{%2, %0|%0, %2}"
8747 [(set_attr "type" "alu")
8748 (set_attr "mode" "QI")])
8749
8750 (define_insn "*iorqi_2_slp"
8751 [(set (reg FLAGS_REG)
8752 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8753 (match_operand:QI 1 "general_operand" "qim,qi"))
8754 (const_int 0)))
8755 (set (strict_low_part (match_dup 0))
8756 (ior:QI (match_dup 0) (match_dup 1)))]
8757 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8758 && ix86_match_ccmode (insn, CCNOmode)
8759 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8760 "or{b}\t{%1, %0|%0, %1}"
8761 [(set_attr "type" "alu1")
8762 (set_attr "mode" "QI")])
8763
8764 (define_insn "*iorqi_3"
8765 [(set (reg FLAGS_REG)
8766 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8767 (match_operand:QI 2 "general_operand" "qim"))
8768 (const_int 0)))
8769 (clobber (match_scratch:QI 0 "=q"))]
8770 "ix86_match_ccmode (insn, CCNOmode)
8771 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8772 "or{b}\t{%2, %0|%0, %2}"
8773 [(set_attr "type" "alu")
8774 (set_attr "mode" "QI")])
8775
8776 (define_insn "iorqi_ext_0"
8777 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8778 (const_int 8)
8779 (const_int 8))
8780 (ior:SI
8781 (zero_extract:SI
8782 (match_operand 1 "ext_register_operand" "0")
8783 (const_int 8)
8784 (const_int 8))
8785 (match_operand 2 "const_int_operand" "n")))
8786 (clobber (reg:CC FLAGS_REG))]
8787 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8788 "or{b}\t{%2, %h0|%h0, %2}"
8789 [(set_attr "type" "alu")
8790 (set_attr "length_immediate" "1")
8791 (set_attr "mode" "QI")])
8792
8793 (define_insn "*iorqi_ext_1"
8794 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8795 (const_int 8)
8796 (const_int 8))
8797 (ior:SI
8798 (zero_extract:SI
8799 (match_operand 1 "ext_register_operand" "0")
8800 (const_int 8)
8801 (const_int 8))
8802 (zero_extend:SI
8803 (match_operand:QI 2 "general_operand" "Qm"))))
8804 (clobber (reg:CC FLAGS_REG))]
8805 "!TARGET_64BIT
8806 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8807 "or{b}\t{%2, %h0|%h0, %2}"
8808 [(set_attr "type" "alu")
8809 (set_attr "length_immediate" "0")
8810 (set_attr "mode" "QI")])
8811
8812 (define_insn "*iorqi_ext_1_rex64"
8813 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8814 (const_int 8)
8815 (const_int 8))
8816 (ior:SI
8817 (zero_extract:SI
8818 (match_operand 1 "ext_register_operand" "0")
8819 (const_int 8)
8820 (const_int 8))
8821 (zero_extend:SI
8822 (match_operand 2 "ext_register_operand" "Q"))))
8823 (clobber (reg:CC FLAGS_REG))]
8824 "TARGET_64BIT
8825 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8826 "or{b}\t{%2, %h0|%h0, %2}"
8827 [(set_attr "type" "alu")
8828 (set_attr "length_immediate" "0")
8829 (set_attr "mode" "QI")])
8830
8831 (define_insn "*iorqi_ext_2"
8832 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8833 (const_int 8)
8834 (const_int 8))
8835 (ior:SI
8836 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8837 (const_int 8)
8838 (const_int 8))
8839 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8840 (const_int 8)
8841 (const_int 8))))
8842 (clobber (reg:CC FLAGS_REG))]
8843 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8844 "ior{b}\t{%h2, %h0|%h0, %h2}"
8845 [(set_attr "type" "alu")
8846 (set_attr "length_immediate" "0")
8847 (set_attr "mode" "QI")])
8848
8849 (define_split
8850 [(set (match_operand 0 "register_operand" "")
8851 (ior (match_operand 1 "register_operand" "")
8852 (match_operand 2 "const_int_operand" "")))
8853 (clobber (reg:CC FLAGS_REG))]
8854 "reload_completed
8855 && QI_REG_P (operands[0])
8856 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8857 && !(INTVAL (operands[2]) & ~(255 << 8))
8858 && GET_MODE (operands[0]) != QImode"
8859 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8860 (ior:SI (zero_extract:SI (match_dup 1)
8861 (const_int 8) (const_int 8))
8862 (match_dup 2)))
8863 (clobber (reg:CC FLAGS_REG))])]
8864 "operands[0] = gen_lowpart (SImode, operands[0]);
8865 operands[1] = gen_lowpart (SImode, operands[1]);
8866 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8867
8868 ;; Since OR can be encoded with sign extended immediate, this is only
8869 ;; profitable when 7th bit is set.
8870 (define_split
8871 [(set (match_operand 0 "register_operand" "")
8872 (ior (match_operand 1 "general_operand" "")
8873 (match_operand 2 "const_int_operand" "")))
8874 (clobber (reg:CC FLAGS_REG))]
8875 "reload_completed
8876 && ANY_QI_REG_P (operands[0])
8877 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8878 && !(INTVAL (operands[2]) & ~255)
8879 && (INTVAL (operands[2]) & 128)
8880 && GET_MODE (operands[0]) != QImode"
8881 [(parallel [(set (strict_low_part (match_dup 0))
8882 (ior:QI (match_dup 1)
8883 (match_dup 2)))
8884 (clobber (reg:CC FLAGS_REG))])]
8885 "operands[0] = gen_lowpart (QImode, operands[0]);
8886 operands[1] = gen_lowpart (QImode, operands[1]);
8887 operands[2] = gen_lowpart (QImode, operands[2]);")
8888 \f
8889 ;; Logical XOR instructions
8890
8891 ;; %%% This used to optimize known byte-wide and operations to memory.
8892 ;; If this is considered useful, it should be done with splitters.
8893
8894 (define_expand "xordi3"
8895 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8896 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8897 (match_operand:DI 2 "x86_64_general_operand" "")))
8898 (clobber (reg:CC FLAGS_REG))]
8899 "TARGET_64BIT"
8900 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8901
8902 (define_insn "*xordi_1_rex64"
8903 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8904 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8905 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8906 (clobber (reg:CC FLAGS_REG))]
8907 "TARGET_64BIT
8908 && ix86_binary_operator_ok (XOR, DImode, operands)"
8909 "@
8910 xor{q}\t{%2, %0|%0, %2}
8911 xor{q}\t{%2, %0|%0, %2}"
8912 [(set_attr "type" "alu")
8913 (set_attr "mode" "DI,DI")])
8914
8915 (define_insn "*xordi_2_rex64"
8916 [(set (reg FLAGS_REG)
8917 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8918 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8919 (const_int 0)))
8920 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8921 (xor:DI (match_dup 1) (match_dup 2)))]
8922 "TARGET_64BIT
8923 && ix86_match_ccmode (insn, CCNOmode)
8924 && ix86_binary_operator_ok (XOR, DImode, operands)"
8925 "@
8926 xor{q}\t{%2, %0|%0, %2}
8927 xor{q}\t{%2, %0|%0, %2}"
8928 [(set_attr "type" "alu")
8929 (set_attr "mode" "DI,DI")])
8930
8931 (define_insn "*xordi_3_rex64"
8932 [(set (reg FLAGS_REG)
8933 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8934 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8935 (const_int 0)))
8936 (clobber (match_scratch:DI 0 "=r"))]
8937 "TARGET_64BIT
8938 && ix86_match_ccmode (insn, CCNOmode)
8939 && ix86_binary_operator_ok (XOR, DImode, operands)"
8940 "xor{q}\t{%2, %0|%0, %2}"
8941 [(set_attr "type" "alu")
8942 (set_attr "mode" "DI")])
8943
8944 (define_expand "xorsi3"
8945 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8946 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8947 (match_operand:SI 2 "general_operand" "")))
8948 (clobber (reg:CC FLAGS_REG))]
8949 ""
8950 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8951
8952 (define_insn "*xorsi_1"
8953 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8954 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8955 (match_operand:SI 2 "general_operand" "ri,rm")))
8956 (clobber (reg:CC FLAGS_REG))]
8957 "ix86_binary_operator_ok (XOR, SImode, operands)"
8958 "xor{l}\t{%2, %0|%0, %2}"
8959 [(set_attr "type" "alu")
8960 (set_attr "mode" "SI")])
8961
8962 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8963 ;; Add speccase for immediates
8964 (define_insn "*xorsi_1_zext"
8965 [(set (match_operand:DI 0 "register_operand" "=r")
8966 (zero_extend:DI
8967 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8968 (match_operand:SI 2 "general_operand" "rim"))))
8969 (clobber (reg:CC FLAGS_REG))]
8970 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8971 "xor{l}\t{%2, %k0|%k0, %2}"
8972 [(set_attr "type" "alu")
8973 (set_attr "mode" "SI")])
8974
8975 (define_insn "*xorsi_1_zext_imm"
8976 [(set (match_operand:DI 0 "register_operand" "=r")
8977 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8978 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8979 (clobber (reg:CC FLAGS_REG))]
8980 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8981 "xor{l}\t{%2, %k0|%k0, %2}"
8982 [(set_attr "type" "alu")
8983 (set_attr "mode" "SI")])
8984
8985 (define_insn "*xorsi_2"
8986 [(set (reg FLAGS_REG)
8987 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8988 (match_operand:SI 2 "general_operand" "rim,ri"))
8989 (const_int 0)))
8990 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8991 (xor:SI (match_dup 1) (match_dup 2)))]
8992 "ix86_match_ccmode (insn, CCNOmode)
8993 && ix86_binary_operator_ok (XOR, SImode, operands)"
8994 "xor{l}\t{%2, %0|%0, %2}"
8995 [(set_attr "type" "alu")
8996 (set_attr "mode" "SI")])
8997
8998 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8999 ;; ??? Special case for immediate operand is missing - it is tricky.
9000 (define_insn "*xorsi_2_zext"
9001 [(set (reg FLAGS_REG)
9002 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9003 (match_operand:SI 2 "general_operand" "rim"))
9004 (const_int 0)))
9005 (set (match_operand:DI 0 "register_operand" "=r")
9006 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9007 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9008 && ix86_binary_operator_ok (XOR, SImode, operands)"
9009 "xor{l}\t{%2, %k0|%k0, %2}"
9010 [(set_attr "type" "alu")
9011 (set_attr "mode" "SI")])
9012
9013 (define_insn "*xorsi_2_zext_imm"
9014 [(set (reg FLAGS_REG)
9015 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9016 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9017 (const_int 0)))
9018 (set (match_operand:DI 0 "register_operand" "=r")
9019 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9020 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9021 && ix86_binary_operator_ok (XOR, SImode, operands)"
9022 "xor{l}\t{%2, %k0|%k0, %2}"
9023 [(set_attr "type" "alu")
9024 (set_attr "mode" "SI")])
9025
9026 (define_insn "*xorsi_3"
9027 [(set (reg FLAGS_REG)
9028 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9029 (match_operand:SI 2 "general_operand" "rim"))
9030 (const_int 0)))
9031 (clobber (match_scratch:SI 0 "=r"))]
9032 "ix86_match_ccmode (insn, CCNOmode)
9033 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9034 "xor{l}\t{%2, %0|%0, %2}"
9035 [(set_attr "type" "alu")
9036 (set_attr "mode" "SI")])
9037
9038 (define_expand "xorhi3"
9039 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9040 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9041 (match_operand:HI 2 "general_operand" "")))
9042 (clobber (reg:CC FLAGS_REG))]
9043 "TARGET_HIMODE_MATH"
9044 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9045
9046 (define_insn "*xorhi_1"
9047 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9048 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9049 (match_operand:HI 2 "general_operand" "rmi,ri")))
9050 (clobber (reg:CC FLAGS_REG))]
9051 "ix86_binary_operator_ok (XOR, HImode, operands)"
9052 "xor{w}\t{%2, %0|%0, %2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "mode" "HI")])
9055
9056 (define_insn "*xorhi_2"
9057 [(set (reg FLAGS_REG)
9058 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9059 (match_operand:HI 2 "general_operand" "rim,ri"))
9060 (const_int 0)))
9061 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9062 (xor:HI (match_dup 1) (match_dup 2)))]
9063 "ix86_match_ccmode (insn, CCNOmode)
9064 && ix86_binary_operator_ok (XOR, HImode, operands)"
9065 "xor{w}\t{%2, %0|%0, %2}"
9066 [(set_attr "type" "alu")
9067 (set_attr "mode" "HI")])
9068
9069 (define_insn "*xorhi_3"
9070 [(set (reg FLAGS_REG)
9071 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9072 (match_operand:HI 2 "general_operand" "rim"))
9073 (const_int 0)))
9074 (clobber (match_scratch:HI 0 "=r"))]
9075 "ix86_match_ccmode (insn, CCNOmode)
9076 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9077 "xor{w}\t{%2, %0|%0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "mode" "HI")])
9080
9081 (define_expand "xorqi3"
9082 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9083 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9084 (match_operand:QI 2 "general_operand" "")))
9085 (clobber (reg:CC FLAGS_REG))]
9086 "TARGET_QIMODE_MATH"
9087 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9088
9089 ;; %%% Potential partial reg stall on alternative 2. What to do?
9090 (define_insn "*xorqi_1"
9091 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9092 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9093 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9094 (clobber (reg:CC FLAGS_REG))]
9095 "ix86_binary_operator_ok (XOR, QImode, operands)"
9096 "@
9097 xor{b}\t{%2, %0|%0, %2}
9098 xor{b}\t{%2, %0|%0, %2}
9099 xor{l}\t{%k2, %k0|%k0, %k2}"
9100 [(set_attr "type" "alu")
9101 (set_attr "mode" "QI,QI,SI")])
9102
9103 (define_insn "*xorqi_1_slp"
9104 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9105 (xor:QI (match_dup 0)
9106 (match_operand:QI 1 "general_operand" "qi,qmi")))
9107 (clobber (reg:CC FLAGS_REG))]
9108 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9109 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9110 "xor{b}\t{%1, %0|%0, %1}"
9111 [(set_attr "type" "alu1")
9112 (set_attr "mode" "QI")])
9113
9114 (define_insn "xorqi_ext_0"
9115 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9116 (const_int 8)
9117 (const_int 8))
9118 (xor:SI
9119 (zero_extract:SI
9120 (match_operand 1 "ext_register_operand" "0")
9121 (const_int 8)
9122 (const_int 8))
9123 (match_operand 2 "const_int_operand" "n")))
9124 (clobber (reg:CC FLAGS_REG))]
9125 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9126 "xor{b}\t{%2, %h0|%h0, %2}"
9127 [(set_attr "type" "alu")
9128 (set_attr "length_immediate" "1")
9129 (set_attr "mode" "QI")])
9130
9131 (define_insn "*xorqi_ext_1"
9132 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9133 (const_int 8)
9134 (const_int 8))
9135 (xor:SI
9136 (zero_extract:SI
9137 (match_operand 1 "ext_register_operand" "0")
9138 (const_int 8)
9139 (const_int 8))
9140 (zero_extend:SI
9141 (match_operand:QI 2 "general_operand" "Qm"))))
9142 (clobber (reg:CC FLAGS_REG))]
9143 "!TARGET_64BIT
9144 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9145 "xor{b}\t{%2, %h0|%h0, %2}"
9146 [(set_attr "type" "alu")
9147 (set_attr "length_immediate" "0")
9148 (set_attr "mode" "QI")])
9149
9150 (define_insn "*xorqi_ext_1_rex64"
9151 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9152 (const_int 8)
9153 (const_int 8))
9154 (xor:SI
9155 (zero_extract:SI
9156 (match_operand 1 "ext_register_operand" "0")
9157 (const_int 8)
9158 (const_int 8))
9159 (zero_extend:SI
9160 (match_operand 2 "ext_register_operand" "Q"))))
9161 (clobber (reg:CC FLAGS_REG))]
9162 "TARGET_64BIT
9163 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9164 "xor{b}\t{%2, %h0|%h0, %2}"
9165 [(set_attr "type" "alu")
9166 (set_attr "length_immediate" "0")
9167 (set_attr "mode" "QI")])
9168
9169 (define_insn "*xorqi_ext_2"
9170 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9171 (const_int 8)
9172 (const_int 8))
9173 (xor:SI
9174 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9175 (const_int 8)
9176 (const_int 8))
9177 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9178 (const_int 8)
9179 (const_int 8))))
9180 (clobber (reg:CC FLAGS_REG))]
9181 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9182 "xor{b}\t{%h2, %h0|%h0, %h2}"
9183 [(set_attr "type" "alu")
9184 (set_attr "length_immediate" "0")
9185 (set_attr "mode" "QI")])
9186
9187 (define_insn "*xorqi_cc_1"
9188 [(set (reg FLAGS_REG)
9189 (compare
9190 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9191 (match_operand:QI 2 "general_operand" "qim,qi"))
9192 (const_int 0)))
9193 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9194 (xor:QI (match_dup 1) (match_dup 2)))]
9195 "ix86_match_ccmode (insn, CCNOmode)
9196 && ix86_binary_operator_ok (XOR, QImode, operands)"
9197 "xor{b}\t{%2, %0|%0, %2}"
9198 [(set_attr "type" "alu")
9199 (set_attr "mode" "QI")])
9200
9201 (define_insn "*xorqi_2_slp"
9202 [(set (reg FLAGS_REG)
9203 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9204 (match_operand:QI 1 "general_operand" "qim,qi"))
9205 (const_int 0)))
9206 (set (strict_low_part (match_dup 0))
9207 (xor:QI (match_dup 0) (match_dup 1)))]
9208 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9209 && ix86_match_ccmode (insn, CCNOmode)
9210 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9211 "xor{b}\t{%1, %0|%0, %1}"
9212 [(set_attr "type" "alu1")
9213 (set_attr "mode" "QI")])
9214
9215 (define_insn "*xorqi_cc_2"
9216 [(set (reg FLAGS_REG)
9217 (compare
9218 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9219 (match_operand:QI 2 "general_operand" "qim"))
9220 (const_int 0)))
9221 (clobber (match_scratch:QI 0 "=q"))]
9222 "ix86_match_ccmode (insn, CCNOmode)
9223 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9224 "xor{b}\t{%2, %0|%0, %2}"
9225 [(set_attr "type" "alu")
9226 (set_attr "mode" "QI")])
9227
9228 (define_insn "*xorqi_cc_ext_1"
9229 [(set (reg FLAGS_REG)
9230 (compare
9231 (xor:SI
9232 (zero_extract:SI
9233 (match_operand 1 "ext_register_operand" "0")
9234 (const_int 8)
9235 (const_int 8))
9236 (match_operand:QI 2 "general_operand" "qmn"))
9237 (const_int 0)))
9238 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9239 (const_int 8)
9240 (const_int 8))
9241 (xor:SI
9242 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9243 (match_dup 2)))]
9244 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9245 "xor{b}\t{%2, %h0|%h0, %2}"
9246 [(set_attr "type" "alu")
9247 (set_attr "mode" "QI")])
9248
9249 (define_insn "*xorqi_cc_ext_1_rex64"
9250 [(set (reg FLAGS_REG)
9251 (compare
9252 (xor:SI
9253 (zero_extract:SI
9254 (match_operand 1 "ext_register_operand" "0")
9255 (const_int 8)
9256 (const_int 8))
9257 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9258 (const_int 0)))
9259 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9260 (const_int 8)
9261 (const_int 8))
9262 (xor:SI
9263 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9264 (match_dup 2)))]
9265 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9266 "xor{b}\t{%2, %h0|%h0, %2}"
9267 [(set_attr "type" "alu")
9268 (set_attr "mode" "QI")])
9269
9270 (define_expand "xorqi_cc_ext_1"
9271 [(parallel [
9272 (set (reg:CCNO FLAGS_REG)
9273 (compare:CCNO
9274 (xor:SI
9275 (zero_extract:SI
9276 (match_operand 1 "ext_register_operand" "")
9277 (const_int 8)
9278 (const_int 8))
9279 (match_operand:QI 2 "general_operand" ""))
9280 (const_int 0)))
9281 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9282 (const_int 8)
9283 (const_int 8))
9284 (xor:SI
9285 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9286 (match_dup 2)))])]
9287 ""
9288 "")
9289
9290 (define_split
9291 [(set (match_operand 0 "register_operand" "")
9292 (xor (match_operand 1 "register_operand" "")
9293 (match_operand 2 "const_int_operand" "")))
9294 (clobber (reg:CC FLAGS_REG))]
9295 "reload_completed
9296 && QI_REG_P (operands[0])
9297 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9298 && !(INTVAL (operands[2]) & ~(255 << 8))
9299 && GET_MODE (operands[0]) != QImode"
9300 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9301 (xor:SI (zero_extract:SI (match_dup 1)
9302 (const_int 8) (const_int 8))
9303 (match_dup 2)))
9304 (clobber (reg:CC FLAGS_REG))])]
9305 "operands[0] = gen_lowpart (SImode, operands[0]);
9306 operands[1] = gen_lowpart (SImode, operands[1]);
9307 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9308
9309 ;; Since XOR can be encoded with sign extended immediate, this is only
9310 ;; profitable when 7th bit is set.
9311 (define_split
9312 [(set (match_operand 0 "register_operand" "")
9313 (xor (match_operand 1 "general_operand" "")
9314 (match_operand 2 "const_int_operand" "")))
9315 (clobber (reg:CC FLAGS_REG))]
9316 "reload_completed
9317 && ANY_QI_REG_P (operands[0])
9318 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9319 && !(INTVAL (operands[2]) & ~255)
9320 && (INTVAL (operands[2]) & 128)
9321 && GET_MODE (operands[0]) != QImode"
9322 [(parallel [(set (strict_low_part (match_dup 0))
9323 (xor:QI (match_dup 1)
9324 (match_dup 2)))
9325 (clobber (reg:CC FLAGS_REG))])]
9326 "operands[0] = gen_lowpart (QImode, operands[0]);
9327 operands[1] = gen_lowpart (QImode, operands[1]);
9328 operands[2] = gen_lowpart (QImode, operands[2]);")
9329 \f
9330 ;; Negation instructions
9331
9332 (define_expand "negti2"
9333 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9334 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9335 (clobber (reg:CC FLAGS_REG))])]
9336 "TARGET_64BIT"
9337 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9338
9339 (define_insn "*negti2_1"
9340 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9341 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9342 (clobber (reg:CC FLAGS_REG))]
9343 "TARGET_64BIT
9344 && ix86_unary_operator_ok (NEG, TImode, operands)"
9345 "#")
9346
9347 (define_split
9348 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9349 (neg:TI (match_operand:TI 1 "general_operand" "")))
9350 (clobber (reg:CC FLAGS_REG))]
9351 "TARGET_64BIT && reload_completed"
9352 [(parallel
9353 [(set (reg:CCZ FLAGS_REG)
9354 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9355 (set (match_dup 0) (neg:DI (match_dup 2)))])
9356 (parallel
9357 [(set (match_dup 1)
9358 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9359 (match_dup 3))
9360 (const_int 0)))
9361 (clobber (reg:CC FLAGS_REG))])
9362 (parallel
9363 [(set (match_dup 1)
9364 (neg:DI (match_dup 1)))
9365 (clobber (reg:CC FLAGS_REG))])]
9366 "split_ti (operands+1, 1, operands+2, operands+3);
9367 split_ti (operands+0, 1, operands+0, operands+1);")
9368
9369 (define_expand "negdi2"
9370 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9371 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9372 (clobber (reg:CC FLAGS_REG))])]
9373 ""
9374 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9375
9376 (define_insn "*negdi2_1"
9377 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9378 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9379 (clobber (reg:CC FLAGS_REG))]
9380 "!TARGET_64BIT
9381 && ix86_unary_operator_ok (NEG, DImode, operands)"
9382 "#")
9383
9384 (define_split
9385 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9386 (neg:DI (match_operand:DI 1 "general_operand" "")))
9387 (clobber (reg:CC FLAGS_REG))]
9388 "!TARGET_64BIT && reload_completed"
9389 [(parallel
9390 [(set (reg:CCZ FLAGS_REG)
9391 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9392 (set (match_dup 0) (neg:SI (match_dup 2)))])
9393 (parallel
9394 [(set (match_dup 1)
9395 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9396 (match_dup 3))
9397 (const_int 0)))
9398 (clobber (reg:CC FLAGS_REG))])
9399 (parallel
9400 [(set (match_dup 1)
9401 (neg:SI (match_dup 1)))
9402 (clobber (reg:CC FLAGS_REG))])]
9403 "split_di (operands+1, 1, operands+2, operands+3);
9404 split_di (operands+0, 1, operands+0, operands+1);")
9405
9406 (define_insn "*negdi2_1_rex64"
9407 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9408 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9409 (clobber (reg:CC FLAGS_REG))]
9410 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9411 "neg{q}\t%0"
9412 [(set_attr "type" "negnot")
9413 (set_attr "mode" "DI")])
9414
9415 ;; The problem with neg is that it does not perform (compare x 0),
9416 ;; it really performs (compare 0 x), which leaves us with the zero
9417 ;; flag being the only useful item.
9418
9419 (define_insn "*negdi2_cmpz_rex64"
9420 [(set (reg:CCZ FLAGS_REG)
9421 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9422 (const_int 0)))
9423 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9424 (neg:DI (match_dup 1)))]
9425 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9426 "neg{q}\t%0"
9427 [(set_attr "type" "negnot")
9428 (set_attr "mode" "DI")])
9429
9430
9431 (define_expand "negsi2"
9432 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9433 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9434 (clobber (reg:CC FLAGS_REG))])]
9435 ""
9436 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9437
9438 (define_insn "*negsi2_1"
9439 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9440 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9441 (clobber (reg:CC FLAGS_REG))]
9442 "ix86_unary_operator_ok (NEG, SImode, operands)"
9443 "neg{l}\t%0"
9444 [(set_attr "type" "negnot")
9445 (set_attr "mode" "SI")])
9446
9447 ;; Combine is quite creative about this pattern.
9448 (define_insn "*negsi2_1_zext"
9449 [(set (match_operand:DI 0 "register_operand" "=r")
9450 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9451 (const_int 32)))
9452 (const_int 32)))
9453 (clobber (reg:CC FLAGS_REG))]
9454 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9455 "neg{l}\t%k0"
9456 [(set_attr "type" "negnot")
9457 (set_attr "mode" "SI")])
9458
9459 ;; The problem with neg is that it does not perform (compare x 0),
9460 ;; it really performs (compare 0 x), which leaves us with the zero
9461 ;; flag being the only useful item.
9462
9463 (define_insn "*negsi2_cmpz"
9464 [(set (reg:CCZ FLAGS_REG)
9465 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9466 (const_int 0)))
9467 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9468 (neg:SI (match_dup 1)))]
9469 "ix86_unary_operator_ok (NEG, SImode, operands)"
9470 "neg{l}\t%0"
9471 [(set_attr "type" "negnot")
9472 (set_attr "mode" "SI")])
9473
9474 (define_insn "*negsi2_cmpz_zext"
9475 [(set (reg:CCZ FLAGS_REG)
9476 (compare:CCZ (lshiftrt:DI
9477 (neg:DI (ashift:DI
9478 (match_operand:DI 1 "register_operand" "0")
9479 (const_int 32)))
9480 (const_int 32))
9481 (const_int 0)))
9482 (set (match_operand:DI 0 "register_operand" "=r")
9483 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9484 (const_int 32)))
9485 (const_int 32)))]
9486 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9487 "neg{l}\t%k0"
9488 [(set_attr "type" "negnot")
9489 (set_attr "mode" "SI")])
9490
9491 (define_expand "neghi2"
9492 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9493 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9494 (clobber (reg:CC FLAGS_REG))])]
9495 "TARGET_HIMODE_MATH"
9496 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9497
9498 (define_insn "*neghi2_1"
9499 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9500 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9501 (clobber (reg:CC FLAGS_REG))]
9502 "ix86_unary_operator_ok (NEG, HImode, operands)"
9503 "neg{w}\t%0"
9504 [(set_attr "type" "negnot")
9505 (set_attr "mode" "HI")])
9506
9507 (define_insn "*neghi2_cmpz"
9508 [(set (reg:CCZ FLAGS_REG)
9509 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9510 (const_int 0)))
9511 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9512 (neg:HI (match_dup 1)))]
9513 "ix86_unary_operator_ok (NEG, HImode, operands)"
9514 "neg{w}\t%0"
9515 [(set_attr "type" "negnot")
9516 (set_attr "mode" "HI")])
9517
9518 (define_expand "negqi2"
9519 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9520 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9521 (clobber (reg:CC FLAGS_REG))])]
9522 "TARGET_QIMODE_MATH"
9523 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9524
9525 (define_insn "*negqi2_1"
9526 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9527 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9528 (clobber (reg:CC FLAGS_REG))]
9529 "ix86_unary_operator_ok (NEG, QImode, operands)"
9530 "neg{b}\t%0"
9531 [(set_attr "type" "negnot")
9532 (set_attr "mode" "QI")])
9533
9534 (define_insn "*negqi2_cmpz"
9535 [(set (reg:CCZ FLAGS_REG)
9536 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9537 (const_int 0)))
9538 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9539 (neg:QI (match_dup 1)))]
9540 "ix86_unary_operator_ok (NEG, QImode, operands)"
9541 "neg{b}\t%0"
9542 [(set_attr "type" "negnot")
9543 (set_attr "mode" "QI")])
9544
9545 ;; Changing of sign for FP values is doable using integer unit too.
9546
9547 (define_expand "negsf2"
9548 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9549 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9550 "TARGET_80387 || TARGET_SSE_MATH"
9551 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9552
9553 (define_expand "abssf2"
9554 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9555 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9556 "TARGET_80387 || TARGET_SSE_MATH"
9557 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9558
9559 (define_insn "*absnegsf2_mixed"
9560 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9561 (match_operator:SF 3 "absneg_operator"
9562 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9563 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9564 (clobber (reg:CC FLAGS_REG))]
9565 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9566 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9567 "#")
9568
9569 (define_insn "*absnegsf2_sse"
9570 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9571 (match_operator:SF 3 "absneg_operator"
9572 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9573 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9574 (clobber (reg:CC FLAGS_REG))]
9575 "TARGET_SSE_MATH
9576 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9577 "#")
9578
9579 (define_insn "*absnegsf2_i387"
9580 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9581 (match_operator:SF 3 "absneg_operator"
9582 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9583 (use (match_operand 2 "" ""))
9584 (clobber (reg:CC FLAGS_REG))]
9585 "TARGET_80387 && !TARGET_SSE_MATH
9586 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9587 "#")
9588
9589 (define_expand "copysignsf3"
9590 [(match_operand:SF 0 "register_operand" "")
9591 (match_operand:SF 1 "nonmemory_operand" "")
9592 (match_operand:SF 2 "register_operand" "")]
9593 "TARGET_SSE_MATH"
9594 {
9595 ix86_expand_copysign (operands);
9596 DONE;
9597 })
9598
9599 (define_insn_and_split "copysignsf3_const"
9600 [(set (match_operand:SF 0 "register_operand" "=x")
9601 (unspec:SF
9602 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9603 (match_operand:SF 2 "register_operand" "0")
9604 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9605 UNSPEC_COPYSIGN))]
9606 "TARGET_SSE_MATH"
9607 "#"
9608 "&& reload_completed"
9609 [(const_int 0)]
9610 {
9611 ix86_split_copysign_const (operands);
9612 DONE;
9613 })
9614
9615 (define_insn "copysignsf3_var"
9616 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9617 (unspec:SF
9618 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9619 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9620 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9621 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9622 UNSPEC_COPYSIGN))
9623 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9624 "TARGET_SSE_MATH"
9625 "#")
9626
9627 (define_split
9628 [(set (match_operand:SF 0 "register_operand" "")
9629 (unspec:SF
9630 [(match_operand:SF 2 "register_operand" "")
9631 (match_operand:SF 3 "register_operand" "")
9632 (match_operand:V4SF 4 "" "")
9633 (match_operand:V4SF 5 "" "")]
9634 UNSPEC_COPYSIGN))
9635 (clobber (match_scratch:V4SF 1 ""))]
9636 "TARGET_SSE_MATH && reload_completed"
9637 [(const_int 0)]
9638 {
9639 ix86_split_copysign_var (operands);
9640 DONE;
9641 })
9642
9643 (define_expand "negdf2"
9644 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9645 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9646 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9647 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9648
9649 (define_expand "absdf2"
9650 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9651 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9652 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9653 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9654
9655 (define_insn "*absnegdf2_mixed"
9656 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9657 (match_operator:DF 3 "absneg_operator"
9658 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9659 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9660 (clobber (reg:CC FLAGS_REG))]
9661 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9662 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9663 "#")
9664
9665 (define_insn "*absnegdf2_sse"
9666 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9667 (match_operator:DF 3 "absneg_operator"
9668 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9669 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9670 (clobber (reg:CC FLAGS_REG))]
9671 "TARGET_SSE2 && TARGET_SSE_MATH
9672 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9673 "#")
9674
9675 (define_insn "*absnegdf2_i387"
9676 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9677 (match_operator:DF 3 "absneg_operator"
9678 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9679 (use (match_operand 2 "" ""))
9680 (clobber (reg:CC FLAGS_REG))]
9681 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9682 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9683 "#")
9684
9685 (define_expand "copysigndf3"
9686 [(match_operand:DF 0 "register_operand" "")
9687 (match_operand:DF 1 "nonmemory_operand" "")
9688 (match_operand:DF 2 "register_operand" "")]
9689 "TARGET_SSE2 && TARGET_SSE_MATH"
9690 {
9691 ix86_expand_copysign (operands);
9692 DONE;
9693 })
9694
9695 (define_insn_and_split "copysigndf3_const"
9696 [(set (match_operand:DF 0 "register_operand" "=x")
9697 (unspec:DF
9698 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9699 (match_operand:DF 2 "register_operand" "0")
9700 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9701 UNSPEC_COPYSIGN))]
9702 "TARGET_SSE2 && TARGET_SSE_MATH"
9703 "#"
9704 "&& reload_completed"
9705 [(const_int 0)]
9706 {
9707 ix86_split_copysign_const (operands);
9708 DONE;
9709 })
9710
9711 (define_insn "copysigndf3_var"
9712 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9713 (unspec:DF
9714 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9715 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9716 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9717 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9718 UNSPEC_COPYSIGN))
9719 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9720 "TARGET_SSE2 && TARGET_SSE_MATH"
9721 "#")
9722
9723 (define_split
9724 [(set (match_operand:DF 0 "register_operand" "")
9725 (unspec:DF
9726 [(match_operand:DF 2 "register_operand" "")
9727 (match_operand:DF 3 "register_operand" "")
9728 (match_operand:V2DF 4 "" "")
9729 (match_operand:V2DF 5 "" "")]
9730 UNSPEC_COPYSIGN))
9731 (clobber (match_scratch:V2DF 1 ""))]
9732 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9733 [(const_int 0)]
9734 {
9735 ix86_split_copysign_var (operands);
9736 DONE;
9737 })
9738
9739 (define_expand "negxf2"
9740 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9741 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9742 "TARGET_80387"
9743 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9744
9745 (define_expand "absxf2"
9746 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9747 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9748 "TARGET_80387"
9749 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9750
9751 (define_insn "*absnegxf2_i387"
9752 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9753 (match_operator:XF 3 "absneg_operator"
9754 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9755 (use (match_operand 2 "" ""))
9756 (clobber (reg:CC FLAGS_REG))]
9757 "TARGET_80387
9758 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9759 "#")
9760
9761 ;; Splitters for fp abs and neg.
9762
9763 (define_split
9764 [(set (match_operand 0 "fp_register_operand" "")
9765 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9766 (use (match_operand 2 "" ""))
9767 (clobber (reg:CC FLAGS_REG))]
9768 "reload_completed"
9769 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9770
9771 (define_split
9772 [(set (match_operand 0 "register_operand" "")
9773 (match_operator 3 "absneg_operator"
9774 [(match_operand 1 "register_operand" "")]))
9775 (use (match_operand 2 "nonimmediate_operand" ""))
9776 (clobber (reg:CC FLAGS_REG))]
9777 "reload_completed && SSE_REG_P (operands[0])"
9778 [(set (match_dup 0) (match_dup 3))]
9779 {
9780 enum machine_mode mode = GET_MODE (operands[0]);
9781 enum machine_mode vmode = GET_MODE (operands[2]);
9782 rtx tmp;
9783
9784 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9785 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9786 if (operands_match_p (operands[0], operands[2]))
9787 {
9788 tmp = operands[1];
9789 operands[1] = operands[2];
9790 operands[2] = tmp;
9791 }
9792 if (GET_CODE (operands[3]) == ABS)
9793 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9794 else
9795 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9796 operands[3] = tmp;
9797 })
9798
9799 (define_split
9800 [(set (match_operand:SF 0 "register_operand" "")
9801 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9802 (use (match_operand:V4SF 2 "" ""))
9803 (clobber (reg:CC FLAGS_REG))]
9804 "reload_completed"
9805 [(parallel [(set (match_dup 0) (match_dup 1))
9806 (clobber (reg:CC FLAGS_REG))])]
9807 {
9808 rtx tmp;
9809 operands[0] = gen_lowpart (SImode, operands[0]);
9810 if (GET_CODE (operands[1]) == ABS)
9811 {
9812 tmp = gen_int_mode (0x7fffffff, SImode);
9813 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9814 }
9815 else
9816 {
9817 tmp = gen_int_mode (0x80000000, SImode);
9818 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9819 }
9820 operands[1] = tmp;
9821 })
9822
9823 (define_split
9824 [(set (match_operand:DF 0 "register_operand" "")
9825 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9826 (use (match_operand 2 "" ""))
9827 (clobber (reg:CC FLAGS_REG))]
9828 "reload_completed"
9829 [(parallel [(set (match_dup 0) (match_dup 1))
9830 (clobber (reg:CC FLAGS_REG))])]
9831 {
9832 rtx tmp;
9833 if (TARGET_64BIT)
9834 {
9835 tmp = gen_lowpart (DImode, operands[0]);
9836 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9837 operands[0] = tmp;
9838
9839 if (GET_CODE (operands[1]) == ABS)
9840 tmp = const0_rtx;
9841 else
9842 tmp = gen_rtx_NOT (DImode, tmp);
9843 }
9844 else
9845 {
9846 operands[0] = gen_highpart (SImode, operands[0]);
9847 if (GET_CODE (operands[1]) == ABS)
9848 {
9849 tmp = gen_int_mode (0x7fffffff, SImode);
9850 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9851 }
9852 else
9853 {
9854 tmp = gen_int_mode (0x80000000, SImode);
9855 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9856 }
9857 }
9858 operands[1] = tmp;
9859 })
9860
9861 (define_split
9862 [(set (match_operand:XF 0 "register_operand" "")
9863 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9864 (use (match_operand 2 "" ""))
9865 (clobber (reg:CC FLAGS_REG))]
9866 "reload_completed"
9867 [(parallel [(set (match_dup 0) (match_dup 1))
9868 (clobber (reg:CC FLAGS_REG))])]
9869 {
9870 rtx tmp;
9871 operands[0] = gen_rtx_REG (SImode,
9872 true_regnum (operands[0])
9873 + (TARGET_64BIT ? 1 : 2));
9874 if (GET_CODE (operands[1]) == ABS)
9875 {
9876 tmp = GEN_INT (0x7fff);
9877 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9878 }
9879 else
9880 {
9881 tmp = GEN_INT (0x8000);
9882 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9883 }
9884 operands[1] = tmp;
9885 })
9886
9887 (define_split
9888 [(set (match_operand 0 "memory_operand" "")
9889 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9890 (use (match_operand 2 "" ""))
9891 (clobber (reg:CC FLAGS_REG))]
9892 "reload_completed"
9893 [(parallel [(set (match_dup 0) (match_dup 1))
9894 (clobber (reg:CC FLAGS_REG))])]
9895 {
9896 enum machine_mode mode = GET_MODE (operands[0]);
9897 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9898 rtx tmp;
9899
9900 operands[0] = adjust_address (operands[0], QImode, size - 1);
9901 if (GET_CODE (operands[1]) == ABS)
9902 {
9903 tmp = gen_int_mode (0x7f, QImode);
9904 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9905 }
9906 else
9907 {
9908 tmp = gen_int_mode (0x80, QImode);
9909 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9910 }
9911 operands[1] = tmp;
9912 })
9913
9914 ;; Conditionalize these after reload. If they match before reload, we
9915 ;; lose the clobber and ability to use integer instructions.
9916
9917 (define_insn "*negsf2_1"
9918 [(set (match_operand:SF 0 "register_operand" "=f")
9919 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9920 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9921 "fchs"
9922 [(set_attr "type" "fsgn")
9923 (set_attr "mode" "SF")])
9924
9925 (define_insn "*negdf2_1"
9926 [(set (match_operand:DF 0 "register_operand" "=f")
9927 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9928 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9929 "fchs"
9930 [(set_attr "type" "fsgn")
9931 (set_attr "mode" "DF")])
9932
9933 (define_insn "*negxf2_1"
9934 [(set (match_operand:XF 0 "register_operand" "=f")
9935 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9936 "TARGET_80387"
9937 "fchs"
9938 [(set_attr "type" "fsgn")
9939 (set_attr "mode" "XF")])
9940
9941 (define_insn "*abssf2_1"
9942 [(set (match_operand:SF 0 "register_operand" "=f")
9943 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9944 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9945 "fabs"
9946 [(set_attr "type" "fsgn")
9947 (set_attr "mode" "SF")])
9948
9949 (define_insn "*absdf2_1"
9950 [(set (match_operand:DF 0 "register_operand" "=f")
9951 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9952 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9953 "fabs"
9954 [(set_attr "type" "fsgn")
9955 (set_attr "mode" "DF")])
9956
9957 (define_insn "*absxf2_1"
9958 [(set (match_operand:XF 0 "register_operand" "=f")
9959 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9960 "TARGET_80387"
9961 "fabs"
9962 [(set_attr "type" "fsgn")
9963 (set_attr "mode" "DF")])
9964
9965 (define_insn "*negextendsfdf2"
9966 [(set (match_operand:DF 0 "register_operand" "=f")
9967 (neg:DF (float_extend:DF
9968 (match_operand:SF 1 "register_operand" "0"))))]
9969 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9970 "fchs"
9971 [(set_attr "type" "fsgn")
9972 (set_attr "mode" "DF")])
9973
9974 (define_insn "*negextenddfxf2"
9975 [(set (match_operand:XF 0 "register_operand" "=f")
9976 (neg:XF (float_extend:XF
9977 (match_operand:DF 1 "register_operand" "0"))))]
9978 "TARGET_80387"
9979 "fchs"
9980 [(set_attr "type" "fsgn")
9981 (set_attr "mode" "XF")])
9982
9983 (define_insn "*negextendsfxf2"
9984 [(set (match_operand:XF 0 "register_operand" "=f")
9985 (neg:XF (float_extend:XF
9986 (match_operand:SF 1 "register_operand" "0"))))]
9987 "TARGET_80387"
9988 "fchs"
9989 [(set_attr "type" "fsgn")
9990 (set_attr "mode" "XF")])
9991
9992 (define_insn "*absextendsfdf2"
9993 [(set (match_operand:DF 0 "register_operand" "=f")
9994 (abs:DF (float_extend:DF
9995 (match_operand:SF 1 "register_operand" "0"))))]
9996 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9997 "fabs"
9998 [(set_attr "type" "fsgn")
9999 (set_attr "mode" "DF")])
10000
10001 (define_insn "*absextenddfxf2"
10002 [(set (match_operand:XF 0 "register_operand" "=f")
10003 (abs:XF (float_extend:XF
10004 (match_operand:DF 1 "register_operand" "0"))))]
10005 "TARGET_80387"
10006 "fabs"
10007 [(set_attr "type" "fsgn")
10008 (set_attr "mode" "XF")])
10009
10010 (define_insn "*absextendsfxf2"
10011 [(set (match_operand:XF 0 "register_operand" "=f")
10012 (abs:XF (float_extend:XF
10013 (match_operand:SF 1 "register_operand" "0"))))]
10014 "TARGET_80387"
10015 "fabs"
10016 [(set_attr "type" "fsgn")
10017 (set_attr "mode" "XF")])
10018 \f
10019 ;; One complement instructions
10020
10021 (define_expand "one_cmpldi2"
10022 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10023 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10024 "TARGET_64BIT"
10025 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10026
10027 (define_insn "*one_cmpldi2_1_rex64"
10028 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10029 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10030 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10031 "not{q}\t%0"
10032 [(set_attr "type" "negnot")
10033 (set_attr "mode" "DI")])
10034
10035 (define_insn "*one_cmpldi2_2_rex64"
10036 [(set (reg FLAGS_REG)
10037 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10038 (const_int 0)))
10039 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10040 (not:DI (match_dup 1)))]
10041 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10042 && ix86_unary_operator_ok (NOT, DImode, operands)"
10043 "#"
10044 [(set_attr "type" "alu1")
10045 (set_attr "mode" "DI")])
10046
10047 (define_split
10048 [(set (match_operand 0 "flags_reg_operand" "")
10049 (match_operator 2 "compare_operator"
10050 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10051 (const_int 0)]))
10052 (set (match_operand:DI 1 "nonimmediate_operand" "")
10053 (not:DI (match_dup 3)))]
10054 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10055 [(parallel [(set (match_dup 0)
10056 (match_op_dup 2
10057 [(xor:DI (match_dup 3) (const_int -1))
10058 (const_int 0)]))
10059 (set (match_dup 1)
10060 (xor:DI (match_dup 3) (const_int -1)))])]
10061 "")
10062
10063 (define_expand "one_cmplsi2"
10064 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10065 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10066 ""
10067 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10068
10069 (define_insn "*one_cmplsi2_1"
10070 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10071 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10072 "ix86_unary_operator_ok (NOT, SImode, operands)"
10073 "not{l}\t%0"
10074 [(set_attr "type" "negnot")
10075 (set_attr "mode" "SI")])
10076
10077 ;; ??? Currently never generated - xor is used instead.
10078 (define_insn "*one_cmplsi2_1_zext"
10079 [(set (match_operand:DI 0 "register_operand" "=r")
10080 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10081 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10082 "not{l}\t%k0"
10083 [(set_attr "type" "negnot")
10084 (set_attr "mode" "SI")])
10085
10086 (define_insn "*one_cmplsi2_2"
10087 [(set (reg FLAGS_REG)
10088 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10089 (const_int 0)))
10090 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10091 (not:SI (match_dup 1)))]
10092 "ix86_match_ccmode (insn, CCNOmode)
10093 && ix86_unary_operator_ok (NOT, SImode, operands)"
10094 "#"
10095 [(set_attr "type" "alu1")
10096 (set_attr "mode" "SI")])
10097
10098 (define_split
10099 [(set (match_operand 0 "flags_reg_operand" "")
10100 (match_operator 2 "compare_operator"
10101 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10102 (const_int 0)]))
10103 (set (match_operand:SI 1 "nonimmediate_operand" "")
10104 (not:SI (match_dup 3)))]
10105 "ix86_match_ccmode (insn, CCNOmode)"
10106 [(parallel [(set (match_dup 0)
10107 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10108 (const_int 0)]))
10109 (set (match_dup 1)
10110 (xor:SI (match_dup 3) (const_int -1)))])]
10111 "")
10112
10113 ;; ??? Currently never generated - xor is used instead.
10114 (define_insn "*one_cmplsi2_2_zext"
10115 [(set (reg FLAGS_REG)
10116 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10117 (const_int 0)))
10118 (set (match_operand:DI 0 "register_operand" "=r")
10119 (zero_extend:DI (not:SI (match_dup 1))))]
10120 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10121 && ix86_unary_operator_ok (NOT, SImode, operands)"
10122 "#"
10123 [(set_attr "type" "alu1")
10124 (set_attr "mode" "SI")])
10125
10126 (define_split
10127 [(set (match_operand 0 "flags_reg_operand" "")
10128 (match_operator 2 "compare_operator"
10129 [(not:SI (match_operand:SI 3 "register_operand" ""))
10130 (const_int 0)]))
10131 (set (match_operand:DI 1 "register_operand" "")
10132 (zero_extend:DI (not:SI (match_dup 3))))]
10133 "ix86_match_ccmode (insn, CCNOmode)"
10134 [(parallel [(set (match_dup 0)
10135 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10136 (const_int 0)]))
10137 (set (match_dup 1)
10138 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10139 "")
10140
10141 (define_expand "one_cmplhi2"
10142 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10143 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10144 "TARGET_HIMODE_MATH"
10145 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10146
10147 (define_insn "*one_cmplhi2_1"
10148 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10149 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10150 "ix86_unary_operator_ok (NOT, HImode, operands)"
10151 "not{w}\t%0"
10152 [(set_attr "type" "negnot")
10153 (set_attr "mode" "HI")])
10154
10155 (define_insn "*one_cmplhi2_2"
10156 [(set (reg FLAGS_REG)
10157 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10158 (const_int 0)))
10159 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10160 (not:HI (match_dup 1)))]
10161 "ix86_match_ccmode (insn, CCNOmode)
10162 && ix86_unary_operator_ok (NEG, HImode, operands)"
10163 "#"
10164 [(set_attr "type" "alu1")
10165 (set_attr "mode" "HI")])
10166
10167 (define_split
10168 [(set (match_operand 0 "flags_reg_operand" "")
10169 (match_operator 2 "compare_operator"
10170 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10171 (const_int 0)]))
10172 (set (match_operand:HI 1 "nonimmediate_operand" "")
10173 (not:HI (match_dup 3)))]
10174 "ix86_match_ccmode (insn, CCNOmode)"
10175 [(parallel [(set (match_dup 0)
10176 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10177 (const_int 0)]))
10178 (set (match_dup 1)
10179 (xor:HI (match_dup 3) (const_int -1)))])]
10180 "")
10181
10182 ;; %%% Potential partial reg stall on alternative 1. What to do?
10183 (define_expand "one_cmplqi2"
10184 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10185 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10186 "TARGET_QIMODE_MATH"
10187 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10188
10189 (define_insn "*one_cmplqi2_1"
10190 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10191 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10192 "ix86_unary_operator_ok (NOT, QImode, operands)"
10193 "@
10194 not{b}\t%0
10195 not{l}\t%k0"
10196 [(set_attr "type" "negnot")
10197 (set_attr "mode" "QI,SI")])
10198
10199 (define_insn "*one_cmplqi2_2"
10200 [(set (reg FLAGS_REG)
10201 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10202 (const_int 0)))
10203 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10204 (not:QI (match_dup 1)))]
10205 "ix86_match_ccmode (insn, CCNOmode)
10206 && ix86_unary_operator_ok (NOT, QImode, operands)"
10207 "#"
10208 [(set_attr "type" "alu1")
10209 (set_attr "mode" "QI")])
10210
10211 (define_split
10212 [(set (match_operand 0 "flags_reg_operand" "")
10213 (match_operator 2 "compare_operator"
10214 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10215 (const_int 0)]))
10216 (set (match_operand:QI 1 "nonimmediate_operand" "")
10217 (not:QI (match_dup 3)))]
10218 "ix86_match_ccmode (insn, CCNOmode)"
10219 [(parallel [(set (match_dup 0)
10220 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10221 (const_int 0)]))
10222 (set (match_dup 1)
10223 (xor:QI (match_dup 3) (const_int -1)))])]
10224 "")
10225 \f
10226 ;; Arithmetic shift instructions
10227
10228 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10229 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10230 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10231 ;; from the assembler input.
10232 ;;
10233 ;; This instruction shifts the target reg/mem as usual, but instead of
10234 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10235 ;; is a left shift double, bits are taken from the high order bits of
10236 ;; reg, else if the insn is a shift right double, bits are taken from the
10237 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10238 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10239 ;;
10240 ;; Since sh[lr]d does not change the `reg' operand, that is done
10241 ;; separately, making all shifts emit pairs of shift double and normal
10242 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10243 ;; support a 63 bit shift, each shift where the count is in a reg expands
10244 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10245 ;;
10246 ;; If the shift count is a constant, we need never emit more than one
10247 ;; shift pair, instead using moves and sign extension for counts greater
10248 ;; than 31.
10249
10250 (define_expand "ashlti3"
10251 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10252 (ashift:TI (match_operand:TI 1 "register_operand" "")
10253 (match_operand:QI 2 "nonmemory_operand" "")))
10254 (clobber (reg:CC FLAGS_REG))])]
10255 "TARGET_64BIT"
10256 {
10257 if (! immediate_operand (operands[2], QImode))
10258 {
10259 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10260 DONE;
10261 }
10262 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10263 DONE;
10264 })
10265
10266 (define_insn "ashlti3_1"
10267 [(set (match_operand:TI 0 "register_operand" "=r")
10268 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10269 (match_operand:QI 2 "register_operand" "c")))
10270 (clobber (match_scratch:DI 3 "=&r"))
10271 (clobber (reg:CC FLAGS_REG))]
10272 "TARGET_64BIT"
10273 "#"
10274 [(set_attr "type" "multi")])
10275
10276 (define_insn "*ashlti3_2"
10277 [(set (match_operand:TI 0 "register_operand" "=r")
10278 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10279 (match_operand:QI 2 "immediate_operand" "O")))
10280 (clobber (reg:CC FLAGS_REG))]
10281 "TARGET_64BIT"
10282 "#"
10283 [(set_attr "type" "multi")])
10284
10285 (define_split
10286 [(set (match_operand:TI 0 "register_operand" "")
10287 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10288 (match_operand:QI 2 "register_operand" "")))
10289 (clobber (match_scratch:DI 3 ""))
10290 (clobber (reg:CC FLAGS_REG))]
10291 "TARGET_64BIT && reload_completed"
10292 [(const_int 0)]
10293 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10294
10295 (define_split
10296 [(set (match_operand:TI 0 "register_operand" "")
10297 (ashift:TI (match_operand:TI 1 "register_operand" "")
10298 (match_operand:QI 2 "immediate_operand" "")))
10299 (clobber (reg:CC FLAGS_REG))]
10300 "TARGET_64BIT && reload_completed"
10301 [(const_int 0)]
10302 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10303
10304 (define_insn "x86_64_shld"
10305 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10306 (ior:DI (ashift:DI (match_dup 0)
10307 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10308 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10309 (minus:QI (const_int 64) (match_dup 2)))))
10310 (clobber (reg:CC FLAGS_REG))]
10311 "TARGET_64BIT"
10312 "@
10313 shld{q}\t{%2, %1, %0|%0, %1, %2}
10314 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10315 [(set_attr "type" "ishift")
10316 (set_attr "prefix_0f" "1")
10317 (set_attr "mode" "DI")
10318 (set_attr "athlon_decode" "vector")])
10319
10320 (define_expand "x86_64_shift_adj"
10321 [(set (reg:CCZ FLAGS_REG)
10322 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10323 (const_int 64))
10324 (const_int 0)))
10325 (set (match_operand:DI 0 "register_operand" "")
10326 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10327 (match_operand:DI 1 "register_operand" "")
10328 (match_dup 0)))
10329 (set (match_dup 1)
10330 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10331 (match_operand:DI 3 "register_operand" "r")
10332 (match_dup 1)))]
10333 "TARGET_64BIT"
10334 "")
10335
10336 (define_expand "ashldi3"
10337 [(set (match_operand:DI 0 "shiftdi_operand" "")
10338 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10339 (match_operand:QI 2 "nonmemory_operand" "")))]
10340 ""
10341 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10342
10343 (define_insn "*ashldi3_1_rex64"
10344 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10345 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10346 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10347 (clobber (reg:CC FLAGS_REG))]
10348 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10349 {
10350 switch (get_attr_type (insn))
10351 {
10352 case TYPE_ALU:
10353 gcc_assert (operands[2] == const1_rtx);
10354 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10355 return "add{q}\t{%0, %0|%0, %0}";
10356
10357 case TYPE_LEA:
10358 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10359 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10360 operands[1] = gen_rtx_MULT (DImode, operands[1],
10361 GEN_INT (1 << INTVAL (operands[2])));
10362 return "lea{q}\t{%a1, %0|%0, %a1}";
10363
10364 default:
10365 if (REG_P (operands[2]))
10366 return "sal{q}\t{%b2, %0|%0, %b2}";
10367 else if (operands[2] == const1_rtx
10368 && (TARGET_SHIFT1 || optimize_size))
10369 return "sal{q}\t%0";
10370 else
10371 return "sal{q}\t{%2, %0|%0, %2}";
10372 }
10373 }
10374 [(set (attr "type")
10375 (cond [(eq_attr "alternative" "1")
10376 (const_string "lea")
10377 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10378 (const_int 0))
10379 (match_operand 0 "register_operand" ""))
10380 (match_operand 2 "const1_operand" ""))
10381 (const_string "alu")
10382 ]
10383 (const_string "ishift")))
10384 (set_attr "mode" "DI")])
10385
10386 ;; Convert lea to the lea pattern to avoid flags dependency.
10387 (define_split
10388 [(set (match_operand:DI 0 "register_operand" "")
10389 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10390 (match_operand:QI 2 "immediate_operand" "")))
10391 (clobber (reg:CC FLAGS_REG))]
10392 "TARGET_64BIT && reload_completed
10393 && true_regnum (operands[0]) != true_regnum (operands[1])"
10394 [(set (match_dup 0)
10395 (mult:DI (match_dup 1)
10396 (match_dup 2)))]
10397 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10398
10399 ;; This pattern can't accept a variable shift count, since shifts by
10400 ;; zero don't affect the flags. We assume that shifts by constant
10401 ;; zero are optimized away.
10402 (define_insn "*ashldi3_cmp_rex64"
10403 [(set (reg FLAGS_REG)
10404 (compare
10405 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10406 (match_operand:QI 2 "immediate_operand" "e"))
10407 (const_int 0)))
10408 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10409 (ashift:DI (match_dup 1) (match_dup 2)))]
10410 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10411 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10412 && (optimize_size
10413 || !TARGET_PARTIAL_FLAG_REG_STALL
10414 || (operands[2] == const1_rtx
10415 && (TARGET_SHIFT1
10416 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10417 {
10418 switch (get_attr_type (insn))
10419 {
10420 case TYPE_ALU:
10421 gcc_assert (operands[2] == const1_rtx);
10422 return "add{q}\t{%0, %0|%0, %0}";
10423
10424 default:
10425 if (REG_P (operands[2]))
10426 return "sal{q}\t{%b2, %0|%0, %b2}";
10427 else if (operands[2] == const1_rtx
10428 && (TARGET_SHIFT1 || optimize_size))
10429 return "sal{q}\t%0";
10430 else
10431 return "sal{q}\t{%2, %0|%0, %2}";
10432 }
10433 }
10434 [(set (attr "type")
10435 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10436 (const_int 0))
10437 (match_operand 0 "register_operand" ""))
10438 (match_operand 2 "const1_operand" ""))
10439 (const_string "alu")
10440 ]
10441 (const_string "ishift")))
10442 (set_attr "mode" "DI")])
10443
10444 (define_insn "*ashldi3_cconly_rex64"
10445 [(set (reg FLAGS_REG)
10446 (compare
10447 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10448 (match_operand:QI 2 "immediate_operand" "e"))
10449 (const_int 0)))
10450 (clobber (match_scratch:DI 0 "=r"))]
10451 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10452 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10453 && (optimize_size
10454 || !TARGET_PARTIAL_FLAG_REG_STALL
10455 || (operands[2] == const1_rtx
10456 && (TARGET_SHIFT1
10457 || TARGET_DOUBLE_WITH_ADD)))"
10458 {
10459 switch (get_attr_type (insn))
10460 {
10461 case TYPE_ALU:
10462 gcc_assert (operands[2] == const1_rtx);
10463 return "add{q}\t{%0, %0|%0, %0}";
10464
10465 default:
10466 if (REG_P (operands[2]))
10467 return "sal{q}\t{%b2, %0|%0, %b2}";
10468 else if (operands[2] == const1_rtx
10469 && (TARGET_SHIFT1 || optimize_size))
10470 return "sal{q}\t%0";
10471 else
10472 return "sal{q}\t{%2, %0|%0, %2}";
10473 }
10474 }
10475 [(set (attr "type")
10476 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10477 (const_int 0))
10478 (match_operand 0 "register_operand" ""))
10479 (match_operand 2 "const1_operand" ""))
10480 (const_string "alu")
10481 ]
10482 (const_string "ishift")))
10483 (set_attr "mode" "DI")])
10484
10485 (define_insn "*ashldi3_1"
10486 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10487 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10488 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10489 (clobber (reg:CC FLAGS_REG))]
10490 "!TARGET_64BIT"
10491 "#"
10492 [(set_attr "type" "multi")])
10493
10494 ;; By default we don't ask for a scratch register, because when DImode
10495 ;; values are manipulated, registers are already at a premium. But if
10496 ;; we have one handy, we won't turn it away.
10497 (define_peephole2
10498 [(match_scratch:SI 3 "r")
10499 (parallel [(set (match_operand:DI 0 "register_operand" "")
10500 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10501 (match_operand:QI 2 "nonmemory_operand" "")))
10502 (clobber (reg:CC FLAGS_REG))])
10503 (match_dup 3)]
10504 "!TARGET_64BIT && TARGET_CMOVE"
10505 [(const_int 0)]
10506 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10507
10508 (define_split
10509 [(set (match_operand:DI 0 "register_operand" "")
10510 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10511 (match_operand:QI 2 "nonmemory_operand" "")))
10512 (clobber (reg:CC FLAGS_REG))]
10513 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10514 ? flow2_completed : reload_completed)"
10515 [(const_int 0)]
10516 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10517
10518 (define_insn "x86_shld_1"
10519 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10520 (ior:SI (ashift:SI (match_dup 0)
10521 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10522 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10523 (minus:QI (const_int 32) (match_dup 2)))))
10524 (clobber (reg:CC FLAGS_REG))]
10525 ""
10526 "@
10527 shld{l}\t{%2, %1, %0|%0, %1, %2}
10528 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10529 [(set_attr "type" "ishift")
10530 (set_attr "prefix_0f" "1")
10531 (set_attr "mode" "SI")
10532 (set_attr "pent_pair" "np")
10533 (set_attr "athlon_decode" "vector")])
10534
10535 (define_expand "x86_shift_adj_1"
10536 [(set (reg:CCZ FLAGS_REG)
10537 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10538 (const_int 32))
10539 (const_int 0)))
10540 (set (match_operand:SI 0 "register_operand" "")
10541 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10542 (match_operand:SI 1 "register_operand" "")
10543 (match_dup 0)))
10544 (set (match_dup 1)
10545 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10546 (match_operand:SI 3 "register_operand" "r")
10547 (match_dup 1)))]
10548 "TARGET_CMOVE"
10549 "")
10550
10551 (define_expand "x86_shift_adj_2"
10552 [(use (match_operand:SI 0 "register_operand" ""))
10553 (use (match_operand:SI 1 "register_operand" ""))
10554 (use (match_operand:QI 2 "register_operand" ""))]
10555 ""
10556 {
10557 rtx label = gen_label_rtx ();
10558 rtx tmp;
10559
10560 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10561
10562 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10563 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10564 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10565 gen_rtx_LABEL_REF (VOIDmode, label),
10566 pc_rtx);
10567 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10568 JUMP_LABEL (tmp) = label;
10569
10570 emit_move_insn (operands[0], operands[1]);
10571 ix86_expand_clear (operands[1]);
10572
10573 emit_label (label);
10574 LABEL_NUSES (label) = 1;
10575
10576 DONE;
10577 })
10578
10579 (define_expand "ashlsi3"
10580 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10581 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10582 (match_operand:QI 2 "nonmemory_operand" "")))
10583 (clobber (reg:CC FLAGS_REG))]
10584 ""
10585 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10586
10587 (define_insn "*ashlsi3_1"
10588 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10589 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10590 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10591 (clobber (reg:CC FLAGS_REG))]
10592 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10593 {
10594 switch (get_attr_type (insn))
10595 {
10596 case TYPE_ALU:
10597 gcc_assert (operands[2] == const1_rtx);
10598 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10599 return "add{l}\t{%0, %0|%0, %0}";
10600
10601 case TYPE_LEA:
10602 return "#";
10603
10604 default:
10605 if (REG_P (operands[2]))
10606 return "sal{l}\t{%b2, %0|%0, %b2}";
10607 else if (operands[2] == const1_rtx
10608 && (TARGET_SHIFT1 || optimize_size))
10609 return "sal{l}\t%0";
10610 else
10611 return "sal{l}\t{%2, %0|%0, %2}";
10612 }
10613 }
10614 [(set (attr "type")
10615 (cond [(eq_attr "alternative" "1")
10616 (const_string "lea")
10617 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10618 (const_int 0))
10619 (match_operand 0 "register_operand" ""))
10620 (match_operand 2 "const1_operand" ""))
10621 (const_string "alu")
10622 ]
10623 (const_string "ishift")))
10624 (set_attr "mode" "SI")])
10625
10626 ;; Convert lea to the lea pattern to avoid flags dependency.
10627 (define_split
10628 [(set (match_operand 0 "register_operand" "")
10629 (ashift (match_operand 1 "index_register_operand" "")
10630 (match_operand:QI 2 "const_int_operand" "")))
10631 (clobber (reg:CC FLAGS_REG))]
10632 "reload_completed
10633 && true_regnum (operands[0]) != true_regnum (operands[1])
10634 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10635 [(const_int 0)]
10636 {
10637 rtx pat;
10638 enum machine_mode mode = GET_MODE (operands[0]);
10639
10640 if (GET_MODE_SIZE (mode) < 4)
10641 operands[0] = gen_lowpart (SImode, operands[0]);
10642 if (mode != Pmode)
10643 operands[1] = gen_lowpart (Pmode, operands[1]);
10644 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10645
10646 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10647 if (Pmode != SImode)
10648 pat = gen_rtx_SUBREG (SImode, pat, 0);
10649 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10650 DONE;
10651 })
10652
10653 ;; Rare case of shifting RSP is handled by generating move and shift
10654 (define_split
10655 [(set (match_operand 0 "register_operand" "")
10656 (ashift (match_operand 1 "register_operand" "")
10657 (match_operand:QI 2 "const_int_operand" "")))
10658 (clobber (reg:CC FLAGS_REG))]
10659 "reload_completed
10660 && true_regnum (operands[0]) != true_regnum (operands[1])"
10661 [(const_int 0)]
10662 {
10663 rtx pat, clob;
10664 emit_move_insn (operands[0], operands[1]);
10665 pat = gen_rtx_SET (VOIDmode, operands[0],
10666 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10667 operands[0], operands[2]));
10668 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10669 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10670 DONE;
10671 })
10672
10673 (define_insn "*ashlsi3_1_zext"
10674 [(set (match_operand:DI 0 "register_operand" "=r,r")
10675 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10676 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10677 (clobber (reg:CC FLAGS_REG))]
10678 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10679 {
10680 switch (get_attr_type (insn))
10681 {
10682 case TYPE_ALU:
10683 gcc_assert (operands[2] == const1_rtx);
10684 return "add{l}\t{%k0, %k0|%k0, %k0}";
10685
10686 case TYPE_LEA:
10687 return "#";
10688
10689 default:
10690 if (REG_P (operands[2]))
10691 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10692 else if (operands[2] == const1_rtx
10693 && (TARGET_SHIFT1 || optimize_size))
10694 return "sal{l}\t%k0";
10695 else
10696 return "sal{l}\t{%2, %k0|%k0, %2}";
10697 }
10698 }
10699 [(set (attr "type")
10700 (cond [(eq_attr "alternative" "1")
10701 (const_string "lea")
10702 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10703 (const_int 0))
10704 (match_operand 2 "const1_operand" ""))
10705 (const_string "alu")
10706 ]
10707 (const_string "ishift")))
10708 (set_attr "mode" "SI")])
10709
10710 ;; Convert lea to the lea pattern to avoid flags dependency.
10711 (define_split
10712 [(set (match_operand:DI 0 "register_operand" "")
10713 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10714 (match_operand:QI 2 "const_int_operand" ""))))
10715 (clobber (reg:CC FLAGS_REG))]
10716 "TARGET_64BIT && reload_completed
10717 && true_regnum (operands[0]) != true_regnum (operands[1])"
10718 [(set (match_dup 0) (zero_extend:DI
10719 (subreg:SI (mult:SI (match_dup 1)
10720 (match_dup 2)) 0)))]
10721 {
10722 operands[1] = gen_lowpart (Pmode, operands[1]);
10723 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10724 })
10725
10726 ;; This pattern can't accept a variable shift count, since shifts by
10727 ;; zero don't affect the flags. We assume that shifts by constant
10728 ;; zero are optimized away.
10729 (define_insn "*ashlsi3_cmp"
10730 [(set (reg FLAGS_REG)
10731 (compare
10732 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10733 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10734 (const_int 0)))
10735 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10736 (ashift:SI (match_dup 1) (match_dup 2)))]
10737 "ix86_match_ccmode (insn, CCGOCmode)
10738 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10739 && (optimize_size
10740 || !TARGET_PARTIAL_FLAG_REG_STALL
10741 || (operands[2] == const1_rtx
10742 && (TARGET_SHIFT1
10743 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10744 {
10745 switch (get_attr_type (insn))
10746 {
10747 case TYPE_ALU:
10748 gcc_assert (operands[2] == const1_rtx);
10749 return "add{l}\t{%0, %0|%0, %0}";
10750
10751 default:
10752 if (REG_P (operands[2]))
10753 return "sal{l}\t{%b2, %0|%0, %b2}";
10754 else if (operands[2] == const1_rtx
10755 && (TARGET_SHIFT1 || optimize_size))
10756 return "sal{l}\t%0";
10757 else
10758 return "sal{l}\t{%2, %0|%0, %2}";
10759 }
10760 }
10761 [(set (attr "type")
10762 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10763 (const_int 0))
10764 (match_operand 0 "register_operand" ""))
10765 (match_operand 2 "const1_operand" ""))
10766 (const_string "alu")
10767 ]
10768 (const_string "ishift")))
10769 (set_attr "mode" "SI")])
10770
10771 (define_insn "*ashlsi3_cconly"
10772 [(set (reg FLAGS_REG)
10773 (compare
10774 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10775 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10776 (const_int 0)))
10777 (clobber (match_scratch:SI 0 "=r"))]
10778 "ix86_match_ccmode (insn, CCGOCmode)
10779 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10780 && (optimize_size
10781 || !TARGET_PARTIAL_FLAG_REG_STALL
10782 || (operands[2] == const1_rtx
10783 && (TARGET_SHIFT1
10784 || TARGET_DOUBLE_WITH_ADD)))"
10785 {
10786 switch (get_attr_type (insn))
10787 {
10788 case TYPE_ALU:
10789 gcc_assert (operands[2] == const1_rtx);
10790 return "add{l}\t{%0, %0|%0, %0}";
10791
10792 default:
10793 if (REG_P (operands[2]))
10794 return "sal{l}\t{%b2, %0|%0, %b2}";
10795 else if (operands[2] == const1_rtx
10796 && (TARGET_SHIFT1 || optimize_size))
10797 return "sal{l}\t%0";
10798 else
10799 return "sal{l}\t{%2, %0|%0, %2}";
10800 }
10801 }
10802 [(set (attr "type")
10803 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10804 (const_int 0))
10805 (match_operand 0 "register_operand" ""))
10806 (match_operand 2 "const1_operand" ""))
10807 (const_string "alu")
10808 ]
10809 (const_string "ishift")))
10810 (set_attr "mode" "SI")])
10811
10812 (define_insn "*ashlsi3_cmp_zext"
10813 [(set (reg FLAGS_REG)
10814 (compare
10815 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10816 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10817 (const_int 0)))
10818 (set (match_operand:DI 0 "register_operand" "=r")
10819 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10820 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10821 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10822 && (optimize_size
10823 || !TARGET_PARTIAL_FLAG_REG_STALL
10824 || (operands[2] == const1_rtx
10825 && (TARGET_SHIFT1
10826 || TARGET_DOUBLE_WITH_ADD)))"
10827 {
10828 switch (get_attr_type (insn))
10829 {
10830 case TYPE_ALU:
10831 gcc_assert (operands[2] == const1_rtx);
10832 return "add{l}\t{%k0, %k0|%k0, %k0}";
10833
10834 default:
10835 if (REG_P (operands[2]))
10836 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10837 else if (operands[2] == const1_rtx
10838 && (TARGET_SHIFT1 || optimize_size))
10839 return "sal{l}\t%k0";
10840 else
10841 return "sal{l}\t{%2, %k0|%k0, %2}";
10842 }
10843 }
10844 [(set (attr "type")
10845 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10846 (const_int 0))
10847 (match_operand 2 "const1_operand" ""))
10848 (const_string "alu")
10849 ]
10850 (const_string "ishift")))
10851 (set_attr "mode" "SI")])
10852
10853 (define_expand "ashlhi3"
10854 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10855 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10856 (match_operand:QI 2 "nonmemory_operand" "")))
10857 (clobber (reg:CC FLAGS_REG))]
10858 "TARGET_HIMODE_MATH"
10859 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10860
10861 (define_insn "*ashlhi3_1_lea"
10862 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10863 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10864 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10865 (clobber (reg:CC FLAGS_REG))]
10866 "!TARGET_PARTIAL_REG_STALL
10867 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10868 {
10869 switch (get_attr_type (insn))
10870 {
10871 case TYPE_LEA:
10872 return "#";
10873 case TYPE_ALU:
10874 gcc_assert (operands[2] == const1_rtx);
10875 return "add{w}\t{%0, %0|%0, %0}";
10876
10877 default:
10878 if (REG_P (operands[2]))
10879 return "sal{w}\t{%b2, %0|%0, %b2}";
10880 else if (operands[2] == const1_rtx
10881 && (TARGET_SHIFT1 || optimize_size))
10882 return "sal{w}\t%0";
10883 else
10884 return "sal{w}\t{%2, %0|%0, %2}";
10885 }
10886 }
10887 [(set (attr "type")
10888 (cond [(eq_attr "alternative" "1")
10889 (const_string "lea")
10890 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10891 (const_int 0))
10892 (match_operand 0 "register_operand" ""))
10893 (match_operand 2 "const1_operand" ""))
10894 (const_string "alu")
10895 ]
10896 (const_string "ishift")))
10897 (set_attr "mode" "HI,SI")])
10898
10899 (define_insn "*ashlhi3_1"
10900 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10901 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10902 (match_operand:QI 2 "nonmemory_operand" "cI")))
10903 (clobber (reg:CC FLAGS_REG))]
10904 "TARGET_PARTIAL_REG_STALL
10905 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10906 {
10907 switch (get_attr_type (insn))
10908 {
10909 case TYPE_ALU:
10910 gcc_assert (operands[2] == const1_rtx);
10911 return "add{w}\t{%0, %0|%0, %0}";
10912
10913 default:
10914 if (REG_P (operands[2]))
10915 return "sal{w}\t{%b2, %0|%0, %b2}";
10916 else if (operands[2] == const1_rtx
10917 && (TARGET_SHIFT1 || optimize_size))
10918 return "sal{w}\t%0";
10919 else
10920 return "sal{w}\t{%2, %0|%0, %2}";
10921 }
10922 }
10923 [(set (attr "type")
10924 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10925 (const_int 0))
10926 (match_operand 0 "register_operand" ""))
10927 (match_operand 2 "const1_operand" ""))
10928 (const_string "alu")
10929 ]
10930 (const_string "ishift")))
10931 (set_attr "mode" "HI")])
10932
10933 ;; This pattern can't accept a variable shift count, since shifts by
10934 ;; zero don't affect the flags. We assume that shifts by constant
10935 ;; zero are optimized away.
10936 (define_insn "*ashlhi3_cmp"
10937 [(set (reg FLAGS_REG)
10938 (compare
10939 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10940 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10941 (const_int 0)))
10942 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10943 (ashift:HI (match_dup 1) (match_dup 2)))]
10944 "ix86_match_ccmode (insn, CCGOCmode)
10945 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10946 && (optimize_size
10947 || !TARGET_PARTIAL_FLAG_REG_STALL
10948 || (operands[2] == const1_rtx
10949 && (TARGET_SHIFT1
10950 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10951 {
10952 switch (get_attr_type (insn))
10953 {
10954 case TYPE_ALU:
10955 gcc_assert (operands[2] == const1_rtx);
10956 return "add{w}\t{%0, %0|%0, %0}";
10957
10958 default:
10959 if (REG_P (operands[2]))
10960 return "sal{w}\t{%b2, %0|%0, %b2}";
10961 else if (operands[2] == const1_rtx
10962 && (TARGET_SHIFT1 || optimize_size))
10963 return "sal{w}\t%0";
10964 else
10965 return "sal{w}\t{%2, %0|%0, %2}";
10966 }
10967 }
10968 [(set (attr "type")
10969 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10970 (const_int 0))
10971 (match_operand 0 "register_operand" ""))
10972 (match_operand 2 "const1_operand" ""))
10973 (const_string "alu")
10974 ]
10975 (const_string "ishift")))
10976 (set_attr "mode" "HI")])
10977
10978 (define_insn "*ashlhi3_cconly"
10979 [(set (reg FLAGS_REG)
10980 (compare
10981 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10982 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10983 (const_int 0)))
10984 (clobber (match_scratch:HI 0 "=r"))]
10985 "ix86_match_ccmode (insn, CCGOCmode)
10986 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10987 && (optimize_size
10988 || !TARGET_PARTIAL_FLAG_REG_STALL
10989 || (operands[2] == const1_rtx
10990 && (TARGET_SHIFT1
10991 || TARGET_DOUBLE_WITH_ADD)))"
10992 {
10993 switch (get_attr_type (insn))
10994 {
10995 case TYPE_ALU:
10996 gcc_assert (operands[2] == const1_rtx);
10997 return "add{w}\t{%0, %0|%0, %0}";
10998
10999 default:
11000 if (REG_P (operands[2]))
11001 return "sal{w}\t{%b2, %0|%0, %b2}";
11002 else if (operands[2] == const1_rtx
11003 && (TARGET_SHIFT1 || optimize_size))
11004 return "sal{w}\t%0";
11005 else
11006 return "sal{w}\t{%2, %0|%0, %2}";
11007 }
11008 }
11009 [(set (attr "type")
11010 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11011 (const_int 0))
11012 (match_operand 0 "register_operand" ""))
11013 (match_operand 2 "const1_operand" ""))
11014 (const_string "alu")
11015 ]
11016 (const_string "ishift")))
11017 (set_attr "mode" "HI")])
11018
11019 (define_expand "ashlqi3"
11020 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11021 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11022 (match_operand:QI 2 "nonmemory_operand" "")))
11023 (clobber (reg:CC FLAGS_REG))]
11024 "TARGET_QIMODE_MATH"
11025 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11026
11027 ;; %%% Potential partial reg stall on alternative 2. What to do?
11028
11029 (define_insn "*ashlqi3_1_lea"
11030 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11031 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11032 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11033 (clobber (reg:CC FLAGS_REG))]
11034 "!TARGET_PARTIAL_REG_STALL
11035 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11036 {
11037 switch (get_attr_type (insn))
11038 {
11039 case TYPE_LEA:
11040 return "#";
11041 case TYPE_ALU:
11042 gcc_assert (operands[2] == const1_rtx);
11043 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11044 return "add{l}\t{%k0, %k0|%k0, %k0}";
11045 else
11046 return "add{b}\t{%0, %0|%0, %0}";
11047
11048 default:
11049 if (REG_P (operands[2]))
11050 {
11051 if (get_attr_mode (insn) == MODE_SI)
11052 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11053 else
11054 return "sal{b}\t{%b2, %0|%0, %b2}";
11055 }
11056 else if (operands[2] == const1_rtx
11057 && (TARGET_SHIFT1 || optimize_size))
11058 {
11059 if (get_attr_mode (insn) == MODE_SI)
11060 return "sal{l}\t%0";
11061 else
11062 return "sal{b}\t%0";
11063 }
11064 else
11065 {
11066 if (get_attr_mode (insn) == MODE_SI)
11067 return "sal{l}\t{%2, %k0|%k0, %2}";
11068 else
11069 return "sal{b}\t{%2, %0|%0, %2}";
11070 }
11071 }
11072 }
11073 [(set (attr "type")
11074 (cond [(eq_attr "alternative" "2")
11075 (const_string "lea")
11076 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11077 (const_int 0))
11078 (match_operand 0 "register_operand" ""))
11079 (match_operand 2 "const1_operand" ""))
11080 (const_string "alu")
11081 ]
11082 (const_string "ishift")))
11083 (set_attr "mode" "QI,SI,SI")])
11084
11085 (define_insn "*ashlqi3_1"
11086 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11087 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11088 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11089 (clobber (reg:CC FLAGS_REG))]
11090 "TARGET_PARTIAL_REG_STALL
11091 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11092 {
11093 switch (get_attr_type (insn))
11094 {
11095 case TYPE_ALU:
11096 gcc_assert (operands[2] == const1_rtx);
11097 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11098 return "add{l}\t{%k0, %k0|%k0, %k0}";
11099 else
11100 return "add{b}\t{%0, %0|%0, %0}";
11101
11102 default:
11103 if (REG_P (operands[2]))
11104 {
11105 if (get_attr_mode (insn) == MODE_SI)
11106 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11107 else
11108 return "sal{b}\t{%b2, %0|%0, %b2}";
11109 }
11110 else if (operands[2] == const1_rtx
11111 && (TARGET_SHIFT1 || optimize_size))
11112 {
11113 if (get_attr_mode (insn) == MODE_SI)
11114 return "sal{l}\t%0";
11115 else
11116 return "sal{b}\t%0";
11117 }
11118 else
11119 {
11120 if (get_attr_mode (insn) == MODE_SI)
11121 return "sal{l}\t{%2, %k0|%k0, %2}";
11122 else
11123 return "sal{b}\t{%2, %0|%0, %2}";
11124 }
11125 }
11126 }
11127 [(set (attr "type")
11128 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11129 (const_int 0))
11130 (match_operand 0 "register_operand" ""))
11131 (match_operand 2 "const1_operand" ""))
11132 (const_string "alu")
11133 ]
11134 (const_string "ishift")))
11135 (set_attr "mode" "QI,SI")])
11136
11137 ;; This pattern can't accept a variable shift count, since shifts by
11138 ;; zero don't affect the flags. We assume that shifts by constant
11139 ;; zero are optimized away.
11140 (define_insn "*ashlqi3_cmp"
11141 [(set (reg FLAGS_REG)
11142 (compare
11143 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11144 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11145 (const_int 0)))
11146 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11147 (ashift:QI (match_dup 1) (match_dup 2)))]
11148 "ix86_match_ccmode (insn, CCGOCmode)
11149 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11150 && (optimize_size
11151 || !TARGET_PARTIAL_FLAG_REG_STALL
11152 || (operands[2] == const1_rtx
11153 && (TARGET_SHIFT1
11154 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11155 {
11156 switch (get_attr_type (insn))
11157 {
11158 case TYPE_ALU:
11159 gcc_assert (operands[2] == const1_rtx);
11160 return "add{b}\t{%0, %0|%0, %0}";
11161
11162 default:
11163 if (REG_P (operands[2]))
11164 return "sal{b}\t{%b2, %0|%0, %b2}";
11165 else if (operands[2] == const1_rtx
11166 && (TARGET_SHIFT1 || optimize_size))
11167 return "sal{b}\t%0";
11168 else
11169 return "sal{b}\t{%2, %0|%0, %2}";
11170 }
11171 }
11172 [(set (attr "type")
11173 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11174 (const_int 0))
11175 (match_operand 0 "register_operand" ""))
11176 (match_operand 2 "const1_operand" ""))
11177 (const_string "alu")
11178 ]
11179 (const_string "ishift")))
11180 (set_attr "mode" "QI")])
11181
11182 (define_insn "*ashlqi3_cconly"
11183 [(set (reg FLAGS_REG)
11184 (compare
11185 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11186 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11187 (const_int 0)))
11188 (clobber (match_scratch:QI 0 "=q"))]
11189 "ix86_match_ccmode (insn, CCGOCmode)
11190 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11191 && (optimize_size
11192 || !TARGET_PARTIAL_FLAG_REG_STALL
11193 || (operands[2] == const1_rtx
11194 && (TARGET_SHIFT1
11195 || TARGET_DOUBLE_WITH_ADD)))"
11196 {
11197 switch (get_attr_type (insn))
11198 {
11199 case TYPE_ALU:
11200 gcc_assert (operands[2] == const1_rtx);
11201 return "add{b}\t{%0, %0|%0, %0}";
11202
11203 default:
11204 if (REG_P (operands[2]))
11205 return "sal{b}\t{%b2, %0|%0, %b2}";
11206 else if (operands[2] == const1_rtx
11207 && (TARGET_SHIFT1 || optimize_size))
11208 return "sal{b}\t%0";
11209 else
11210 return "sal{b}\t{%2, %0|%0, %2}";
11211 }
11212 }
11213 [(set (attr "type")
11214 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11215 (const_int 0))
11216 (match_operand 0 "register_operand" ""))
11217 (match_operand 2 "const1_operand" ""))
11218 (const_string "alu")
11219 ]
11220 (const_string "ishift")))
11221 (set_attr "mode" "QI")])
11222
11223 ;; See comment above `ashldi3' about how this works.
11224
11225 (define_expand "ashrti3"
11226 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11227 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11228 (match_operand:QI 2 "nonmemory_operand" "")))
11229 (clobber (reg:CC FLAGS_REG))])]
11230 "TARGET_64BIT"
11231 {
11232 if (! immediate_operand (operands[2], QImode))
11233 {
11234 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11235 DONE;
11236 }
11237 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11238 DONE;
11239 })
11240
11241 (define_insn "ashrti3_1"
11242 [(set (match_operand:TI 0 "register_operand" "=r")
11243 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11244 (match_operand:QI 2 "register_operand" "c")))
11245 (clobber (match_scratch:DI 3 "=&r"))
11246 (clobber (reg:CC FLAGS_REG))]
11247 "TARGET_64BIT"
11248 "#"
11249 [(set_attr "type" "multi")])
11250
11251 (define_insn "*ashrti3_2"
11252 [(set (match_operand:TI 0 "register_operand" "=r")
11253 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11254 (match_operand:QI 2 "immediate_operand" "O")))
11255 (clobber (reg:CC FLAGS_REG))]
11256 "TARGET_64BIT"
11257 "#"
11258 [(set_attr "type" "multi")])
11259
11260 (define_split
11261 [(set (match_operand:TI 0 "register_operand" "")
11262 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11263 (match_operand:QI 2 "register_operand" "")))
11264 (clobber (match_scratch:DI 3 ""))
11265 (clobber (reg:CC FLAGS_REG))]
11266 "TARGET_64BIT && reload_completed"
11267 [(const_int 0)]
11268 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11269
11270 (define_split
11271 [(set (match_operand:TI 0 "register_operand" "")
11272 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11273 (match_operand:QI 2 "immediate_operand" "")))
11274 (clobber (reg:CC FLAGS_REG))]
11275 "TARGET_64BIT && reload_completed"
11276 [(const_int 0)]
11277 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11278
11279 (define_insn "x86_64_shrd"
11280 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11281 (ior:DI (ashiftrt:DI (match_dup 0)
11282 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11283 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11284 (minus:QI (const_int 64) (match_dup 2)))))
11285 (clobber (reg:CC FLAGS_REG))]
11286 "TARGET_64BIT"
11287 "@
11288 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11289 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11290 [(set_attr "type" "ishift")
11291 (set_attr "prefix_0f" "1")
11292 (set_attr "mode" "DI")
11293 (set_attr "athlon_decode" "vector")])
11294
11295 (define_expand "ashrdi3"
11296 [(set (match_operand:DI 0 "shiftdi_operand" "")
11297 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11298 (match_operand:QI 2 "nonmemory_operand" "")))]
11299 ""
11300 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11301
11302 (define_insn "*ashrdi3_63_rex64"
11303 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11304 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11305 (match_operand:DI 2 "const_int_operand" "i,i")))
11306 (clobber (reg:CC FLAGS_REG))]
11307 "TARGET_64BIT && INTVAL (operands[2]) == 63
11308 && (TARGET_USE_CLTD || optimize_size)
11309 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11310 "@
11311 {cqto|cqo}
11312 sar{q}\t{%2, %0|%0, %2}"
11313 [(set_attr "type" "imovx,ishift")
11314 (set_attr "prefix_0f" "0,*")
11315 (set_attr "length_immediate" "0,*")
11316 (set_attr "modrm" "0,1")
11317 (set_attr "mode" "DI")])
11318
11319 (define_insn "*ashrdi3_1_one_bit_rex64"
11320 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11321 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11322 (match_operand:QI 2 "const1_operand" "")))
11323 (clobber (reg:CC FLAGS_REG))]
11324 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11325 && (TARGET_SHIFT1 || optimize_size)"
11326 "sar{q}\t%0"
11327 [(set_attr "type" "ishift")
11328 (set (attr "length")
11329 (if_then_else (match_operand:DI 0 "register_operand" "")
11330 (const_string "2")
11331 (const_string "*")))])
11332
11333 (define_insn "*ashrdi3_1_rex64"
11334 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11335 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11336 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11337 (clobber (reg:CC FLAGS_REG))]
11338 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11339 "@
11340 sar{q}\t{%2, %0|%0, %2}
11341 sar{q}\t{%b2, %0|%0, %b2}"
11342 [(set_attr "type" "ishift")
11343 (set_attr "mode" "DI")])
11344
11345 ;; This pattern can't accept a variable shift count, since shifts by
11346 ;; zero don't affect the flags. We assume that shifts by constant
11347 ;; zero are optimized away.
11348 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11349 [(set (reg FLAGS_REG)
11350 (compare
11351 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11352 (match_operand:QI 2 "const1_operand" ""))
11353 (const_int 0)))
11354 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11355 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11356 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11357 && (TARGET_SHIFT1 || optimize_size)
11358 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11359 "sar{q}\t%0"
11360 [(set_attr "type" "ishift")
11361 (set (attr "length")
11362 (if_then_else (match_operand:DI 0 "register_operand" "")
11363 (const_string "2")
11364 (const_string "*")))])
11365
11366 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11367 [(set (reg FLAGS_REG)
11368 (compare
11369 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11370 (match_operand:QI 2 "const1_operand" ""))
11371 (const_int 0)))
11372 (clobber (match_scratch:DI 0 "=r"))]
11373 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11374 && (TARGET_SHIFT1 || optimize_size)
11375 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11376 "sar{q}\t%0"
11377 [(set_attr "type" "ishift")
11378 (set_attr "length" "2")])
11379
11380 ;; This pattern can't accept a variable shift count, since shifts by
11381 ;; zero don't affect the flags. We assume that shifts by constant
11382 ;; zero are optimized away.
11383 (define_insn "*ashrdi3_cmp_rex64"
11384 [(set (reg FLAGS_REG)
11385 (compare
11386 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11387 (match_operand:QI 2 "const_int_operand" "n"))
11388 (const_int 0)))
11389 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11390 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11391 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11392 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11393 && (optimize_size
11394 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11395 "sar{q}\t{%2, %0|%0, %2}"
11396 [(set_attr "type" "ishift")
11397 (set_attr "mode" "DI")])
11398
11399 (define_insn "*ashrdi3_cconly_rex64"
11400 [(set (reg FLAGS_REG)
11401 (compare
11402 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11403 (match_operand:QI 2 "const_int_operand" "n"))
11404 (const_int 0)))
11405 (clobber (match_scratch:DI 0 "=r"))]
11406 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11407 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11408 && (optimize_size
11409 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11410 "sar{q}\t{%2, %0|%0, %2}"
11411 [(set_attr "type" "ishift")
11412 (set_attr "mode" "DI")])
11413
11414 (define_insn "*ashrdi3_1"
11415 [(set (match_operand:DI 0 "register_operand" "=r")
11416 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11417 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11418 (clobber (reg:CC FLAGS_REG))]
11419 "!TARGET_64BIT"
11420 "#"
11421 [(set_attr "type" "multi")])
11422
11423 ;; By default we don't ask for a scratch register, because when DImode
11424 ;; values are manipulated, registers are already at a premium. But if
11425 ;; we have one handy, we won't turn it away.
11426 (define_peephole2
11427 [(match_scratch:SI 3 "r")
11428 (parallel [(set (match_operand:DI 0 "register_operand" "")
11429 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11430 (match_operand:QI 2 "nonmemory_operand" "")))
11431 (clobber (reg:CC FLAGS_REG))])
11432 (match_dup 3)]
11433 "!TARGET_64BIT && TARGET_CMOVE"
11434 [(const_int 0)]
11435 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11436
11437 (define_split
11438 [(set (match_operand:DI 0 "register_operand" "")
11439 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11440 (match_operand:QI 2 "nonmemory_operand" "")))
11441 (clobber (reg:CC FLAGS_REG))]
11442 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11443 ? flow2_completed : reload_completed)"
11444 [(const_int 0)]
11445 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11446
11447 (define_insn "x86_shrd_1"
11448 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11449 (ior:SI (ashiftrt:SI (match_dup 0)
11450 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11451 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11452 (minus:QI (const_int 32) (match_dup 2)))))
11453 (clobber (reg:CC FLAGS_REG))]
11454 ""
11455 "@
11456 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11457 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11458 [(set_attr "type" "ishift")
11459 (set_attr "prefix_0f" "1")
11460 (set_attr "pent_pair" "np")
11461 (set_attr "mode" "SI")])
11462
11463 (define_expand "x86_shift_adj_3"
11464 [(use (match_operand:SI 0 "register_operand" ""))
11465 (use (match_operand:SI 1 "register_operand" ""))
11466 (use (match_operand:QI 2 "register_operand" ""))]
11467 ""
11468 {
11469 rtx label = gen_label_rtx ();
11470 rtx tmp;
11471
11472 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11473
11474 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11475 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11476 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11477 gen_rtx_LABEL_REF (VOIDmode, label),
11478 pc_rtx);
11479 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11480 JUMP_LABEL (tmp) = label;
11481
11482 emit_move_insn (operands[0], operands[1]);
11483 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11484
11485 emit_label (label);
11486 LABEL_NUSES (label) = 1;
11487
11488 DONE;
11489 })
11490
11491 (define_insn "ashrsi3_31"
11492 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11493 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11494 (match_operand:SI 2 "const_int_operand" "i,i")))
11495 (clobber (reg:CC FLAGS_REG))]
11496 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11497 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11498 "@
11499 {cltd|cdq}
11500 sar{l}\t{%2, %0|%0, %2}"
11501 [(set_attr "type" "imovx,ishift")
11502 (set_attr "prefix_0f" "0,*")
11503 (set_attr "length_immediate" "0,*")
11504 (set_attr "modrm" "0,1")
11505 (set_attr "mode" "SI")])
11506
11507 (define_insn "*ashrsi3_31_zext"
11508 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11509 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11510 (match_operand:SI 2 "const_int_operand" "i,i"))))
11511 (clobber (reg:CC FLAGS_REG))]
11512 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11513 && INTVAL (operands[2]) == 31
11514 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11515 "@
11516 {cltd|cdq}
11517 sar{l}\t{%2, %k0|%k0, %2}"
11518 [(set_attr "type" "imovx,ishift")
11519 (set_attr "prefix_0f" "0,*")
11520 (set_attr "length_immediate" "0,*")
11521 (set_attr "modrm" "0,1")
11522 (set_attr "mode" "SI")])
11523
11524 (define_expand "ashrsi3"
11525 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11526 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11527 (match_operand:QI 2 "nonmemory_operand" "")))
11528 (clobber (reg:CC FLAGS_REG))]
11529 ""
11530 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11531
11532 (define_insn "*ashrsi3_1_one_bit"
11533 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11534 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11535 (match_operand:QI 2 "const1_operand" "")))
11536 (clobber (reg:CC FLAGS_REG))]
11537 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11538 && (TARGET_SHIFT1 || optimize_size)"
11539 "sar{l}\t%0"
11540 [(set_attr "type" "ishift")
11541 (set (attr "length")
11542 (if_then_else (match_operand:SI 0 "register_operand" "")
11543 (const_string "2")
11544 (const_string "*")))])
11545
11546 (define_insn "*ashrsi3_1_one_bit_zext"
11547 [(set (match_operand:DI 0 "register_operand" "=r")
11548 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11549 (match_operand:QI 2 "const1_operand" ""))))
11550 (clobber (reg:CC FLAGS_REG))]
11551 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11552 && (TARGET_SHIFT1 || optimize_size)"
11553 "sar{l}\t%k0"
11554 [(set_attr "type" "ishift")
11555 (set_attr "length" "2")])
11556
11557 (define_insn "*ashrsi3_1"
11558 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11559 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11560 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11561 (clobber (reg:CC FLAGS_REG))]
11562 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11563 "@
11564 sar{l}\t{%2, %0|%0, %2}
11565 sar{l}\t{%b2, %0|%0, %b2}"
11566 [(set_attr "type" "ishift")
11567 (set_attr "mode" "SI")])
11568
11569 (define_insn "*ashrsi3_1_zext"
11570 [(set (match_operand:DI 0 "register_operand" "=r,r")
11571 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11572 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11573 (clobber (reg:CC FLAGS_REG))]
11574 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11575 "@
11576 sar{l}\t{%2, %k0|%k0, %2}
11577 sar{l}\t{%b2, %k0|%k0, %b2}"
11578 [(set_attr "type" "ishift")
11579 (set_attr "mode" "SI")])
11580
11581 ;; This pattern can't accept a variable shift count, since shifts by
11582 ;; zero don't affect the flags. We assume that shifts by constant
11583 ;; zero are optimized away.
11584 (define_insn "*ashrsi3_one_bit_cmp"
11585 [(set (reg FLAGS_REG)
11586 (compare
11587 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11588 (match_operand:QI 2 "const1_operand" ""))
11589 (const_int 0)))
11590 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11591 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11592 "ix86_match_ccmode (insn, CCGOCmode)
11593 && (TARGET_SHIFT1 || optimize_size)
11594 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11595 "sar{l}\t%0"
11596 [(set_attr "type" "ishift")
11597 (set (attr "length")
11598 (if_then_else (match_operand:SI 0 "register_operand" "")
11599 (const_string "2")
11600 (const_string "*")))])
11601
11602 (define_insn "*ashrsi3_one_bit_cconly"
11603 [(set (reg FLAGS_REG)
11604 (compare
11605 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11606 (match_operand:QI 2 "const1_operand" ""))
11607 (const_int 0)))
11608 (clobber (match_scratch:SI 0 "=r"))]
11609 "ix86_match_ccmode (insn, CCGOCmode)
11610 && (TARGET_SHIFT1 || optimize_size)
11611 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11612 "sar{l}\t%0"
11613 [(set_attr "type" "ishift")
11614 (set_attr "length" "2")])
11615
11616 (define_insn "*ashrsi3_one_bit_cmp_zext"
11617 [(set (reg FLAGS_REG)
11618 (compare
11619 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11620 (match_operand:QI 2 "const1_operand" ""))
11621 (const_int 0)))
11622 (set (match_operand:DI 0 "register_operand" "=r")
11623 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11624 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11625 && (TARGET_SHIFT1 || optimize_size)
11626 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11627 "sar{l}\t%k0"
11628 [(set_attr "type" "ishift")
11629 (set_attr "length" "2")])
11630
11631 ;; This pattern can't accept a variable shift count, since shifts by
11632 ;; zero don't affect the flags. We assume that shifts by constant
11633 ;; zero are optimized away.
11634 (define_insn "*ashrsi3_cmp"
11635 [(set (reg FLAGS_REG)
11636 (compare
11637 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11638 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11639 (const_int 0)))
11640 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11641 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11642 "ix86_match_ccmode (insn, CCGOCmode)
11643 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11644 && (optimize_size
11645 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11646 "sar{l}\t{%2, %0|%0, %2}"
11647 [(set_attr "type" "ishift")
11648 (set_attr "mode" "SI")])
11649
11650 (define_insn "*ashrsi3_cconly"
11651 [(set (reg FLAGS_REG)
11652 (compare
11653 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11654 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11655 (const_int 0)))
11656 (clobber (match_scratch:SI 0 "=r"))]
11657 "ix86_match_ccmode (insn, CCGOCmode)
11658 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11659 && (optimize_size
11660 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11661 "sar{l}\t{%2, %0|%0, %2}"
11662 [(set_attr "type" "ishift")
11663 (set_attr "mode" "SI")])
11664
11665 (define_insn "*ashrsi3_cmp_zext"
11666 [(set (reg FLAGS_REG)
11667 (compare
11668 (ashiftrt: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 (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11673 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11674 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11675 && (optimize_size
11676 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11677 "sar{l}\t{%2, %k0|%k0, %2}"
11678 [(set_attr "type" "ishift")
11679 (set_attr "mode" "SI")])
11680
11681 (define_expand "ashrhi3"
11682 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11683 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11684 (match_operand:QI 2 "nonmemory_operand" "")))
11685 (clobber (reg:CC FLAGS_REG))]
11686 "TARGET_HIMODE_MATH"
11687 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11688
11689 (define_insn "*ashrhi3_1_one_bit"
11690 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11691 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11692 (match_operand:QI 2 "const1_operand" "")))
11693 (clobber (reg:CC FLAGS_REG))]
11694 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11695 && (TARGET_SHIFT1 || optimize_size)"
11696 "sar{w}\t%0"
11697 [(set_attr "type" "ishift")
11698 (set (attr "length")
11699 (if_then_else (match_operand 0 "register_operand" "")
11700 (const_string "2")
11701 (const_string "*")))])
11702
11703 (define_insn "*ashrhi3_1"
11704 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11705 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11706 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11707 (clobber (reg:CC FLAGS_REG))]
11708 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11709 "@
11710 sar{w}\t{%2, %0|%0, %2}
11711 sar{w}\t{%b2, %0|%0, %b2}"
11712 [(set_attr "type" "ishift")
11713 (set_attr "mode" "HI")])
11714
11715 ;; This pattern can't accept a variable shift count, since shifts by
11716 ;; zero don't affect the flags. We assume that shifts by constant
11717 ;; zero are optimized away.
11718 (define_insn "*ashrhi3_one_bit_cmp"
11719 [(set (reg FLAGS_REG)
11720 (compare
11721 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11722 (match_operand:QI 2 "const1_operand" ""))
11723 (const_int 0)))
11724 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11725 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11726 "ix86_match_ccmode (insn, CCGOCmode)
11727 && (TARGET_SHIFT1 || optimize_size)
11728 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11729 "sar{w}\t%0"
11730 [(set_attr "type" "ishift")
11731 (set (attr "length")
11732 (if_then_else (match_operand 0 "register_operand" "")
11733 (const_string "2")
11734 (const_string "*")))])
11735
11736 (define_insn "*ashrhi3_one_bit_cconly"
11737 [(set (reg FLAGS_REG)
11738 (compare
11739 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11740 (match_operand:QI 2 "const1_operand" ""))
11741 (const_int 0)))
11742 (clobber (match_scratch:HI 0 "=r"))]
11743 "ix86_match_ccmode (insn, CCGOCmode)
11744 && (TARGET_SHIFT1 || optimize_size)
11745 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11746 "sar{w}\t%0"
11747 [(set_attr "type" "ishift")
11748 (set_attr "length" "2")])
11749
11750 ;; This pattern can't accept a variable shift count, since shifts by
11751 ;; zero don't affect the flags. We assume that shifts by constant
11752 ;; zero are optimized away.
11753 (define_insn "*ashrhi3_cmp"
11754 [(set (reg FLAGS_REG)
11755 (compare
11756 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11757 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11758 (const_int 0)))
11759 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11760 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11761 "ix86_match_ccmode (insn, CCGOCmode)
11762 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11763 && (optimize_size
11764 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11765 "sar{w}\t{%2, %0|%0, %2}"
11766 [(set_attr "type" "ishift")
11767 (set_attr "mode" "HI")])
11768
11769 (define_insn "*ashrhi3_cconly"
11770 [(set (reg FLAGS_REG)
11771 (compare
11772 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11773 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11774 (const_int 0)))
11775 (clobber (match_scratch:HI 0 "=r"))]
11776 "ix86_match_ccmode (insn, CCGOCmode)
11777 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11778 && (optimize_size
11779 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11780 "sar{w}\t{%2, %0|%0, %2}"
11781 [(set_attr "type" "ishift")
11782 (set_attr "mode" "HI")])
11783
11784 (define_expand "ashrqi3"
11785 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11786 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11787 (match_operand:QI 2 "nonmemory_operand" "")))
11788 (clobber (reg:CC FLAGS_REG))]
11789 "TARGET_QIMODE_MATH"
11790 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11791
11792 (define_insn "*ashrqi3_1_one_bit"
11793 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11794 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11795 (match_operand:QI 2 "const1_operand" "")))
11796 (clobber (reg:CC FLAGS_REG))]
11797 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11798 && (TARGET_SHIFT1 || optimize_size)"
11799 "sar{b}\t%0"
11800 [(set_attr "type" "ishift")
11801 (set (attr "length")
11802 (if_then_else (match_operand 0 "register_operand" "")
11803 (const_string "2")
11804 (const_string "*")))])
11805
11806 (define_insn "*ashrqi3_1_one_bit_slp"
11807 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11808 (ashiftrt:QI (match_dup 0)
11809 (match_operand:QI 1 "const1_operand" "")))
11810 (clobber (reg:CC FLAGS_REG))]
11811 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11812 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11813 && (TARGET_SHIFT1 || optimize_size)"
11814 "sar{b}\t%0"
11815 [(set_attr "type" "ishift1")
11816 (set (attr "length")
11817 (if_then_else (match_operand 0 "register_operand" "")
11818 (const_string "2")
11819 (const_string "*")))])
11820
11821 (define_insn "*ashrqi3_1"
11822 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11823 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11824 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11825 (clobber (reg:CC FLAGS_REG))]
11826 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11827 "@
11828 sar{b}\t{%2, %0|%0, %2}
11829 sar{b}\t{%b2, %0|%0, %b2}"
11830 [(set_attr "type" "ishift")
11831 (set_attr "mode" "QI")])
11832
11833 (define_insn "*ashrqi3_1_slp"
11834 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11835 (ashiftrt:QI (match_dup 0)
11836 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11837 (clobber (reg:CC FLAGS_REG))]
11838 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11839 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11840 "@
11841 sar{b}\t{%1, %0|%0, %1}
11842 sar{b}\t{%b1, %0|%0, %b1}"
11843 [(set_attr "type" "ishift1")
11844 (set_attr "mode" "QI")])
11845
11846 ;; This pattern can't accept a variable shift count, since shifts by
11847 ;; zero don't affect the flags. We assume that shifts by constant
11848 ;; zero are optimized away.
11849 (define_insn "*ashrqi3_one_bit_cmp"
11850 [(set (reg FLAGS_REG)
11851 (compare
11852 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11853 (match_operand:QI 2 "const1_operand" "I"))
11854 (const_int 0)))
11855 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11856 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11857 "ix86_match_ccmode (insn, CCGOCmode)
11858 && (TARGET_SHIFT1 || optimize_size)
11859 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11860 "sar{b}\t%0"
11861 [(set_attr "type" "ishift")
11862 (set (attr "length")
11863 (if_then_else (match_operand 0 "register_operand" "")
11864 (const_string "2")
11865 (const_string "*")))])
11866
11867 (define_insn "*ashrqi3_one_bit_cconly"
11868 [(set (reg FLAGS_REG)
11869 (compare
11870 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11871 (match_operand:QI 2 "const1_operand" "I"))
11872 (const_int 0)))
11873 (clobber (match_scratch:QI 0 "=q"))]
11874 "ix86_match_ccmode (insn, CCGOCmode)
11875 && (TARGET_SHIFT1 || optimize_size)
11876 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11877 "sar{b}\t%0"
11878 [(set_attr "type" "ishift")
11879 (set_attr "length" "2")])
11880
11881 ;; This pattern can't accept a variable shift count, since shifts by
11882 ;; zero don't affect the flags. We assume that shifts by constant
11883 ;; zero are optimized away.
11884 (define_insn "*ashrqi3_cmp"
11885 [(set (reg FLAGS_REG)
11886 (compare
11887 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11888 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11889 (const_int 0)))
11890 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11891 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11892 "ix86_match_ccmode (insn, CCGOCmode)
11893 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11894 && (optimize_size
11895 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11896 "sar{b}\t{%2, %0|%0, %2}"
11897 [(set_attr "type" "ishift")
11898 (set_attr "mode" "QI")])
11899
11900 (define_insn "*ashrqi3_cconly"
11901 [(set (reg FLAGS_REG)
11902 (compare
11903 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11904 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11905 (const_int 0)))
11906 (clobber (match_scratch:QI 0 "=q"))]
11907 "ix86_match_ccmode (insn, CCGOCmode)
11908 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11909 && (optimize_size
11910 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11911 "sar{b}\t{%2, %0|%0, %2}"
11912 [(set_attr "type" "ishift")
11913 (set_attr "mode" "QI")])
11914
11915 \f
11916 ;; Logical shift instructions
11917
11918 ;; See comment above `ashldi3' about how this works.
11919
11920 (define_expand "lshrti3"
11921 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11922 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11923 (match_operand:QI 2 "nonmemory_operand" "")))
11924 (clobber (reg:CC FLAGS_REG))])]
11925 "TARGET_64BIT"
11926 {
11927 if (! immediate_operand (operands[2], QImode))
11928 {
11929 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11930 DONE;
11931 }
11932 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11933 DONE;
11934 })
11935
11936 (define_insn "lshrti3_1"
11937 [(set (match_operand:TI 0 "register_operand" "=r")
11938 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11939 (match_operand:QI 2 "register_operand" "c")))
11940 (clobber (match_scratch:DI 3 "=&r"))
11941 (clobber (reg:CC FLAGS_REG))]
11942 "TARGET_64BIT"
11943 "#"
11944 [(set_attr "type" "multi")])
11945
11946 (define_insn "*lshrti3_2"
11947 [(set (match_operand:TI 0 "register_operand" "=r")
11948 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11949 (match_operand:QI 2 "immediate_operand" "O")))
11950 (clobber (reg:CC FLAGS_REG))]
11951 "TARGET_64BIT"
11952 "#"
11953 [(set_attr "type" "multi")])
11954
11955 (define_split
11956 [(set (match_operand:TI 0 "register_operand" "")
11957 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11958 (match_operand:QI 2 "register_operand" "")))
11959 (clobber (match_scratch:DI 3 ""))
11960 (clobber (reg:CC FLAGS_REG))]
11961 "TARGET_64BIT && reload_completed"
11962 [(const_int 0)]
11963 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11964
11965 (define_split
11966 [(set (match_operand:TI 0 "register_operand" "")
11967 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11968 (match_operand:QI 2 "immediate_operand" "")))
11969 (clobber (reg:CC FLAGS_REG))]
11970 "TARGET_64BIT && reload_completed"
11971 [(const_int 0)]
11972 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11973
11974 (define_expand "lshrdi3"
11975 [(set (match_operand:DI 0 "shiftdi_operand" "")
11976 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11977 (match_operand:QI 2 "nonmemory_operand" "")))]
11978 ""
11979 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11980
11981 (define_insn "*lshrdi3_1_one_bit_rex64"
11982 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11983 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11984 (match_operand:QI 2 "const1_operand" "")))
11985 (clobber (reg:CC FLAGS_REG))]
11986 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11987 && (TARGET_SHIFT1 || optimize_size)"
11988 "shr{q}\t%0"
11989 [(set_attr "type" "ishift")
11990 (set (attr "length")
11991 (if_then_else (match_operand:DI 0 "register_operand" "")
11992 (const_string "2")
11993 (const_string "*")))])
11994
11995 (define_insn "*lshrdi3_1_rex64"
11996 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11997 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11998 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11999 (clobber (reg:CC FLAGS_REG))]
12000 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12001 "@
12002 shr{q}\t{%2, %0|%0, %2}
12003 shr{q}\t{%b2, %0|%0, %b2}"
12004 [(set_attr "type" "ishift")
12005 (set_attr "mode" "DI")])
12006
12007 ;; This pattern can't accept a variable shift count, since shifts by
12008 ;; zero don't affect the flags. We assume that shifts by constant
12009 ;; zero are optimized away.
12010 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12011 [(set (reg FLAGS_REG)
12012 (compare
12013 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12014 (match_operand:QI 2 "const1_operand" ""))
12015 (const_int 0)))
12016 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12017 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12018 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12019 && (TARGET_SHIFT1 || optimize_size)
12020 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12021 "shr{q}\t%0"
12022 [(set_attr "type" "ishift")
12023 (set (attr "length")
12024 (if_then_else (match_operand:DI 0 "register_operand" "")
12025 (const_string "2")
12026 (const_string "*")))])
12027
12028 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12029 [(set (reg FLAGS_REG)
12030 (compare
12031 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12032 (match_operand:QI 2 "const1_operand" ""))
12033 (const_int 0)))
12034 (clobber (match_scratch:DI 0 "=r"))]
12035 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12036 && (TARGET_SHIFT1 || optimize_size)
12037 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12038 "shr{q}\t%0"
12039 [(set_attr "type" "ishift")
12040 (set_attr "length" "2")])
12041
12042 ;; This pattern can't accept a variable shift count, since shifts by
12043 ;; zero don't affect the flags. We assume that shifts by constant
12044 ;; zero are optimized away.
12045 (define_insn "*lshrdi3_cmp_rex64"
12046 [(set (reg FLAGS_REG)
12047 (compare
12048 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12049 (match_operand:QI 2 "const_int_operand" "e"))
12050 (const_int 0)))
12051 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12052 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12053 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12054 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12055 && (optimize_size
12056 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12057 "shr{q}\t{%2, %0|%0, %2}"
12058 [(set_attr "type" "ishift")
12059 (set_attr "mode" "DI")])
12060
12061 (define_insn "*lshrdi3_cconly_rex64"
12062 [(set (reg FLAGS_REG)
12063 (compare
12064 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12065 (match_operand:QI 2 "const_int_operand" "e"))
12066 (const_int 0)))
12067 (clobber (match_scratch:DI 0 "=r"))]
12068 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12069 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12070 && (optimize_size
12071 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12072 "shr{q}\t{%2, %0|%0, %2}"
12073 [(set_attr "type" "ishift")
12074 (set_attr "mode" "DI")])
12075
12076 (define_insn "*lshrdi3_1"
12077 [(set (match_operand:DI 0 "register_operand" "=r")
12078 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12079 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12080 (clobber (reg:CC FLAGS_REG))]
12081 "!TARGET_64BIT"
12082 "#"
12083 [(set_attr "type" "multi")])
12084
12085 ;; By default we don't ask for a scratch register, because when DImode
12086 ;; values are manipulated, registers are already at a premium. But if
12087 ;; we have one handy, we won't turn it away.
12088 (define_peephole2
12089 [(match_scratch:SI 3 "r")
12090 (parallel [(set (match_operand:DI 0 "register_operand" "")
12091 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12092 (match_operand:QI 2 "nonmemory_operand" "")))
12093 (clobber (reg:CC FLAGS_REG))])
12094 (match_dup 3)]
12095 "!TARGET_64BIT && TARGET_CMOVE"
12096 [(const_int 0)]
12097 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12098
12099 (define_split
12100 [(set (match_operand:DI 0 "register_operand" "")
12101 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12102 (match_operand:QI 2 "nonmemory_operand" "")))
12103 (clobber (reg:CC FLAGS_REG))]
12104 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12105 ? flow2_completed : reload_completed)"
12106 [(const_int 0)]
12107 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12108
12109 (define_expand "lshrsi3"
12110 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12111 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12112 (match_operand:QI 2 "nonmemory_operand" "")))
12113 (clobber (reg:CC FLAGS_REG))]
12114 ""
12115 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12116
12117 (define_insn "*lshrsi3_1_one_bit"
12118 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12119 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12120 (match_operand:QI 2 "const1_operand" "")))
12121 (clobber (reg:CC FLAGS_REG))]
12122 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12123 && (TARGET_SHIFT1 || optimize_size)"
12124 "shr{l}\t%0"
12125 [(set_attr "type" "ishift")
12126 (set (attr "length")
12127 (if_then_else (match_operand:SI 0 "register_operand" "")
12128 (const_string "2")
12129 (const_string "*")))])
12130
12131 (define_insn "*lshrsi3_1_one_bit_zext"
12132 [(set (match_operand:DI 0 "register_operand" "=r")
12133 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12134 (match_operand:QI 2 "const1_operand" "")))
12135 (clobber (reg:CC FLAGS_REG))]
12136 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12137 && (TARGET_SHIFT1 || optimize_size)"
12138 "shr{l}\t%k0"
12139 [(set_attr "type" "ishift")
12140 (set_attr "length" "2")])
12141
12142 (define_insn "*lshrsi3_1"
12143 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12144 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12145 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12148 "@
12149 shr{l}\t{%2, %0|%0, %2}
12150 shr{l}\t{%b2, %0|%0, %b2}"
12151 [(set_attr "type" "ishift")
12152 (set_attr "mode" "SI")])
12153
12154 (define_insn "*lshrsi3_1_zext"
12155 [(set (match_operand:DI 0 "register_operand" "=r,r")
12156 (zero_extend:DI
12157 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12158 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12159 (clobber (reg:CC FLAGS_REG))]
12160 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12161 "@
12162 shr{l}\t{%2, %k0|%k0, %2}
12163 shr{l}\t{%b2, %k0|%k0, %b2}"
12164 [(set_attr "type" "ishift")
12165 (set_attr "mode" "SI")])
12166
12167 ;; This pattern can't accept a variable shift count, since shifts by
12168 ;; zero don't affect the flags. We assume that shifts by constant
12169 ;; zero are optimized away.
12170 (define_insn "*lshrsi3_one_bit_cmp"
12171 [(set (reg FLAGS_REG)
12172 (compare
12173 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12174 (match_operand:QI 2 "const1_operand" ""))
12175 (const_int 0)))
12176 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12177 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12178 "ix86_match_ccmode (insn, CCGOCmode)
12179 && (TARGET_SHIFT1 || optimize_size)
12180 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12181 "shr{l}\t%0"
12182 [(set_attr "type" "ishift")
12183 (set (attr "length")
12184 (if_then_else (match_operand:SI 0 "register_operand" "")
12185 (const_string "2")
12186 (const_string "*")))])
12187
12188 (define_insn "*lshrsi3_one_bit_cconly"
12189 [(set (reg FLAGS_REG)
12190 (compare
12191 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12192 (match_operand:QI 2 "const1_operand" ""))
12193 (const_int 0)))
12194 (clobber (match_scratch:SI 0 "=r"))]
12195 "ix86_match_ccmode (insn, CCGOCmode)
12196 && (TARGET_SHIFT1 || optimize_size)
12197 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12198 "shr{l}\t%0"
12199 [(set_attr "type" "ishift")
12200 (set_attr "length" "2")])
12201
12202 (define_insn "*lshrsi3_cmp_one_bit_zext"
12203 [(set (reg FLAGS_REG)
12204 (compare
12205 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12206 (match_operand:QI 2 "const1_operand" ""))
12207 (const_int 0)))
12208 (set (match_operand:DI 0 "register_operand" "=r")
12209 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12210 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12211 && (TARGET_SHIFT1 || optimize_size)
12212 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12213 "shr{l}\t%k0"
12214 [(set_attr "type" "ishift")
12215 (set_attr "length" "2")])
12216
12217 ;; This pattern can't accept a variable shift count, since shifts by
12218 ;; zero don't affect the flags. We assume that shifts by constant
12219 ;; zero are optimized away.
12220 (define_insn "*lshrsi3_cmp"
12221 [(set (reg FLAGS_REG)
12222 (compare
12223 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12224 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12225 (const_int 0)))
12226 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12227 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12228 "ix86_match_ccmode (insn, CCGOCmode)
12229 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12230 && (optimize_size
12231 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12232 "shr{l}\t{%2, %0|%0, %2}"
12233 [(set_attr "type" "ishift")
12234 (set_attr "mode" "SI")])
12235
12236 (define_insn "*lshrsi3_cconly"
12237 [(set (reg FLAGS_REG)
12238 (compare
12239 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12240 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12241 (const_int 0)))
12242 (clobber (match_scratch:SI 0 "=r"))]
12243 "ix86_match_ccmode (insn, CCGOCmode)
12244 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12245 && (optimize_size
12246 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12247 "shr{l}\t{%2, %0|%0, %2}"
12248 [(set_attr "type" "ishift")
12249 (set_attr "mode" "SI")])
12250
12251 (define_insn "*lshrsi3_cmp_zext"
12252 [(set (reg FLAGS_REG)
12253 (compare
12254 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12255 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12256 (const_int 0)))
12257 (set (match_operand:DI 0 "register_operand" "=r")
12258 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12259 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12260 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12261 && (optimize_size
12262 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12263 "shr{l}\t{%2, %k0|%k0, %2}"
12264 [(set_attr "type" "ishift")
12265 (set_attr "mode" "SI")])
12266
12267 (define_expand "lshrhi3"
12268 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12269 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12270 (match_operand:QI 2 "nonmemory_operand" "")))
12271 (clobber (reg:CC FLAGS_REG))]
12272 "TARGET_HIMODE_MATH"
12273 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12274
12275 (define_insn "*lshrhi3_1_one_bit"
12276 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12277 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12278 (match_operand:QI 2 "const1_operand" "")))
12279 (clobber (reg:CC FLAGS_REG))]
12280 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12281 && (TARGET_SHIFT1 || optimize_size)"
12282 "shr{w}\t%0"
12283 [(set_attr "type" "ishift")
12284 (set (attr "length")
12285 (if_then_else (match_operand 0 "register_operand" "")
12286 (const_string "2")
12287 (const_string "*")))])
12288
12289 (define_insn "*lshrhi3_1"
12290 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12291 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12292 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12293 (clobber (reg:CC FLAGS_REG))]
12294 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12295 "@
12296 shr{w}\t{%2, %0|%0, %2}
12297 shr{w}\t{%b2, %0|%0, %b2}"
12298 [(set_attr "type" "ishift")
12299 (set_attr "mode" "HI")])
12300
12301 ;; This pattern can't accept a variable shift count, since shifts by
12302 ;; zero don't affect the flags. We assume that shifts by constant
12303 ;; zero are optimized away.
12304 (define_insn "*lshrhi3_one_bit_cmp"
12305 [(set (reg FLAGS_REG)
12306 (compare
12307 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12308 (match_operand:QI 2 "const1_operand" ""))
12309 (const_int 0)))
12310 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12311 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12312 "ix86_match_ccmode (insn, CCGOCmode)
12313 && (TARGET_SHIFT1 || optimize_size)
12314 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12315 "shr{w}\t%0"
12316 [(set_attr "type" "ishift")
12317 (set (attr "length")
12318 (if_then_else (match_operand:SI 0 "register_operand" "")
12319 (const_string "2")
12320 (const_string "*")))])
12321
12322 (define_insn "*lshrhi3_one_bit_cconly"
12323 [(set (reg FLAGS_REG)
12324 (compare
12325 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12326 (match_operand:QI 2 "const1_operand" ""))
12327 (const_int 0)))
12328 (clobber (match_scratch:HI 0 "=r"))]
12329 "ix86_match_ccmode (insn, CCGOCmode)
12330 && (TARGET_SHIFT1 || optimize_size)
12331 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12332 "shr{w}\t%0"
12333 [(set_attr "type" "ishift")
12334 (set_attr "length" "2")])
12335
12336 ;; This pattern can't accept a variable shift count, since shifts by
12337 ;; zero don't affect the flags. We assume that shifts by constant
12338 ;; zero are optimized away.
12339 (define_insn "*lshrhi3_cmp"
12340 [(set (reg FLAGS_REG)
12341 (compare
12342 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12343 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12344 (const_int 0)))
12345 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12346 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12347 "ix86_match_ccmode (insn, CCGOCmode)
12348 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12349 && (optimize_size
12350 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12351 "shr{w}\t{%2, %0|%0, %2}"
12352 [(set_attr "type" "ishift")
12353 (set_attr "mode" "HI")])
12354
12355 (define_insn "*lshrhi3_cconly"
12356 [(set (reg FLAGS_REG)
12357 (compare
12358 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12359 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12360 (const_int 0)))
12361 (clobber (match_scratch:HI 0 "=r"))]
12362 "ix86_match_ccmode (insn, CCGOCmode)
12363 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12364 && (optimize_size
12365 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12366 "shr{w}\t{%2, %0|%0, %2}"
12367 [(set_attr "type" "ishift")
12368 (set_attr "mode" "HI")])
12369
12370 (define_expand "lshrqi3"
12371 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12372 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12373 (match_operand:QI 2 "nonmemory_operand" "")))
12374 (clobber (reg:CC FLAGS_REG))]
12375 "TARGET_QIMODE_MATH"
12376 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12377
12378 (define_insn "*lshrqi3_1_one_bit"
12379 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12380 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12381 (match_operand:QI 2 "const1_operand" "")))
12382 (clobber (reg:CC FLAGS_REG))]
12383 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12384 && (TARGET_SHIFT1 || optimize_size)"
12385 "shr{b}\t%0"
12386 [(set_attr "type" "ishift")
12387 (set (attr "length")
12388 (if_then_else (match_operand 0 "register_operand" "")
12389 (const_string "2")
12390 (const_string "*")))])
12391
12392 (define_insn "*lshrqi3_1_one_bit_slp"
12393 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12394 (lshiftrt:QI (match_dup 0)
12395 (match_operand:QI 1 "const1_operand" "")))
12396 (clobber (reg:CC FLAGS_REG))]
12397 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12398 && (TARGET_SHIFT1 || optimize_size)"
12399 "shr{b}\t%0"
12400 [(set_attr "type" "ishift1")
12401 (set (attr "length")
12402 (if_then_else (match_operand 0 "register_operand" "")
12403 (const_string "2")
12404 (const_string "*")))])
12405
12406 (define_insn "*lshrqi3_1"
12407 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12408 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12409 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12410 (clobber (reg:CC FLAGS_REG))]
12411 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12412 "@
12413 shr{b}\t{%2, %0|%0, %2}
12414 shr{b}\t{%b2, %0|%0, %b2}"
12415 [(set_attr "type" "ishift")
12416 (set_attr "mode" "QI")])
12417
12418 (define_insn "*lshrqi3_1_slp"
12419 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12420 (lshiftrt:QI (match_dup 0)
12421 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12422 (clobber (reg:CC FLAGS_REG))]
12423 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12424 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12425 "@
12426 shr{b}\t{%1, %0|%0, %1}
12427 shr{b}\t{%b1, %0|%0, %b1}"
12428 [(set_attr "type" "ishift1")
12429 (set_attr "mode" "QI")])
12430
12431 ;; This pattern can't accept a variable shift count, since shifts by
12432 ;; zero don't affect the flags. We assume that shifts by constant
12433 ;; zero are optimized away.
12434 (define_insn "*lshrqi2_one_bit_cmp"
12435 [(set (reg FLAGS_REG)
12436 (compare
12437 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12438 (match_operand:QI 2 "const1_operand" ""))
12439 (const_int 0)))
12440 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12441 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12442 "ix86_match_ccmode (insn, CCGOCmode)
12443 && (TARGET_SHIFT1 || optimize_size)
12444 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12445 "shr{b}\t%0"
12446 [(set_attr "type" "ishift")
12447 (set (attr "length")
12448 (if_then_else (match_operand:SI 0 "register_operand" "")
12449 (const_string "2")
12450 (const_string "*")))])
12451
12452 (define_insn "*lshrqi2_one_bit_cconly"
12453 [(set (reg FLAGS_REG)
12454 (compare
12455 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12456 (match_operand:QI 2 "const1_operand" ""))
12457 (const_int 0)))
12458 (clobber (match_scratch:QI 0 "=q"))]
12459 "ix86_match_ccmode (insn, CCGOCmode)
12460 && (TARGET_SHIFT1 || optimize_size)
12461 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12462 "shr{b}\t%0"
12463 [(set_attr "type" "ishift")
12464 (set_attr "length" "2")])
12465
12466 ;; This pattern can't accept a variable shift count, since shifts by
12467 ;; zero don't affect the flags. We assume that shifts by constant
12468 ;; zero are optimized away.
12469 (define_insn "*lshrqi2_cmp"
12470 [(set (reg FLAGS_REG)
12471 (compare
12472 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12473 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12474 (const_int 0)))
12475 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12476 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12477 "ix86_match_ccmode (insn, CCGOCmode)
12478 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12479 && (optimize_size
12480 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12481 "shr{b}\t{%2, %0|%0, %2}"
12482 [(set_attr "type" "ishift")
12483 (set_attr "mode" "QI")])
12484
12485 (define_insn "*lshrqi2_cconly"
12486 [(set (reg FLAGS_REG)
12487 (compare
12488 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12489 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12490 (const_int 0)))
12491 (clobber (match_scratch:QI 0 "=q"))]
12492 "ix86_match_ccmode (insn, CCGOCmode)
12493 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12494 && (optimize_size
12495 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12496 "shr{b}\t{%2, %0|%0, %2}"
12497 [(set_attr "type" "ishift")
12498 (set_attr "mode" "QI")])
12499 \f
12500 ;; Rotate instructions
12501
12502 (define_expand "rotldi3"
12503 [(set (match_operand:DI 0 "shiftdi_operand" "")
12504 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12505 (match_operand:QI 2 "nonmemory_operand" "")))
12506 (clobber (reg:CC FLAGS_REG))]
12507 ""
12508 {
12509 if (TARGET_64BIT)
12510 {
12511 ix86_expand_binary_operator (ROTATE, DImode, operands);
12512 DONE;
12513 }
12514 if (!const_1_to_31_operand (operands[2], VOIDmode))
12515 FAIL;
12516 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12517 DONE;
12518 })
12519
12520 ;; Implement rotation using two double-precision shift instructions
12521 ;; and a scratch register.
12522 (define_insn_and_split "ix86_rotldi3"
12523 [(set (match_operand:DI 0 "register_operand" "=r")
12524 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12525 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12526 (clobber (reg:CC FLAGS_REG))
12527 (clobber (match_scratch:SI 3 "=&r"))]
12528 "!TARGET_64BIT"
12529 ""
12530 "&& reload_completed"
12531 [(set (match_dup 3) (match_dup 4))
12532 (parallel
12533 [(set (match_dup 4)
12534 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12535 (lshiftrt:SI (match_dup 5)
12536 (minus:QI (const_int 32) (match_dup 2)))))
12537 (clobber (reg:CC FLAGS_REG))])
12538 (parallel
12539 [(set (match_dup 5)
12540 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12541 (lshiftrt:SI (match_dup 3)
12542 (minus:QI (const_int 32) (match_dup 2)))))
12543 (clobber (reg:CC FLAGS_REG))])]
12544 "split_di (operands, 1, operands + 4, operands + 5);")
12545
12546 (define_insn "*rotlsi3_1_one_bit_rex64"
12547 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12548 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12549 (match_operand:QI 2 "const1_operand" "")))
12550 (clobber (reg:CC FLAGS_REG))]
12551 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12552 && (TARGET_SHIFT1 || optimize_size)"
12553 "rol{q}\t%0"
12554 [(set_attr "type" "rotate")
12555 (set (attr "length")
12556 (if_then_else (match_operand:DI 0 "register_operand" "")
12557 (const_string "2")
12558 (const_string "*")))])
12559
12560 (define_insn "*rotldi3_1_rex64"
12561 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12562 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12563 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12564 (clobber (reg:CC FLAGS_REG))]
12565 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12566 "@
12567 rol{q}\t{%2, %0|%0, %2}
12568 rol{q}\t{%b2, %0|%0, %b2}"
12569 [(set_attr "type" "rotate")
12570 (set_attr "mode" "DI")])
12571
12572 (define_expand "rotlsi3"
12573 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12574 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12575 (match_operand:QI 2 "nonmemory_operand" "")))
12576 (clobber (reg:CC FLAGS_REG))]
12577 ""
12578 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12579
12580 (define_insn "*rotlsi3_1_one_bit"
12581 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12582 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12583 (match_operand:QI 2 "const1_operand" "")))
12584 (clobber (reg:CC FLAGS_REG))]
12585 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12586 && (TARGET_SHIFT1 || optimize_size)"
12587 "rol{l}\t%0"
12588 [(set_attr "type" "rotate")
12589 (set (attr "length")
12590 (if_then_else (match_operand:SI 0 "register_operand" "")
12591 (const_string "2")
12592 (const_string "*")))])
12593
12594 (define_insn "*rotlsi3_1_one_bit_zext"
12595 [(set (match_operand:DI 0 "register_operand" "=r")
12596 (zero_extend:DI
12597 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12598 (match_operand:QI 2 "const1_operand" ""))))
12599 (clobber (reg:CC FLAGS_REG))]
12600 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12601 && (TARGET_SHIFT1 || optimize_size)"
12602 "rol{l}\t%k0"
12603 [(set_attr "type" "rotate")
12604 (set_attr "length" "2")])
12605
12606 (define_insn "*rotlsi3_1"
12607 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12608 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12609 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12610 (clobber (reg:CC FLAGS_REG))]
12611 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12612 "@
12613 rol{l}\t{%2, %0|%0, %2}
12614 rol{l}\t{%b2, %0|%0, %b2}"
12615 [(set_attr "type" "rotate")
12616 (set_attr "mode" "SI")])
12617
12618 (define_insn "*rotlsi3_1_zext"
12619 [(set (match_operand:DI 0 "register_operand" "=r,r")
12620 (zero_extend:DI
12621 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12622 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12623 (clobber (reg:CC FLAGS_REG))]
12624 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12625 "@
12626 rol{l}\t{%2, %k0|%k0, %2}
12627 rol{l}\t{%b2, %k0|%k0, %b2}"
12628 [(set_attr "type" "rotate")
12629 (set_attr "mode" "SI")])
12630
12631 (define_expand "rotlhi3"
12632 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12633 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12634 (match_operand:QI 2 "nonmemory_operand" "")))
12635 (clobber (reg:CC FLAGS_REG))]
12636 "TARGET_HIMODE_MATH"
12637 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12638
12639 (define_insn "*rotlhi3_1_one_bit"
12640 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12641 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12642 (match_operand:QI 2 "const1_operand" "")))
12643 (clobber (reg:CC FLAGS_REG))]
12644 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12645 && (TARGET_SHIFT1 || optimize_size)"
12646 "rol{w}\t%0"
12647 [(set_attr "type" "rotate")
12648 (set (attr "length")
12649 (if_then_else (match_operand 0 "register_operand" "")
12650 (const_string "2")
12651 (const_string "*")))])
12652
12653 (define_insn "*rotlhi3_1"
12654 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12655 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12656 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12657 (clobber (reg:CC FLAGS_REG))]
12658 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12659 "@
12660 rol{w}\t{%2, %0|%0, %2}
12661 rol{w}\t{%b2, %0|%0, %b2}"
12662 [(set_attr "type" "rotate")
12663 (set_attr "mode" "HI")])
12664
12665 (define_expand "rotlqi3"
12666 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12667 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12668 (match_operand:QI 2 "nonmemory_operand" "")))
12669 (clobber (reg:CC FLAGS_REG))]
12670 "TARGET_QIMODE_MATH"
12671 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12672
12673 (define_insn "*rotlqi3_1_one_bit_slp"
12674 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12675 (rotate:QI (match_dup 0)
12676 (match_operand:QI 1 "const1_operand" "")))
12677 (clobber (reg:CC FLAGS_REG))]
12678 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12679 && (TARGET_SHIFT1 || optimize_size)"
12680 "rol{b}\t%0"
12681 [(set_attr "type" "rotate1")
12682 (set (attr "length")
12683 (if_then_else (match_operand 0 "register_operand" "")
12684 (const_string "2")
12685 (const_string "*")))])
12686
12687 (define_insn "*rotlqi3_1_one_bit"
12688 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12689 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12690 (match_operand:QI 2 "const1_operand" "")))
12691 (clobber (reg:CC FLAGS_REG))]
12692 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12693 && (TARGET_SHIFT1 || optimize_size)"
12694 "rol{b}\t%0"
12695 [(set_attr "type" "rotate")
12696 (set (attr "length")
12697 (if_then_else (match_operand 0 "register_operand" "")
12698 (const_string "2")
12699 (const_string "*")))])
12700
12701 (define_insn "*rotlqi3_1_slp"
12702 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12703 (rotate:QI (match_dup 0)
12704 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12705 (clobber (reg:CC FLAGS_REG))]
12706 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12707 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12708 "@
12709 rol{b}\t{%1, %0|%0, %1}
12710 rol{b}\t{%b1, %0|%0, %b1}"
12711 [(set_attr "type" "rotate1")
12712 (set_attr "mode" "QI")])
12713
12714 (define_insn "*rotlqi3_1"
12715 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12716 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12717 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12718 (clobber (reg:CC FLAGS_REG))]
12719 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12720 "@
12721 rol{b}\t{%2, %0|%0, %2}
12722 rol{b}\t{%b2, %0|%0, %b2}"
12723 [(set_attr "type" "rotate")
12724 (set_attr "mode" "QI")])
12725
12726 (define_expand "rotrdi3"
12727 [(set (match_operand:DI 0 "shiftdi_operand" "")
12728 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12729 (match_operand:QI 2 "nonmemory_operand" "")))
12730 (clobber (reg:CC FLAGS_REG))]
12731 ""
12732 {
12733 if (TARGET_64BIT)
12734 {
12735 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12736 DONE;
12737 }
12738 if (!const_1_to_31_operand (operands[2], VOIDmode))
12739 FAIL;
12740 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12741 DONE;
12742 })
12743
12744 ;; Implement rotation using two double-precision shift instructions
12745 ;; and a scratch register.
12746 (define_insn_and_split "ix86_rotrdi3"
12747 [(set (match_operand:DI 0 "register_operand" "=r")
12748 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12749 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12750 (clobber (reg:CC FLAGS_REG))
12751 (clobber (match_scratch:SI 3 "=&r"))]
12752 "!TARGET_64BIT"
12753 ""
12754 "&& reload_completed"
12755 [(set (match_dup 3) (match_dup 4))
12756 (parallel
12757 [(set (match_dup 4)
12758 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12759 (ashift:SI (match_dup 5)
12760 (minus:QI (const_int 32) (match_dup 2)))))
12761 (clobber (reg:CC FLAGS_REG))])
12762 (parallel
12763 [(set (match_dup 5)
12764 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12765 (ashift:SI (match_dup 3)
12766 (minus:QI (const_int 32) (match_dup 2)))))
12767 (clobber (reg:CC FLAGS_REG))])]
12768 "split_di (operands, 1, operands + 4, operands + 5);")
12769
12770 (define_insn "*rotrdi3_1_one_bit_rex64"
12771 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12772 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12773 (match_operand:QI 2 "const1_operand" "")))
12774 (clobber (reg:CC FLAGS_REG))]
12775 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12776 && (TARGET_SHIFT1 || optimize_size)"
12777 "ror{q}\t%0"
12778 [(set_attr "type" "rotate")
12779 (set (attr "length")
12780 (if_then_else (match_operand:DI 0 "register_operand" "")
12781 (const_string "2")
12782 (const_string "*")))])
12783
12784 (define_insn "*rotrdi3_1_rex64"
12785 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12786 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12787 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12788 (clobber (reg:CC FLAGS_REG))]
12789 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12790 "@
12791 ror{q}\t{%2, %0|%0, %2}
12792 ror{q}\t{%b2, %0|%0, %b2}"
12793 [(set_attr "type" "rotate")
12794 (set_attr "mode" "DI")])
12795
12796 (define_expand "rotrsi3"
12797 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12798 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12799 (match_operand:QI 2 "nonmemory_operand" "")))
12800 (clobber (reg:CC FLAGS_REG))]
12801 ""
12802 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12803
12804 (define_insn "*rotrsi3_1_one_bit"
12805 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12806 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12807 (match_operand:QI 2 "const1_operand" "")))
12808 (clobber (reg:CC FLAGS_REG))]
12809 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12810 && (TARGET_SHIFT1 || optimize_size)"
12811 "ror{l}\t%0"
12812 [(set_attr "type" "rotate")
12813 (set (attr "length")
12814 (if_then_else (match_operand:SI 0 "register_operand" "")
12815 (const_string "2")
12816 (const_string "*")))])
12817
12818 (define_insn "*rotrsi3_1_one_bit_zext"
12819 [(set (match_operand:DI 0 "register_operand" "=r")
12820 (zero_extend:DI
12821 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12822 (match_operand:QI 2 "const1_operand" ""))))
12823 (clobber (reg:CC FLAGS_REG))]
12824 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12825 && (TARGET_SHIFT1 || optimize_size)"
12826 "ror{l}\t%k0"
12827 [(set_attr "type" "rotate")
12828 (set (attr "length")
12829 (if_then_else (match_operand:SI 0 "register_operand" "")
12830 (const_string "2")
12831 (const_string "*")))])
12832
12833 (define_insn "*rotrsi3_1"
12834 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12835 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12836 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12837 (clobber (reg:CC FLAGS_REG))]
12838 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12839 "@
12840 ror{l}\t{%2, %0|%0, %2}
12841 ror{l}\t{%b2, %0|%0, %b2}"
12842 [(set_attr "type" "rotate")
12843 (set_attr "mode" "SI")])
12844
12845 (define_insn "*rotrsi3_1_zext"
12846 [(set (match_operand:DI 0 "register_operand" "=r,r")
12847 (zero_extend:DI
12848 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12849 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12850 (clobber (reg:CC FLAGS_REG))]
12851 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12852 "@
12853 ror{l}\t{%2, %k0|%k0, %2}
12854 ror{l}\t{%b2, %k0|%k0, %b2}"
12855 [(set_attr "type" "rotate")
12856 (set_attr "mode" "SI")])
12857
12858 (define_expand "rotrhi3"
12859 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12860 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12861 (match_operand:QI 2 "nonmemory_operand" "")))
12862 (clobber (reg:CC FLAGS_REG))]
12863 "TARGET_HIMODE_MATH"
12864 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12865
12866 (define_insn "*rotrhi3_one_bit"
12867 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12868 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12869 (match_operand:QI 2 "const1_operand" "")))
12870 (clobber (reg:CC FLAGS_REG))]
12871 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12872 && (TARGET_SHIFT1 || optimize_size)"
12873 "ror{w}\t%0"
12874 [(set_attr "type" "rotate")
12875 (set (attr "length")
12876 (if_then_else (match_operand 0 "register_operand" "")
12877 (const_string "2")
12878 (const_string "*")))])
12879
12880 (define_insn "*rotrhi3"
12881 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12882 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12883 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12884 (clobber (reg:CC FLAGS_REG))]
12885 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12886 "@
12887 ror{w}\t{%2, %0|%0, %2}
12888 ror{w}\t{%b2, %0|%0, %b2}"
12889 [(set_attr "type" "rotate")
12890 (set_attr "mode" "HI")])
12891
12892 (define_expand "rotrqi3"
12893 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12894 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12895 (match_operand:QI 2 "nonmemory_operand" "")))
12896 (clobber (reg:CC FLAGS_REG))]
12897 "TARGET_QIMODE_MATH"
12898 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12899
12900 (define_insn "*rotrqi3_1_one_bit"
12901 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12902 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12903 (match_operand:QI 2 "const1_operand" "")))
12904 (clobber (reg:CC FLAGS_REG))]
12905 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12906 && (TARGET_SHIFT1 || optimize_size)"
12907 "ror{b}\t%0"
12908 [(set_attr "type" "rotate")
12909 (set (attr "length")
12910 (if_then_else (match_operand 0 "register_operand" "")
12911 (const_string "2")
12912 (const_string "*")))])
12913
12914 (define_insn "*rotrqi3_1_one_bit_slp"
12915 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12916 (rotatert:QI (match_dup 0)
12917 (match_operand:QI 1 "const1_operand" "")))
12918 (clobber (reg:CC FLAGS_REG))]
12919 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12920 && (TARGET_SHIFT1 || optimize_size)"
12921 "ror{b}\t%0"
12922 [(set_attr "type" "rotate1")
12923 (set (attr "length")
12924 (if_then_else (match_operand 0 "register_operand" "")
12925 (const_string "2")
12926 (const_string "*")))])
12927
12928 (define_insn "*rotrqi3_1"
12929 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12930 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12931 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12932 (clobber (reg:CC FLAGS_REG))]
12933 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12934 "@
12935 ror{b}\t{%2, %0|%0, %2}
12936 ror{b}\t{%b2, %0|%0, %b2}"
12937 [(set_attr "type" "rotate")
12938 (set_attr "mode" "QI")])
12939
12940 (define_insn "*rotrqi3_1_slp"
12941 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12942 (rotatert:QI (match_dup 0)
12943 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12944 (clobber (reg:CC FLAGS_REG))]
12945 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12946 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12947 "@
12948 ror{b}\t{%1, %0|%0, %1}
12949 ror{b}\t{%b1, %0|%0, %b1}"
12950 [(set_attr "type" "rotate1")
12951 (set_attr "mode" "QI")])
12952 \f
12953 ;; Bit set / bit test instructions
12954
12955 (define_expand "extv"
12956 [(set (match_operand:SI 0 "register_operand" "")
12957 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12958 (match_operand:SI 2 "const8_operand" "")
12959 (match_operand:SI 3 "const8_operand" "")))]
12960 ""
12961 {
12962 /* Handle extractions from %ah et al. */
12963 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12964 FAIL;
12965
12966 /* From mips.md: extract_bit_field doesn't verify that our source
12967 matches the predicate, so check it again here. */
12968 if (! ext_register_operand (operands[1], VOIDmode))
12969 FAIL;
12970 })
12971
12972 (define_expand "extzv"
12973 [(set (match_operand:SI 0 "register_operand" "")
12974 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12975 (match_operand:SI 2 "const8_operand" "")
12976 (match_operand:SI 3 "const8_operand" "")))]
12977 ""
12978 {
12979 /* Handle extractions from %ah et al. */
12980 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12981 FAIL;
12982
12983 /* From mips.md: extract_bit_field doesn't verify that our source
12984 matches the predicate, so check it again here. */
12985 if (! ext_register_operand (operands[1], VOIDmode))
12986 FAIL;
12987 })
12988
12989 (define_expand "insv"
12990 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12991 (match_operand 1 "const8_operand" "")
12992 (match_operand 2 "const8_operand" ""))
12993 (match_operand 3 "register_operand" ""))]
12994 ""
12995 {
12996 /* Handle insertions to %ah et al. */
12997 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12998 FAIL;
12999
13000 /* From mips.md: insert_bit_field doesn't verify that our source
13001 matches the predicate, so check it again here. */
13002 if (! ext_register_operand (operands[0], VOIDmode))
13003 FAIL;
13004
13005 if (TARGET_64BIT)
13006 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13007 else
13008 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13009
13010 DONE;
13011 })
13012
13013 ;; %%% bts, btr, btc, bt.
13014 ;; In general these instructions are *slow* when applied to memory,
13015 ;; since they enforce atomic operation. When applied to registers,
13016 ;; it depends on the cpu implementation. They're never faster than
13017 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13018 ;; no point. But in 64-bit, we can't hold the relevant immediates
13019 ;; within the instruction itself, so operating on bits in the high
13020 ;; 32-bits of a register becomes easier.
13021 ;;
13022 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13023 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13024 ;; negdf respectively, so they can never be disabled entirely.
13025
13026 (define_insn "*btsq"
13027 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13028 (const_int 1)
13029 (match_operand:DI 1 "const_0_to_63_operand" ""))
13030 (const_int 1))
13031 (clobber (reg:CC FLAGS_REG))]
13032 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13033 "bts{q} %1,%0"
13034 [(set_attr "type" "alu1")])
13035
13036 (define_insn "*btrq"
13037 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13038 (const_int 1)
13039 (match_operand:DI 1 "const_0_to_63_operand" ""))
13040 (const_int 0))
13041 (clobber (reg:CC FLAGS_REG))]
13042 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13043 "btr{q} %1,%0"
13044 [(set_attr "type" "alu1")])
13045
13046 (define_insn "*btcq"
13047 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13048 (const_int 1)
13049 (match_operand:DI 1 "const_0_to_63_operand" ""))
13050 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13051 (clobber (reg:CC FLAGS_REG))]
13052 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13053 "btc{q} %1,%0"
13054 [(set_attr "type" "alu1")])
13055
13056 ;; Allow Nocona to avoid these instructions if a register is available.
13057
13058 (define_peephole2
13059 [(match_scratch:DI 2 "r")
13060 (parallel [(set (zero_extract:DI
13061 (match_operand:DI 0 "register_operand" "")
13062 (const_int 1)
13063 (match_operand:DI 1 "const_0_to_63_operand" ""))
13064 (const_int 1))
13065 (clobber (reg:CC FLAGS_REG))])]
13066 "TARGET_64BIT && !TARGET_USE_BT"
13067 [(const_int 0)]
13068 {
13069 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13070 rtx op1;
13071
13072 if (HOST_BITS_PER_WIDE_INT >= 64)
13073 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13074 else if (i < HOST_BITS_PER_WIDE_INT)
13075 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13076 else
13077 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13078
13079 op1 = immed_double_const (lo, hi, DImode);
13080 if (i >= 31)
13081 {
13082 emit_move_insn (operands[2], op1);
13083 op1 = operands[2];
13084 }
13085
13086 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13087 DONE;
13088 })
13089
13090 (define_peephole2
13091 [(match_scratch:DI 2 "r")
13092 (parallel [(set (zero_extract:DI
13093 (match_operand:DI 0 "register_operand" "")
13094 (const_int 1)
13095 (match_operand:DI 1 "const_0_to_63_operand" ""))
13096 (const_int 0))
13097 (clobber (reg:CC FLAGS_REG))])]
13098 "TARGET_64BIT && !TARGET_USE_BT"
13099 [(const_int 0)]
13100 {
13101 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13102 rtx op1;
13103
13104 if (HOST_BITS_PER_WIDE_INT >= 64)
13105 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13106 else if (i < HOST_BITS_PER_WIDE_INT)
13107 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13108 else
13109 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13110
13111 op1 = immed_double_const (~lo, ~hi, DImode);
13112 if (i >= 32)
13113 {
13114 emit_move_insn (operands[2], op1);
13115 op1 = operands[2];
13116 }
13117
13118 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13119 DONE;
13120 })
13121
13122 (define_peephole2
13123 [(match_scratch:DI 2 "r")
13124 (parallel [(set (zero_extract:DI
13125 (match_operand:DI 0 "register_operand" "")
13126 (const_int 1)
13127 (match_operand:DI 1 "const_0_to_63_operand" ""))
13128 (not:DI (zero_extract:DI
13129 (match_dup 0) (const_int 1) (match_dup 1))))
13130 (clobber (reg:CC FLAGS_REG))])]
13131 "TARGET_64BIT && !TARGET_USE_BT"
13132 [(const_int 0)]
13133 {
13134 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13135 rtx op1;
13136
13137 if (HOST_BITS_PER_WIDE_INT >= 64)
13138 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13139 else if (i < HOST_BITS_PER_WIDE_INT)
13140 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13141 else
13142 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13143
13144 op1 = immed_double_const (lo, hi, DImode);
13145 if (i >= 31)
13146 {
13147 emit_move_insn (operands[2], op1);
13148 op1 = operands[2];
13149 }
13150
13151 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13152 DONE;
13153 })
13154 \f
13155 ;; Store-flag instructions.
13156
13157 ;; For all sCOND expanders, also expand the compare or test insn that
13158 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13159
13160 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13161 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13162 ;; way, which can later delete the movzx if only QImode is needed.
13163
13164 (define_expand "seq"
13165 [(set (match_operand:QI 0 "register_operand" "")
13166 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13167 ""
13168 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13169
13170 (define_expand "sne"
13171 [(set (match_operand:QI 0 "register_operand" "")
13172 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13173 ""
13174 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13175
13176 (define_expand "sgt"
13177 [(set (match_operand:QI 0 "register_operand" "")
13178 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13179 ""
13180 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13181
13182 (define_expand "sgtu"
13183 [(set (match_operand:QI 0 "register_operand" "")
13184 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13185 ""
13186 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13187
13188 (define_expand "slt"
13189 [(set (match_operand:QI 0 "register_operand" "")
13190 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13191 ""
13192 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13193
13194 (define_expand "sltu"
13195 [(set (match_operand:QI 0 "register_operand" "")
13196 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13197 ""
13198 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13199
13200 (define_expand "sge"
13201 [(set (match_operand:QI 0 "register_operand" "")
13202 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13203 ""
13204 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13205
13206 (define_expand "sgeu"
13207 [(set (match_operand:QI 0 "register_operand" "")
13208 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13209 ""
13210 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13211
13212 (define_expand "sle"
13213 [(set (match_operand:QI 0 "register_operand" "")
13214 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13215 ""
13216 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13217
13218 (define_expand "sleu"
13219 [(set (match_operand:QI 0 "register_operand" "")
13220 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13221 ""
13222 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13223
13224 (define_expand "sunordered"
13225 [(set (match_operand:QI 0 "register_operand" "")
13226 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13227 "TARGET_80387 || TARGET_SSE"
13228 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13229
13230 (define_expand "sordered"
13231 [(set (match_operand:QI 0 "register_operand" "")
13232 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13233 "TARGET_80387"
13234 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13235
13236 (define_expand "suneq"
13237 [(set (match_operand:QI 0 "register_operand" "")
13238 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13239 "TARGET_80387 || TARGET_SSE"
13240 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13241
13242 (define_expand "sunge"
13243 [(set (match_operand:QI 0 "register_operand" "")
13244 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13245 "TARGET_80387 || TARGET_SSE"
13246 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13247
13248 (define_expand "sungt"
13249 [(set (match_operand:QI 0 "register_operand" "")
13250 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13251 "TARGET_80387 || TARGET_SSE"
13252 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13253
13254 (define_expand "sunle"
13255 [(set (match_operand:QI 0 "register_operand" "")
13256 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257 "TARGET_80387 || TARGET_SSE"
13258 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13259
13260 (define_expand "sunlt"
13261 [(set (match_operand:QI 0 "register_operand" "")
13262 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263 "TARGET_80387 || TARGET_SSE"
13264 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13265
13266 (define_expand "sltgt"
13267 [(set (match_operand:QI 0 "register_operand" "")
13268 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13269 "TARGET_80387 || TARGET_SSE"
13270 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13271
13272 (define_insn "*setcc_1"
13273 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13274 (match_operator:QI 1 "ix86_comparison_operator"
13275 [(reg FLAGS_REG) (const_int 0)]))]
13276 ""
13277 "set%C1\t%0"
13278 [(set_attr "type" "setcc")
13279 (set_attr "mode" "QI")])
13280
13281 (define_insn "*setcc_2"
13282 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13283 (match_operator:QI 1 "ix86_comparison_operator"
13284 [(reg FLAGS_REG) (const_int 0)]))]
13285 ""
13286 "set%C1\t%0"
13287 [(set_attr "type" "setcc")
13288 (set_attr "mode" "QI")])
13289
13290 ;; In general it is not safe to assume too much about CCmode registers,
13291 ;; so simplify-rtx stops when it sees a second one. Under certain
13292 ;; conditions this is safe on x86, so help combine not create
13293 ;;
13294 ;; seta %al
13295 ;; testb %al, %al
13296 ;; sete %al
13297
13298 (define_split
13299 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13300 (ne:QI (match_operator 1 "ix86_comparison_operator"
13301 [(reg FLAGS_REG) (const_int 0)])
13302 (const_int 0)))]
13303 ""
13304 [(set (match_dup 0) (match_dup 1))]
13305 {
13306 PUT_MODE (operands[1], QImode);
13307 })
13308
13309 (define_split
13310 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13311 (ne:QI (match_operator 1 "ix86_comparison_operator"
13312 [(reg FLAGS_REG) (const_int 0)])
13313 (const_int 0)))]
13314 ""
13315 [(set (match_dup 0) (match_dup 1))]
13316 {
13317 PUT_MODE (operands[1], QImode);
13318 })
13319
13320 (define_split
13321 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13322 (eq:QI (match_operator 1 "ix86_comparison_operator"
13323 [(reg FLAGS_REG) (const_int 0)])
13324 (const_int 0)))]
13325 ""
13326 [(set (match_dup 0) (match_dup 1))]
13327 {
13328 rtx new_op1 = copy_rtx (operands[1]);
13329 operands[1] = new_op1;
13330 PUT_MODE (new_op1, QImode);
13331 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13332 GET_MODE (XEXP (new_op1, 0))));
13333
13334 /* Make sure that (a) the CCmode we have for the flags is strong
13335 enough for the reversed compare or (b) we have a valid FP compare. */
13336 if (! ix86_comparison_operator (new_op1, VOIDmode))
13337 FAIL;
13338 })
13339
13340 (define_split
13341 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13342 (eq:QI (match_operator 1 "ix86_comparison_operator"
13343 [(reg FLAGS_REG) (const_int 0)])
13344 (const_int 0)))]
13345 ""
13346 [(set (match_dup 0) (match_dup 1))]
13347 {
13348 rtx new_op1 = copy_rtx (operands[1]);
13349 operands[1] = new_op1;
13350 PUT_MODE (new_op1, QImode);
13351 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13352 GET_MODE (XEXP (new_op1, 0))));
13353
13354 /* Make sure that (a) the CCmode we have for the flags is strong
13355 enough for the reversed compare or (b) we have a valid FP compare. */
13356 if (! ix86_comparison_operator (new_op1, VOIDmode))
13357 FAIL;
13358 })
13359
13360 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13361 ;; subsequent logical operations are used to imitate conditional moves.
13362 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13363 ;; it directly.
13364
13365 (define_insn "*sse_setccsf"
13366 [(set (match_operand:SF 0 "register_operand" "=x")
13367 (match_operator:SF 1 "sse_comparison_operator"
13368 [(match_operand:SF 2 "register_operand" "0")
13369 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13370 "TARGET_SSE"
13371 "cmp%D1ss\t{%3, %0|%0, %3}"
13372 [(set_attr "type" "ssecmp")
13373 (set_attr "mode" "SF")])
13374
13375 (define_insn "*sse_setccdf"
13376 [(set (match_operand:DF 0 "register_operand" "=Y")
13377 (match_operator:DF 1 "sse_comparison_operator"
13378 [(match_operand:DF 2 "register_operand" "0")
13379 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13380 "TARGET_SSE2"
13381 "cmp%D1sd\t{%3, %0|%0, %3}"
13382 [(set_attr "type" "ssecmp")
13383 (set_attr "mode" "DF")])
13384 \f
13385 ;; Basic conditional jump instructions.
13386 ;; We ignore the overflow flag for signed branch instructions.
13387
13388 ;; For all bCOND expanders, also expand the compare or test insn that
13389 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13390
13391 (define_expand "beq"
13392 [(set (pc)
13393 (if_then_else (match_dup 1)
13394 (label_ref (match_operand 0 "" ""))
13395 (pc)))]
13396 ""
13397 "ix86_expand_branch (EQ, operands[0]); DONE;")
13398
13399 (define_expand "bne"
13400 [(set (pc)
13401 (if_then_else (match_dup 1)
13402 (label_ref (match_operand 0 "" ""))
13403 (pc)))]
13404 ""
13405 "ix86_expand_branch (NE, operands[0]); DONE;")
13406
13407 (define_expand "bgt"
13408 [(set (pc)
13409 (if_then_else (match_dup 1)
13410 (label_ref (match_operand 0 "" ""))
13411 (pc)))]
13412 ""
13413 "ix86_expand_branch (GT, operands[0]); DONE;")
13414
13415 (define_expand "bgtu"
13416 [(set (pc)
13417 (if_then_else (match_dup 1)
13418 (label_ref (match_operand 0 "" ""))
13419 (pc)))]
13420 ""
13421 "ix86_expand_branch (GTU, operands[0]); DONE;")
13422
13423 (define_expand "blt"
13424 [(set (pc)
13425 (if_then_else (match_dup 1)
13426 (label_ref (match_operand 0 "" ""))
13427 (pc)))]
13428 ""
13429 "ix86_expand_branch (LT, operands[0]); DONE;")
13430
13431 (define_expand "bltu"
13432 [(set (pc)
13433 (if_then_else (match_dup 1)
13434 (label_ref (match_operand 0 "" ""))
13435 (pc)))]
13436 ""
13437 "ix86_expand_branch (LTU, operands[0]); DONE;")
13438
13439 (define_expand "bge"
13440 [(set (pc)
13441 (if_then_else (match_dup 1)
13442 (label_ref (match_operand 0 "" ""))
13443 (pc)))]
13444 ""
13445 "ix86_expand_branch (GE, operands[0]); DONE;")
13446
13447 (define_expand "bgeu"
13448 [(set (pc)
13449 (if_then_else (match_dup 1)
13450 (label_ref (match_operand 0 "" ""))
13451 (pc)))]
13452 ""
13453 "ix86_expand_branch (GEU, operands[0]); DONE;")
13454
13455 (define_expand "ble"
13456 [(set (pc)
13457 (if_then_else (match_dup 1)
13458 (label_ref (match_operand 0 "" ""))
13459 (pc)))]
13460 ""
13461 "ix86_expand_branch (LE, operands[0]); DONE;")
13462
13463 (define_expand "bleu"
13464 [(set (pc)
13465 (if_then_else (match_dup 1)
13466 (label_ref (match_operand 0 "" ""))
13467 (pc)))]
13468 ""
13469 "ix86_expand_branch (LEU, operands[0]); DONE;")
13470
13471 (define_expand "bunordered"
13472 [(set (pc)
13473 (if_then_else (match_dup 1)
13474 (label_ref (match_operand 0 "" ""))
13475 (pc)))]
13476 "TARGET_80387 || TARGET_SSE_MATH"
13477 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13478
13479 (define_expand "bordered"
13480 [(set (pc)
13481 (if_then_else (match_dup 1)
13482 (label_ref (match_operand 0 "" ""))
13483 (pc)))]
13484 "TARGET_80387 || TARGET_SSE_MATH"
13485 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13486
13487 (define_expand "buneq"
13488 [(set (pc)
13489 (if_then_else (match_dup 1)
13490 (label_ref (match_operand 0 "" ""))
13491 (pc)))]
13492 "TARGET_80387 || TARGET_SSE_MATH"
13493 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13494
13495 (define_expand "bunge"
13496 [(set (pc)
13497 (if_then_else (match_dup 1)
13498 (label_ref (match_operand 0 "" ""))
13499 (pc)))]
13500 "TARGET_80387 || TARGET_SSE_MATH"
13501 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13502
13503 (define_expand "bungt"
13504 [(set (pc)
13505 (if_then_else (match_dup 1)
13506 (label_ref (match_operand 0 "" ""))
13507 (pc)))]
13508 "TARGET_80387 || TARGET_SSE_MATH"
13509 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13510
13511 (define_expand "bunle"
13512 [(set (pc)
13513 (if_then_else (match_dup 1)
13514 (label_ref (match_operand 0 "" ""))
13515 (pc)))]
13516 "TARGET_80387 || TARGET_SSE_MATH"
13517 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13518
13519 (define_expand "bunlt"
13520 [(set (pc)
13521 (if_then_else (match_dup 1)
13522 (label_ref (match_operand 0 "" ""))
13523 (pc)))]
13524 "TARGET_80387 || TARGET_SSE_MATH"
13525 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13526
13527 (define_expand "bltgt"
13528 [(set (pc)
13529 (if_then_else (match_dup 1)
13530 (label_ref (match_operand 0 "" ""))
13531 (pc)))]
13532 "TARGET_80387 || TARGET_SSE_MATH"
13533 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13534
13535 (define_insn "*jcc_1"
13536 [(set (pc)
13537 (if_then_else (match_operator 1 "ix86_comparison_operator"
13538 [(reg FLAGS_REG) (const_int 0)])
13539 (label_ref (match_operand 0 "" ""))
13540 (pc)))]
13541 ""
13542 "%+j%C1\t%l0"
13543 [(set_attr "type" "ibr")
13544 (set_attr "modrm" "0")
13545 (set (attr "length")
13546 (if_then_else (and (ge (minus (match_dup 0) (pc))
13547 (const_int -126))
13548 (lt (minus (match_dup 0) (pc))
13549 (const_int 128)))
13550 (const_int 2)
13551 (const_int 6)))])
13552
13553 (define_insn "*jcc_2"
13554 [(set (pc)
13555 (if_then_else (match_operator 1 "ix86_comparison_operator"
13556 [(reg FLAGS_REG) (const_int 0)])
13557 (pc)
13558 (label_ref (match_operand 0 "" ""))))]
13559 ""
13560 "%+j%c1\t%l0"
13561 [(set_attr "type" "ibr")
13562 (set_attr "modrm" "0")
13563 (set (attr "length")
13564 (if_then_else (and (ge (minus (match_dup 0) (pc))
13565 (const_int -126))
13566 (lt (minus (match_dup 0) (pc))
13567 (const_int 128)))
13568 (const_int 2)
13569 (const_int 6)))])
13570
13571 ;; In general it is not safe to assume too much about CCmode registers,
13572 ;; so simplify-rtx stops when it sees a second one. Under certain
13573 ;; conditions this is safe on x86, so help combine not create
13574 ;;
13575 ;; seta %al
13576 ;; testb %al, %al
13577 ;; je Lfoo
13578
13579 (define_split
13580 [(set (pc)
13581 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13582 [(reg FLAGS_REG) (const_int 0)])
13583 (const_int 0))
13584 (label_ref (match_operand 1 "" ""))
13585 (pc)))]
13586 ""
13587 [(set (pc)
13588 (if_then_else (match_dup 0)
13589 (label_ref (match_dup 1))
13590 (pc)))]
13591 {
13592 PUT_MODE (operands[0], VOIDmode);
13593 })
13594
13595 (define_split
13596 [(set (pc)
13597 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13598 [(reg FLAGS_REG) (const_int 0)])
13599 (const_int 0))
13600 (label_ref (match_operand 1 "" ""))
13601 (pc)))]
13602 ""
13603 [(set (pc)
13604 (if_then_else (match_dup 0)
13605 (label_ref (match_dup 1))
13606 (pc)))]
13607 {
13608 rtx new_op0 = copy_rtx (operands[0]);
13609 operands[0] = new_op0;
13610 PUT_MODE (new_op0, VOIDmode);
13611 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13612 GET_MODE (XEXP (new_op0, 0))));
13613
13614 /* Make sure that (a) the CCmode we have for the flags is strong
13615 enough for the reversed compare or (b) we have a valid FP compare. */
13616 if (! ix86_comparison_operator (new_op0, VOIDmode))
13617 FAIL;
13618 })
13619
13620 ;; Define combination compare-and-branch fp compare instructions to use
13621 ;; during early optimization. Splitting the operation apart early makes
13622 ;; for bad code when we want to reverse the operation.
13623
13624 (define_insn "*fp_jcc_1_mixed"
13625 [(set (pc)
13626 (if_then_else (match_operator 0 "comparison_operator"
13627 [(match_operand 1 "register_operand" "f,x")
13628 (match_operand 2 "nonimmediate_operand" "f,xm")])
13629 (label_ref (match_operand 3 "" ""))
13630 (pc)))
13631 (clobber (reg:CCFP FPSR_REG))
13632 (clobber (reg:CCFP FLAGS_REG))]
13633 "TARGET_MIX_SSE_I387
13634 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13635 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13636 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13637 "#")
13638
13639 (define_insn "*fp_jcc_1_sse"
13640 [(set (pc)
13641 (if_then_else (match_operator 0 "comparison_operator"
13642 [(match_operand 1 "register_operand" "x")
13643 (match_operand 2 "nonimmediate_operand" "xm")])
13644 (label_ref (match_operand 3 "" ""))
13645 (pc)))
13646 (clobber (reg:CCFP FPSR_REG))
13647 (clobber (reg:CCFP FLAGS_REG))]
13648 "TARGET_SSE_MATH
13649 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13650 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13651 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13652 "#")
13653
13654 (define_insn "*fp_jcc_1_387"
13655 [(set (pc)
13656 (if_then_else (match_operator 0 "comparison_operator"
13657 [(match_operand 1 "register_operand" "f")
13658 (match_operand 2 "register_operand" "f")])
13659 (label_ref (match_operand 3 "" ""))
13660 (pc)))
13661 (clobber (reg:CCFP FPSR_REG))
13662 (clobber (reg:CCFP FLAGS_REG))]
13663 "TARGET_CMOVE && TARGET_80387
13664 && FLOAT_MODE_P (GET_MODE (operands[1]))
13665 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13666 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13667 "#")
13668
13669 (define_insn "*fp_jcc_2_mixed"
13670 [(set (pc)
13671 (if_then_else (match_operator 0 "comparison_operator"
13672 [(match_operand 1 "register_operand" "f,x")
13673 (match_operand 2 "nonimmediate_operand" "f,xm")])
13674 (pc)
13675 (label_ref (match_operand 3 "" ""))))
13676 (clobber (reg:CCFP FPSR_REG))
13677 (clobber (reg:CCFP FLAGS_REG))]
13678 "TARGET_MIX_SSE_I387
13679 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13680 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13681 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13682 "#")
13683
13684 (define_insn "*fp_jcc_2_sse"
13685 [(set (pc)
13686 (if_then_else (match_operator 0 "comparison_operator"
13687 [(match_operand 1 "register_operand" "x")
13688 (match_operand 2 "nonimmediate_operand" "xm")])
13689 (pc)
13690 (label_ref (match_operand 3 "" ""))))
13691 (clobber (reg:CCFP FPSR_REG))
13692 (clobber (reg:CCFP FLAGS_REG))]
13693 "TARGET_SSE_MATH
13694 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13695 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13696 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13697 "#")
13698
13699 (define_insn "*fp_jcc_2_387"
13700 [(set (pc)
13701 (if_then_else (match_operator 0 "comparison_operator"
13702 [(match_operand 1 "register_operand" "f")
13703 (match_operand 2 "register_operand" "f")])
13704 (pc)
13705 (label_ref (match_operand 3 "" ""))))
13706 (clobber (reg:CCFP FPSR_REG))
13707 (clobber (reg:CCFP FLAGS_REG))]
13708 "TARGET_CMOVE && TARGET_80387
13709 && FLOAT_MODE_P (GET_MODE (operands[1]))
13710 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13711 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13712 "#")
13713
13714 (define_insn "*fp_jcc_3_387"
13715 [(set (pc)
13716 (if_then_else (match_operator 0 "comparison_operator"
13717 [(match_operand 1 "register_operand" "f")
13718 (match_operand 2 "nonimmediate_operand" "fm")])
13719 (label_ref (match_operand 3 "" ""))
13720 (pc)))
13721 (clobber (reg:CCFP FPSR_REG))
13722 (clobber (reg:CCFP FLAGS_REG))
13723 (clobber (match_scratch:HI 4 "=a"))]
13724 "TARGET_80387
13725 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13726 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13727 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13728 && SELECT_CC_MODE (GET_CODE (operands[0]),
13729 operands[1], operands[2]) == CCFPmode
13730 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13731 "#")
13732
13733 (define_insn "*fp_jcc_4_387"
13734 [(set (pc)
13735 (if_then_else (match_operator 0 "comparison_operator"
13736 [(match_operand 1 "register_operand" "f")
13737 (match_operand 2 "nonimmediate_operand" "fm")])
13738 (pc)
13739 (label_ref (match_operand 3 "" ""))))
13740 (clobber (reg:CCFP FPSR_REG))
13741 (clobber (reg:CCFP FLAGS_REG))
13742 (clobber (match_scratch:HI 4 "=a"))]
13743 "TARGET_80387
13744 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13745 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13746 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13747 && SELECT_CC_MODE (GET_CODE (operands[0]),
13748 operands[1], operands[2]) == CCFPmode
13749 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13750 "#")
13751
13752 (define_insn "*fp_jcc_5_387"
13753 [(set (pc)
13754 (if_then_else (match_operator 0 "comparison_operator"
13755 [(match_operand 1 "register_operand" "f")
13756 (match_operand 2 "register_operand" "f")])
13757 (label_ref (match_operand 3 "" ""))
13758 (pc)))
13759 (clobber (reg:CCFP FPSR_REG))
13760 (clobber (reg:CCFP FLAGS_REG))
13761 (clobber (match_scratch:HI 4 "=a"))]
13762 "TARGET_80387
13763 && FLOAT_MODE_P (GET_MODE (operands[1]))
13764 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13765 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13766 "#")
13767
13768 (define_insn "*fp_jcc_6_387"
13769 [(set (pc)
13770 (if_then_else (match_operator 0 "comparison_operator"
13771 [(match_operand 1 "register_operand" "f")
13772 (match_operand 2 "register_operand" "f")])
13773 (pc)
13774 (label_ref (match_operand 3 "" ""))))
13775 (clobber (reg:CCFP FPSR_REG))
13776 (clobber (reg:CCFP FLAGS_REG))
13777 (clobber (match_scratch:HI 4 "=a"))]
13778 "TARGET_80387
13779 && FLOAT_MODE_P (GET_MODE (operands[1]))
13780 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13781 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13782 "#")
13783
13784 (define_insn "*fp_jcc_7_387"
13785 [(set (pc)
13786 (if_then_else (match_operator 0 "comparison_operator"
13787 [(match_operand 1 "register_operand" "f")
13788 (match_operand 2 "const0_operand" "X")])
13789 (label_ref (match_operand 3 "" ""))
13790 (pc)))
13791 (clobber (reg:CCFP FPSR_REG))
13792 (clobber (reg:CCFP FLAGS_REG))
13793 (clobber (match_scratch:HI 4 "=a"))]
13794 "TARGET_80387
13795 && FLOAT_MODE_P (GET_MODE (operands[1]))
13796 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13797 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13798 && SELECT_CC_MODE (GET_CODE (operands[0]),
13799 operands[1], operands[2]) == CCFPmode
13800 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13801 "#")
13802
13803 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13804 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13805 ;; with a precedence over other operators and is always put in the first
13806 ;; place. Swap condition and operands to match ficom instruction.
13807
13808 (define_insn "*fp_jcc_8<mode>_387"
13809 [(set (pc)
13810 (if_then_else (match_operator 0 "comparison_operator"
13811 [(match_operator 1 "float_operator"
13812 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13813 (match_operand 3 "register_operand" "f,f")])
13814 (label_ref (match_operand 4 "" ""))
13815 (pc)))
13816 (clobber (reg:CCFP FPSR_REG))
13817 (clobber (reg:CCFP FLAGS_REG))
13818 (clobber (match_scratch:HI 5 "=a,a"))]
13819 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13820 && FLOAT_MODE_P (GET_MODE (operands[3]))
13821 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13822 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13823 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13824 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13825 "#")
13826
13827 (define_split
13828 [(set (pc)
13829 (if_then_else (match_operator 0 "comparison_operator"
13830 [(match_operand 1 "register_operand" "")
13831 (match_operand 2 "nonimmediate_operand" "")])
13832 (match_operand 3 "" "")
13833 (match_operand 4 "" "")))
13834 (clobber (reg:CCFP FPSR_REG))
13835 (clobber (reg:CCFP FLAGS_REG))]
13836 "reload_completed"
13837 [(const_int 0)]
13838 {
13839 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13840 operands[3], operands[4], NULL_RTX, NULL_RTX);
13841 DONE;
13842 })
13843
13844 (define_split
13845 [(set (pc)
13846 (if_then_else (match_operator 0 "comparison_operator"
13847 [(match_operand 1 "register_operand" "")
13848 (match_operand 2 "general_operand" "")])
13849 (match_operand 3 "" "")
13850 (match_operand 4 "" "")))
13851 (clobber (reg:CCFP FPSR_REG))
13852 (clobber (reg:CCFP FLAGS_REG))
13853 (clobber (match_scratch:HI 5 "=a"))]
13854 "reload_completed"
13855 [(const_int 0)]
13856 {
13857 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13858 operands[3], operands[4], operands[5], NULL_RTX);
13859 DONE;
13860 })
13861
13862 (define_split
13863 [(set (pc)
13864 (if_then_else (match_operator 0 "comparison_operator"
13865 [(match_operator 1 "float_operator"
13866 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13867 (match_operand 3 "register_operand" "")])
13868 (match_operand 4 "" "")
13869 (match_operand 5 "" "")))
13870 (clobber (reg:CCFP FPSR_REG))
13871 (clobber (reg:CCFP FLAGS_REG))
13872 (clobber (match_scratch:HI 6 "=a"))]
13873 "reload_completed"
13874 [(const_int 0)]
13875 {
13876 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13877 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13878 operands[3], operands[7],
13879 operands[4], operands[5], operands[6], NULL_RTX);
13880 DONE;
13881 })
13882
13883 ;; %%% Kill this when reload knows how to do it.
13884 (define_split
13885 [(set (pc)
13886 (if_then_else (match_operator 0 "comparison_operator"
13887 [(match_operator 1 "float_operator"
13888 [(match_operand:X87MODEI12 2 "register_operand" "")])
13889 (match_operand 3 "register_operand" "")])
13890 (match_operand 4 "" "")
13891 (match_operand 5 "" "")))
13892 (clobber (reg:CCFP FPSR_REG))
13893 (clobber (reg:CCFP FLAGS_REG))
13894 (clobber (match_scratch:HI 6 "=a"))]
13895 "reload_completed"
13896 [(const_int 0)]
13897 {
13898 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13899 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13900 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13901 operands[3], operands[7],
13902 operands[4], operands[5], operands[6], operands[2]);
13903 DONE;
13904 })
13905 \f
13906 ;; Unconditional and other jump instructions
13907
13908 (define_insn "jump"
13909 [(set (pc)
13910 (label_ref (match_operand 0 "" "")))]
13911 ""
13912 "jmp\t%l0"
13913 [(set_attr "type" "ibr")
13914 (set (attr "length")
13915 (if_then_else (and (ge (minus (match_dup 0) (pc))
13916 (const_int -126))
13917 (lt (minus (match_dup 0) (pc))
13918 (const_int 128)))
13919 (const_int 2)
13920 (const_int 5)))
13921 (set_attr "modrm" "0")])
13922
13923 (define_expand "indirect_jump"
13924 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13925 ""
13926 "")
13927
13928 (define_insn "*indirect_jump"
13929 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13930 "!TARGET_64BIT"
13931 "jmp\t%A0"
13932 [(set_attr "type" "ibr")
13933 (set_attr "length_immediate" "0")])
13934
13935 (define_insn "*indirect_jump_rtx64"
13936 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13937 "TARGET_64BIT"
13938 "jmp\t%A0"
13939 [(set_attr "type" "ibr")
13940 (set_attr "length_immediate" "0")])
13941
13942 (define_expand "tablejump"
13943 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13944 (use (label_ref (match_operand 1 "" "")))])]
13945 ""
13946 {
13947 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13948 relative. Convert the relative address to an absolute address. */
13949 if (flag_pic)
13950 {
13951 rtx op0, op1;
13952 enum rtx_code code;
13953
13954 if (TARGET_64BIT)
13955 {
13956 code = PLUS;
13957 op0 = operands[0];
13958 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13959 }
13960 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13961 {
13962 code = PLUS;
13963 op0 = operands[0];
13964 op1 = pic_offset_table_rtx;
13965 }
13966 else
13967 {
13968 code = MINUS;
13969 op0 = pic_offset_table_rtx;
13970 op1 = operands[0];
13971 }
13972
13973 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13974 OPTAB_DIRECT);
13975 }
13976 })
13977
13978 (define_insn "*tablejump_1"
13979 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13980 (use (label_ref (match_operand 1 "" "")))]
13981 "!TARGET_64BIT"
13982 "jmp\t%A0"
13983 [(set_attr "type" "ibr")
13984 (set_attr "length_immediate" "0")])
13985
13986 (define_insn "*tablejump_1_rtx64"
13987 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13988 (use (label_ref (match_operand 1 "" "")))]
13989 "TARGET_64BIT"
13990 "jmp\t%A0"
13991 [(set_attr "type" "ibr")
13992 (set_attr "length_immediate" "0")])
13993 \f
13994 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13995
13996 (define_peephole2
13997 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13998 (set (match_operand:QI 1 "register_operand" "")
13999 (match_operator:QI 2 "ix86_comparison_operator"
14000 [(reg FLAGS_REG) (const_int 0)]))
14001 (set (match_operand 3 "q_regs_operand" "")
14002 (zero_extend (match_dup 1)))]
14003 "(peep2_reg_dead_p (3, operands[1])
14004 || operands_match_p (operands[1], operands[3]))
14005 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14006 [(set (match_dup 4) (match_dup 0))
14007 (set (strict_low_part (match_dup 5))
14008 (match_dup 2))]
14009 {
14010 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14011 operands[5] = gen_lowpart (QImode, operands[3]);
14012 ix86_expand_clear (operands[3]);
14013 })
14014
14015 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14016
14017 (define_peephole2
14018 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14019 (set (match_operand:QI 1 "register_operand" "")
14020 (match_operator:QI 2 "ix86_comparison_operator"
14021 [(reg FLAGS_REG) (const_int 0)]))
14022 (parallel [(set (match_operand 3 "q_regs_operand" "")
14023 (zero_extend (match_dup 1)))
14024 (clobber (reg:CC FLAGS_REG))])]
14025 "(peep2_reg_dead_p (3, operands[1])
14026 || operands_match_p (operands[1], operands[3]))
14027 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14028 [(set (match_dup 4) (match_dup 0))
14029 (set (strict_low_part (match_dup 5))
14030 (match_dup 2))]
14031 {
14032 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14033 operands[5] = gen_lowpart (QImode, operands[3]);
14034 ix86_expand_clear (operands[3]);
14035 })
14036 \f
14037 ;; Call instructions.
14038
14039 ;; The predicates normally associated with named expanders are not properly
14040 ;; checked for calls. This is a bug in the generic code, but it isn't that
14041 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14042
14043 ;; Call subroutine returning no value.
14044
14045 (define_expand "call_pop"
14046 [(parallel [(call (match_operand:QI 0 "" "")
14047 (match_operand:SI 1 "" ""))
14048 (set (reg:SI SP_REG)
14049 (plus:SI (reg:SI SP_REG)
14050 (match_operand:SI 3 "" "")))])]
14051 "!TARGET_64BIT"
14052 {
14053 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14054 DONE;
14055 })
14056
14057 (define_insn "*call_pop_0"
14058 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14059 (match_operand:SI 1 "" ""))
14060 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14061 (match_operand:SI 2 "immediate_operand" "")))]
14062 "!TARGET_64BIT"
14063 {
14064 if (SIBLING_CALL_P (insn))
14065 return "jmp\t%P0";
14066 else
14067 return "call\t%P0";
14068 }
14069 [(set_attr "type" "call")])
14070
14071 (define_insn "*call_pop_1"
14072 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14073 (match_operand:SI 1 "" ""))
14074 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14075 (match_operand:SI 2 "immediate_operand" "i")))]
14076 "!TARGET_64BIT"
14077 {
14078 if (constant_call_address_operand (operands[0], Pmode))
14079 {
14080 if (SIBLING_CALL_P (insn))
14081 return "jmp\t%P0";
14082 else
14083 return "call\t%P0";
14084 }
14085 if (SIBLING_CALL_P (insn))
14086 return "jmp\t%A0";
14087 else
14088 return "call\t%A0";
14089 }
14090 [(set_attr "type" "call")])
14091
14092 (define_expand "call"
14093 [(call (match_operand:QI 0 "" "")
14094 (match_operand 1 "" ""))
14095 (use (match_operand 2 "" ""))]
14096 ""
14097 {
14098 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14099 DONE;
14100 })
14101
14102 (define_expand "sibcall"
14103 [(call (match_operand:QI 0 "" "")
14104 (match_operand 1 "" ""))
14105 (use (match_operand 2 "" ""))]
14106 ""
14107 {
14108 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14109 DONE;
14110 })
14111
14112 (define_insn "*call_0"
14113 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14114 (match_operand 1 "" ""))]
14115 ""
14116 {
14117 if (SIBLING_CALL_P (insn))
14118 return "jmp\t%P0";
14119 else
14120 return "call\t%P0";
14121 }
14122 [(set_attr "type" "call")])
14123
14124 (define_insn "*call_1"
14125 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14126 (match_operand 1 "" ""))]
14127 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14128 {
14129 if (constant_call_address_operand (operands[0], Pmode))
14130 return "call\t%P0";
14131 return "call\t%A0";
14132 }
14133 [(set_attr "type" "call")])
14134
14135 (define_insn "*sibcall_1"
14136 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14137 (match_operand 1 "" ""))]
14138 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14139 {
14140 if (constant_call_address_operand (operands[0], Pmode))
14141 return "jmp\t%P0";
14142 return "jmp\t%A0";
14143 }
14144 [(set_attr "type" "call")])
14145
14146 (define_insn "*call_1_rex64"
14147 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14148 (match_operand 1 "" ""))]
14149 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14150 {
14151 if (constant_call_address_operand (operands[0], Pmode))
14152 return "call\t%P0";
14153 return "call\t%A0";
14154 }
14155 [(set_attr "type" "call")])
14156
14157 (define_insn "*sibcall_1_rex64"
14158 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14159 (match_operand 1 "" ""))]
14160 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14161 "jmp\t%P0"
14162 [(set_attr "type" "call")])
14163
14164 (define_insn "*sibcall_1_rex64_v"
14165 [(call (mem:QI (reg:DI 40))
14166 (match_operand 0 "" ""))]
14167 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14168 "jmp\t*%%r11"
14169 [(set_attr "type" "call")])
14170
14171
14172 ;; Call subroutine, returning value in operand 0
14173
14174 (define_expand "call_value_pop"
14175 [(parallel [(set (match_operand 0 "" "")
14176 (call (match_operand:QI 1 "" "")
14177 (match_operand:SI 2 "" "")))
14178 (set (reg:SI SP_REG)
14179 (plus:SI (reg:SI SP_REG)
14180 (match_operand:SI 4 "" "")))])]
14181 "!TARGET_64BIT"
14182 {
14183 ix86_expand_call (operands[0], operands[1], operands[2],
14184 operands[3], operands[4], 0);
14185 DONE;
14186 })
14187
14188 (define_expand "call_value"
14189 [(set (match_operand 0 "" "")
14190 (call (match_operand:QI 1 "" "")
14191 (match_operand:SI 2 "" "")))
14192 (use (match_operand:SI 3 "" ""))]
14193 ;; Operand 2 not used on the i386.
14194 ""
14195 {
14196 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14197 DONE;
14198 })
14199
14200 (define_expand "sibcall_value"
14201 [(set (match_operand 0 "" "")
14202 (call (match_operand:QI 1 "" "")
14203 (match_operand:SI 2 "" "")))
14204 (use (match_operand:SI 3 "" ""))]
14205 ;; Operand 2 not used on the i386.
14206 ""
14207 {
14208 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14209 DONE;
14210 })
14211
14212 ;; Call subroutine returning any type.
14213
14214 (define_expand "untyped_call"
14215 [(parallel [(call (match_operand 0 "" "")
14216 (const_int 0))
14217 (match_operand 1 "" "")
14218 (match_operand 2 "" "")])]
14219 ""
14220 {
14221 int i;
14222
14223 /* In order to give reg-stack an easier job in validating two
14224 coprocessor registers as containing a possible return value,
14225 simply pretend the untyped call returns a complex long double
14226 value. */
14227
14228 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14229 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14230 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14231 NULL, 0);
14232
14233 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14234 {
14235 rtx set = XVECEXP (operands[2], 0, i);
14236 emit_move_insn (SET_DEST (set), SET_SRC (set));
14237 }
14238
14239 /* The optimizer does not know that the call sets the function value
14240 registers we stored in the result block. We avoid problems by
14241 claiming that all hard registers are used and clobbered at this
14242 point. */
14243 emit_insn (gen_blockage (const0_rtx));
14244
14245 DONE;
14246 })
14247 \f
14248 ;; Prologue and epilogue instructions
14249
14250 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14251 ;; all of memory. This blocks insns from being moved across this point.
14252
14253 (define_insn "blockage"
14254 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14255 ""
14256 ""
14257 [(set_attr "length" "0")])
14258
14259 ;; Insn emitted into the body of a function to return from a function.
14260 ;; This is only done if the function's epilogue is known to be simple.
14261 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14262
14263 (define_expand "return"
14264 [(return)]
14265 "ix86_can_use_return_insn_p ()"
14266 {
14267 if (current_function_pops_args)
14268 {
14269 rtx popc = GEN_INT (current_function_pops_args);
14270 emit_jump_insn (gen_return_pop_internal (popc));
14271 DONE;
14272 }
14273 })
14274
14275 (define_insn "return_internal"
14276 [(return)]
14277 "reload_completed"
14278 "ret"
14279 [(set_attr "length" "1")
14280 (set_attr "length_immediate" "0")
14281 (set_attr "modrm" "0")])
14282
14283 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14284 ;; instruction Athlon and K8 have.
14285
14286 (define_insn "return_internal_long"
14287 [(return)
14288 (unspec [(const_int 0)] UNSPEC_REP)]
14289 "reload_completed"
14290 "rep {;} ret"
14291 [(set_attr "length" "1")
14292 (set_attr "length_immediate" "0")
14293 (set_attr "prefix_rep" "1")
14294 (set_attr "modrm" "0")])
14295
14296 (define_insn "return_pop_internal"
14297 [(return)
14298 (use (match_operand:SI 0 "const_int_operand" ""))]
14299 "reload_completed"
14300 "ret\t%0"
14301 [(set_attr "length" "3")
14302 (set_attr "length_immediate" "2")
14303 (set_attr "modrm" "0")])
14304
14305 (define_insn "return_indirect_internal"
14306 [(return)
14307 (use (match_operand:SI 0 "register_operand" "r"))]
14308 "reload_completed"
14309 "jmp\t%A0"
14310 [(set_attr "type" "ibr")
14311 (set_attr "length_immediate" "0")])
14312
14313 (define_insn "nop"
14314 [(const_int 0)]
14315 ""
14316 "nop"
14317 [(set_attr "length" "1")
14318 (set_attr "length_immediate" "0")
14319 (set_attr "modrm" "0")])
14320
14321 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14322 ;; branch prediction penalty for the third jump in a 16-byte
14323 ;; block on K8.
14324
14325 (define_insn "align"
14326 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14327 ""
14328 {
14329 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14330 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14331 #else
14332 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14333 The align insn is used to avoid 3 jump instructions in the row to improve
14334 branch prediction and the benefits hardly outweigh the cost of extra 8
14335 nops on the average inserted by full alignment pseudo operation. */
14336 #endif
14337 return "";
14338 }
14339 [(set_attr "length" "16")])
14340
14341 (define_expand "prologue"
14342 [(const_int 1)]
14343 ""
14344 "ix86_expand_prologue (); DONE;")
14345
14346 (define_insn "set_got"
14347 [(set (match_operand:SI 0 "register_operand" "=r")
14348 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14349 (clobber (reg:CC FLAGS_REG))]
14350 "!TARGET_64BIT"
14351 { return output_set_got (operands[0], NULL_RTX); }
14352 [(set_attr "type" "multi")
14353 (set_attr "length" "12")])
14354
14355 (define_insn "set_got_labelled"
14356 [(set (match_operand:SI 0 "register_operand" "=r")
14357 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14358 UNSPEC_SET_GOT))
14359 (clobber (reg:CC FLAGS_REG))]
14360 "!TARGET_64BIT"
14361 { return output_set_got (operands[0], operands[1]); }
14362 [(set_attr "type" "multi")
14363 (set_attr "length" "12")])
14364
14365 (define_insn "set_got_rex64"
14366 [(set (match_operand:DI 0 "register_operand" "=r")
14367 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14368 "TARGET_64BIT"
14369 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14370 [(set_attr "type" "lea")
14371 (set_attr "length" "6")])
14372
14373 (define_expand "epilogue"
14374 [(const_int 1)]
14375 ""
14376 "ix86_expand_epilogue (1); DONE;")
14377
14378 (define_expand "sibcall_epilogue"
14379 [(const_int 1)]
14380 ""
14381 "ix86_expand_epilogue (0); DONE;")
14382
14383 (define_expand "eh_return"
14384 [(use (match_operand 0 "register_operand" ""))]
14385 ""
14386 {
14387 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14388
14389 /* Tricky bit: we write the address of the handler to which we will
14390 be returning into someone else's stack frame, one word below the
14391 stack address we wish to restore. */
14392 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14393 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14394 tmp = gen_rtx_MEM (Pmode, tmp);
14395 emit_move_insn (tmp, ra);
14396
14397 if (Pmode == SImode)
14398 emit_jump_insn (gen_eh_return_si (sa));
14399 else
14400 emit_jump_insn (gen_eh_return_di (sa));
14401 emit_barrier ();
14402 DONE;
14403 })
14404
14405 (define_insn_and_split "eh_return_si"
14406 [(set (pc)
14407 (unspec [(match_operand:SI 0 "register_operand" "c")]
14408 UNSPEC_EH_RETURN))]
14409 "!TARGET_64BIT"
14410 "#"
14411 "reload_completed"
14412 [(const_int 1)]
14413 "ix86_expand_epilogue (2); DONE;")
14414
14415 (define_insn_and_split "eh_return_di"
14416 [(set (pc)
14417 (unspec [(match_operand:DI 0 "register_operand" "c")]
14418 UNSPEC_EH_RETURN))]
14419 "TARGET_64BIT"
14420 "#"
14421 "reload_completed"
14422 [(const_int 1)]
14423 "ix86_expand_epilogue (2); DONE;")
14424
14425 (define_insn "leave"
14426 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14427 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14428 (clobber (mem:BLK (scratch)))]
14429 "!TARGET_64BIT"
14430 "leave"
14431 [(set_attr "type" "leave")])
14432
14433 (define_insn "leave_rex64"
14434 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14435 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14436 (clobber (mem:BLK (scratch)))]
14437 "TARGET_64BIT"
14438 "leave"
14439 [(set_attr "type" "leave")])
14440 \f
14441 (define_expand "ffssi2"
14442 [(parallel
14443 [(set (match_operand:SI 0 "register_operand" "")
14444 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14445 (clobber (match_scratch:SI 2 ""))
14446 (clobber (reg:CC FLAGS_REG))])]
14447 ""
14448 "")
14449
14450 (define_insn_and_split "*ffs_cmove"
14451 [(set (match_operand:SI 0 "register_operand" "=r")
14452 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14453 (clobber (match_scratch:SI 2 "=&r"))
14454 (clobber (reg:CC FLAGS_REG))]
14455 "TARGET_CMOVE"
14456 "#"
14457 "&& reload_completed"
14458 [(set (match_dup 2) (const_int -1))
14459 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14460 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14461 (set (match_dup 0) (if_then_else:SI
14462 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14463 (match_dup 2)
14464 (match_dup 0)))
14465 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14466 (clobber (reg:CC FLAGS_REG))])]
14467 "")
14468
14469 (define_insn_and_split "*ffs_no_cmove"
14470 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14471 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14472 (clobber (match_scratch:SI 2 "=&q"))
14473 (clobber (reg:CC FLAGS_REG))]
14474 ""
14475 "#"
14476 "reload_completed"
14477 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14478 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14479 (set (strict_low_part (match_dup 3))
14480 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14481 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14482 (clobber (reg:CC FLAGS_REG))])
14483 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14484 (clobber (reg:CC FLAGS_REG))])
14485 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14486 (clobber (reg:CC FLAGS_REG))])]
14487 {
14488 operands[3] = gen_lowpart (QImode, operands[2]);
14489 ix86_expand_clear (operands[2]);
14490 })
14491
14492 (define_insn "*ffssi_1"
14493 [(set (reg:CCZ FLAGS_REG)
14494 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14495 (const_int 0)))
14496 (set (match_operand:SI 0 "register_operand" "=r")
14497 (ctz:SI (match_dup 1)))]
14498 ""
14499 "bsf{l}\t{%1, %0|%0, %1}"
14500 [(set_attr "prefix_0f" "1")])
14501
14502 (define_expand "ffsdi2"
14503 [(parallel
14504 [(set (match_operand:DI 0 "register_operand" "")
14505 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14506 (clobber (match_scratch:DI 2 ""))
14507 (clobber (reg:CC FLAGS_REG))])]
14508 "TARGET_64BIT && TARGET_CMOVE"
14509 "")
14510
14511 (define_insn_and_split "*ffs_rex64"
14512 [(set (match_operand:DI 0 "register_operand" "=r")
14513 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14514 (clobber (match_scratch:DI 2 "=&r"))
14515 (clobber (reg:CC FLAGS_REG))]
14516 "TARGET_64BIT && TARGET_CMOVE"
14517 "#"
14518 "&& reload_completed"
14519 [(set (match_dup 2) (const_int -1))
14520 (parallel [(set (reg:CCZ FLAGS_REG)
14521 (compare:CCZ (match_dup 1) (const_int 0)))
14522 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14523 (set (match_dup 0) (if_then_else:DI
14524 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14525 (match_dup 2)
14526 (match_dup 0)))
14527 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14528 (clobber (reg:CC FLAGS_REG))])]
14529 "")
14530
14531 (define_insn "*ffsdi_1"
14532 [(set (reg:CCZ FLAGS_REG)
14533 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14534 (const_int 0)))
14535 (set (match_operand:DI 0 "register_operand" "=r")
14536 (ctz:DI (match_dup 1)))]
14537 "TARGET_64BIT"
14538 "bsf{q}\t{%1, %0|%0, %1}"
14539 [(set_attr "prefix_0f" "1")])
14540
14541 (define_insn "ctzsi2"
14542 [(set (match_operand:SI 0 "register_operand" "=r")
14543 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14544 (clobber (reg:CC FLAGS_REG))]
14545 ""
14546 "bsf{l}\t{%1, %0|%0, %1}"
14547 [(set_attr "prefix_0f" "1")])
14548
14549 (define_insn "ctzdi2"
14550 [(set (match_operand:DI 0 "register_operand" "=r")
14551 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14552 (clobber (reg:CC FLAGS_REG))]
14553 "TARGET_64BIT"
14554 "bsf{q}\t{%1, %0|%0, %1}"
14555 [(set_attr "prefix_0f" "1")])
14556
14557 (define_expand "clzsi2"
14558 [(parallel
14559 [(set (match_operand:SI 0 "register_operand" "")
14560 (minus:SI (const_int 31)
14561 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14562 (clobber (reg:CC FLAGS_REG))])
14563 (parallel
14564 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14565 (clobber (reg:CC FLAGS_REG))])]
14566 ""
14567 "")
14568
14569 (define_insn "*bsr"
14570 [(set (match_operand:SI 0 "register_operand" "=r")
14571 (minus:SI (const_int 31)
14572 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14573 (clobber (reg:CC FLAGS_REG))]
14574 ""
14575 "bsr{l}\t{%1, %0|%0, %1}"
14576 [(set_attr "prefix_0f" "1")])
14577
14578 (define_expand "clzdi2"
14579 [(parallel
14580 [(set (match_operand:DI 0 "register_operand" "")
14581 (minus:DI (const_int 63)
14582 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14583 (clobber (reg:CC FLAGS_REG))])
14584 (parallel
14585 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14586 (clobber (reg:CC FLAGS_REG))])]
14587 "TARGET_64BIT"
14588 "")
14589
14590 (define_insn "*bsr_rex64"
14591 [(set (match_operand:DI 0 "register_operand" "=r")
14592 (minus:DI (const_int 63)
14593 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14594 (clobber (reg:CC FLAGS_REG))]
14595 "TARGET_64BIT"
14596 "bsr{q}\t{%1, %0|%0, %1}"
14597 [(set_attr "prefix_0f" "1")])
14598 \f
14599 ;; Thread-local storage patterns for ELF.
14600 ;;
14601 ;; Note that these code sequences must appear exactly as shown
14602 ;; in order to allow linker relaxation.
14603
14604 (define_insn "*tls_global_dynamic_32_gnu"
14605 [(set (match_operand:SI 0 "register_operand" "=a")
14606 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14607 (match_operand:SI 2 "tls_symbolic_operand" "")
14608 (match_operand:SI 3 "call_insn_operand" "")]
14609 UNSPEC_TLS_GD))
14610 (clobber (match_scratch:SI 4 "=d"))
14611 (clobber (match_scratch:SI 5 "=c"))
14612 (clobber (reg:CC FLAGS_REG))]
14613 "!TARGET_64BIT && TARGET_GNU_TLS"
14614 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14615 [(set_attr "type" "multi")
14616 (set_attr "length" "12")])
14617
14618 (define_insn "*tls_global_dynamic_32_sun"
14619 [(set (match_operand:SI 0 "register_operand" "=a")
14620 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14621 (match_operand:SI 2 "tls_symbolic_operand" "")
14622 (match_operand:SI 3 "call_insn_operand" "")]
14623 UNSPEC_TLS_GD))
14624 (clobber (match_scratch:SI 4 "=d"))
14625 (clobber (match_scratch:SI 5 "=c"))
14626 (clobber (reg:CC FLAGS_REG))]
14627 "!TARGET_64BIT && TARGET_SUN_TLS"
14628 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14629 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14630 [(set_attr "type" "multi")
14631 (set_attr "length" "14")])
14632
14633 (define_expand "tls_global_dynamic_32"
14634 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14635 (unspec:SI
14636 [(match_dup 2)
14637 (match_operand:SI 1 "tls_symbolic_operand" "")
14638 (match_dup 3)]
14639 UNSPEC_TLS_GD))
14640 (clobber (match_scratch:SI 4 ""))
14641 (clobber (match_scratch:SI 5 ""))
14642 (clobber (reg:CC FLAGS_REG))])]
14643 ""
14644 {
14645 if (flag_pic)
14646 operands[2] = pic_offset_table_rtx;
14647 else
14648 {
14649 operands[2] = gen_reg_rtx (Pmode);
14650 emit_insn (gen_set_got (operands[2]));
14651 }
14652 if (TARGET_GNU2_TLS)
14653 {
14654 emit_insn (gen_tls_dynamic_gnu2_32
14655 (operands[0], operands[1], operands[2]));
14656 DONE;
14657 }
14658 operands[3] = ix86_tls_get_addr ();
14659 })
14660
14661 (define_insn "*tls_global_dynamic_64"
14662 [(set (match_operand:DI 0 "register_operand" "=a")
14663 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14664 (match_operand:DI 3 "" "")))
14665 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14666 UNSPEC_TLS_GD)]
14667 "TARGET_64BIT"
14668 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14669 [(set_attr "type" "multi")
14670 (set_attr "length" "16")])
14671
14672 (define_expand "tls_global_dynamic_64"
14673 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14674 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14675 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14676 UNSPEC_TLS_GD)])]
14677 ""
14678 {
14679 if (TARGET_GNU2_TLS)
14680 {
14681 emit_insn (gen_tls_dynamic_gnu2_64
14682 (operands[0], operands[1]));
14683 DONE;
14684 }
14685 operands[2] = ix86_tls_get_addr ();
14686 })
14687
14688 (define_insn "*tls_local_dynamic_base_32_gnu"
14689 [(set (match_operand:SI 0 "register_operand" "=a")
14690 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14691 (match_operand:SI 2 "call_insn_operand" "")]
14692 UNSPEC_TLS_LD_BASE))
14693 (clobber (match_scratch:SI 3 "=d"))
14694 (clobber (match_scratch:SI 4 "=c"))
14695 (clobber (reg:CC FLAGS_REG))]
14696 "!TARGET_64BIT && TARGET_GNU_TLS"
14697 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14698 [(set_attr "type" "multi")
14699 (set_attr "length" "11")])
14700
14701 (define_insn "*tls_local_dynamic_base_32_sun"
14702 [(set (match_operand:SI 0 "register_operand" "=a")
14703 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14704 (match_operand:SI 2 "call_insn_operand" "")]
14705 UNSPEC_TLS_LD_BASE))
14706 (clobber (match_scratch:SI 3 "=d"))
14707 (clobber (match_scratch:SI 4 "=c"))
14708 (clobber (reg:CC FLAGS_REG))]
14709 "!TARGET_64BIT && TARGET_SUN_TLS"
14710 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14711 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14712 [(set_attr "type" "multi")
14713 (set_attr "length" "13")])
14714
14715 (define_expand "tls_local_dynamic_base_32"
14716 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14717 (unspec:SI [(match_dup 1) (match_dup 2)]
14718 UNSPEC_TLS_LD_BASE))
14719 (clobber (match_scratch:SI 3 ""))
14720 (clobber (match_scratch:SI 4 ""))
14721 (clobber (reg:CC FLAGS_REG))])]
14722 ""
14723 {
14724 if (flag_pic)
14725 operands[1] = pic_offset_table_rtx;
14726 else
14727 {
14728 operands[1] = gen_reg_rtx (Pmode);
14729 emit_insn (gen_set_got (operands[1]));
14730 }
14731 if (TARGET_GNU2_TLS)
14732 {
14733 emit_insn (gen_tls_dynamic_gnu2_32
14734 (operands[0], ix86_tls_module_base (), operands[1]));
14735 DONE;
14736 }
14737 operands[2] = ix86_tls_get_addr ();
14738 })
14739
14740 (define_insn "*tls_local_dynamic_base_64"
14741 [(set (match_operand:DI 0 "register_operand" "=a")
14742 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14743 (match_operand:DI 2 "" "")))
14744 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14745 "TARGET_64BIT"
14746 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14747 [(set_attr "type" "multi")
14748 (set_attr "length" "12")])
14749
14750 (define_expand "tls_local_dynamic_base_64"
14751 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14752 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14753 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14754 ""
14755 {
14756 if (TARGET_GNU2_TLS)
14757 {
14758 emit_insn (gen_tls_dynamic_gnu2_64
14759 (operands[0], ix86_tls_module_base ()));
14760 DONE;
14761 }
14762 operands[1] = ix86_tls_get_addr ();
14763 })
14764
14765 ;; Local dynamic of a single variable is a lose. Show combine how
14766 ;; to convert that back to global dynamic.
14767
14768 (define_insn_and_split "*tls_local_dynamic_32_once"
14769 [(set (match_operand:SI 0 "register_operand" "=a")
14770 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14771 (match_operand:SI 2 "call_insn_operand" "")]
14772 UNSPEC_TLS_LD_BASE)
14773 (const:SI (unspec:SI
14774 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14775 UNSPEC_DTPOFF))))
14776 (clobber (match_scratch:SI 4 "=d"))
14777 (clobber (match_scratch:SI 5 "=c"))
14778 (clobber (reg:CC FLAGS_REG))]
14779 ""
14780 "#"
14781 ""
14782 [(parallel [(set (match_dup 0)
14783 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14784 UNSPEC_TLS_GD))
14785 (clobber (match_dup 4))
14786 (clobber (match_dup 5))
14787 (clobber (reg:CC FLAGS_REG))])]
14788 "")
14789
14790 ;; Load and add the thread base pointer from %gs:0.
14791
14792 (define_insn "*load_tp_si"
14793 [(set (match_operand:SI 0 "register_operand" "=r")
14794 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14795 "!TARGET_64BIT"
14796 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14797 [(set_attr "type" "imov")
14798 (set_attr "modrm" "0")
14799 (set_attr "length" "7")
14800 (set_attr "memory" "load")
14801 (set_attr "imm_disp" "false")])
14802
14803 (define_insn "*add_tp_si"
14804 [(set (match_operand:SI 0 "register_operand" "=r")
14805 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14806 (match_operand:SI 1 "register_operand" "0")))
14807 (clobber (reg:CC FLAGS_REG))]
14808 "!TARGET_64BIT"
14809 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14810 [(set_attr "type" "alu")
14811 (set_attr "modrm" "0")
14812 (set_attr "length" "7")
14813 (set_attr "memory" "load")
14814 (set_attr "imm_disp" "false")])
14815
14816 (define_insn "*load_tp_di"
14817 [(set (match_operand:DI 0 "register_operand" "=r")
14818 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14819 "TARGET_64BIT"
14820 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14821 [(set_attr "type" "imov")
14822 (set_attr "modrm" "0")
14823 (set_attr "length" "7")
14824 (set_attr "memory" "load")
14825 (set_attr "imm_disp" "false")])
14826
14827 (define_insn "*add_tp_di"
14828 [(set (match_operand:DI 0 "register_operand" "=r")
14829 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14830 (match_operand:DI 1 "register_operand" "0")))
14831 (clobber (reg:CC FLAGS_REG))]
14832 "TARGET_64BIT"
14833 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14834 [(set_attr "type" "alu")
14835 (set_attr "modrm" "0")
14836 (set_attr "length" "7")
14837 (set_attr "memory" "load")
14838 (set_attr "imm_disp" "false")])
14839
14840 ;; GNU2 TLS patterns can be split.
14841
14842 (define_expand "tls_dynamic_gnu2_32"
14843 [(set (match_dup 3)
14844 (plus:SI (match_operand:SI 2 "register_operand" "")
14845 (const:SI
14846 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14847 UNSPEC_TLSDESC))))
14848 (parallel
14849 [(set (match_operand:SI 0 "register_operand" "")
14850 (unspec:SI [(match_dup 1) (match_dup 3)
14851 (match_dup 2) (reg:SI SP_REG)]
14852 UNSPEC_TLSDESC))
14853 (clobber (reg:CC FLAGS_REG))])]
14854 "!TARGET_64BIT && TARGET_GNU2_TLS"
14855 {
14856 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14857 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14858 })
14859
14860 (define_insn "*tls_dynamic_lea_32"
14861 [(set (match_operand:SI 0 "register_operand" "=r")
14862 (plus:SI (match_operand:SI 1 "register_operand" "b")
14863 (const:SI
14864 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14865 UNSPEC_TLSDESC))))]
14866 "!TARGET_64BIT && TARGET_GNU2_TLS"
14867 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14868 [(set_attr "type" "lea")
14869 (set_attr "mode" "SI")
14870 (set_attr "length" "6")
14871 (set_attr "length_address" "4")])
14872
14873 (define_insn "*tls_dynamic_call_32"
14874 [(set (match_operand:SI 0 "register_operand" "=a")
14875 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14876 (match_operand:SI 2 "register_operand" "0")
14877 ;; we have to make sure %ebx still points to the GOT
14878 (match_operand:SI 3 "register_operand" "b")
14879 (reg:SI SP_REG)]
14880 UNSPEC_TLSDESC))
14881 (clobber (reg:CC FLAGS_REG))]
14882 "!TARGET_64BIT && TARGET_GNU2_TLS"
14883 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14884 [(set_attr "type" "call")
14885 (set_attr "length" "2")
14886 (set_attr "length_address" "0")])
14887
14888 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14889 [(set (match_operand:SI 0 "register_operand" "=&a")
14890 (plus:SI
14891 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14892 (match_operand:SI 4 "" "")
14893 (match_operand:SI 2 "register_operand" "b")
14894 (reg:SI SP_REG)]
14895 UNSPEC_TLSDESC)
14896 (const:SI (unspec:SI
14897 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14898 UNSPEC_DTPOFF))))
14899 (clobber (reg:CC FLAGS_REG))]
14900 "!TARGET_64BIT && TARGET_GNU2_TLS"
14901 "#"
14902 ""
14903 [(set (match_dup 0) (match_dup 5))]
14904 {
14905 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14906 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14907 })
14908
14909 (define_expand "tls_dynamic_gnu2_64"
14910 [(set (match_dup 2)
14911 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14912 UNSPEC_TLSDESC))
14913 (parallel
14914 [(set (match_operand:DI 0 "register_operand" "")
14915 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14916 UNSPEC_TLSDESC))
14917 (clobber (reg:CC FLAGS_REG))])]
14918 "TARGET_64BIT && TARGET_GNU2_TLS"
14919 {
14920 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14921 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14922 })
14923
14924 (define_insn "*tls_dynamic_lea_64"
14925 [(set (match_operand:DI 0 "register_operand" "=r")
14926 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14927 UNSPEC_TLSDESC))]
14928 "TARGET_64BIT && TARGET_GNU2_TLS"
14929 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14930 [(set_attr "type" "lea")
14931 (set_attr "mode" "DI")
14932 (set_attr "length" "7")
14933 (set_attr "length_address" "4")])
14934
14935 (define_insn "*tls_dynamic_call_64"
14936 [(set (match_operand:DI 0 "register_operand" "=a")
14937 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14938 (match_operand:DI 2 "register_operand" "0")
14939 (reg:DI SP_REG)]
14940 UNSPEC_TLSDESC))
14941 (clobber (reg:CC FLAGS_REG))]
14942 "TARGET_64BIT && TARGET_GNU2_TLS"
14943 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14944 [(set_attr "type" "call")
14945 (set_attr "length" "2")
14946 (set_attr "length_address" "0")])
14947
14948 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14949 [(set (match_operand:DI 0 "register_operand" "=&a")
14950 (plus:DI
14951 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14952 (match_operand:DI 3 "" "")
14953 (reg:DI SP_REG)]
14954 UNSPEC_TLSDESC)
14955 (const:DI (unspec:DI
14956 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14957 UNSPEC_DTPOFF))))
14958 (clobber (reg:CC FLAGS_REG))]
14959 "TARGET_64BIT && TARGET_GNU2_TLS"
14960 "#"
14961 ""
14962 [(set (match_dup 0) (match_dup 4))]
14963 {
14964 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14965 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14966 })
14967
14968 ;;
14969 \f
14970 ;; These patterns match the binary 387 instructions for addM3, subM3,
14971 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14972 ;; SFmode. The first is the normal insn, the second the same insn but
14973 ;; with one operand a conversion, and the third the same insn but with
14974 ;; the other operand a conversion. The conversion may be SFmode or
14975 ;; SImode if the target mode DFmode, but only SImode if the target mode
14976 ;; is SFmode.
14977
14978 ;; Gcc is slightly more smart about handling normal two address instructions
14979 ;; so use special patterns for add and mull.
14980
14981 (define_insn "*fop_sf_comm_mixed"
14982 [(set (match_operand:SF 0 "register_operand" "=f,x")
14983 (match_operator:SF 3 "binary_fp_operator"
14984 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14985 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14986 "TARGET_MIX_SSE_I387
14987 && COMMUTATIVE_ARITH_P (operands[3])
14988 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14989 "* return output_387_binary_op (insn, operands);"
14990 [(set (attr "type")
14991 (if_then_else (eq_attr "alternative" "1")
14992 (if_then_else (match_operand:SF 3 "mult_operator" "")
14993 (const_string "ssemul")
14994 (const_string "sseadd"))
14995 (if_then_else (match_operand:SF 3 "mult_operator" "")
14996 (const_string "fmul")
14997 (const_string "fop"))))
14998 (set_attr "mode" "SF")])
14999
15000 (define_insn "*fop_sf_comm_sse"
15001 [(set (match_operand:SF 0 "register_operand" "=x")
15002 (match_operator:SF 3 "binary_fp_operator"
15003 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15004 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15005 "TARGET_SSE_MATH
15006 && COMMUTATIVE_ARITH_P (operands[3])
15007 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15008 "* return output_387_binary_op (insn, operands);"
15009 [(set (attr "type")
15010 (if_then_else (match_operand:SF 3 "mult_operator" "")
15011 (const_string "ssemul")
15012 (const_string "sseadd")))
15013 (set_attr "mode" "SF")])
15014
15015 (define_insn "*fop_sf_comm_i387"
15016 [(set (match_operand:SF 0 "register_operand" "=f")
15017 (match_operator:SF 3 "binary_fp_operator"
15018 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15019 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15020 "TARGET_80387
15021 && COMMUTATIVE_ARITH_P (operands[3])
15022 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15023 "* return output_387_binary_op (insn, operands);"
15024 [(set (attr "type")
15025 (if_then_else (match_operand:SF 3 "mult_operator" "")
15026 (const_string "fmul")
15027 (const_string "fop")))
15028 (set_attr "mode" "SF")])
15029
15030 (define_insn "*fop_sf_1_mixed"
15031 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15032 (match_operator:SF 3 "binary_fp_operator"
15033 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15034 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15035 "TARGET_MIX_SSE_I387
15036 && !COMMUTATIVE_ARITH_P (operands[3])
15037 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15038 "* return output_387_binary_op (insn, operands);"
15039 [(set (attr "type")
15040 (cond [(and (eq_attr "alternative" "2")
15041 (match_operand:SF 3 "mult_operator" ""))
15042 (const_string "ssemul")
15043 (and (eq_attr "alternative" "2")
15044 (match_operand:SF 3 "div_operator" ""))
15045 (const_string "ssediv")
15046 (eq_attr "alternative" "2")
15047 (const_string "sseadd")
15048 (match_operand:SF 3 "mult_operator" "")
15049 (const_string "fmul")
15050 (match_operand:SF 3 "div_operator" "")
15051 (const_string "fdiv")
15052 ]
15053 (const_string "fop")))
15054 (set_attr "mode" "SF")])
15055
15056 (define_insn "*fop_sf_1_sse"
15057 [(set (match_operand:SF 0 "register_operand" "=x")
15058 (match_operator:SF 3 "binary_fp_operator"
15059 [(match_operand:SF 1 "register_operand" "0")
15060 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15061 "TARGET_SSE_MATH
15062 && !COMMUTATIVE_ARITH_P (operands[3])"
15063 "* return output_387_binary_op (insn, operands);"
15064 [(set (attr "type")
15065 (cond [(match_operand:SF 3 "mult_operator" "")
15066 (const_string "ssemul")
15067 (match_operand:SF 3 "div_operator" "")
15068 (const_string "ssediv")
15069 ]
15070 (const_string "sseadd")))
15071 (set_attr "mode" "SF")])
15072
15073 ;; This pattern is not fully shadowed by the pattern above.
15074 (define_insn "*fop_sf_1_i387"
15075 [(set (match_operand:SF 0 "register_operand" "=f,f")
15076 (match_operator:SF 3 "binary_fp_operator"
15077 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15078 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15079 "TARGET_80387 && !TARGET_SSE_MATH
15080 && !COMMUTATIVE_ARITH_P (operands[3])
15081 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15082 "* return output_387_binary_op (insn, operands);"
15083 [(set (attr "type")
15084 (cond [(match_operand:SF 3 "mult_operator" "")
15085 (const_string "fmul")
15086 (match_operand:SF 3 "div_operator" "")
15087 (const_string "fdiv")
15088 ]
15089 (const_string "fop")))
15090 (set_attr "mode" "SF")])
15091
15092 ;; ??? Add SSE splitters for these!
15093 (define_insn "*fop_sf_2<mode>_i387"
15094 [(set (match_operand:SF 0 "register_operand" "=f,f")
15095 (match_operator:SF 3 "binary_fp_operator"
15096 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15097 (match_operand:SF 2 "register_operand" "0,0")]))]
15098 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15099 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15100 [(set (attr "type")
15101 (cond [(match_operand:SF 3 "mult_operator" "")
15102 (const_string "fmul")
15103 (match_operand:SF 3 "div_operator" "")
15104 (const_string "fdiv")
15105 ]
15106 (const_string "fop")))
15107 (set_attr "fp_int_src" "true")
15108 (set_attr "mode" "<MODE>")])
15109
15110 (define_insn "*fop_sf_3<mode>_i387"
15111 [(set (match_operand:SF 0 "register_operand" "=f,f")
15112 (match_operator:SF 3 "binary_fp_operator"
15113 [(match_operand:SF 1 "register_operand" "0,0")
15114 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15115 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15116 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15117 [(set (attr "type")
15118 (cond [(match_operand:SF 3 "mult_operator" "")
15119 (const_string "fmul")
15120 (match_operand:SF 3 "div_operator" "")
15121 (const_string "fdiv")
15122 ]
15123 (const_string "fop")))
15124 (set_attr "fp_int_src" "true")
15125 (set_attr "mode" "<MODE>")])
15126
15127 (define_insn "*fop_df_comm_mixed"
15128 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15129 (match_operator:DF 3 "binary_fp_operator"
15130 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15131 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15132 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15133 && COMMUTATIVE_ARITH_P (operands[3])
15134 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15135 "* return output_387_binary_op (insn, operands);"
15136 [(set (attr "type")
15137 (if_then_else (eq_attr "alternative" "1")
15138 (if_then_else (match_operand:DF 3 "mult_operator" "")
15139 (const_string "ssemul")
15140 (const_string "sseadd"))
15141 (if_then_else (match_operand:DF 3 "mult_operator" "")
15142 (const_string "fmul")
15143 (const_string "fop"))))
15144 (set_attr "mode" "DF")])
15145
15146 (define_insn "*fop_df_comm_sse"
15147 [(set (match_operand:DF 0 "register_operand" "=Y")
15148 (match_operator:DF 3 "binary_fp_operator"
15149 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15150 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15151 "TARGET_SSE2 && TARGET_SSE_MATH
15152 && COMMUTATIVE_ARITH_P (operands[3])
15153 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15154 "* return output_387_binary_op (insn, operands);"
15155 [(set (attr "type")
15156 (if_then_else (match_operand:DF 3 "mult_operator" "")
15157 (const_string "ssemul")
15158 (const_string "sseadd")))
15159 (set_attr "mode" "DF")])
15160
15161 (define_insn "*fop_df_comm_i387"
15162 [(set (match_operand:DF 0 "register_operand" "=f")
15163 (match_operator:DF 3 "binary_fp_operator"
15164 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15165 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15166 "TARGET_80387
15167 && COMMUTATIVE_ARITH_P (operands[3])
15168 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15169 "* return output_387_binary_op (insn, operands);"
15170 [(set (attr "type")
15171 (if_then_else (match_operand:DF 3 "mult_operator" "")
15172 (const_string "fmul")
15173 (const_string "fop")))
15174 (set_attr "mode" "DF")])
15175
15176 (define_insn "*fop_df_1_mixed"
15177 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15178 (match_operator:DF 3 "binary_fp_operator"
15179 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15180 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15181 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15182 && !COMMUTATIVE_ARITH_P (operands[3])
15183 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15184 "* return output_387_binary_op (insn, operands);"
15185 [(set (attr "type")
15186 (cond [(and (eq_attr "alternative" "2")
15187 (match_operand:DF 3 "mult_operator" ""))
15188 (const_string "ssemul")
15189 (and (eq_attr "alternative" "2")
15190 (match_operand:DF 3 "div_operator" ""))
15191 (const_string "ssediv")
15192 (eq_attr "alternative" "2")
15193 (const_string "sseadd")
15194 (match_operand:DF 3 "mult_operator" "")
15195 (const_string "fmul")
15196 (match_operand:DF 3 "div_operator" "")
15197 (const_string "fdiv")
15198 ]
15199 (const_string "fop")))
15200 (set_attr "mode" "DF")])
15201
15202 (define_insn "*fop_df_1_sse"
15203 [(set (match_operand:DF 0 "register_operand" "=Y")
15204 (match_operator:DF 3 "binary_fp_operator"
15205 [(match_operand:DF 1 "register_operand" "0")
15206 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15207 "TARGET_SSE2 && TARGET_SSE_MATH
15208 && !COMMUTATIVE_ARITH_P (operands[3])"
15209 "* return output_387_binary_op (insn, operands);"
15210 [(set_attr "mode" "DF")
15211 (set (attr "type")
15212 (cond [(match_operand:DF 3 "mult_operator" "")
15213 (const_string "ssemul")
15214 (match_operand:DF 3 "div_operator" "")
15215 (const_string "ssediv")
15216 ]
15217 (const_string "sseadd")))])
15218
15219 ;; This pattern is not fully shadowed by the pattern above.
15220 (define_insn "*fop_df_1_i387"
15221 [(set (match_operand:DF 0 "register_operand" "=f,f")
15222 (match_operator:DF 3 "binary_fp_operator"
15223 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15224 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15225 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15226 && !COMMUTATIVE_ARITH_P (operands[3])
15227 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15228 "* return output_387_binary_op (insn, operands);"
15229 [(set (attr "type")
15230 (cond [(match_operand:DF 3 "mult_operator" "")
15231 (const_string "fmul")
15232 (match_operand:DF 3 "div_operator" "")
15233 (const_string "fdiv")
15234 ]
15235 (const_string "fop")))
15236 (set_attr "mode" "DF")])
15237
15238 ;; ??? Add SSE splitters for these!
15239 (define_insn "*fop_df_2<mode>_i387"
15240 [(set (match_operand:DF 0 "register_operand" "=f,f")
15241 (match_operator:DF 3 "binary_fp_operator"
15242 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15243 (match_operand:DF 2 "register_operand" "0,0")]))]
15244 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15245 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15246 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15247 [(set (attr "type")
15248 (cond [(match_operand:DF 3 "mult_operator" "")
15249 (const_string "fmul")
15250 (match_operand:DF 3 "div_operator" "")
15251 (const_string "fdiv")
15252 ]
15253 (const_string "fop")))
15254 (set_attr "fp_int_src" "true")
15255 (set_attr "mode" "<MODE>")])
15256
15257 (define_insn "*fop_df_3<mode>_i387"
15258 [(set (match_operand:DF 0 "register_operand" "=f,f")
15259 (match_operator:DF 3 "binary_fp_operator"
15260 [(match_operand:DF 1 "register_operand" "0,0")
15261 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15262 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15263 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15264 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15265 [(set (attr "type")
15266 (cond [(match_operand:DF 3 "mult_operator" "")
15267 (const_string "fmul")
15268 (match_operand:DF 3 "div_operator" "")
15269 (const_string "fdiv")
15270 ]
15271 (const_string "fop")))
15272 (set_attr "fp_int_src" "true")
15273 (set_attr "mode" "<MODE>")])
15274
15275 (define_insn "*fop_df_4_i387"
15276 [(set (match_operand:DF 0 "register_operand" "=f,f")
15277 (match_operator:DF 3 "binary_fp_operator"
15278 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15279 (match_operand:DF 2 "register_operand" "0,f")]))]
15280 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15281 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15282 "* return output_387_binary_op (insn, operands);"
15283 [(set (attr "type")
15284 (cond [(match_operand:DF 3 "mult_operator" "")
15285 (const_string "fmul")
15286 (match_operand:DF 3 "div_operator" "")
15287 (const_string "fdiv")
15288 ]
15289 (const_string "fop")))
15290 (set_attr "mode" "SF")])
15291
15292 (define_insn "*fop_df_5_i387"
15293 [(set (match_operand:DF 0 "register_operand" "=f,f")
15294 (match_operator:DF 3 "binary_fp_operator"
15295 [(match_operand:DF 1 "register_operand" "0,f")
15296 (float_extend:DF
15297 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15298 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15299 "* return output_387_binary_op (insn, operands);"
15300 [(set (attr "type")
15301 (cond [(match_operand:DF 3 "mult_operator" "")
15302 (const_string "fmul")
15303 (match_operand:DF 3 "div_operator" "")
15304 (const_string "fdiv")
15305 ]
15306 (const_string "fop")))
15307 (set_attr "mode" "SF")])
15308
15309 (define_insn "*fop_df_6_i387"
15310 [(set (match_operand:DF 0 "register_operand" "=f,f")
15311 (match_operator:DF 3 "binary_fp_operator"
15312 [(float_extend:DF
15313 (match_operand:SF 1 "register_operand" "0,f"))
15314 (float_extend:DF
15315 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15316 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15317 "* return output_387_binary_op (insn, operands);"
15318 [(set (attr "type")
15319 (cond [(match_operand:DF 3 "mult_operator" "")
15320 (const_string "fmul")
15321 (match_operand:DF 3 "div_operator" "")
15322 (const_string "fdiv")
15323 ]
15324 (const_string "fop")))
15325 (set_attr "mode" "SF")])
15326
15327 (define_insn "*fop_xf_comm_i387"
15328 [(set (match_operand:XF 0 "register_operand" "=f")
15329 (match_operator:XF 3 "binary_fp_operator"
15330 [(match_operand:XF 1 "register_operand" "%0")
15331 (match_operand:XF 2 "register_operand" "f")]))]
15332 "TARGET_80387
15333 && COMMUTATIVE_ARITH_P (operands[3])"
15334 "* return output_387_binary_op (insn, operands);"
15335 [(set (attr "type")
15336 (if_then_else (match_operand:XF 3 "mult_operator" "")
15337 (const_string "fmul")
15338 (const_string "fop")))
15339 (set_attr "mode" "XF")])
15340
15341 (define_insn "*fop_xf_1_i387"
15342 [(set (match_operand:XF 0 "register_operand" "=f,f")
15343 (match_operator:XF 3 "binary_fp_operator"
15344 [(match_operand:XF 1 "register_operand" "0,f")
15345 (match_operand:XF 2 "register_operand" "f,0")]))]
15346 "TARGET_80387
15347 && !COMMUTATIVE_ARITH_P (operands[3])"
15348 "* return output_387_binary_op (insn, operands);"
15349 [(set (attr "type")
15350 (cond [(match_operand:XF 3 "mult_operator" "")
15351 (const_string "fmul")
15352 (match_operand:XF 3 "div_operator" "")
15353 (const_string "fdiv")
15354 ]
15355 (const_string "fop")))
15356 (set_attr "mode" "XF")])
15357
15358 (define_insn "*fop_xf_2<mode>_i387"
15359 [(set (match_operand:XF 0 "register_operand" "=f,f")
15360 (match_operator:XF 3 "binary_fp_operator"
15361 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15362 (match_operand:XF 2 "register_operand" "0,0")]))]
15363 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15364 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15365 [(set (attr "type")
15366 (cond [(match_operand:XF 3 "mult_operator" "")
15367 (const_string "fmul")
15368 (match_operand:XF 3 "div_operator" "")
15369 (const_string "fdiv")
15370 ]
15371 (const_string "fop")))
15372 (set_attr "fp_int_src" "true")
15373 (set_attr "mode" "<MODE>")])
15374
15375 (define_insn "*fop_xf_3<mode>_i387"
15376 [(set (match_operand:XF 0 "register_operand" "=f,f")
15377 (match_operator:XF 3 "binary_fp_operator"
15378 [(match_operand:XF 1 "register_operand" "0,0")
15379 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15380 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15381 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15382 [(set (attr "type")
15383 (cond [(match_operand:XF 3 "mult_operator" "")
15384 (const_string "fmul")
15385 (match_operand:XF 3 "div_operator" "")
15386 (const_string "fdiv")
15387 ]
15388 (const_string "fop")))
15389 (set_attr "fp_int_src" "true")
15390 (set_attr "mode" "<MODE>")])
15391
15392 (define_insn "*fop_xf_4_i387"
15393 [(set (match_operand:XF 0 "register_operand" "=f,f")
15394 (match_operator:XF 3 "binary_fp_operator"
15395 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15396 (match_operand:XF 2 "register_operand" "0,f")]))]
15397 "TARGET_80387"
15398 "* return output_387_binary_op (insn, operands);"
15399 [(set (attr "type")
15400 (cond [(match_operand:XF 3 "mult_operator" "")
15401 (const_string "fmul")
15402 (match_operand:XF 3 "div_operator" "")
15403 (const_string "fdiv")
15404 ]
15405 (const_string "fop")))
15406 (set_attr "mode" "SF")])
15407
15408 (define_insn "*fop_xf_5_i387"
15409 [(set (match_operand:XF 0 "register_operand" "=f,f")
15410 (match_operator:XF 3 "binary_fp_operator"
15411 [(match_operand:XF 1 "register_operand" "0,f")
15412 (float_extend:XF
15413 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15414 "TARGET_80387"
15415 "* return output_387_binary_op (insn, operands);"
15416 [(set (attr "type")
15417 (cond [(match_operand:XF 3 "mult_operator" "")
15418 (const_string "fmul")
15419 (match_operand:XF 3 "div_operator" "")
15420 (const_string "fdiv")
15421 ]
15422 (const_string "fop")))
15423 (set_attr "mode" "SF")])
15424
15425 (define_insn "*fop_xf_6_i387"
15426 [(set (match_operand:XF 0 "register_operand" "=f,f")
15427 (match_operator:XF 3 "binary_fp_operator"
15428 [(float_extend:XF
15429 (match_operand 1 "register_operand" "0,f"))
15430 (float_extend:XF
15431 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15432 "TARGET_80387"
15433 "* return output_387_binary_op (insn, operands);"
15434 [(set (attr "type")
15435 (cond [(match_operand:XF 3 "mult_operator" "")
15436 (const_string "fmul")
15437 (match_operand:XF 3 "div_operator" "")
15438 (const_string "fdiv")
15439 ]
15440 (const_string "fop")))
15441 (set_attr "mode" "SF")])
15442
15443 (define_split
15444 [(set (match_operand 0 "register_operand" "")
15445 (match_operator 3 "binary_fp_operator"
15446 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15447 (match_operand 2 "register_operand" "")]))]
15448 "TARGET_80387 && reload_completed
15449 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15450 [(const_int 0)]
15451 {
15452 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15453 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15454 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15455 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15456 GET_MODE (operands[3]),
15457 operands[4],
15458 operands[2])));
15459 ix86_free_from_memory (GET_MODE (operands[1]));
15460 DONE;
15461 })
15462
15463 (define_split
15464 [(set (match_operand 0 "register_operand" "")
15465 (match_operator 3 "binary_fp_operator"
15466 [(match_operand 1 "register_operand" "")
15467 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15468 "TARGET_80387 && reload_completed
15469 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15470 [(const_int 0)]
15471 {
15472 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15473 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15474 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15475 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15476 GET_MODE (operands[3]),
15477 operands[1],
15478 operands[4])));
15479 ix86_free_from_memory (GET_MODE (operands[2]));
15480 DONE;
15481 })
15482 \f
15483 ;; FPU special functions.
15484
15485 (define_expand "sqrtsf2"
15486 [(set (match_operand:SF 0 "register_operand" "")
15487 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15488 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15489 {
15490 if (!TARGET_SSE_MATH)
15491 operands[1] = force_reg (SFmode, operands[1]);
15492 })
15493
15494 (define_insn "*sqrtsf2_mixed"
15495 [(set (match_operand:SF 0 "register_operand" "=f,x")
15496 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15497 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15498 "@
15499 fsqrt
15500 sqrtss\t{%1, %0|%0, %1}"
15501 [(set_attr "type" "fpspc,sse")
15502 (set_attr "mode" "SF,SF")
15503 (set_attr "athlon_decode" "direct,*")])
15504
15505 (define_insn "*sqrtsf2_sse"
15506 [(set (match_operand:SF 0 "register_operand" "=x")
15507 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15508 "TARGET_SSE_MATH"
15509 "sqrtss\t{%1, %0|%0, %1}"
15510 [(set_attr "type" "sse")
15511 (set_attr "mode" "SF")
15512 (set_attr "athlon_decode" "*")])
15513
15514 (define_insn "*sqrtsf2_i387"
15515 [(set (match_operand:SF 0 "register_operand" "=f")
15516 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15517 "TARGET_USE_FANCY_MATH_387"
15518 "fsqrt"
15519 [(set_attr "type" "fpspc")
15520 (set_attr "mode" "SF")
15521 (set_attr "athlon_decode" "direct")])
15522
15523 (define_expand "sqrtdf2"
15524 [(set (match_operand:DF 0 "register_operand" "")
15525 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15526 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15527 {
15528 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15529 operands[1] = force_reg (DFmode, operands[1]);
15530 })
15531
15532 (define_insn "*sqrtdf2_mixed"
15533 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15534 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15535 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15536 "@
15537 fsqrt
15538 sqrtsd\t{%1, %0|%0, %1}"
15539 [(set_attr "type" "fpspc,sse")
15540 (set_attr "mode" "DF,DF")
15541 (set_attr "athlon_decode" "direct,*")])
15542
15543 (define_insn "*sqrtdf2_sse"
15544 [(set (match_operand:DF 0 "register_operand" "=Y")
15545 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15546 "TARGET_SSE2 && TARGET_SSE_MATH"
15547 "sqrtsd\t{%1, %0|%0, %1}"
15548 [(set_attr "type" "sse")
15549 (set_attr "mode" "DF")
15550 (set_attr "athlon_decode" "*")])
15551
15552 (define_insn "*sqrtdf2_i387"
15553 [(set (match_operand:DF 0 "register_operand" "=f")
15554 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15555 "TARGET_USE_FANCY_MATH_387"
15556 "fsqrt"
15557 [(set_attr "type" "fpspc")
15558 (set_attr "mode" "DF")
15559 (set_attr "athlon_decode" "direct")])
15560
15561 (define_insn "*sqrtextendsfdf2_i387"
15562 [(set (match_operand:DF 0 "register_operand" "=f")
15563 (sqrt:DF (float_extend:DF
15564 (match_operand:SF 1 "register_operand" "0"))))]
15565 "TARGET_USE_FANCY_MATH_387
15566 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15567 "fsqrt"
15568 [(set_attr "type" "fpspc")
15569 (set_attr "mode" "DF")
15570 (set_attr "athlon_decode" "direct")])
15571
15572 (define_insn "sqrtxf2"
15573 [(set (match_operand:XF 0 "register_operand" "=f")
15574 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15575 "TARGET_USE_FANCY_MATH_387"
15576 "fsqrt"
15577 [(set_attr "type" "fpspc")
15578 (set_attr "mode" "XF")
15579 (set_attr "athlon_decode" "direct")])
15580
15581 (define_insn "*sqrtextendsfxf2_i387"
15582 [(set (match_operand:XF 0 "register_operand" "=f")
15583 (sqrt:XF (float_extend:XF
15584 (match_operand:SF 1 "register_operand" "0"))))]
15585 "TARGET_USE_FANCY_MATH_387"
15586 "fsqrt"
15587 [(set_attr "type" "fpspc")
15588 (set_attr "mode" "XF")
15589 (set_attr "athlon_decode" "direct")])
15590
15591 (define_insn "*sqrtextenddfxf2_i387"
15592 [(set (match_operand:XF 0 "register_operand" "=f")
15593 (sqrt:XF (float_extend:XF
15594 (match_operand:DF 1 "register_operand" "0"))))]
15595 "TARGET_USE_FANCY_MATH_387"
15596 "fsqrt"
15597 [(set_attr "type" "fpspc")
15598 (set_attr "mode" "XF")
15599 (set_attr "athlon_decode" "direct")])
15600
15601 (define_insn "fpremxf4"
15602 [(set (match_operand:XF 0 "register_operand" "=f")
15603 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15604 (match_operand:XF 3 "register_operand" "1")]
15605 UNSPEC_FPREM_F))
15606 (set (match_operand:XF 1 "register_operand" "=u")
15607 (unspec:XF [(match_dup 2) (match_dup 3)]
15608 UNSPEC_FPREM_U))
15609 (set (reg:CCFP FPSR_REG)
15610 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15611 "TARGET_USE_FANCY_MATH_387
15612 && flag_unsafe_math_optimizations"
15613 "fprem"
15614 [(set_attr "type" "fpspc")
15615 (set_attr "mode" "XF")])
15616
15617 (define_expand "fmodsf3"
15618 [(use (match_operand:SF 0 "register_operand" ""))
15619 (use (match_operand:SF 1 "register_operand" ""))
15620 (use (match_operand:SF 2 "register_operand" ""))]
15621 "TARGET_USE_FANCY_MATH_387
15622 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15623 && flag_unsafe_math_optimizations"
15624 {
15625 rtx label = gen_label_rtx ();
15626
15627 rtx op1 = gen_reg_rtx (XFmode);
15628 rtx op2 = gen_reg_rtx (XFmode);
15629
15630 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15631 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15632
15633 emit_label (label);
15634
15635 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15636 ix86_emit_fp_unordered_jump (label);
15637
15638 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15639 DONE;
15640 })
15641
15642 (define_expand "fmoddf3"
15643 [(use (match_operand:DF 0 "register_operand" ""))
15644 (use (match_operand:DF 1 "register_operand" ""))
15645 (use (match_operand:DF 2 "register_operand" ""))]
15646 "TARGET_USE_FANCY_MATH_387
15647 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15648 && flag_unsafe_math_optimizations"
15649 {
15650 rtx label = gen_label_rtx ();
15651
15652 rtx op1 = gen_reg_rtx (XFmode);
15653 rtx op2 = gen_reg_rtx (XFmode);
15654
15655 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15656 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15657
15658 emit_label (label);
15659
15660 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15661 ix86_emit_fp_unordered_jump (label);
15662
15663 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15664 DONE;
15665 })
15666
15667 (define_expand "fmodxf3"
15668 [(use (match_operand:XF 0 "register_operand" ""))
15669 (use (match_operand:XF 1 "register_operand" ""))
15670 (use (match_operand:XF 2 "register_operand" ""))]
15671 "TARGET_USE_FANCY_MATH_387
15672 && flag_unsafe_math_optimizations"
15673 {
15674 rtx label = gen_label_rtx ();
15675
15676 emit_label (label);
15677
15678 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15679 operands[1], operands[2]));
15680 ix86_emit_fp_unordered_jump (label);
15681
15682 emit_move_insn (operands[0], operands[1]);
15683 DONE;
15684 })
15685
15686 (define_insn "fprem1xf4"
15687 [(set (match_operand:XF 0 "register_operand" "=f")
15688 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15689 (match_operand:XF 3 "register_operand" "1")]
15690 UNSPEC_FPREM1_F))
15691 (set (match_operand:XF 1 "register_operand" "=u")
15692 (unspec:XF [(match_dup 2) (match_dup 3)]
15693 UNSPEC_FPREM1_U))
15694 (set (reg:CCFP FPSR_REG)
15695 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15696 "TARGET_USE_FANCY_MATH_387
15697 && flag_unsafe_math_optimizations"
15698 "fprem1"
15699 [(set_attr "type" "fpspc")
15700 (set_attr "mode" "XF")])
15701
15702 (define_expand "dremsf3"
15703 [(use (match_operand:SF 0 "register_operand" ""))
15704 (use (match_operand:SF 1 "register_operand" ""))
15705 (use (match_operand:SF 2 "register_operand" ""))]
15706 "TARGET_USE_FANCY_MATH_387
15707 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15708 && flag_unsafe_math_optimizations"
15709 {
15710 rtx label = gen_label_rtx ();
15711
15712 rtx op1 = gen_reg_rtx (XFmode);
15713 rtx op2 = gen_reg_rtx (XFmode);
15714
15715 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15716 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15717
15718 emit_label (label);
15719
15720 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15721 ix86_emit_fp_unordered_jump (label);
15722
15723 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15724 DONE;
15725 })
15726
15727 (define_expand "dremdf3"
15728 [(use (match_operand:DF 0 "register_operand" ""))
15729 (use (match_operand:DF 1 "register_operand" ""))
15730 (use (match_operand:DF 2 "register_operand" ""))]
15731 "TARGET_USE_FANCY_MATH_387
15732 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15733 && flag_unsafe_math_optimizations"
15734 {
15735 rtx label = gen_label_rtx ();
15736
15737 rtx op1 = gen_reg_rtx (XFmode);
15738 rtx op2 = gen_reg_rtx (XFmode);
15739
15740 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15741 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15742
15743 emit_label (label);
15744
15745 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15746 ix86_emit_fp_unordered_jump (label);
15747
15748 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15749 DONE;
15750 })
15751
15752 (define_expand "dremxf3"
15753 [(use (match_operand:XF 0 "register_operand" ""))
15754 (use (match_operand:XF 1 "register_operand" ""))
15755 (use (match_operand:XF 2 "register_operand" ""))]
15756 "TARGET_USE_FANCY_MATH_387
15757 && flag_unsafe_math_optimizations"
15758 {
15759 rtx label = gen_label_rtx ();
15760
15761 emit_label (label);
15762
15763 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15764 operands[1], operands[2]));
15765 ix86_emit_fp_unordered_jump (label);
15766
15767 emit_move_insn (operands[0], operands[1]);
15768 DONE;
15769 })
15770
15771 (define_insn "*sindf2"
15772 [(set (match_operand:DF 0 "register_operand" "=f")
15773 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15774 "TARGET_USE_FANCY_MATH_387
15775 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15776 && flag_unsafe_math_optimizations"
15777 "fsin"
15778 [(set_attr "type" "fpspc")
15779 (set_attr "mode" "DF")])
15780
15781 (define_insn "*sinsf2"
15782 [(set (match_operand:SF 0 "register_operand" "=f")
15783 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15784 "TARGET_USE_FANCY_MATH_387
15785 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15786 && flag_unsafe_math_optimizations"
15787 "fsin"
15788 [(set_attr "type" "fpspc")
15789 (set_attr "mode" "SF")])
15790
15791 (define_insn "*sinextendsfdf2"
15792 [(set (match_operand:DF 0 "register_operand" "=f")
15793 (unspec:DF [(float_extend:DF
15794 (match_operand:SF 1 "register_operand" "0"))]
15795 UNSPEC_SIN))]
15796 "TARGET_USE_FANCY_MATH_387
15797 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15798 && flag_unsafe_math_optimizations"
15799 "fsin"
15800 [(set_attr "type" "fpspc")
15801 (set_attr "mode" "DF")])
15802
15803 (define_insn "*sinxf2"
15804 [(set (match_operand:XF 0 "register_operand" "=f")
15805 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15806 "TARGET_USE_FANCY_MATH_387
15807 && flag_unsafe_math_optimizations"
15808 "fsin"
15809 [(set_attr "type" "fpspc")
15810 (set_attr "mode" "XF")])
15811
15812 (define_insn "*cosdf2"
15813 [(set (match_operand:DF 0 "register_operand" "=f")
15814 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15815 "TARGET_USE_FANCY_MATH_387
15816 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15817 && flag_unsafe_math_optimizations"
15818 "fcos"
15819 [(set_attr "type" "fpspc")
15820 (set_attr "mode" "DF")])
15821
15822 (define_insn "*cossf2"
15823 [(set (match_operand:SF 0 "register_operand" "=f")
15824 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15825 "TARGET_USE_FANCY_MATH_387
15826 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15827 && flag_unsafe_math_optimizations"
15828 "fcos"
15829 [(set_attr "type" "fpspc")
15830 (set_attr "mode" "SF")])
15831
15832 (define_insn "*cosextendsfdf2"
15833 [(set (match_operand:DF 0 "register_operand" "=f")
15834 (unspec:DF [(float_extend:DF
15835 (match_operand:SF 1 "register_operand" "0"))]
15836 UNSPEC_COS))]
15837 "TARGET_USE_FANCY_MATH_387
15838 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15839 && flag_unsafe_math_optimizations"
15840 "fcos"
15841 [(set_attr "type" "fpspc")
15842 (set_attr "mode" "DF")])
15843
15844 (define_insn "*cosxf2"
15845 [(set (match_operand:XF 0 "register_operand" "=f")
15846 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15847 "TARGET_USE_FANCY_MATH_387
15848 && flag_unsafe_math_optimizations"
15849 "fcos"
15850 [(set_attr "type" "fpspc")
15851 (set_attr "mode" "XF")])
15852
15853 ;; With sincos pattern defined, sin and cos builtin function will be
15854 ;; expanded to sincos pattern with one of its outputs left unused.
15855 ;; Cse pass will detected, if two sincos patterns can be combined,
15856 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15857 ;; depending on the unused output.
15858
15859 (define_insn "sincosdf3"
15860 [(set (match_operand:DF 0 "register_operand" "=f")
15861 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15862 UNSPEC_SINCOS_COS))
15863 (set (match_operand:DF 1 "register_operand" "=u")
15864 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15865 "TARGET_USE_FANCY_MATH_387
15866 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15867 && flag_unsafe_math_optimizations"
15868 "fsincos"
15869 [(set_attr "type" "fpspc")
15870 (set_attr "mode" "DF")])
15871
15872 (define_split
15873 [(set (match_operand:DF 0 "register_operand" "")
15874 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15875 UNSPEC_SINCOS_COS))
15876 (set (match_operand:DF 1 "register_operand" "")
15877 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15878 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15879 && !reload_completed && !reload_in_progress"
15880 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15881 "")
15882
15883 (define_split
15884 [(set (match_operand:DF 0 "register_operand" "")
15885 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15886 UNSPEC_SINCOS_COS))
15887 (set (match_operand:DF 1 "register_operand" "")
15888 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15889 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15890 && !reload_completed && !reload_in_progress"
15891 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15892 "")
15893
15894 (define_insn "sincossf3"
15895 [(set (match_operand:SF 0 "register_operand" "=f")
15896 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15897 UNSPEC_SINCOS_COS))
15898 (set (match_operand:SF 1 "register_operand" "=u")
15899 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15900 "TARGET_USE_FANCY_MATH_387
15901 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15902 && flag_unsafe_math_optimizations"
15903 "fsincos"
15904 [(set_attr "type" "fpspc")
15905 (set_attr "mode" "SF")])
15906
15907 (define_split
15908 [(set (match_operand:SF 0 "register_operand" "")
15909 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15910 UNSPEC_SINCOS_COS))
15911 (set (match_operand:SF 1 "register_operand" "")
15912 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15913 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15914 && !reload_completed && !reload_in_progress"
15915 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15916 "")
15917
15918 (define_split
15919 [(set (match_operand:SF 0 "register_operand" "")
15920 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15921 UNSPEC_SINCOS_COS))
15922 (set (match_operand:SF 1 "register_operand" "")
15923 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15924 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15925 && !reload_completed && !reload_in_progress"
15926 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15927 "")
15928
15929 (define_insn "*sincosextendsfdf3"
15930 [(set (match_operand:DF 0 "register_operand" "=f")
15931 (unspec:DF [(float_extend:DF
15932 (match_operand:SF 2 "register_operand" "0"))]
15933 UNSPEC_SINCOS_COS))
15934 (set (match_operand:DF 1 "register_operand" "=u")
15935 (unspec:DF [(float_extend:DF
15936 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15937 "TARGET_USE_FANCY_MATH_387
15938 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15939 && flag_unsafe_math_optimizations"
15940 "fsincos"
15941 [(set_attr "type" "fpspc")
15942 (set_attr "mode" "DF")])
15943
15944 (define_split
15945 [(set (match_operand:DF 0 "register_operand" "")
15946 (unspec:DF [(float_extend:DF
15947 (match_operand:SF 2 "register_operand" ""))]
15948 UNSPEC_SINCOS_COS))
15949 (set (match_operand:DF 1 "register_operand" "")
15950 (unspec:DF [(float_extend:DF
15951 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15952 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15953 && !reload_completed && !reload_in_progress"
15954 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15955 (match_dup 2))] UNSPEC_SIN))]
15956 "")
15957
15958 (define_split
15959 [(set (match_operand:DF 0 "register_operand" "")
15960 (unspec:DF [(float_extend:DF
15961 (match_operand:SF 2 "register_operand" ""))]
15962 UNSPEC_SINCOS_COS))
15963 (set (match_operand:DF 1 "register_operand" "")
15964 (unspec:DF [(float_extend:DF
15965 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15966 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15967 && !reload_completed && !reload_in_progress"
15968 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15969 (match_dup 2))] UNSPEC_COS))]
15970 "")
15971
15972 (define_insn "sincosxf3"
15973 [(set (match_operand:XF 0 "register_operand" "=f")
15974 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15975 UNSPEC_SINCOS_COS))
15976 (set (match_operand:XF 1 "register_operand" "=u")
15977 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15978 "TARGET_USE_FANCY_MATH_387
15979 && flag_unsafe_math_optimizations"
15980 "fsincos"
15981 [(set_attr "type" "fpspc")
15982 (set_attr "mode" "XF")])
15983
15984 (define_split
15985 [(set (match_operand:XF 0 "register_operand" "")
15986 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15987 UNSPEC_SINCOS_COS))
15988 (set (match_operand:XF 1 "register_operand" "")
15989 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15990 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15991 && !reload_completed && !reload_in_progress"
15992 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15993 "")
15994
15995 (define_split
15996 [(set (match_operand:XF 0 "register_operand" "")
15997 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15998 UNSPEC_SINCOS_COS))
15999 (set (match_operand:XF 1 "register_operand" "")
16000 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16001 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16002 && !reload_completed && !reload_in_progress"
16003 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16004 "")
16005
16006 (define_insn "*tandf3_1"
16007 [(set (match_operand:DF 0 "register_operand" "=f")
16008 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16009 UNSPEC_TAN_ONE))
16010 (set (match_operand:DF 1 "register_operand" "=u")
16011 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16012 "TARGET_USE_FANCY_MATH_387
16013 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16014 && flag_unsafe_math_optimizations"
16015 "fptan"
16016 [(set_attr "type" "fpspc")
16017 (set_attr "mode" "DF")])
16018
16019 ;; optimize sequence: fptan
16020 ;; fstp %st(0)
16021 ;; fld1
16022 ;; into fptan insn.
16023
16024 (define_peephole2
16025 [(parallel[(set (match_operand:DF 0 "register_operand" "")
16026 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16027 UNSPEC_TAN_ONE))
16028 (set (match_operand:DF 1 "register_operand" "")
16029 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16030 (set (match_dup 0)
16031 (match_operand:DF 3 "immediate_operand" ""))]
16032 "standard_80387_constant_p (operands[3]) == 2"
16033 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16034 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16035 "")
16036
16037 (define_expand "tandf2"
16038 [(parallel [(set (match_dup 2)
16039 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16040 UNSPEC_TAN_ONE))
16041 (set (match_operand:DF 0 "register_operand" "")
16042 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16043 "TARGET_USE_FANCY_MATH_387
16044 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16045 && flag_unsafe_math_optimizations"
16046 {
16047 operands[2] = gen_reg_rtx (DFmode);
16048 })
16049
16050 (define_insn "*tansf3_1"
16051 [(set (match_operand:SF 0 "register_operand" "=f")
16052 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16053 UNSPEC_TAN_ONE))
16054 (set (match_operand:SF 1 "register_operand" "=u")
16055 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16056 "TARGET_USE_FANCY_MATH_387
16057 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16058 && flag_unsafe_math_optimizations"
16059 "fptan"
16060 [(set_attr "type" "fpspc")
16061 (set_attr "mode" "SF")])
16062
16063 ;; optimize sequence: fptan
16064 ;; fstp %st(0)
16065 ;; fld1
16066 ;; into fptan insn.
16067
16068 (define_peephole2
16069 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16070 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16071 UNSPEC_TAN_ONE))
16072 (set (match_operand:SF 1 "register_operand" "")
16073 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16074 (set (match_dup 0)
16075 (match_operand:SF 3 "immediate_operand" ""))]
16076 "standard_80387_constant_p (operands[3]) == 2"
16077 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16078 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16079 "")
16080
16081 (define_expand "tansf2"
16082 [(parallel [(set (match_dup 2)
16083 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16084 UNSPEC_TAN_ONE))
16085 (set (match_operand:SF 0 "register_operand" "")
16086 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16087 "TARGET_USE_FANCY_MATH_387
16088 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16089 && flag_unsafe_math_optimizations"
16090 {
16091 operands[2] = gen_reg_rtx (SFmode);
16092 })
16093
16094 (define_insn "*tanxf3_1"
16095 [(set (match_operand:XF 0 "register_operand" "=f")
16096 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16097 UNSPEC_TAN_ONE))
16098 (set (match_operand:XF 1 "register_operand" "=u")
16099 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16100 "TARGET_USE_FANCY_MATH_387
16101 && flag_unsafe_math_optimizations"
16102 "fptan"
16103 [(set_attr "type" "fpspc")
16104 (set_attr "mode" "XF")])
16105
16106 ;; optimize sequence: fptan
16107 ;; fstp %st(0)
16108 ;; fld1
16109 ;; into fptan insn.
16110
16111 (define_peephole2
16112 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16113 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16114 UNSPEC_TAN_ONE))
16115 (set (match_operand:XF 1 "register_operand" "")
16116 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16117 (set (match_dup 0)
16118 (match_operand:XF 3 "immediate_operand" ""))]
16119 "standard_80387_constant_p (operands[3]) == 2"
16120 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16121 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16122 "")
16123
16124 (define_expand "tanxf2"
16125 [(parallel [(set (match_dup 2)
16126 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16127 UNSPEC_TAN_ONE))
16128 (set (match_operand:XF 0 "register_operand" "")
16129 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16130 "TARGET_USE_FANCY_MATH_387
16131 && flag_unsafe_math_optimizations"
16132 {
16133 operands[2] = gen_reg_rtx (XFmode);
16134 })
16135
16136 (define_insn "atan2df3_1"
16137 [(set (match_operand:DF 0 "register_operand" "=f")
16138 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16139 (match_operand:DF 1 "register_operand" "u")]
16140 UNSPEC_FPATAN))
16141 (clobber (match_scratch:DF 3 "=1"))]
16142 "TARGET_USE_FANCY_MATH_387
16143 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16144 && flag_unsafe_math_optimizations"
16145 "fpatan"
16146 [(set_attr "type" "fpspc")
16147 (set_attr "mode" "DF")])
16148
16149 (define_expand "atan2df3"
16150 [(use (match_operand:DF 0 "register_operand" ""))
16151 (use (match_operand:DF 2 "register_operand" ""))
16152 (use (match_operand:DF 1 "register_operand" ""))]
16153 "TARGET_USE_FANCY_MATH_387
16154 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16155 && flag_unsafe_math_optimizations"
16156 {
16157 rtx copy = gen_reg_rtx (DFmode);
16158 emit_move_insn (copy, operands[1]);
16159 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16160 DONE;
16161 })
16162
16163 (define_expand "atandf2"
16164 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16165 (unspec:DF [(match_dup 2)
16166 (match_operand:DF 1 "register_operand" "")]
16167 UNSPEC_FPATAN))
16168 (clobber (match_scratch:DF 3 ""))])]
16169 "TARGET_USE_FANCY_MATH_387
16170 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16171 && flag_unsafe_math_optimizations"
16172 {
16173 operands[2] = gen_reg_rtx (DFmode);
16174 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16175 })
16176
16177 (define_insn "atan2sf3_1"
16178 [(set (match_operand:SF 0 "register_operand" "=f")
16179 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16180 (match_operand:SF 1 "register_operand" "u")]
16181 UNSPEC_FPATAN))
16182 (clobber (match_scratch:SF 3 "=1"))]
16183 "TARGET_USE_FANCY_MATH_387
16184 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16185 && flag_unsafe_math_optimizations"
16186 "fpatan"
16187 [(set_attr "type" "fpspc")
16188 (set_attr "mode" "SF")])
16189
16190 (define_expand "atan2sf3"
16191 [(use (match_operand:SF 0 "register_operand" ""))
16192 (use (match_operand:SF 2 "register_operand" ""))
16193 (use (match_operand:SF 1 "register_operand" ""))]
16194 "TARGET_USE_FANCY_MATH_387
16195 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16196 && flag_unsafe_math_optimizations"
16197 {
16198 rtx copy = gen_reg_rtx (SFmode);
16199 emit_move_insn (copy, operands[1]);
16200 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16201 DONE;
16202 })
16203
16204 (define_expand "atansf2"
16205 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16206 (unspec:SF [(match_dup 2)
16207 (match_operand:SF 1 "register_operand" "")]
16208 UNSPEC_FPATAN))
16209 (clobber (match_scratch:SF 3 ""))])]
16210 "TARGET_USE_FANCY_MATH_387
16211 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16212 && flag_unsafe_math_optimizations"
16213 {
16214 operands[2] = gen_reg_rtx (SFmode);
16215 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16216 })
16217
16218 (define_insn "atan2xf3_1"
16219 [(set (match_operand:XF 0 "register_operand" "=f")
16220 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16221 (match_operand:XF 1 "register_operand" "u")]
16222 UNSPEC_FPATAN))
16223 (clobber (match_scratch:XF 3 "=1"))]
16224 "TARGET_USE_FANCY_MATH_387
16225 && flag_unsafe_math_optimizations"
16226 "fpatan"
16227 [(set_attr "type" "fpspc")
16228 (set_attr "mode" "XF")])
16229
16230 (define_expand "atan2xf3"
16231 [(use (match_operand:XF 0 "register_operand" ""))
16232 (use (match_operand:XF 2 "register_operand" ""))
16233 (use (match_operand:XF 1 "register_operand" ""))]
16234 "TARGET_USE_FANCY_MATH_387
16235 && flag_unsafe_math_optimizations"
16236 {
16237 rtx copy = gen_reg_rtx (XFmode);
16238 emit_move_insn (copy, operands[1]);
16239 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16240 DONE;
16241 })
16242
16243 (define_expand "atanxf2"
16244 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16245 (unspec:XF [(match_dup 2)
16246 (match_operand:XF 1 "register_operand" "")]
16247 UNSPEC_FPATAN))
16248 (clobber (match_scratch:XF 3 ""))])]
16249 "TARGET_USE_FANCY_MATH_387
16250 && flag_unsafe_math_optimizations"
16251 {
16252 operands[2] = gen_reg_rtx (XFmode);
16253 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16254 })
16255
16256 (define_expand "asindf2"
16257 [(set (match_dup 2)
16258 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16259 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16260 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16261 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16262 (parallel [(set (match_dup 7)
16263 (unspec:XF [(match_dup 6) (match_dup 2)]
16264 UNSPEC_FPATAN))
16265 (clobber (match_scratch:XF 8 ""))])
16266 (set (match_operand:DF 0 "register_operand" "")
16267 (float_truncate:DF (match_dup 7)))]
16268 "TARGET_USE_FANCY_MATH_387
16269 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16270 && flag_unsafe_math_optimizations"
16271 {
16272 int i;
16273
16274 for (i=2; i<8; i++)
16275 operands[i] = gen_reg_rtx (XFmode);
16276
16277 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16278 })
16279
16280 (define_expand "asinsf2"
16281 [(set (match_dup 2)
16282 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16283 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16284 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16285 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16286 (parallel [(set (match_dup 7)
16287 (unspec:XF [(match_dup 6) (match_dup 2)]
16288 UNSPEC_FPATAN))
16289 (clobber (match_scratch:XF 8 ""))])
16290 (set (match_operand:SF 0 "register_operand" "")
16291 (float_truncate:SF (match_dup 7)))]
16292 "TARGET_USE_FANCY_MATH_387
16293 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16294 && flag_unsafe_math_optimizations"
16295 {
16296 int i;
16297
16298 for (i=2; i<8; i++)
16299 operands[i] = gen_reg_rtx (XFmode);
16300
16301 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16302 })
16303
16304 (define_expand "asinxf2"
16305 [(set (match_dup 2)
16306 (mult:XF (match_operand:XF 1 "register_operand" "")
16307 (match_dup 1)))
16308 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16309 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16310 (parallel [(set (match_operand:XF 0 "register_operand" "")
16311 (unspec:XF [(match_dup 5) (match_dup 1)]
16312 UNSPEC_FPATAN))
16313 (clobber (match_scratch:XF 6 ""))])]
16314 "TARGET_USE_FANCY_MATH_387
16315 && flag_unsafe_math_optimizations"
16316 {
16317 int i;
16318
16319 for (i=2; i<6; i++)
16320 operands[i] = gen_reg_rtx (XFmode);
16321
16322 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16323 })
16324
16325 (define_expand "acosdf2"
16326 [(set (match_dup 2)
16327 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16328 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16329 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16330 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16331 (parallel [(set (match_dup 7)
16332 (unspec:XF [(match_dup 2) (match_dup 6)]
16333 UNSPEC_FPATAN))
16334 (clobber (match_scratch:XF 8 ""))])
16335 (set (match_operand:DF 0 "register_operand" "")
16336 (float_truncate:DF (match_dup 7)))]
16337 "TARGET_USE_FANCY_MATH_387
16338 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16339 && flag_unsafe_math_optimizations"
16340 {
16341 int i;
16342
16343 for (i=2; i<8; i++)
16344 operands[i] = gen_reg_rtx (XFmode);
16345
16346 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16347 })
16348
16349 (define_expand "acossf2"
16350 [(set (match_dup 2)
16351 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16352 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16353 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16354 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16355 (parallel [(set (match_dup 7)
16356 (unspec:XF [(match_dup 2) (match_dup 6)]
16357 UNSPEC_FPATAN))
16358 (clobber (match_scratch:XF 8 ""))])
16359 (set (match_operand:SF 0 "register_operand" "")
16360 (float_truncate:SF (match_dup 7)))]
16361 "TARGET_USE_FANCY_MATH_387
16362 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16363 && flag_unsafe_math_optimizations"
16364 {
16365 int i;
16366
16367 for (i=2; i<8; i++)
16368 operands[i] = gen_reg_rtx (XFmode);
16369
16370 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16371 })
16372
16373 (define_expand "acosxf2"
16374 [(set (match_dup 2)
16375 (mult:XF (match_operand:XF 1 "register_operand" "")
16376 (match_dup 1)))
16377 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16378 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16379 (parallel [(set (match_operand:XF 0 "register_operand" "")
16380 (unspec:XF [(match_dup 1) (match_dup 5)]
16381 UNSPEC_FPATAN))
16382 (clobber (match_scratch:XF 6 ""))])]
16383 "TARGET_USE_FANCY_MATH_387
16384 && flag_unsafe_math_optimizations"
16385 {
16386 int i;
16387
16388 for (i=2; i<6; i++)
16389 operands[i] = gen_reg_rtx (XFmode);
16390
16391 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16392 })
16393
16394 (define_insn "fyl2x_xf3"
16395 [(set (match_operand:XF 0 "register_operand" "=f")
16396 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16397 (match_operand:XF 1 "register_operand" "u")]
16398 UNSPEC_FYL2X))
16399 (clobber (match_scratch:XF 3 "=1"))]
16400 "TARGET_USE_FANCY_MATH_387
16401 && flag_unsafe_math_optimizations"
16402 "fyl2x"
16403 [(set_attr "type" "fpspc")
16404 (set_attr "mode" "XF")])
16405
16406 (define_expand "logsf2"
16407 [(set (match_dup 2)
16408 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16409 (parallel [(set (match_dup 4)
16410 (unspec:XF [(match_dup 2)
16411 (match_dup 3)] UNSPEC_FYL2X))
16412 (clobber (match_scratch:XF 5 ""))])
16413 (set (match_operand:SF 0 "register_operand" "")
16414 (float_truncate:SF (match_dup 4)))]
16415 "TARGET_USE_FANCY_MATH_387
16416 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16417 && flag_unsafe_math_optimizations"
16418 {
16419 rtx temp;
16420
16421 operands[2] = gen_reg_rtx (XFmode);
16422 operands[3] = gen_reg_rtx (XFmode);
16423 operands[4] = gen_reg_rtx (XFmode);
16424
16425 temp = standard_80387_constant_rtx (4); /* fldln2 */
16426 emit_move_insn (operands[3], temp);
16427 })
16428
16429 (define_expand "logdf2"
16430 [(set (match_dup 2)
16431 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16432 (parallel [(set (match_dup 4)
16433 (unspec:XF [(match_dup 2)
16434 (match_dup 3)] UNSPEC_FYL2X))
16435 (clobber (match_scratch:XF 5 ""))])
16436 (set (match_operand:DF 0 "register_operand" "")
16437 (float_truncate:DF (match_dup 4)))]
16438 "TARGET_USE_FANCY_MATH_387
16439 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16440 && flag_unsafe_math_optimizations"
16441 {
16442 rtx temp;
16443
16444 operands[2] = gen_reg_rtx (XFmode);
16445 operands[3] = gen_reg_rtx (XFmode);
16446 operands[4] = gen_reg_rtx (XFmode);
16447
16448 temp = standard_80387_constant_rtx (4); /* fldln2 */
16449 emit_move_insn (operands[3], temp);
16450 })
16451
16452 (define_expand "logxf2"
16453 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16454 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16455 (match_dup 2)] UNSPEC_FYL2X))
16456 (clobber (match_scratch:XF 3 ""))])]
16457 "TARGET_USE_FANCY_MATH_387
16458 && flag_unsafe_math_optimizations"
16459 {
16460 rtx temp;
16461
16462 operands[2] = gen_reg_rtx (XFmode);
16463 temp = standard_80387_constant_rtx (4); /* fldln2 */
16464 emit_move_insn (operands[2], temp);
16465 })
16466
16467 (define_expand "log10sf2"
16468 [(set (match_dup 2)
16469 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16470 (parallel [(set (match_dup 4)
16471 (unspec:XF [(match_dup 2)
16472 (match_dup 3)] UNSPEC_FYL2X))
16473 (clobber (match_scratch:XF 5 ""))])
16474 (set (match_operand:SF 0 "register_operand" "")
16475 (float_truncate:SF (match_dup 4)))]
16476 "TARGET_USE_FANCY_MATH_387
16477 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16478 && flag_unsafe_math_optimizations"
16479 {
16480 rtx temp;
16481
16482 operands[2] = gen_reg_rtx (XFmode);
16483 operands[3] = gen_reg_rtx (XFmode);
16484 operands[4] = gen_reg_rtx (XFmode);
16485
16486 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16487 emit_move_insn (operands[3], temp);
16488 })
16489
16490 (define_expand "log10df2"
16491 [(set (match_dup 2)
16492 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16493 (parallel [(set (match_dup 4)
16494 (unspec:XF [(match_dup 2)
16495 (match_dup 3)] UNSPEC_FYL2X))
16496 (clobber (match_scratch:XF 5 ""))])
16497 (set (match_operand:DF 0 "register_operand" "")
16498 (float_truncate:DF (match_dup 4)))]
16499 "TARGET_USE_FANCY_MATH_387
16500 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16501 && flag_unsafe_math_optimizations"
16502 {
16503 rtx temp;
16504
16505 operands[2] = gen_reg_rtx (XFmode);
16506 operands[3] = gen_reg_rtx (XFmode);
16507 operands[4] = gen_reg_rtx (XFmode);
16508
16509 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16510 emit_move_insn (operands[3], temp);
16511 })
16512
16513 (define_expand "log10xf2"
16514 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16515 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16516 (match_dup 2)] UNSPEC_FYL2X))
16517 (clobber (match_scratch:XF 3 ""))])]
16518 "TARGET_USE_FANCY_MATH_387
16519 && flag_unsafe_math_optimizations"
16520 {
16521 rtx temp;
16522
16523 operands[2] = gen_reg_rtx (XFmode);
16524 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16525 emit_move_insn (operands[2], temp);
16526 })
16527
16528 (define_expand "log2sf2"
16529 [(set (match_dup 2)
16530 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16531 (parallel [(set (match_dup 4)
16532 (unspec:XF [(match_dup 2)
16533 (match_dup 3)] UNSPEC_FYL2X))
16534 (clobber (match_scratch:XF 5 ""))])
16535 (set (match_operand:SF 0 "register_operand" "")
16536 (float_truncate:SF (match_dup 4)))]
16537 "TARGET_USE_FANCY_MATH_387
16538 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16539 && flag_unsafe_math_optimizations"
16540 {
16541 operands[2] = gen_reg_rtx (XFmode);
16542 operands[3] = gen_reg_rtx (XFmode);
16543 operands[4] = gen_reg_rtx (XFmode);
16544
16545 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16546 })
16547
16548 (define_expand "log2df2"
16549 [(set (match_dup 2)
16550 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16551 (parallel [(set (match_dup 4)
16552 (unspec:XF [(match_dup 2)
16553 (match_dup 3)] UNSPEC_FYL2X))
16554 (clobber (match_scratch:XF 5 ""))])
16555 (set (match_operand:DF 0 "register_operand" "")
16556 (float_truncate:DF (match_dup 4)))]
16557 "TARGET_USE_FANCY_MATH_387
16558 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16559 && flag_unsafe_math_optimizations"
16560 {
16561 operands[2] = gen_reg_rtx (XFmode);
16562 operands[3] = gen_reg_rtx (XFmode);
16563 operands[4] = gen_reg_rtx (XFmode);
16564
16565 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16566 })
16567
16568 (define_expand "log2xf2"
16569 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16570 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16571 (match_dup 2)] UNSPEC_FYL2X))
16572 (clobber (match_scratch:XF 3 ""))])]
16573 "TARGET_USE_FANCY_MATH_387
16574 && flag_unsafe_math_optimizations"
16575 {
16576 operands[2] = gen_reg_rtx (XFmode);
16577 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16578 })
16579
16580 (define_insn "fyl2xp1_xf3"
16581 [(set (match_operand:XF 0 "register_operand" "=f")
16582 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16583 (match_operand:XF 1 "register_operand" "u")]
16584 UNSPEC_FYL2XP1))
16585 (clobber (match_scratch:XF 3 "=1"))]
16586 "TARGET_USE_FANCY_MATH_387
16587 && flag_unsafe_math_optimizations"
16588 "fyl2xp1"
16589 [(set_attr "type" "fpspc")
16590 (set_attr "mode" "XF")])
16591
16592 (define_expand "log1psf2"
16593 [(use (match_operand:SF 0 "register_operand" ""))
16594 (use (match_operand:SF 1 "register_operand" ""))]
16595 "TARGET_USE_FANCY_MATH_387
16596 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16597 && flag_unsafe_math_optimizations"
16598 {
16599 rtx op0 = gen_reg_rtx (XFmode);
16600 rtx op1 = gen_reg_rtx (XFmode);
16601
16602 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16603 ix86_emit_i387_log1p (op0, op1);
16604 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16605 DONE;
16606 })
16607
16608 (define_expand "log1pdf2"
16609 [(use (match_operand:DF 0 "register_operand" ""))
16610 (use (match_operand:DF 1 "register_operand" ""))]
16611 "TARGET_USE_FANCY_MATH_387
16612 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16613 && flag_unsafe_math_optimizations"
16614 {
16615 rtx op0 = gen_reg_rtx (XFmode);
16616 rtx op1 = gen_reg_rtx (XFmode);
16617
16618 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16619 ix86_emit_i387_log1p (op0, op1);
16620 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16621 DONE;
16622 })
16623
16624 (define_expand "log1pxf2"
16625 [(use (match_operand:XF 0 "register_operand" ""))
16626 (use (match_operand:XF 1 "register_operand" ""))]
16627 "TARGET_USE_FANCY_MATH_387
16628 && flag_unsafe_math_optimizations"
16629 {
16630 ix86_emit_i387_log1p (operands[0], operands[1]);
16631 DONE;
16632 })
16633
16634 (define_insn "*fxtractxf3"
16635 [(set (match_operand:XF 0 "register_operand" "=f")
16636 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16637 UNSPEC_XTRACT_FRACT))
16638 (set (match_operand:XF 1 "register_operand" "=u")
16639 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16640 "TARGET_USE_FANCY_MATH_387
16641 && flag_unsafe_math_optimizations"
16642 "fxtract"
16643 [(set_attr "type" "fpspc")
16644 (set_attr "mode" "XF")])
16645
16646 (define_expand "logbsf2"
16647 [(set (match_dup 2)
16648 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16649 (parallel [(set (match_dup 3)
16650 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16651 (set (match_dup 4)
16652 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16653 (set (match_operand:SF 0 "register_operand" "")
16654 (float_truncate:SF (match_dup 4)))]
16655 "TARGET_USE_FANCY_MATH_387
16656 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16657 && flag_unsafe_math_optimizations"
16658 {
16659 operands[2] = gen_reg_rtx (XFmode);
16660 operands[3] = gen_reg_rtx (XFmode);
16661 operands[4] = gen_reg_rtx (XFmode);
16662 })
16663
16664 (define_expand "logbdf2"
16665 [(set (match_dup 2)
16666 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16667 (parallel [(set (match_dup 3)
16668 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16669 (set (match_dup 4)
16670 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16671 (set (match_operand:DF 0 "register_operand" "")
16672 (float_truncate:DF (match_dup 4)))]
16673 "TARGET_USE_FANCY_MATH_387
16674 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16675 && flag_unsafe_math_optimizations"
16676 {
16677 operands[2] = gen_reg_rtx (XFmode);
16678 operands[3] = gen_reg_rtx (XFmode);
16679 operands[4] = gen_reg_rtx (XFmode);
16680 })
16681
16682 (define_expand "logbxf2"
16683 [(parallel [(set (match_dup 2)
16684 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16685 UNSPEC_XTRACT_FRACT))
16686 (set (match_operand:XF 0 "register_operand" "")
16687 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16688 "TARGET_USE_FANCY_MATH_387
16689 && flag_unsafe_math_optimizations"
16690 {
16691 operands[2] = gen_reg_rtx (XFmode);
16692 })
16693
16694 (define_expand "ilogbsi2"
16695 [(parallel [(set (match_dup 2)
16696 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16697 UNSPEC_XTRACT_FRACT))
16698 (set (match_operand:XF 3 "register_operand" "")
16699 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16700 (parallel [(set (match_operand:SI 0 "register_operand" "")
16701 (fix:SI (match_dup 3)))
16702 (clobber (reg:CC FLAGS_REG))])]
16703 "TARGET_USE_FANCY_MATH_387
16704 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16705 && flag_unsafe_math_optimizations"
16706 {
16707 operands[2] = gen_reg_rtx (XFmode);
16708 operands[3] = gen_reg_rtx (XFmode);
16709 })
16710
16711 (define_insn "*f2xm1xf2"
16712 [(set (match_operand:XF 0 "register_operand" "=f")
16713 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16714 UNSPEC_F2XM1))]
16715 "TARGET_USE_FANCY_MATH_387
16716 && flag_unsafe_math_optimizations"
16717 "f2xm1"
16718 [(set_attr "type" "fpspc")
16719 (set_attr "mode" "XF")])
16720
16721 (define_insn "*fscalexf4"
16722 [(set (match_operand:XF 0 "register_operand" "=f")
16723 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16724 (match_operand:XF 3 "register_operand" "1")]
16725 UNSPEC_FSCALE_FRACT))
16726 (set (match_operand:XF 1 "register_operand" "=u")
16727 (unspec:XF [(match_dup 2) (match_dup 3)]
16728 UNSPEC_FSCALE_EXP))]
16729 "TARGET_USE_FANCY_MATH_387
16730 && flag_unsafe_math_optimizations"
16731 "fscale"
16732 [(set_attr "type" "fpspc")
16733 (set_attr "mode" "XF")])
16734
16735 (define_expand "expsf2"
16736 [(set (match_dup 2)
16737 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16738 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16739 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16740 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16741 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16742 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16743 (parallel [(set (match_dup 10)
16744 (unspec:XF [(match_dup 9) (match_dup 5)]
16745 UNSPEC_FSCALE_FRACT))
16746 (set (match_dup 11)
16747 (unspec:XF [(match_dup 9) (match_dup 5)]
16748 UNSPEC_FSCALE_EXP))])
16749 (set (match_operand:SF 0 "register_operand" "")
16750 (float_truncate:SF (match_dup 10)))]
16751 "TARGET_USE_FANCY_MATH_387
16752 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16753 && flag_unsafe_math_optimizations"
16754 {
16755 rtx temp;
16756 int i;
16757
16758 for (i=2; i<12; i++)
16759 operands[i] = gen_reg_rtx (XFmode);
16760 temp = standard_80387_constant_rtx (5); /* fldl2e */
16761 emit_move_insn (operands[3], temp);
16762 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16763 })
16764
16765 (define_expand "expdf2"
16766 [(set (match_dup 2)
16767 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16768 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16769 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16770 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16771 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16772 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16773 (parallel [(set (match_dup 10)
16774 (unspec:XF [(match_dup 9) (match_dup 5)]
16775 UNSPEC_FSCALE_FRACT))
16776 (set (match_dup 11)
16777 (unspec:XF [(match_dup 9) (match_dup 5)]
16778 UNSPEC_FSCALE_EXP))])
16779 (set (match_operand:DF 0 "register_operand" "")
16780 (float_truncate:DF (match_dup 10)))]
16781 "TARGET_USE_FANCY_MATH_387
16782 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16783 && flag_unsafe_math_optimizations"
16784 {
16785 rtx temp;
16786 int i;
16787
16788 for (i=2; i<12; i++)
16789 operands[i] = gen_reg_rtx (XFmode);
16790 temp = standard_80387_constant_rtx (5); /* fldl2e */
16791 emit_move_insn (operands[3], temp);
16792 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16793 })
16794
16795 (define_expand "expxf2"
16796 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16797 (match_dup 2)))
16798 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16799 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16800 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16801 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16802 (parallel [(set (match_operand:XF 0 "register_operand" "")
16803 (unspec:XF [(match_dup 8) (match_dup 4)]
16804 UNSPEC_FSCALE_FRACT))
16805 (set (match_dup 9)
16806 (unspec:XF [(match_dup 8) (match_dup 4)]
16807 UNSPEC_FSCALE_EXP))])]
16808 "TARGET_USE_FANCY_MATH_387
16809 && flag_unsafe_math_optimizations"
16810 {
16811 rtx temp;
16812 int i;
16813
16814 for (i=2; i<10; i++)
16815 operands[i] = gen_reg_rtx (XFmode);
16816 temp = standard_80387_constant_rtx (5); /* fldl2e */
16817 emit_move_insn (operands[2], temp);
16818 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16819 })
16820
16821 (define_expand "exp10sf2"
16822 [(set (match_dup 2)
16823 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16824 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16825 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16826 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16827 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16828 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16829 (parallel [(set (match_dup 10)
16830 (unspec:XF [(match_dup 9) (match_dup 5)]
16831 UNSPEC_FSCALE_FRACT))
16832 (set (match_dup 11)
16833 (unspec:XF [(match_dup 9) (match_dup 5)]
16834 UNSPEC_FSCALE_EXP))])
16835 (set (match_operand:SF 0 "register_operand" "")
16836 (float_truncate:SF (match_dup 10)))]
16837 "TARGET_USE_FANCY_MATH_387
16838 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16839 && flag_unsafe_math_optimizations"
16840 {
16841 rtx temp;
16842 int i;
16843
16844 for (i=2; i<12; i++)
16845 operands[i] = gen_reg_rtx (XFmode);
16846 temp = standard_80387_constant_rtx (6); /* fldl2t */
16847 emit_move_insn (operands[3], temp);
16848 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16849 })
16850
16851 (define_expand "exp10df2"
16852 [(set (match_dup 2)
16853 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16854 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16855 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16856 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16857 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16858 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16859 (parallel [(set (match_dup 10)
16860 (unspec:XF [(match_dup 9) (match_dup 5)]
16861 UNSPEC_FSCALE_FRACT))
16862 (set (match_dup 11)
16863 (unspec:XF [(match_dup 9) (match_dup 5)]
16864 UNSPEC_FSCALE_EXP))])
16865 (set (match_operand:DF 0 "register_operand" "")
16866 (float_truncate:DF (match_dup 10)))]
16867 "TARGET_USE_FANCY_MATH_387
16868 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16869 && flag_unsafe_math_optimizations"
16870 {
16871 rtx temp;
16872 int i;
16873
16874 for (i=2; i<12; i++)
16875 operands[i] = gen_reg_rtx (XFmode);
16876 temp = standard_80387_constant_rtx (6); /* fldl2t */
16877 emit_move_insn (operands[3], temp);
16878 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16879 })
16880
16881 (define_expand "exp10xf2"
16882 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16883 (match_dup 2)))
16884 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16885 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16886 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16887 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16888 (parallel [(set (match_operand:XF 0 "register_operand" "")
16889 (unspec:XF [(match_dup 8) (match_dup 4)]
16890 UNSPEC_FSCALE_FRACT))
16891 (set (match_dup 9)
16892 (unspec:XF [(match_dup 8) (match_dup 4)]
16893 UNSPEC_FSCALE_EXP))])]
16894 "TARGET_USE_FANCY_MATH_387
16895 && flag_unsafe_math_optimizations"
16896 {
16897 rtx temp;
16898 int i;
16899
16900 for (i=2; i<10; i++)
16901 operands[i] = gen_reg_rtx (XFmode);
16902 temp = standard_80387_constant_rtx (6); /* fldl2t */
16903 emit_move_insn (operands[2], temp);
16904 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16905 })
16906
16907 (define_expand "exp2sf2"
16908 [(set (match_dup 2)
16909 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16910 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16911 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16912 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16913 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16914 (parallel [(set (match_dup 8)
16915 (unspec:XF [(match_dup 7) (match_dup 3)]
16916 UNSPEC_FSCALE_FRACT))
16917 (set (match_dup 9)
16918 (unspec:XF [(match_dup 7) (match_dup 3)]
16919 UNSPEC_FSCALE_EXP))])
16920 (set (match_operand:SF 0 "register_operand" "")
16921 (float_truncate:SF (match_dup 8)))]
16922 "TARGET_USE_FANCY_MATH_387
16923 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16924 && flag_unsafe_math_optimizations"
16925 {
16926 int i;
16927
16928 for (i=2; i<10; i++)
16929 operands[i] = gen_reg_rtx (XFmode);
16930 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16931 })
16932
16933 (define_expand "exp2df2"
16934 [(set (match_dup 2)
16935 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16936 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16937 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16938 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16939 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16940 (parallel [(set (match_dup 8)
16941 (unspec:XF [(match_dup 7) (match_dup 3)]
16942 UNSPEC_FSCALE_FRACT))
16943 (set (match_dup 9)
16944 (unspec:XF [(match_dup 7) (match_dup 3)]
16945 UNSPEC_FSCALE_EXP))])
16946 (set (match_operand:DF 0 "register_operand" "")
16947 (float_truncate:DF (match_dup 8)))]
16948 "TARGET_USE_FANCY_MATH_387
16949 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16950 && flag_unsafe_math_optimizations"
16951 {
16952 int i;
16953
16954 for (i=2; i<10; i++)
16955 operands[i] = gen_reg_rtx (XFmode);
16956 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16957 })
16958
16959 (define_expand "exp2xf2"
16960 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16961 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16962 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16963 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16964 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16965 (parallel [(set (match_operand:XF 0 "register_operand" "")
16966 (unspec:XF [(match_dup 7) (match_dup 3)]
16967 UNSPEC_FSCALE_FRACT))
16968 (set (match_dup 8)
16969 (unspec:XF [(match_dup 7) (match_dup 3)]
16970 UNSPEC_FSCALE_EXP))])]
16971 "TARGET_USE_FANCY_MATH_387
16972 && flag_unsafe_math_optimizations"
16973 {
16974 int i;
16975
16976 for (i=2; i<9; i++)
16977 operands[i] = gen_reg_rtx (XFmode);
16978 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16979 })
16980
16981 (define_expand "expm1df2"
16982 [(set (match_dup 2)
16983 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16984 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16985 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16986 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16987 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16988 (parallel [(set (match_dup 8)
16989 (unspec:XF [(match_dup 7) (match_dup 5)]
16990 UNSPEC_FSCALE_FRACT))
16991 (set (match_dup 9)
16992 (unspec:XF [(match_dup 7) (match_dup 5)]
16993 UNSPEC_FSCALE_EXP))])
16994 (parallel [(set (match_dup 11)
16995 (unspec:XF [(match_dup 10) (match_dup 9)]
16996 UNSPEC_FSCALE_FRACT))
16997 (set (match_dup 12)
16998 (unspec:XF [(match_dup 10) (match_dup 9)]
16999 UNSPEC_FSCALE_EXP))])
17000 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17001 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17002 (set (match_operand:DF 0 "register_operand" "")
17003 (float_truncate:DF (match_dup 14)))]
17004 "TARGET_USE_FANCY_MATH_387
17005 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17006 && flag_unsafe_math_optimizations"
17007 {
17008 rtx temp;
17009 int i;
17010
17011 for (i=2; i<15; i++)
17012 operands[i] = gen_reg_rtx (XFmode);
17013 temp = standard_80387_constant_rtx (5); /* fldl2e */
17014 emit_move_insn (operands[3], temp);
17015 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17016 })
17017
17018 (define_expand "expm1sf2"
17019 [(set (match_dup 2)
17020 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17021 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17022 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17023 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17024 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17025 (parallel [(set (match_dup 8)
17026 (unspec:XF [(match_dup 7) (match_dup 5)]
17027 UNSPEC_FSCALE_FRACT))
17028 (set (match_dup 9)
17029 (unspec:XF [(match_dup 7) (match_dup 5)]
17030 UNSPEC_FSCALE_EXP))])
17031 (parallel [(set (match_dup 11)
17032 (unspec:XF [(match_dup 10) (match_dup 9)]
17033 UNSPEC_FSCALE_FRACT))
17034 (set (match_dup 12)
17035 (unspec:XF [(match_dup 10) (match_dup 9)]
17036 UNSPEC_FSCALE_EXP))])
17037 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17038 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17039 (set (match_operand:SF 0 "register_operand" "")
17040 (float_truncate:SF (match_dup 14)))]
17041 "TARGET_USE_FANCY_MATH_387
17042 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17043 && flag_unsafe_math_optimizations"
17044 {
17045 rtx temp;
17046 int i;
17047
17048 for (i=2; i<15; i++)
17049 operands[i] = gen_reg_rtx (XFmode);
17050 temp = standard_80387_constant_rtx (5); /* fldl2e */
17051 emit_move_insn (operands[3], temp);
17052 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17053 })
17054
17055 (define_expand "expm1xf2"
17056 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17057 (match_dup 2)))
17058 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17059 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17060 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17061 (parallel [(set (match_dup 7)
17062 (unspec:XF [(match_dup 6) (match_dup 4)]
17063 UNSPEC_FSCALE_FRACT))
17064 (set (match_dup 8)
17065 (unspec:XF [(match_dup 6) (match_dup 4)]
17066 UNSPEC_FSCALE_EXP))])
17067 (parallel [(set (match_dup 10)
17068 (unspec:XF [(match_dup 9) (match_dup 8)]
17069 UNSPEC_FSCALE_FRACT))
17070 (set (match_dup 11)
17071 (unspec:XF [(match_dup 9) (match_dup 8)]
17072 UNSPEC_FSCALE_EXP))])
17073 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17074 (set (match_operand:XF 0 "register_operand" "")
17075 (plus:XF (match_dup 12) (match_dup 7)))]
17076 "TARGET_USE_FANCY_MATH_387
17077 && flag_unsafe_math_optimizations"
17078 {
17079 rtx temp;
17080 int i;
17081
17082 for (i=2; i<13; i++)
17083 operands[i] = gen_reg_rtx (XFmode);
17084 temp = standard_80387_constant_rtx (5); /* fldl2e */
17085 emit_move_insn (operands[2], temp);
17086 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17087 })
17088
17089 (define_expand "ldexpdf3"
17090 [(set (match_dup 3)
17091 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17092 (set (match_dup 4)
17093 (float:XF (match_operand:SI 2 "register_operand" "")))
17094 (parallel [(set (match_dup 5)
17095 (unspec:XF [(match_dup 3) (match_dup 4)]
17096 UNSPEC_FSCALE_FRACT))
17097 (set (match_dup 6)
17098 (unspec:XF [(match_dup 3) (match_dup 4)]
17099 UNSPEC_FSCALE_EXP))])
17100 (set (match_operand:DF 0 "register_operand" "")
17101 (float_truncate:DF (match_dup 5)))]
17102 "TARGET_USE_FANCY_MATH_387
17103 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17104 && flag_unsafe_math_optimizations"
17105 {
17106 int i;
17107
17108 for (i=3; i<7; i++)
17109 operands[i] = gen_reg_rtx (XFmode);
17110 })
17111
17112 (define_expand "ldexpsf3"
17113 [(set (match_dup 3)
17114 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17115 (set (match_dup 4)
17116 (float:XF (match_operand:SI 2 "register_operand" "")))
17117 (parallel [(set (match_dup 5)
17118 (unspec:XF [(match_dup 3) (match_dup 4)]
17119 UNSPEC_FSCALE_FRACT))
17120 (set (match_dup 6)
17121 (unspec:XF [(match_dup 3) (match_dup 4)]
17122 UNSPEC_FSCALE_EXP))])
17123 (set (match_operand:SF 0 "register_operand" "")
17124 (float_truncate:SF (match_dup 5)))]
17125 "TARGET_USE_FANCY_MATH_387
17126 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17127 && flag_unsafe_math_optimizations"
17128 {
17129 int i;
17130
17131 for (i=3; i<7; i++)
17132 operands[i] = gen_reg_rtx (XFmode);
17133 })
17134
17135 (define_expand "ldexpxf3"
17136 [(set (match_dup 3)
17137 (float:XF (match_operand:SI 2 "register_operand" "")))
17138 (parallel [(set (match_operand:XF 0 " register_operand" "")
17139 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17140 (match_dup 3)]
17141 UNSPEC_FSCALE_FRACT))
17142 (set (match_dup 4)
17143 (unspec:XF [(match_dup 1) (match_dup 3)]
17144 UNSPEC_FSCALE_EXP))])]
17145 "TARGET_USE_FANCY_MATH_387
17146 && flag_unsafe_math_optimizations"
17147 {
17148 int i;
17149
17150 for (i=3; i<5; i++)
17151 operands[i] = gen_reg_rtx (XFmode);
17152 })
17153 \f
17154
17155 (define_insn "frndintxf2"
17156 [(set (match_operand:XF 0 "register_operand" "=f")
17157 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17158 UNSPEC_FRNDINT))]
17159 "TARGET_USE_FANCY_MATH_387
17160 && flag_unsafe_math_optimizations"
17161 "frndint"
17162 [(set_attr "type" "fpspc")
17163 (set_attr "mode" "XF")])
17164
17165 (define_expand "rintdf2"
17166 [(use (match_operand:DF 0 "register_operand" ""))
17167 (use (match_operand:DF 1 "register_operand" ""))]
17168 "TARGET_USE_FANCY_MATH_387
17169 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17170 && flag_unsafe_math_optimizations"
17171 {
17172 rtx op0 = gen_reg_rtx (XFmode);
17173 rtx op1 = gen_reg_rtx (XFmode);
17174
17175 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17176 emit_insn (gen_frndintxf2 (op0, op1));
17177
17178 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17179 DONE;
17180 })
17181
17182 (define_expand "rintsf2"
17183 [(use (match_operand:SF 0 "register_operand" ""))
17184 (use (match_operand:SF 1 "register_operand" ""))]
17185 "TARGET_USE_FANCY_MATH_387
17186 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17187 && flag_unsafe_math_optimizations"
17188 {
17189 rtx op0 = gen_reg_rtx (XFmode);
17190 rtx op1 = gen_reg_rtx (XFmode);
17191
17192 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17193 emit_insn (gen_frndintxf2 (op0, op1));
17194
17195 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17196 DONE;
17197 })
17198
17199 (define_expand "rintxf2"
17200 [(use (match_operand:XF 0 "register_operand" ""))
17201 (use (match_operand:XF 1 "register_operand" ""))]
17202 "TARGET_USE_FANCY_MATH_387
17203 && flag_unsafe_math_optimizations"
17204 {
17205 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17206 DONE;
17207 })
17208
17209 (define_insn_and_split "*fistdi2_1"
17210 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17211 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17212 UNSPEC_FIST))]
17213 "TARGET_USE_FANCY_MATH_387
17214 && flag_unsafe_math_optimizations
17215 && !(reload_completed || reload_in_progress)"
17216 "#"
17217 "&& 1"
17218 [(const_int 0)]
17219 {
17220 if (memory_operand (operands[0], VOIDmode))
17221 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17222 else
17223 {
17224 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17225 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17226 operands[2]));
17227 }
17228 DONE;
17229 }
17230 [(set_attr "type" "fpspc")
17231 (set_attr "mode" "DI")])
17232
17233 (define_insn "fistdi2"
17234 [(set (match_operand:DI 0 "memory_operand" "=m")
17235 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17236 UNSPEC_FIST))
17237 (clobber (match_scratch:XF 2 "=&1f"))]
17238 "TARGET_USE_FANCY_MATH_387
17239 && flag_unsafe_math_optimizations"
17240 "* return output_fix_trunc (insn, operands, 0);"
17241 [(set_attr "type" "fpspc")
17242 (set_attr "mode" "DI")])
17243
17244 (define_insn "fistdi2_with_temp"
17245 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17246 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17247 UNSPEC_FIST))
17248 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17249 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17250 "TARGET_USE_FANCY_MATH_387
17251 && flag_unsafe_math_optimizations"
17252 "#"
17253 [(set_attr "type" "fpspc")
17254 (set_attr "mode" "DI")])
17255
17256 (define_split
17257 [(set (match_operand:DI 0 "register_operand" "")
17258 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17259 UNSPEC_FIST))
17260 (clobber (match_operand:DI 2 "memory_operand" ""))
17261 (clobber (match_scratch 3 ""))]
17262 "reload_completed"
17263 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17264 (clobber (match_dup 3))])
17265 (set (match_dup 0) (match_dup 2))]
17266 "")
17267
17268 (define_split
17269 [(set (match_operand:DI 0 "memory_operand" "")
17270 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17271 UNSPEC_FIST))
17272 (clobber (match_operand:DI 2 "memory_operand" ""))
17273 (clobber (match_scratch 3 ""))]
17274 "reload_completed"
17275 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17276 (clobber (match_dup 3))])]
17277 "")
17278
17279 (define_insn_and_split "*fist<mode>2_1"
17280 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17281 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17282 UNSPEC_FIST))]
17283 "TARGET_USE_FANCY_MATH_387
17284 && flag_unsafe_math_optimizations
17285 && !(reload_completed || reload_in_progress)"
17286 "#"
17287 "&& 1"
17288 [(const_int 0)]
17289 {
17290 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17291 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17292 operands[2]));
17293 DONE;
17294 }
17295 [(set_attr "type" "fpspc")
17296 (set_attr "mode" "<MODE>")])
17297
17298 (define_insn "fist<mode>2"
17299 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17300 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17301 UNSPEC_FIST))]
17302 "TARGET_USE_FANCY_MATH_387
17303 && flag_unsafe_math_optimizations"
17304 "* return output_fix_trunc (insn, operands, 0);"
17305 [(set_attr "type" "fpspc")
17306 (set_attr "mode" "<MODE>")])
17307
17308 (define_insn "fist<mode>2_with_temp"
17309 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17310 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17311 UNSPEC_FIST))
17312 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17313 "TARGET_USE_FANCY_MATH_387
17314 && flag_unsafe_math_optimizations"
17315 "#"
17316 [(set_attr "type" "fpspc")
17317 (set_attr "mode" "<MODE>")])
17318
17319 (define_split
17320 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17321 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17322 UNSPEC_FIST))
17323 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17324 "reload_completed"
17325 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17326 UNSPEC_FIST))
17327 (set (match_dup 0) (match_dup 2))]
17328 "")
17329
17330 (define_split
17331 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17332 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17333 UNSPEC_FIST))
17334 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17335 "reload_completed"
17336 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17337 UNSPEC_FIST))]
17338 "")
17339
17340 (define_expand "lrint<mode>2"
17341 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17342 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17343 UNSPEC_FIST))]
17344 "TARGET_USE_FANCY_MATH_387
17345 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17346 && flag_unsafe_math_optimizations"
17347 "")
17348
17349 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17350 (define_insn_and_split "frndintxf2_floor"
17351 [(set (match_operand:XF 0 "register_operand" "=f")
17352 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17353 UNSPEC_FRNDINT_FLOOR))
17354 (clobber (reg:CC FLAGS_REG))]
17355 "TARGET_USE_FANCY_MATH_387
17356 && flag_unsafe_math_optimizations
17357 && !(reload_completed || reload_in_progress)"
17358 "#"
17359 "&& 1"
17360 [(const_int 0)]
17361 {
17362 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17363
17364 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17365 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17366
17367 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17368 operands[2], operands[3]));
17369 DONE;
17370 }
17371 [(set_attr "type" "frndint")
17372 (set_attr "i387_cw" "floor")
17373 (set_attr "mode" "XF")])
17374
17375 (define_insn "frndintxf2_floor_i387"
17376 [(set (match_operand:XF 0 "register_operand" "=f")
17377 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17378 UNSPEC_FRNDINT_FLOOR))
17379 (use (match_operand:HI 2 "memory_operand" "m"))
17380 (use (match_operand:HI 3 "memory_operand" "m"))]
17381 "TARGET_USE_FANCY_MATH_387
17382 && flag_unsafe_math_optimizations"
17383 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17384 [(set_attr "type" "frndint")
17385 (set_attr "i387_cw" "floor")
17386 (set_attr "mode" "XF")])
17387
17388 (define_expand "floorxf2"
17389 [(use (match_operand:XF 0 "register_operand" ""))
17390 (use (match_operand:XF 1 "register_operand" ""))]
17391 "TARGET_USE_FANCY_MATH_387
17392 && flag_unsafe_math_optimizations"
17393 {
17394 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17395 DONE;
17396 })
17397
17398 (define_expand "floordf2"
17399 [(use (match_operand:DF 0 "register_operand" ""))
17400 (use (match_operand:DF 1 "register_operand" ""))]
17401 "TARGET_USE_FANCY_MATH_387
17402 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17403 && flag_unsafe_math_optimizations"
17404 {
17405 rtx op0 = gen_reg_rtx (XFmode);
17406 rtx op1 = gen_reg_rtx (XFmode);
17407
17408 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17409 emit_insn (gen_frndintxf2_floor (op0, op1));
17410
17411 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17412 DONE;
17413 })
17414
17415 (define_expand "floorsf2"
17416 [(use (match_operand:SF 0 "register_operand" ""))
17417 (use (match_operand:SF 1 "register_operand" ""))]
17418 "TARGET_USE_FANCY_MATH_387
17419 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17420 && flag_unsafe_math_optimizations"
17421 {
17422 rtx op0 = gen_reg_rtx (XFmode);
17423 rtx op1 = gen_reg_rtx (XFmode);
17424
17425 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17426 emit_insn (gen_frndintxf2_floor (op0, op1));
17427
17428 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17429 DONE;
17430 })
17431
17432 (define_insn_and_split "*fist<mode>2_floor_1"
17433 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17434 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17435 UNSPEC_FIST_FLOOR))
17436 (clobber (reg:CC FLAGS_REG))]
17437 "TARGET_USE_FANCY_MATH_387
17438 && flag_unsafe_math_optimizations
17439 && !(reload_completed || reload_in_progress)"
17440 "#"
17441 "&& 1"
17442 [(const_int 0)]
17443 {
17444 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17445
17446 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17447 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17448 if (memory_operand (operands[0], VOIDmode))
17449 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17450 operands[2], operands[3]));
17451 else
17452 {
17453 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17454 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17455 operands[2], operands[3],
17456 operands[4]));
17457 }
17458 DONE;
17459 }
17460 [(set_attr "type" "fistp")
17461 (set_attr "i387_cw" "floor")
17462 (set_attr "mode" "<MODE>")])
17463
17464 (define_insn "fistdi2_floor"
17465 [(set (match_operand:DI 0 "memory_operand" "=m")
17466 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17467 UNSPEC_FIST_FLOOR))
17468 (use (match_operand:HI 2 "memory_operand" "m"))
17469 (use (match_operand:HI 3 "memory_operand" "m"))
17470 (clobber (match_scratch:XF 4 "=&1f"))]
17471 "TARGET_USE_FANCY_MATH_387
17472 && flag_unsafe_math_optimizations"
17473 "* return output_fix_trunc (insn, operands, 0);"
17474 [(set_attr "type" "fistp")
17475 (set_attr "i387_cw" "floor")
17476 (set_attr "mode" "DI")])
17477
17478 (define_insn "fistdi2_floor_with_temp"
17479 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17480 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17481 UNSPEC_FIST_FLOOR))
17482 (use (match_operand:HI 2 "memory_operand" "m,m"))
17483 (use (match_operand:HI 3 "memory_operand" "m,m"))
17484 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17485 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17486 "TARGET_USE_FANCY_MATH_387
17487 && flag_unsafe_math_optimizations"
17488 "#"
17489 [(set_attr "type" "fistp")
17490 (set_attr "i387_cw" "floor")
17491 (set_attr "mode" "DI")])
17492
17493 (define_split
17494 [(set (match_operand:DI 0 "register_operand" "")
17495 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17496 UNSPEC_FIST_FLOOR))
17497 (use (match_operand:HI 2 "memory_operand" ""))
17498 (use (match_operand:HI 3 "memory_operand" ""))
17499 (clobber (match_operand:DI 4 "memory_operand" ""))
17500 (clobber (match_scratch 5 ""))]
17501 "reload_completed"
17502 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17503 (use (match_dup 2))
17504 (use (match_dup 3))
17505 (clobber (match_dup 5))])
17506 (set (match_dup 0) (match_dup 4))]
17507 "")
17508
17509 (define_split
17510 [(set (match_operand:DI 0 "memory_operand" "")
17511 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17512 UNSPEC_FIST_FLOOR))
17513 (use (match_operand:HI 2 "memory_operand" ""))
17514 (use (match_operand:HI 3 "memory_operand" ""))
17515 (clobber (match_operand:DI 4 "memory_operand" ""))
17516 (clobber (match_scratch 5 ""))]
17517 "reload_completed"
17518 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17519 (use (match_dup 2))
17520 (use (match_dup 3))
17521 (clobber (match_dup 5))])]
17522 "")
17523
17524 (define_insn "fist<mode>2_floor"
17525 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17526 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17527 UNSPEC_FIST_FLOOR))
17528 (use (match_operand:HI 2 "memory_operand" "m"))
17529 (use (match_operand:HI 3 "memory_operand" "m"))]
17530 "TARGET_USE_FANCY_MATH_387
17531 && flag_unsafe_math_optimizations"
17532 "* return output_fix_trunc (insn, operands, 0);"
17533 [(set_attr "type" "fistp")
17534 (set_attr "i387_cw" "floor")
17535 (set_attr "mode" "<MODE>")])
17536
17537 (define_insn "fist<mode>2_floor_with_temp"
17538 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17539 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17540 UNSPEC_FIST_FLOOR))
17541 (use (match_operand:HI 2 "memory_operand" "m,m"))
17542 (use (match_operand:HI 3 "memory_operand" "m,m"))
17543 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17544 "TARGET_USE_FANCY_MATH_387
17545 && flag_unsafe_math_optimizations"
17546 "#"
17547 [(set_attr "type" "fistp")
17548 (set_attr "i387_cw" "floor")
17549 (set_attr "mode" "<MODE>")])
17550
17551 (define_split
17552 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17553 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17554 UNSPEC_FIST_FLOOR))
17555 (use (match_operand:HI 2 "memory_operand" ""))
17556 (use (match_operand:HI 3 "memory_operand" ""))
17557 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17558 "reload_completed"
17559 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17560 UNSPEC_FIST_FLOOR))
17561 (use (match_dup 2))
17562 (use (match_dup 3))])
17563 (set (match_dup 0) (match_dup 4))]
17564 "")
17565
17566 (define_split
17567 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17568 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17569 UNSPEC_FIST_FLOOR))
17570 (use (match_operand:HI 2 "memory_operand" ""))
17571 (use (match_operand:HI 3 "memory_operand" ""))
17572 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17573 "reload_completed"
17574 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17575 UNSPEC_FIST_FLOOR))
17576 (use (match_dup 2))
17577 (use (match_dup 3))])]
17578 "")
17579
17580 (define_expand "lfloor<mode>2"
17581 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17582 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17583 UNSPEC_FIST_FLOOR))
17584 (clobber (reg:CC FLAGS_REG))])]
17585 "TARGET_USE_FANCY_MATH_387
17586 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17587 && flag_unsafe_math_optimizations"
17588 "")
17589
17590 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17591 (define_insn_and_split "frndintxf2_ceil"
17592 [(set (match_operand:XF 0 "register_operand" "=f")
17593 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17594 UNSPEC_FRNDINT_CEIL))
17595 (clobber (reg:CC FLAGS_REG))]
17596 "TARGET_USE_FANCY_MATH_387
17597 && flag_unsafe_math_optimizations
17598 && !(reload_completed || reload_in_progress)"
17599 "#"
17600 "&& 1"
17601 [(const_int 0)]
17602 {
17603 ix86_optimize_mode_switching[I387_CEIL] = 1;
17604
17605 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17606 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17607
17608 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17609 operands[2], operands[3]));
17610 DONE;
17611 }
17612 [(set_attr "type" "frndint")
17613 (set_attr "i387_cw" "ceil")
17614 (set_attr "mode" "XF")])
17615
17616 (define_insn "frndintxf2_ceil_i387"
17617 [(set (match_operand:XF 0 "register_operand" "=f")
17618 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17619 UNSPEC_FRNDINT_CEIL))
17620 (use (match_operand:HI 2 "memory_operand" "m"))
17621 (use (match_operand:HI 3 "memory_operand" "m"))]
17622 "TARGET_USE_FANCY_MATH_387
17623 && flag_unsafe_math_optimizations"
17624 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17625 [(set_attr "type" "frndint")
17626 (set_attr "i387_cw" "ceil")
17627 (set_attr "mode" "XF")])
17628
17629 (define_expand "ceilxf2"
17630 [(use (match_operand:XF 0 "register_operand" ""))
17631 (use (match_operand:XF 1 "register_operand" ""))]
17632 "TARGET_USE_FANCY_MATH_387
17633 && flag_unsafe_math_optimizations"
17634 {
17635 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17636 DONE;
17637 })
17638
17639 (define_expand "ceildf2"
17640 [(use (match_operand:DF 0 "register_operand" ""))
17641 (use (match_operand:DF 1 "register_operand" ""))]
17642 "TARGET_USE_FANCY_MATH_387
17643 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17644 && flag_unsafe_math_optimizations"
17645 {
17646 rtx op0 = gen_reg_rtx (XFmode);
17647 rtx op1 = gen_reg_rtx (XFmode);
17648
17649 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17650 emit_insn (gen_frndintxf2_ceil (op0, op1));
17651
17652 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17653 DONE;
17654 })
17655
17656 (define_expand "ceilsf2"
17657 [(use (match_operand:SF 0 "register_operand" ""))
17658 (use (match_operand:SF 1 "register_operand" ""))]
17659 "TARGET_USE_FANCY_MATH_387
17660 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17661 && flag_unsafe_math_optimizations"
17662 {
17663 rtx op0 = gen_reg_rtx (XFmode);
17664 rtx op1 = gen_reg_rtx (XFmode);
17665
17666 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17667 emit_insn (gen_frndintxf2_ceil (op0, op1));
17668
17669 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17670 DONE;
17671 })
17672
17673 (define_insn_and_split "*fist<mode>2_ceil_1"
17674 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17675 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17676 UNSPEC_FIST_CEIL))
17677 (clobber (reg:CC FLAGS_REG))]
17678 "TARGET_USE_FANCY_MATH_387
17679 && flag_unsafe_math_optimizations
17680 && !(reload_completed || reload_in_progress)"
17681 "#"
17682 "&& 1"
17683 [(const_int 0)]
17684 {
17685 ix86_optimize_mode_switching[I387_CEIL] = 1;
17686
17687 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17688 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17689 if (memory_operand (operands[0], VOIDmode))
17690 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17691 operands[2], operands[3]));
17692 else
17693 {
17694 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17695 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17696 operands[2], operands[3],
17697 operands[4]));
17698 }
17699 DONE;
17700 }
17701 [(set_attr "type" "fistp")
17702 (set_attr "i387_cw" "ceil")
17703 (set_attr "mode" "<MODE>")])
17704
17705 (define_insn "fistdi2_ceil"
17706 [(set (match_operand:DI 0 "memory_operand" "=m")
17707 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17708 UNSPEC_FIST_CEIL))
17709 (use (match_operand:HI 2 "memory_operand" "m"))
17710 (use (match_operand:HI 3 "memory_operand" "m"))
17711 (clobber (match_scratch:XF 4 "=&1f"))]
17712 "TARGET_USE_FANCY_MATH_387
17713 && flag_unsafe_math_optimizations"
17714 "* return output_fix_trunc (insn, operands, 0);"
17715 [(set_attr "type" "fistp")
17716 (set_attr "i387_cw" "ceil")
17717 (set_attr "mode" "DI")])
17718
17719 (define_insn "fistdi2_ceil_with_temp"
17720 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17721 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17722 UNSPEC_FIST_CEIL))
17723 (use (match_operand:HI 2 "memory_operand" "m,m"))
17724 (use (match_operand:HI 3 "memory_operand" "m,m"))
17725 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17726 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17727 "TARGET_USE_FANCY_MATH_387
17728 && flag_unsafe_math_optimizations"
17729 "#"
17730 [(set_attr "type" "fistp")
17731 (set_attr "i387_cw" "ceil")
17732 (set_attr "mode" "DI")])
17733
17734 (define_split
17735 [(set (match_operand:DI 0 "register_operand" "")
17736 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17737 UNSPEC_FIST_CEIL))
17738 (use (match_operand:HI 2 "memory_operand" ""))
17739 (use (match_operand:HI 3 "memory_operand" ""))
17740 (clobber (match_operand:DI 4 "memory_operand" ""))
17741 (clobber (match_scratch 5 ""))]
17742 "reload_completed"
17743 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17744 (use (match_dup 2))
17745 (use (match_dup 3))
17746 (clobber (match_dup 5))])
17747 (set (match_dup 0) (match_dup 4))]
17748 "")
17749
17750 (define_split
17751 [(set (match_operand:DI 0 "memory_operand" "")
17752 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17753 UNSPEC_FIST_CEIL))
17754 (use (match_operand:HI 2 "memory_operand" ""))
17755 (use (match_operand:HI 3 "memory_operand" ""))
17756 (clobber (match_operand:DI 4 "memory_operand" ""))
17757 (clobber (match_scratch 5 ""))]
17758 "reload_completed"
17759 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17760 (use (match_dup 2))
17761 (use (match_dup 3))
17762 (clobber (match_dup 5))])]
17763 "")
17764
17765 (define_insn "fist<mode>2_ceil"
17766 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17767 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17768 UNSPEC_FIST_CEIL))
17769 (use (match_operand:HI 2 "memory_operand" "m"))
17770 (use (match_operand:HI 3 "memory_operand" "m"))]
17771 "TARGET_USE_FANCY_MATH_387
17772 && flag_unsafe_math_optimizations"
17773 "* return output_fix_trunc (insn, operands, 0);"
17774 [(set_attr "type" "fistp")
17775 (set_attr "i387_cw" "ceil")
17776 (set_attr "mode" "<MODE>")])
17777
17778 (define_insn "fist<mode>2_ceil_with_temp"
17779 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17780 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17781 UNSPEC_FIST_CEIL))
17782 (use (match_operand:HI 2 "memory_operand" "m,m"))
17783 (use (match_operand:HI 3 "memory_operand" "m,m"))
17784 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17785 "TARGET_USE_FANCY_MATH_387
17786 && flag_unsafe_math_optimizations"
17787 "#"
17788 [(set_attr "type" "fistp")
17789 (set_attr "i387_cw" "ceil")
17790 (set_attr "mode" "<MODE>")])
17791
17792 (define_split
17793 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17794 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17795 UNSPEC_FIST_CEIL))
17796 (use (match_operand:HI 2 "memory_operand" ""))
17797 (use (match_operand:HI 3 "memory_operand" ""))
17798 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17799 "reload_completed"
17800 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17801 UNSPEC_FIST_CEIL))
17802 (use (match_dup 2))
17803 (use (match_dup 3))])
17804 (set (match_dup 0) (match_dup 4))]
17805 "")
17806
17807 (define_split
17808 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17809 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17810 UNSPEC_FIST_CEIL))
17811 (use (match_operand:HI 2 "memory_operand" ""))
17812 (use (match_operand:HI 3 "memory_operand" ""))
17813 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17814 "reload_completed"
17815 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17816 UNSPEC_FIST_CEIL))
17817 (use (match_dup 2))
17818 (use (match_dup 3))])]
17819 "")
17820
17821 (define_expand "lceil<mode>2"
17822 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17823 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17824 UNSPEC_FIST_CEIL))
17825 (clobber (reg:CC FLAGS_REG))])]
17826 "TARGET_USE_FANCY_MATH_387
17827 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17828 && flag_unsafe_math_optimizations"
17829 "")
17830
17831 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17832 (define_insn_and_split "frndintxf2_trunc"
17833 [(set (match_operand:XF 0 "register_operand" "=f")
17834 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17835 UNSPEC_FRNDINT_TRUNC))
17836 (clobber (reg:CC FLAGS_REG))]
17837 "TARGET_USE_FANCY_MATH_387
17838 && flag_unsafe_math_optimizations
17839 && !(reload_completed || reload_in_progress)"
17840 "#"
17841 "&& 1"
17842 [(const_int 0)]
17843 {
17844 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17845
17846 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17847 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17848
17849 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17850 operands[2], operands[3]));
17851 DONE;
17852 }
17853 [(set_attr "type" "frndint")
17854 (set_attr "i387_cw" "trunc")
17855 (set_attr "mode" "XF")])
17856
17857 (define_insn "frndintxf2_trunc_i387"
17858 [(set (match_operand:XF 0 "register_operand" "=f")
17859 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17860 UNSPEC_FRNDINT_TRUNC))
17861 (use (match_operand:HI 2 "memory_operand" "m"))
17862 (use (match_operand:HI 3 "memory_operand" "m"))]
17863 "TARGET_USE_FANCY_MATH_387
17864 && flag_unsafe_math_optimizations"
17865 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17866 [(set_attr "type" "frndint")
17867 (set_attr "i387_cw" "trunc")
17868 (set_attr "mode" "XF")])
17869
17870 (define_expand "btruncxf2"
17871 [(use (match_operand:XF 0 "register_operand" ""))
17872 (use (match_operand:XF 1 "register_operand" ""))]
17873 "TARGET_USE_FANCY_MATH_387
17874 && flag_unsafe_math_optimizations"
17875 {
17876 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17877 DONE;
17878 })
17879
17880 (define_expand "btruncdf2"
17881 [(use (match_operand:DF 0 "register_operand" ""))
17882 (use (match_operand:DF 1 "register_operand" ""))]
17883 "TARGET_USE_FANCY_MATH_387
17884 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17885 && flag_unsafe_math_optimizations"
17886 {
17887 rtx op0 = gen_reg_rtx (XFmode);
17888 rtx op1 = gen_reg_rtx (XFmode);
17889
17890 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17891 emit_insn (gen_frndintxf2_trunc (op0, op1));
17892
17893 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17894 DONE;
17895 })
17896
17897 (define_expand "btruncsf2"
17898 [(use (match_operand:SF 0 "register_operand" ""))
17899 (use (match_operand:SF 1 "register_operand" ""))]
17900 "TARGET_USE_FANCY_MATH_387
17901 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17902 && flag_unsafe_math_optimizations"
17903 {
17904 rtx op0 = gen_reg_rtx (XFmode);
17905 rtx op1 = gen_reg_rtx (XFmode);
17906
17907 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17908 emit_insn (gen_frndintxf2_trunc (op0, op1));
17909
17910 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17911 DONE;
17912 })
17913
17914 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17915 (define_insn_and_split "frndintxf2_mask_pm"
17916 [(set (match_operand:XF 0 "register_operand" "=f")
17917 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17918 UNSPEC_FRNDINT_MASK_PM))
17919 (clobber (reg:CC FLAGS_REG))]
17920 "TARGET_USE_FANCY_MATH_387
17921 && flag_unsafe_math_optimizations
17922 && !(reload_completed || reload_in_progress)"
17923 "#"
17924 "&& 1"
17925 [(const_int 0)]
17926 {
17927 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17928
17929 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17930 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17931
17932 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17933 operands[2], operands[3]));
17934 DONE;
17935 }
17936 [(set_attr "type" "frndint")
17937 (set_attr "i387_cw" "mask_pm")
17938 (set_attr "mode" "XF")])
17939
17940 (define_insn "frndintxf2_mask_pm_i387"
17941 [(set (match_operand:XF 0 "register_operand" "=f")
17942 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17943 UNSPEC_FRNDINT_MASK_PM))
17944 (use (match_operand:HI 2 "memory_operand" "m"))
17945 (use (match_operand:HI 3 "memory_operand" "m"))]
17946 "TARGET_USE_FANCY_MATH_387
17947 && flag_unsafe_math_optimizations"
17948 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17949 [(set_attr "type" "frndint")
17950 (set_attr "i387_cw" "mask_pm")
17951 (set_attr "mode" "XF")])
17952
17953 (define_expand "nearbyintxf2"
17954 [(use (match_operand:XF 0 "register_operand" ""))
17955 (use (match_operand:XF 1 "register_operand" ""))]
17956 "TARGET_USE_FANCY_MATH_387
17957 && flag_unsafe_math_optimizations"
17958 {
17959 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17960
17961 DONE;
17962 })
17963
17964 (define_expand "nearbyintdf2"
17965 [(use (match_operand:DF 0 "register_operand" ""))
17966 (use (match_operand:DF 1 "register_operand" ""))]
17967 "TARGET_USE_FANCY_MATH_387
17968 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17969 && flag_unsafe_math_optimizations"
17970 {
17971 rtx op0 = gen_reg_rtx (XFmode);
17972 rtx op1 = gen_reg_rtx (XFmode);
17973
17974 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17975 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17976
17977 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17978 DONE;
17979 })
17980
17981 (define_expand "nearbyintsf2"
17982 [(use (match_operand:SF 0 "register_operand" ""))
17983 (use (match_operand:SF 1 "register_operand" ""))]
17984 "TARGET_USE_FANCY_MATH_387
17985 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17986 && flag_unsafe_math_optimizations"
17987 {
17988 rtx op0 = gen_reg_rtx (XFmode);
17989 rtx op1 = gen_reg_rtx (XFmode);
17990
17991 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17992 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17993
17994 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17995 DONE;
17996 })
17997
17998 \f
17999 ;; Block operation instructions
18000
18001 (define_insn "cld"
18002 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18003 ""
18004 "cld"
18005 [(set_attr "type" "cld")])
18006
18007 (define_expand "movmemsi"
18008 [(use (match_operand:BLK 0 "memory_operand" ""))
18009 (use (match_operand:BLK 1 "memory_operand" ""))
18010 (use (match_operand:SI 2 "nonmemory_operand" ""))
18011 (use (match_operand:SI 3 "const_int_operand" ""))]
18012 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18013 {
18014 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18015 DONE;
18016 else
18017 FAIL;
18018 })
18019
18020 (define_expand "movmemdi"
18021 [(use (match_operand:BLK 0 "memory_operand" ""))
18022 (use (match_operand:BLK 1 "memory_operand" ""))
18023 (use (match_operand:DI 2 "nonmemory_operand" ""))
18024 (use (match_operand:DI 3 "const_int_operand" ""))]
18025 "TARGET_64BIT"
18026 {
18027 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18028 DONE;
18029 else
18030 FAIL;
18031 })
18032
18033 ;; Most CPUs don't like single string operations
18034 ;; Handle this case here to simplify previous expander.
18035
18036 (define_expand "strmov"
18037 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18038 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18039 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18040 (clobber (reg:CC FLAGS_REG))])
18041 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18042 (clobber (reg:CC FLAGS_REG))])]
18043 ""
18044 {
18045 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18046
18047 /* If .md ever supports :P for Pmode, these can be directly
18048 in the pattern above. */
18049 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18050 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18051
18052 if (TARGET_SINGLE_STRINGOP || optimize_size)
18053 {
18054 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18055 operands[2], operands[3],
18056 operands[5], operands[6]));
18057 DONE;
18058 }
18059
18060 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18061 })
18062
18063 (define_expand "strmov_singleop"
18064 [(parallel [(set (match_operand 1 "memory_operand" "")
18065 (match_operand 3 "memory_operand" ""))
18066 (set (match_operand 0 "register_operand" "")
18067 (match_operand 4 "" ""))
18068 (set (match_operand 2 "register_operand" "")
18069 (match_operand 5 "" ""))
18070 (use (reg:SI DIRFLAG_REG))])]
18071 "TARGET_SINGLE_STRINGOP || optimize_size"
18072 "")
18073
18074 (define_insn "*strmovdi_rex_1"
18075 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18076 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18077 (set (match_operand:DI 0 "register_operand" "=D")
18078 (plus:DI (match_dup 2)
18079 (const_int 8)))
18080 (set (match_operand:DI 1 "register_operand" "=S")
18081 (plus:DI (match_dup 3)
18082 (const_int 8)))
18083 (use (reg:SI DIRFLAG_REG))]
18084 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18085 "movsq"
18086 [(set_attr "type" "str")
18087 (set_attr "mode" "DI")
18088 (set_attr "memory" "both")])
18089
18090 (define_insn "*strmovsi_1"
18091 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18092 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18093 (set (match_operand:SI 0 "register_operand" "=D")
18094 (plus:SI (match_dup 2)
18095 (const_int 4)))
18096 (set (match_operand:SI 1 "register_operand" "=S")
18097 (plus:SI (match_dup 3)
18098 (const_int 4)))
18099 (use (reg:SI DIRFLAG_REG))]
18100 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18101 "{movsl|movsd}"
18102 [(set_attr "type" "str")
18103 (set_attr "mode" "SI")
18104 (set_attr "memory" "both")])
18105
18106 (define_insn "*strmovsi_rex_1"
18107 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18108 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18109 (set (match_operand:DI 0 "register_operand" "=D")
18110 (plus:DI (match_dup 2)
18111 (const_int 4)))
18112 (set (match_operand:DI 1 "register_operand" "=S")
18113 (plus:DI (match_dup 3)
18114 (const_int 4)))
18115 (use (reg:SI DIRFLAG_REG))]
18116 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18117 "{movsl|movsd}"
18118 [(set_attr "type" "str")
18119 (set_attr "mode" "SI")
18120 (set_attr "memory" "both")])
18121
18122 (define_insn "*strmovhi_1"
18123 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18124 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18125 (set (match_operand:SI 0 "register_operand" "=D")
18126 (plus:SI (match_dup 2)
18127 (const_int 2)))
18128 (set (match_operand:SI 1 "register_operand" "=S")
18129 (plus:SI (match_dup 3)
18130 (const_int 2)))
18131 (use (reg:SI DIRFLAG_REG))]
18132 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18133 "movsw"
18134 [(set_attr "type" "str")
18135 (set_attr "memory" "both")
18136 (set_attr "mode" "HI")])
18137
18138 (define_insn "*strmovhi_rex_1"
18139 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18140 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18141 (set (match_operand:DI 0 "register_operand" "=D")
18142 (plus:DI (match_dup 2)
18143 (const_int 2)))
18144 (set (match_operand:DI 1 "register_operand" "=S")
18145 (plus:DI (match_dup 3)
18146 (const_int 2)))
18147 (use (reg:SI DIRFLAG_REG))]
18148 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18149 "movsw"
18150 [(set_attr "type" "str")
18151 (set_attr "memory" "both")
18152 (set_attr "mode" "HI")])
18153
18154 (define_insn "*strmovqi_1"
18155 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18156 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18157 (set (match_operand:SI 0 "register_operand" "=D")
18158 (plus:SI (match_dup 2)
18159 (const_int 1)))
18160 (set (match_operand:SI 1 "register_operand" "=S")
18161 (plus:SI (match_dup 3)
18162 (const_int 1)))
18163 (use (reg:SI DIRFLAG_REG))]
18164 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18165 "movsb"
18166 [(set_attr "type" "str")
18167 (set_attr "memory" "both")
18168 (set_attr "mode" "QI")])
18169
18170 (define_insn "*strmovqi_rex_1"
18171 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18172 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18173 (set (match_operand:DI 0 "register_operand" "=D")
18174 (plus:DI (match_dup 2)
18175 (const_int 1)))
18176 (set (match_operand:DI 1 "register_operand" "=S")
18177 (plus:DI (match_dup 3)
18178 (const_int 1)))
18179 (use (reg:SI DIRFLAG_REG))]
18180 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18181 "movsb"
18182 [(set_attr "type" "str")
18183 (set_attr "memory" "both")
18184 (set_attr "mode" "QI")])
18185
18186 (define_expand "rep_mov"
18187 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18188 (set (match_operand 0 "register_operand" "")
18189 (match_operand 5 "" ""))
18190 (set (match_operand 2 "register_operand" "")
18191 (match_operand 6 "" ""))
18192 (set (match_operand 1 "memory_operand" "")
18193 (match_operand 3 "memory_operand" ""))
18194 (use (match_dup 4))
18195 (use (reg:SI DIRFLAG_REG))])]
18196 ""
18197 "")
18198
18199 (define_insn "*rep_movdi_rex64"
18200 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18201 (set (match_operand:DI 0 "register_operand" "=D")
18202 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18203 (const_int 3))
18204 (match_operand:DI 3 "register_operand" "0")))
18205 (set (match_operand:DI 1 "register_operand" "=S")
18206 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18207 (match_operand:DI 4 "register_operand" "1")))
18208 (set (mem:BLK (match_dup 3))
18209 (mem:BLK (match_dup 4)))
18210 (use (match_dup 5))
18211 (use (reg:SI DIRFLAG_REG))]
18212 "TARGET_64BIT"
18213 "{rep\;movsq|rep movsq}"
18214 [(set_attr "type" "str")
18215 (set_attr "prefix_rep" "1")
18216 (set_attr "memory" "both")
18217 (set_attr "mode" "DI")])
18218
18219 (define_insn "*rep_movsi"
18220 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18221 (set (match_operand:SI 0 "register_operand" "=D")
18222 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18223 (const_int 2))
18224 (match_operand:SI 3 "register_operand" "0")))
18225 (set (match_operand:SI 1 "register_operand" "=S")
18226 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18227 (match_operand:SI 4 "register_operand" "1")))
18228 (set (mem:BLK (match_dup 3))
18229 (mem:BLK (match_dup 4)))
18230 (use (match_dup 5))
18231 (use (reg:SI DIRFLAG_REG))]
18232 "!TARGET_64BIT"
18233 "{rep\;movsl|rep movsd}"
18234 [(set_attr "type" "str")
18235 (set_attr "prefix_rep" "1")
18236 (set_attr "memory" "both")
18237 (set_attr "mode" "SI")])
18238
18239 (define_insn "*rep_movsi_rex64"
18240 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18241 (set (match_operand:DI 0 "register_operand" "=D")
18242 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18243 (const_int 2))
18244 (match_operand:DI 3 "register_operand" "0")))
18245 (set (match_operand:DI 1 "register_operand" "=S")
18246 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18247 (match_operand:DI 4 "register_operand" "1")))
18248 (set (mem:BLK (match_dup 3))
18249 (mem:BLK (match_dup 4)))
18250 (use (match_dup 5))
18251 (use (reg:SI DIRFLAG_REG))]
18252 "TARGET_64BIT"
18253 "{rep\;movsl|rep movsd}"
18254 [(set_attr "type" "str")
18255 (set_attr "prefix_rep" "1")
18256 (set_attr "memory" "both")
18257 (set_attr "mode" "SI")])
18258
18259 (define_insn "*rep_movqi"
18260 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18261 (set (match_operand:SI 0 "register_operand" "=D")
18262 (plus:SI (match_operand:SI 3 "register_operand" "0")
18263 (match_operand:SI 5 "register_operand" "2")))
18264 (set (match_operand:SI 1 "register_operand" "=S")
18265 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18266 (set (mem:BLK (match_dup 3))
18267 (mem:BLK (match_dup 4)))
18268 (use (match_dup 5))
18269 (use (reg:SI DIRFLAG_REG))]
18270 "!TARGET_64BIT"
18271 "{rep\;movsb|rep movsb}"
18272 [(set_attr "type" "str")
18273 (set_attr "prefix_rep" "1")
18274 (set_attr "memory" "both")
18275 (set_attr "mode" "SI")])
18276
18277 (define_insn "*rep_movqi_rex64"
18278 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18279 (set (match_operand:DI 0 "register_operand" "=D")
18280 (plus:DI (match_operand:DI 3 "register_operand" "0")
18281 (match_operand:DI 5 "register_operand" "2")))
18282 (set (match_operand:DI 1 "register_operand" "=S")
18283 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18284 (set (mem:BLK (match_dup 3))
18285 (mem:BLK (match_dup 4)))
18286 (use (match_dup 5))
18287 (use (reg:SI DIRFLAG_REG))]
18288 "TARGET_64BIT"
18289 "{rep\;movsb|rep movsb}"
18290 [(set_attr "type" "str")
18291 (set_attr "prefix_rep" "1")
18292 (set_attr "memory" "both")
18293 (set_attr "mode" "SI")])
18294
18295 (define_expand "setmemsi"
18296 [(use (match_operand:BLK 0 "memory_operand" ""))
18297 (use (match_operand:SI 1 "nonmemory_operand" ""))
18298 (use (match_operand 2 "const_int_operand" ""))
18299 (use (match_operand 3 "const_int_operand" ""))]
18300 ""
18301 {
18302 /* If value to set is not zero, use the library routine. */
18303 if (operands[2] != const0_rtx)
18304 FAIL;
18305
18306 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18307 DONE;
18308 else
18309 FAIL;
18310 })
18311
18312 (define_expand "setmemdi"
18313 [(use (match_operand:BLK 0 "memory_operand" ""))
18314 (use (match_operand:DI 1 "nonmemory_operand" ""))
18315 (use (match_operand 2 "const_int_operand" ""))
18316 (use (match_operand 3 "const_int_operand" ""))]
18317 "TARGET_64BIT"
18318 {
18319 /* If value to set is not zero, use the library routine. */
18320 if (operands[2] != const0_rtx)
18321 FAIL;
18322
18323 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18324 DONE;
18325 else
18326 FAIL;
18327 })
18328
18329 ;; Most CPUs don't like single string operations
18330 ;; Handle this case here to simplify previous expander.
18331
18332 (define_expand "strset"
18333 [(set (match_operand 1 "memory_operand" "")
18334 (match_operand 2 "register_operand" ""))
18335 (parallel [(set (match_operand 0 "register_operand" "")
18336 (match_dup 3))
18337 (clobber (reg:CC FLAGS_REG))])]
18338 ""
18339 {
18340 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18341 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18342
18343 /* If .md ever supports :P for Pmode, this can be directly
18344 in the pattern above. */
18345 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18346 GEN_INT (GET_MODE_SIZE (GET_MODE
18347 (operands[2]))));
18348 if (TARGET_SINGLE_STRINGOP || optimize_size)
18349 {
18350 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18351 operands[3]));
18352 DONE;
18353 }
18354 })
18355
18356 (define_expand "strset_singleop"
18357 [(parallel [(set (match_operand 1 "memory_operand" "")
18358 (match_operand 2 "register_operand" ""))
18359 (set (match_operand 0 "register_operand" "")
18360 (match_operand 3 "" ""))
18361 (use (reg:SI DIRFLAG_REG))])]
18362 "TARGET_SINGLE_STRINGOP || optimize_size"
18363 "")
18364
18365 (define_insn "*strsetdi_rex_1"
18366 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18367 (match_operand:DI 2 "register_operand" "a"))
18368 (set (match_operand:DI 0 "register_operand" "=D")
18369 (plus:DI (match_dup 1)
18370 (const_int 8)))
18371 (use (reg:SI DIRFLAG_REG))]
18372 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18373 "stosq"
18374 [(set_attr "type" "str")
18375 (set_attr "memory" "store")
18376 (set_attr "mode" "DI")])
18377
18378 (define_insn "*strsetsi_1"
18379 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18380 (match_operand:SI 2 "register_operand" "a"))
18381 (set (match_operand:SI 0 "register_operand" "=D")
18382 (plus:SI (match_dup 1)
18383 (const_int 4)))
18384 (use (reg:SI DIRFLAG_REG))]
18385 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18386 "{stosl|stosd}"
18387 [(set_attr "type" "str")
18388 (set_attr "memory" "store")
18389 (set_attr "mode" "SI")])
18390
18391 (define_insn "*strsetsi_rex_1"
18392 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18393 (match_operand:SI 2 "register_operand" "a"))
18394 (set (match_operand:DI 0 "register_operand" "=D")
18395 (plus:DI (match_dup 1)
18396 (const_int 4)))
18397 (use (reg:SI DIRFLAG_REG))]
18398 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18399 "{stosl|stosd}"
18400 [(set_attr "type" "str")
18401 (set_attr "memory" "store")
18402 (set_attr "mode" "SI")])
18403
18404 (define_insn "*strsethi_1"
18405 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18406 (match_operand:HI 2 "register_operand" "a"))
18407 (set (match_operand:SI 0 "register_operand" "=D")
18408 (plus:SI (match_dup 1)
18409 (const_int 2)))
18410 (use (reg:SI DIRFLAG_REG))]
18411 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18412 "stosw"
18413 [(set_attr "type" "str")
18414 (set_attr "memory" "store")
18415 (set_attr "mode" "HI")])
18416
18417 (define_insn "*strsethi_rex_1"
18418 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18419 (match_operand:HI 2 "register_operand" "a"))
18420 (set (match_operand:DI 0 "register_operand" "=D")
18421 (plus:DI (match_dup 1)
18422 (const_int 2)))
18423 (use (reg:SI DIRFLAG_REG))]
18424 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18425 "stosw"
18426 [(set_attr "type" "str")
18427 (set_attr "memory" "store")
18428 (set_attr "mode" "HI")])
18429
18430 (define_insn "*strsetqi_1"
18431 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18432 (match_operand:QI 2 "register_operand" "a"))
18433 (set (match_operand:SI 0 "register_operand" "=D")
18434 (plus:SI (match_dup 1)
18435 (const_int 1)))
18436 (use (reg:SI DIRFLAG_REG))]
18437 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18438 "stosb"
18439 [(set_attr "type" "str")
18440 (set_attr "memory" "store")
18441 (set_attr "mode" "QI")])
18442
18443 (define_insn "*strsetqi_rex_1"
18444 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18445 (match_operand:QI 2 "register_operand" "a"))
18446 (set (match_operand:DI 0 "register_operand" "=D")
18447 (plus:DI (match_dup 1)
18448 (const_int 1)))
18449 (use (reg:SI DIRFLAG_REG))]
18450 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18451 "stosb"
18452 [(set_attr "type" "str")
18453 (set_attr "memory" "store")
18454 (set_attr "mode" "QI")])
18455
18456 (define_expand "rep_stos"
18457 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18458 (set (match_operand 0 "register_operand" "")
18459 (match_operand 4 "" ""))
18460 (set (match_operand 2 "memory_operand" "") (const_int 0))
18461 (use (match_operand 3 "register_operand" ""))
18462 (use (match_dup 1))
18463 (use (reg:SI DIRFLAG_REG))])]
18464 ""
18465 "")
18466
18467 (define_insn "*rep_stosdi_rex64"
18468 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18469 (set (match_operand:DI 0 "register_operand" "=D")
18470 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18471 (const_int 3))
18472 (match_operand:DI 3 "register_operand" "0")))
18473 (set (mem:BLK (match_dup 3))
18474 (const_int 0))
18475 (use (match_operand:DI 2 "register_operand" "a"))
18476 (use (match_dup 4))
18477 (use (reg:SI DIRFLAG_REG))]
18478 "TARGET_64BIT"
18479 "{rep\;stosq|rep stosq}"
18480 [(set_attr "type" "str")
18481 (set_attr "prefix_rep" "1")
18482 (set_attr "memory" "store")
18483 (set_attr "mode" "DI")])
18484
18485 (define_insn "*rep_stossi"
18486 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18487 (set (match_operand:SI 0 "register_operand" "=D")
18488 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18489 (const_int 2))
18490 (match_operand:SI 3 "register_operand" "0")))
18491 (set (mem:BLK (match_dup 3))
18492 (const_int 0))
18493 (use (match_operand:SI 2 "register_operand" "a"))
18494 (use (match_dup 4))
18495 (use (reg:SI DIRFLAG_REG))]
18496 "!TARGET_64BIT"
18497 "{rep\;stosl|rep stosd}"
18498 [(set_attr "type" "str")
18499 (set_attr "prefix_rep" "1")
18500 (set_attr "memory" "store")
18501 (set_attr "mode" "SI")])
18502
18503 (define_insn "*rep_stossi_rex64"
18504 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18505 (set (match_operand:DI 0 "register_operand" "=D")
18506 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18507 (const_int 2))
18508 (match_operand:DI 3 "register_operand" "0")))
18509 (set (mem:BLK (match_dup 3))
18510 (const_int 0))
18511 (use (match_operand:SI 2 "register_operand" "a"))
18512 (use (match_dup 4))
18513 (use (reg:SI DIRFLAG_REG))]
18514 "TARGET_64BIT"
18515 "{rep\;stosl|rep stosd}"
18516 [(set_attr "type" "str")
18517 (set_attr "prefix_rep" "1")
18518 (set_attr "memory" "store")
18519 (set_attr "mode" "SI")])
18520
18521 (define_insn "*rep_stosqi"
18522 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18523 (set (match_operand:SI 0 "register_operand" "=D")
18524 (plus:SI (match_operand:SI 3 "register_operand" "0")
18525 (match_operand:SI 4 "register_operand" "1")))
18526 (set (mem:BLK (match_dup 3))
18527 (const_int 0))
18528 (use (match_operand:QI 2 "register_operand" "a"))
18529 (use (match_dup 4))
18530 (use (reg:SI DIRFLAG_REG))]
18531 "!TARGET_64BIT"
18532 "{rep\;stosb|rep stosb}"
18533 [(set_attr "type" "str")
18534 (set_attr "prefix_rep" "1")
18535 (set_attr "memory" "store")
18536 (set_attr "mode" "QI")])
18537
18538 (define_insn "*rep_stosqi_rex64"
18539 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18540 (set (match_operand:DI 0 "register_operand" "=D")
18541 (plus:DI (match_operand:DI 3 "register_operand" "0")
18542 (match_operand:DI 4 "register_operand" "1")))
18543 (set (mem:BLK (match_dup 3))
18544 (const_int 0))
18545 (use (match_operand:QI 2 "register_operand" "a"))
18546 (use (match_dup 4))
18547 (use (reg:SI DIRFLAG_REG))]
18548 "TARGET_64BIT"
18549 "{rep\;stosb|rep stosb}"
18550 [(set_attr "type" "str")
18551 (set_attr "prefix_rep" "1")
18552 (set_attr "memory" "store")
18553 (set_attr "mode" "QI")])
18554
18555 (define_expand "cmpstrnsi"
18556 [(set (match_operand:SI 0 "register_operand" "")
18557 (compare:SI (match_operand:BLK 1 "general_operand" "")
18558 (match_operand:BLK 2 "general_operand" "")))
18559 (use (match_operand 3 "general_operand" ""))
18560 (use (match_operand 4 "immediate_operand" ""))]
18561 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18562 {
18563 rtx addr1, addr2, out, outlow, count, countreg, align;
18564
18565 /* Can't use this if the user has appropriated esi or edi. */
18566 if (global_regs[4] || global_regs[5])
18567 FAIL;
18568
18569 out = operands[0];
18570 if (GET_CODE (out) != REG)
18571 out = gen_reg_rtx (SImode);
18572
18573 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18574 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18575 if (addr1 != XEXP (operands[1], 0))
18576 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18577 if (addr2 != XEXP (operands[2], 0))
18578 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18579
18580 count = operands[3];
18581 countreg = ix86_zero_extend_to_Pmode (count);
18582
18583 /* %%% Iff we are testing strict equality, we can use known alignment
18584 to good advantage. This may be possible with combine, particularly
18585 once cc0 is dead. */
18586 align = operands[4];
18587
18588 emit_insn (gen_cld ());
18589 if (GET_CODE (count) == CONST_INT)
18590 {
18591 if (INTVAL (count) == 0)
18592 {
18593 emit_move_insn (operands[0], const0_rtx);
18594 DONE;
18595 }
18596 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18597 operands[1], operands[2]));
18598 }
18599 else
18600 {
18601 if (TARGET_64BIT)
18602 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18603 else
18604 emit_insn (gen_cmpsi_1 (countreg, countreg));
18605 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18606 operands[1], operands[2]));
18607 }
18608
18609 outlow = gen_lowpart (QImode, out);
18610 emit_insn (gen_cmpintqi (outlow));
18611 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18612
18613 if (operands[0] != out)
18614 emit_move_insn (operands[0], out);
18615
18616 DONE;
18617 })
18618
18619 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18620
18621 (define_expand "cmpintqi"
18622 [(set (match_dup 1)
18623 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18624 (set (match_dup 2)
18625 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18626 (parallel [(set (match_operand:QI 0 "register_operand" "")
18627 (minus:QI (match_dup 1)
18628 (match_dup 2)))
18629 (clobber (reg:CC FLAGS_REG))])]
18630 ""
18631 "operands[1] = gen_reg_rtx (QImode);
18632 operands[2] = gen_reg_rtx (QImode);")
18633
18634 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18635 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18636
18637 (define_expand "cmpstrnqi_nz_1"
18638 [(parallel [(set (reg:CC FLAGS_REG)
18639 (compare:CC (match_operand 4 "memory_operand" "")
18640 (match_operand 5 "memory_operand" "")))
18641 (use (match_operand 2 "register_operand" ""))
18642 (use (match_operand:SI 3 "immediate_operand" ""))
18643 (use (reg:SI DIRFLAG_REG))
18644 (clobber (match_operand 0 "register_operand" ""))
18645 (clobber (match_operand 1 "register_operand" ""))
18646 (clobber (match_dup 2))])]
18647 ""
18648 "")
18649
18650 (define_insn "*cmpstrnqi_nz_1"
18651 [(set (reg:CC FLAGS_REG)
18652 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18653 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18654 (use (match_operand:SI 6 "register_operand" "2"))
18655 (use (match_operand:SI 3 "immediate_operand" "i"))
18656 (use (reg:SI DIRFLAG_REG))
18657 (clobber (match_operand:SI 0 "register_operand" "=S"))
18658 (clobber (match_operand:SI 1 "register_operand" "=D"))
18659 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18660 "!TARGET_64BIT"
18661 "repz{\;| }cmpsb"
18662 [(set_attr "type" "str")
18663 (set_attr "mode" "QI")
18664 (set_attr "prefix_rep" "1")])
18665
18666 (define_insn "*cmpstrnqi_nz_rex_1"
18667 [(set (reg:CC FLAGS_REG)
18668 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18669 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18670 (use (match_operand:DI 6 "register_operand" "2"))
18671 (use (match_operand:SI 3 "immediate_operand" "i"))
18672 (use (reg:SI DIRFLAG_REG))
18673 (clobber (match_operand:DI 0 "register_operand" "=S"))
18674 (clobber (match_operand:DI 1 "register_operand" "=D"))
18675 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18676 "TARGET_64BIT"
18677 "repz{\;| }cmpsb"
18678 [(set_attr "type" "str")
18679 (set_attr "mode" "QI")
18680 (set_attr "prefix_rep" "1")])
18681
18682 ;; The same, but the count is not known to not be zero.
18683
18684 (define_expand "cmpstrnqi_1"
18685 [(parallel [(set (reg:CC FLAGS_REG)
18686 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18687 (const_int 0))
18688 (compare:CC (match_operand 4 "memory_operand" "")
18689 (match_operand 5 "memory_operand" ""))
18690 (const_int 0)))
18691 (use (match_operand:SI 3 "immediate_operand" ""))
18692 (use (reg:CC FLAGS_REG))
18693 (use (reg:SI DIRFLAG_REG))
18694 (clobber (match_operand 0 "register_operand" ""))
18695 (clobber (match_operand 1 "register_operand" ""))
18696 (clobber (match_dup 2))])]
18697 ""
18698 "")
18699
18700 (define_insn "*cmpstrnqi_1"
18701 [(set (reg:CC FLAGS_REG)
18702 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18703 (const_int 0))
18704 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18705 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18706 (const_int 0)))
18707 (use (match_operand:SI 3 "immediate_operand" "i"))
18708 (use (reg:CC FLAGS_REG))
18709 (use (reg:SI DIRFLAG_REG))
18710 (clobber (match_operand:SI 0 "register_operand" "=S"))
18711 (clobber (match_operand:SI 1 "register_operand" "=D"))
18712 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18713 "!TARGET_64BIT"
18714 "repz{\;| }cmpsb"
18715 [(set_attr "type" "str")
18716 (set_attr "mode" "QI")
18717 (set_attr "prefix_rep" "1")])
18718
18719 (define_insn "*cmpstrnqi_rex_1"
18720 [(set (reg:CC FLAGS_REG)
18721 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18722 (const_int 0))
18723 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18724 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18725 (const_int 0)))
18726 (use (match_operand:SI 3 "immediate_operand" "i"))
18727 (use (reg:CC FLAGS_REG))
18728 (use (reg:SI DIRFLAG_REG))
18729 (clobber (match_operand:DI 0 "register_operand" "=S"))
18730 (clobber (match_operand:DI 1 "register_operand" "=D"))
18731 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18732 "TARGET_64BIT"
18733 "repz{\;| }cmpsb"
18734 [(set_attr "type" "str")
18735 (set_attr "mode" "QI")
18736 (set_attr "prefix_rep" "1")])
18737
18738 (define_expand "strlensi"
18739 [(set (match_operand:SI 0 "register_operand" "")
18740 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18741 (match_operand:QI 2 "immediate_operand" "")
18742 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18743 ""
18744 {
18745 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18746 DONE;
18747 else
18748 FAIL;
18749 })
18750
18751 (define_expand "strlendi"
18752 [(set (match_operand:DI 0 "register_operand" "")
18753 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18754 (match_operand:QI 2 "immediate_operand" "")
18755 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18756 ""
18757 {
18758 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18759 DONE;
18760 else
18761 FAIL;
18762 })
18763
18764 (define_expand "strlenqi_1"
18765 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18766 (use (reg:SI DIRFLAG_REG))
18767 (clobber (match_operand 1 "register_operand" ""))
18768 (clobber (reg:CC FLAGS_REG))])]
18769 ""
18770 "")
18771
18772 (define_insn "*strlenqi_1"
18773 [(set (match_operand:SI 0 "register_operand" "=&c")
18774 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18775 (match_operand:QI 2 "register_operand" "a")
18776 (match_operand:SI 3 "immediate_operand" "i")
18777 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18778 (use (reg:SI DIRFLAG_REG))
18779 (clobber (match_operand:SI 1 "register_operand" "=D"))
18780 (clobber (reg:CC FLAGS_REG))]
18781 "!TARGET_64BIT"
18782 "repnz{\;| }scasb"
18783 [(set_attr "type" "str")
18784 (set_attr "mode" "QI")
18785 (set_attr "prefix_rep" "1")])
18786
18787 (define_insn "*strlenqi_rex_1"
18788 [(set (match_operand:DI 0 "register_operand" "=&c")
18789 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18790 (match_operand:QI 2 "register_operand" "a")
18791 (match_operand:DI 3 "immediate_operand" "i")
18792 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18793 (use (reg:SI DIRFLAG_REG))
18794 (clobber (match_operand:DI 1 "register_operand" "=D"))
18795 (clobber (reg:CC FLAGS_REG))]
18796 "TARGET_64BIT"
18797 "repnz{\;| }scasb"
18798 [(set_attr "type" "str")
18799 (set_attr "mode" "QI")
18800 (set_attr "prefix_rep" "1")])
18801
18802 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18803 ;; handled in combine, but it is not currently up to the task.
18804 ;; When used for their truth value, the cmpstrn* expanders generate
18805 ;; code like this:
18806 ;;
18807 ;; repz cmpsb
18808 ;; seta %al
18809 ;; setb %dl
18810 ;; cmpb %al, %dl
18811 ;; jcc label
18812 ;;
18813 ;; The intermediate three instructions are unnecessary.
18814
18815 ;; This one handles cmpstrn*_nz_1...
18816 (define_peephole2
18817 [(parallel[
18818 (set (reg:CC FLAGS_REG)
18819 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18820 (mem:BLK (match_operand 5 "register_operand" ""))))
18821 (use (match_operand 6 "register_operand" ""))
18822 (use (match_operand:SI 3 "immediate_operand" ""))
18823 (use (reg:SI DIRFLAG_REG))
18824 (clobber (match_operand 0 "register_operand" ""))
18825 (clobber (match_operand 1 "register_operand" ""))
18826 (clobber (match_operand 2 "register_operand" ""))])
18827 (set (match_operand:QI 7 "register_operand" "")
18828 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18829 (set (match_operand:QI 8 "register_operand" "")
18830 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18831 (set (reg FLAGS_REG)
18832 (compare (match_dup 7) (match_dup 8)))
18833 ]
18834 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18835 [(parallel[
18836 (set (reg:CC FLAGS_REG)
18837 (compare:CC (mem:BLK (match_dup 4))
18838 (mem:BLK (match_dup 5))))
18839 (use (match_dup 6))
18840 (use (match_dup 3))
18841 (use (reg:SI DIRFLAG_REG))
18842 (clobber (match_dup 0))
18843 (clobber (match_dup 1))
18844 (clobber (match_dup 2))])]
18845 "")
18846
18847 ;; ...and this one handles cmpstrn*_1.
18848 (define_peephole2
18849 [(parallel[
18850 (set (reg:CC FLAGS_REG)
18851 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18852 (const_int 0))
18853 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18854 (mem:BLK (match_operand 5 "register_operand" "")))
18855 (const_int 0)))
18856 (use (match_operand:SI 3 "immediate_operand" ""))
18857 (use (reg:CC FLAGS_REG))
18858 (use (reg:SI DIRFLAG_REG))
18859 (clobber (match_operand 0 "register_operand" ""))
18860 (clobber (match_operand 1 "register_operand" ""))
18861 (clobber (match_operand 2 "register_operand" ""))])
18862 (set (match_operand:QI 7 "register_operand" "")
18863 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18864 (set (match_operand:QI 8 "register_operand" "")
18865 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18866 (set (reg FLAGS_REG)
18867 (compare (match_dup 7) (match_dup 8)))
18868 ]
18869 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18870 [(parallel[
18871 (set (reg:CC FLAGS_REG)
18872 (if_then_else:CC (ne (match_dup 6)
18873 (const_int 0))
18874 (compare:CC (mem:BLK (match_dup 4))
18875 (mem:BLK (match_dup 5)))
18876 (const_int 0)))
18877 (use (match_dup 3))
18878 (use (reg:CC FLAGS_REG))
18879 (use (reg:SI DIRFLAG_REG))
18880 (clobber (match_dup 0))
18881 (clobber (match_dup 1))
18882 (clobber (match_dup 2))])]
18883 "")
18884
18885
18886 \f
18887 ;; Conditional move instructions.
18888
18889 (define_expand "movdicc"
18890 [(set (match_operand:DI 0 "register_operand" "")
18891 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18892 (match_operand:DI 2 "general_operand" "")
18893 (match_operand:DI 3 "general_operand" "")))]
18894 "TARGET_64BIT"
18895 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18896
18897 (define_insn "x86_movdicc_0_m1_rex64"
18898 [(set (match_operand:DI 0 "register_operand" "=r")
18899 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18900 (const_int -1)
18901 (const_int 0)))
18902 (clobber (reg:CC FLAGS_REG))]
18903 "TARGET_64BIT"
18904 "sbb{q}\t%0, %0"
18905 ; Since we don't have the proper number of operands for an alu insn,
18906 ; fill in all the blanks.
18907 [(set_attr "type" "alu")
18908 (set_attr "pent_pair" "pu")
18909 (set_attr "memory" "none")
18910 (set_attr "imm_disp" "false")
18911 (set_attr "mode" "DI")
18912 (set_attr "length_immediate" "0")])
18913
18914 (define_insn "*movdicc_c_rex64"
18915 [(set (match_operand:DI 0 "register_operand" "=r,r")
18916 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18917 [(reg FLAGS_REG) (const_int 0)])
18918 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18919 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18920 "TARGET_64BIT && TARGET_CMOVE
18921 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18922 "@
18923 cmov%O2%C1\t{%2, %0|%0, %2}
18924 cmov%O2%c1\t{%3, %0|%0, %3}"
18925 [(set_attr "type" "icmov")
18926 (set_attr "mode" "DI")])
18927
18928 (define_expand "movsicc"
18929 [(set (match_operand:SI 0 "register_operand" "")
18930 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18931 (match_operand:SI 2 "general_operand" "")
18932 (match_operand:SI 3 "general_operand" "")))]
18933 ""
18934 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18935
18936 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18937 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18938 ;; So just document what we're doing explicitly.
18939
18940 (define_insn "x86_movsicc_0_m1"
18941 [(set (match_operand:SI 0 "register_operand" "=r")
18942 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18943 (const_int -1)
18944 (const_int 0)))
18945 (clobber (reg:CC FLAGS_REG))]
18946 ""
18947 "sbb{l}\t%0, %0"
18948 ; Since we don't have the proper number of operands for an alu insn,
18949 ; fill in all the blanks.
18950 [(set_attr "type" "alu")
18951 (set_attr "pent_pair" "pu")
18952 (set_attr "memory" "none")
18953 (set_attr "imm_disp" "false")
18954 (set_attr "mode" "SI")
18955 (set_attr "length_immediate" "0")])
18956
18957 (define_insn "*movsicc_noc"
18958 [(set (match_operand:SI 0 "register_operand" "=r,r")
18959 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18960 [(reg FLAGS_REG) (const_int 0)])
18961 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18962 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18963 "TARGET_CMOVE
18964 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18965 "@
18966 cmov%O2%C1\t{%2, %0|%0, %2}
18967 cmov%O2%c1\t{%3, %0|%0, %3}"
18968 [(set_attr "type" "icmov")
18969 (set_attr "mode" "SI")])
18970
18971 (define_expand "movhicc"
18972 [(set (match_operand:HI 0 "register_operand" "")
18973 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18974 (match_operand:HI 2 "general_operand" "")
18975 (match_operand:HI 3 "general_operand" "")))]
18976 "TARGET_HIMODE_MATH"
18977 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18978
18979 (define_insn "*movhicc_noc"
18980 [(set (match_operand:HI 0 "register_operand" "=r,r")
18981 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18982 [(reg FLAGS_REG) (const_int 0)])
18983 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18984 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18985 "TARGET_CMOVE
18986 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18987 "@
18988 cmov%O2%C1\t{%2, %0|%0, %2}
18989 cmov%O2%c1\t{%3, %0|%0, %3}"
18990 [(set_attr "type" "icmov")
18991 (set_attr "mode" "HI")])
18992
18993 (define_expand "movqicc"
18994 [(set (match_operand:QI 0 "register_operand" "")
18995 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18996 (match_operand:QI 2 "general_operand" "")
18997 (match_operand:QI 3 "general_operand" "")))]
18998 "TARGET_QIMODE_MATH"
18999 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19000
19001 (define_insn_and_split "*movqicc_noc"
19002 [(set (match_operand:QI 0 "register_operand" "=r,r")
19003 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19004 [(match_operand 4 "flags_reg_operand" "")
19005 (const_int 0)])
19006 (match_operand:QI 2 "register_operand" "r,0")
19007 (match_operand:QI 3 "register_operand" "0,r")))]
19008 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19009 "#"
19010 "&& reload_completed"
19011 [(set (match_dup 0)
19012 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19013 (match_dup 2)
19014 (match_dup 3)))]
19015 "operands[0] = gen_lowpart (SImode, operands[0]);
19016 operands[2] = gen_lowpart (SImode, operands[2]);
19017 operands[3] = gen_lowpart (SImode, operands[3]);"
19018 [(set_attr "type" "icmov")
19019 (set_attr "mode" "SI")])
19020
19021 (define_expand "movsfcc"
19022 [(set (match_operand:SF 0 "register_operand" "")
19023 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19024 (match_operand:SF 2 "register_operand" "")
19025 (match_operand:SF 3 "register_operand" "")))]
19026 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19027 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19028
19029 (define_insn "*movsfcc_1_387"
19030 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19031 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19032 [(reg FLAGS_REG) (const_int 0)])
19033 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19034 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19035 "TARGET_80387 && TARGET_CMOVE
19036 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19037 "@
19038 fcmov%F1\t{%2, %0|%0, %2}
19039 fcmov%f1\t{%3, %0|%0, %3}
19040 cmov%O2%C1\t{%2, %0|%0, %2}
19041 cmov%O2%c1\t{%3, %0|%0, %3}"
19042 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19043 (set_attr "mode" "SF,SF,SI,SI")])
19044
19045 (define_expand "movdfcc"
19046 [(set (match_operand:DF 0 "register_operand" "")
19047 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19048 (match_operand:DF 2 "register_operand" "")
19049 (match_operand:DF 3 "register_operand" "")))]
19050 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19051 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19052
19053 (define_insn "*movdfcc_1"
19054 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19055 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19056 [(reg FLAGS_REG) (const_int 0)])
19057 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19058 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19059 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19060 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19061 "@
19062 fcmov%F1\t{%2, %0|%0, %2}
19063 fcmov%f1\t{%3, %0|%0, %3}
19064 #
19065 #"
19066 [(set_attr "type" "fcmov,fcmov,multi,multi")
19067 (set_attr "mode" "DF")])
19068
19069 (define_insn "*movdfcc_1_rex64"
19070 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19071 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19072 [(reg FLAGS_REG) (const_int 0)])
19073 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19074 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19075 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19076 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19077 "@
19078 fcmov%F1\t{%2, %0|%0, %2}
19079 fcmov%f1\t{%3, %0|%0, %3}
19080 cmov%O2%C1\t{%2, %0|%0, %2}
19081 cmov%O2%c1\t{%3, %0|%0, %3}"
19082 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19083 (set_attr "mode" "DF")])
19084
19085 (define_split
19086 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19087 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19088 [(match_operand 4 "flags_reg_operand" "")
19089 (const_int 0)])
19090 (match_operand:DF 2 "nonimmediate_operand" "")
19091 (match_operand:DF 3 "nonimmediate_operand" "")))]
19092 "!TARGET_64BIT && reload_completed"
19093 [(set (match_dup 2)
19094 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19095 (match_dup 5)
19096 (match_dup 7)))
19097 (set (match_dup 3)
19098 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19099 (match_dup 6)
19100 (match_dup 8)))]
19101 "split_di (operands+2, 1, operands+5, operands+6);
19102 split_di (operands+3, 1, operands+7, operands+8);
19103 split_di (operands, 1, operands+2, operands+3);")
19104
19105 (define_expand "movxfcc"
19106 [(set (match_operand:XF 0 "register_operand" "")
19107 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19108 (match_operand:XF 2 "register_operand" "")
19109 (match_operand:XF 3 "register_operand" "")))]
19110 "TARGET_80387 && TARGET_CMOVE"
19111 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19112
19113 (define_insn "*movxfcc_1"
19114 [(set (match_operand:XF 0 "register_operand" "=f,f")
19115 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19116 [(reg FLAGS_REG) (const_int 0)])
19117 (match_operand:XF 2 "register_operand" "f,0")
19118 (match_operand:XF 3 "register_operand" "0,f")))]
19119 "TARGET_80387 && TARGET_CMOVE"
19120 "@
19121 fcmov%F1\t{%2, %0|%0, %2}
19122 fcmov%f1\t{%3, %0|%0, %3}"
19123 [(set_attr "type" "fcmov")
19124 (set_attr "mode" "XF")])
19125
19126 ;; These versions of the min/max patterns are intentionally ignorant of
19127 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19128 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19129 ;; are undefined in this condition, we're certain this is correct.
19130
19131 (define_insn "sminsf3"
19132 [(set (match_operand:SF 0 "register_operand" "=x")
19133 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19134 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19135 "TARGET_SSE_MATH"
19136 "minss\t{%2, %0|%0, %2}"
19137 [(set_attr "type" "sseadd")
19138 (set_attr "mode" "SF")])
19139
19140 (define_insn "smaxsf3"
19141 [(set (match_operand:SF 0 "register_operand" "=x")
19142 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19143 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19144 "TARGET_SSE_MATH"
19145 "maxss\t{%2, %0|%0, %2}"
19146 [(set_attr "type" "sseadd")
19147 (set_attr "mode" "SF")])
19148
19149 (define_insn "smindf3"
19150 [(set (match_operand:DF 0 "register_operand" "=x")
19151 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19152 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19153 "TARGET_SSE2 && TARGET_SSE_MATH"
19154 "minsd\t{%2, %0|%0, %2}"
19155 [(set_attr "type" "sseadd")
19156 (set_attr "mode" "DF")])
19157
19158 (define_insn "smaxdf3"
19159 [(set (match_operand:DF 0 "register_operand" "=x")
19160 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19161 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19162 "TARGET_SSE2 && TARGET_SSE_MATH"
19163 "maxsd\t{%2, %0|%0, %2}"
19164 [(set_attr "type" "sseadd")
19165 (set_attr "mode" "DF")])
19166
19167 ;; These versions of the min/max patterns implement exactly the operations
19168 ;; min = (op1 < op2 ? op1 : op2)
19169 ;; max = (!(op1 < op2) ? op1 : op2)
19170 ;; Their operands are not commutative, and thus they may be used in the
19171 ;; presence of -0.0 and NaN.
19172
19173 (define_insn "*ieee_sminsf3"
19174 [(set (match_operand:SF 0 "register_operand" "=x")
19175 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19176 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19177 UNSPEC_IEEE_MIN))]
19178 "TARGET_SSE_MATH"
19179 "minss\t{%2, %0|%0, %2}"
19180 [(set_attr "type" "sseadd")
19181 (set_attr "mode" "SF")])
19182
19183 (define_insn "*ieee_smaxsf3"
19184 [(set (match_operand:SF 0 "register_operand" "=x")
19185 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19186 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19187 UNSPEC_IEEE_MAX))]
19188 "TARGET_SSE_MATH"
19189 "maxss\t{%2, %0|%0, %2}"
19190 [(set_attr "type" "sseadd")
19191 (set_attr "mode" "SF")])
19192
19193 (define_insn "*ieee_smindf3"
19194 [(set (match_operand:DF 0 "register_operand" "=x")
19195 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19196 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19197 UNSPEC_IEEE_MIN))]
19198 "TARGET_SSE2 && TARGET_SSE_MATH"
19199 "minsd\t{%2, %0|%0, %2}"
19200 [(set_attr "type" "sseadd")
19201 (set_attr "mode" "DF")])
19202
19203 (define_insn "*ieee_smaxdf3"
19204 [(set (match_operand:DF 0 "register_operand" "=x")
19205 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19206 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19207 UNSPEC_IEEE_MAX))]
19208 "TARGET_SSE2 && TARGET_SSE_MATH"
19209 "maxsd\t{%2, %0|%0, %2}"
19210 [(set_attr "type" "sseadd")
19211 (set_attr "mode" "DF")])
19212
19213 ;; Make two stack loads independent:
19214 ;; fld aa fld aa
19215 ;; fld %st(0) -> fld bb
19216 ;; fmul bb fmul %st(1), %st
19217 ;;
19218 ;; Actually we only match the last two instructions for simplicity.
19219 (define_peephole2
19220 [(set (match_operand 0 "fp_register_operand" "")
19221 (match_operand 1 "fp_register_operand" ""))
19222 (set (match_dup 0)
19223 (match_operator 2 "binary_fp_operator"
19224 [(match_dup 0)
19225 (match_operand 3 "memory_operand" "")]))]
19226 "REGNO (operands[0]) != REGNO (operands[1])"
19227 [(set (match_dup 0) (match_dup 3))
19228 (set (match_dup 0) (match_dup 4))]
19229
19230 ;; The % modifier is not operational anymore in peephole2's, so we have to
19231 ;; swap the operands manually in the case of addition and multiplication.
19232 "if (COMMUTATIVE_ARITH_P (operands[2]))
19233 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19234 operands[0], operands[1]);
19235 else
19236 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19237 operands[1], operands[0]);")
19238
19239 ;; Conditional addition patterns
19240 (define_expand "addqicc"
19241 [(match_operand:QI 0 "register_operand" "")
19242 (match_operand 1 "comparison_operator" "")
19243 (match_operand:QI 2 "register_operand" "")
19244 (match_operand:QI 3 "const_int_operand" "")]
19245 ""
19246 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19247
19248 (define_expand "addhicc"
19249 [(match_operand:HI 0 "register_operand" "")
19250 (match_operand 1 "comparison_operator" "")
19251 (match_operand:HI 2 "register_operand" "")
19252 (match_operand:HI 3 "const_int_operand" "")]
19253 ""
19254 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19255
19256 (define_expand "addsicc"
19257 [(match_operand:SI 0 "register_operand" "")
19258 (match_operand 1 "comparison_operator" "")
19259 (match_operand:SI 2 "register_operand" "")
19260 (match_operand:SI 3 "const_int_operand" "")]
19261 ""
19262 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19263
19264 (define_expand "adddicc"
19265 [(match_operand:DI 0 "register_operand" "")
19266 (match_operand 1 "comparison_operator" "")
19267 (match_operand:DI 2 "register_operand" "")
19268 (match_operand:DI 3 "const_int_operand" "")]
19269 "TARGET_64BIT"
19270 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19271
19272 \f
19273 ;; Misc patterns (?)
19274
19275 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19276 ;; Otherwise there will be nothing to keep
19277 ;;
19278 ;; [(set (reg ebp) (reg esp))]
19279 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19280 ;; (clobber (eflags)]
19281 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19282 ;;
19283 ;; in proper program order.
19284 (define_insn "pro_epilogue_adjust_stack_1"
19285 [(set (match_operand:SI 0 "register_operand" "=r,r")
19286 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19287 (match_operand:SI 2 "immediate_operand" "i,i")))
19288 (clobber (reg:CC FLAGS_REG))
19289 (clobber (mem:BLK (scratch)))]
19290 "!TARGET_64BIT"
19291 {
19292 switch (get_attr_type (insn))
19293 {
19294 case TYPE_IMOV:
19295 return "mov{l}\t{%1, %0|%0, %1}";
19296
19297 case TYPE_ALU:
19298 if (GET_CODE (operands[2]) == CONST_INT
19299 && (INTVAL (operands[2]) == 128
19300 || (INTVAL (operands[2]) < 0
19301 && INTVAL (operands[2]) != -128)))
19302 {
19303 operands[2] = GEN_INT (-INTVAL (operands[2]));
19304 return "sub{l}\t{%2, %0|%0, %2}";
19305 }
19306 return "add{l}\t{%2, %0|%0, %2}";
19307
19308 case TYPE_LEA:
19309 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19310 return "lea{l}\t{%a2, %0|%0, %a2}";
19311
19312 default:
19313 gcc_unreachable ();
19314 }
19315 }
19316 [(set (attr "type")
19317 (cond [(eq_attr "alternative" "0")
19318 (const_string "alu")
19319 (match_operand:SI 2 "const0_operand" "")
19320 (const_string "imov")
19321 ]
19322 (const_string "lea")))
19323 (set_attr "mode" "SI")])
19324
19325 (define_insn "pro_epilogue_adjust_stack_rex64"
19326 [(set (match_operand:DI 0 "register_operand" "=r,r")
19327 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19328 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19329 (clobber (reg:CC FLAGS_REG))
19330 (clobber (mem:BLK (scratch)))]
19331 "TARGET_64BIT"
19332 {
19333 switch (get_attr_type (insn))
19334 {
19335 case TYPE_IMOV:
19336 return "mov{q}\t{%1, %0|%0, %1}";
19337
19338 case TYPE_ALU:
19339 if (GET_CODE (operands[2]) == CONST_INT
19340 /* Avoid overflows. */
19341 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19342 && (INTVAL (operands[2]) == 128
19343 || (INTVAL (operands[2]) < 0
19344 && INTVAL (operands[2]) != -128)))
19345 {
19346 operands[2] = GEN_INT (-INTVAL (operands[2]));
19347 return "sub{q}\t{%2, %0|%0, %2}";
19348 }
19349 return "add{q}\t{%2, %0|%0, %2}";
19350
19351 case TYPE_LEA:
19352 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19353 return "lea{q}\t{%a2, %0|%0, %a2}";
19354
19355 default:
19356 gcc_unreachable ();
19357 }
19358 }
19359 [(set (attr "type")
19360 (cond [(eq_attr "alternative" "0")
19361 (const_string "alu")
19362 (match_operand:DI 2 "const0_operand" "")
19363 (const_string "imov")
19364 ]
19365 (const_string "lea")))
19366 (set_attr "mode" "DI")])
19367
19368 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19369 [(set (match_operand:DI 0 "register_operand" "=r,r")
19370 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19371 (match_operand:DI 3 "immediate_operand" "i,i")))
19372 (use (match_operand:DI 2 "register_operand" "r,r"))
19373 (clobber (reg:CC FLAGS_REG))
19374 (clobber (mem:BLK (scratch)))]
19375 "TARGET_64BIT"
19376 {
19377 switch (get_attr_type (insn))
19378 {
19379 case TYPE_ALU:
19380 return "add{q}\t{%2, %0|%0, %2}";
19381
19382 case TYPE_LEA:
19383 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19384 return "lea{q}\t{%a2, %0|%0, %a2}";
19385
19386 default:
19387 gcc_unreachable ();
19388 }
19389 }
19390 [(set_attr "type" "alu,lea")
19391 (set_attr "mode" "DI")])
19392
19393 (define_expand "allocate_stack_worker"
19394 [(match_operand:SI 0 "register_operand" "")]
19395 "TARGET_STACK_PROBE"
19396 {
19397 if (reload_completed)
19398 {
19399 if (TARGET_64BIT)
19400 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19401 else
19402 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19403 }
19404 else
19405 {
19406 if (TARGET_64BIT)
19407 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19408 else
19409 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19410 }
19411 DONE;
19412 })
19413
19414 (define_insn "allocate_stack_worker_1"
19415 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19416 UNSPECV_STACK_PROBE)
19417 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19418 (clobber (match_scratch:SI 1 "=0"))
19419 (clobber (reg:CC FLAGS_REG))]
19420 "!TARGET_64BIT && TARGET_STACK_PROBE"
19421 "call\t__alloca"
19422 [(set_attr "type" "multi")
19423 (set_attr "length" "5")])
19424
19425 (define_expand "allocate_stack_worker_postreload"
19426 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19427 UNSPECV_STACK_PROBE)
19428 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19429 (clobber (match_dup 0))
19430 (clobber (reg:CC FLAGS_REG))])]
19431 ""
19432 "")
19433
19434 (define_insn "allocate_stack_worker_rex64"
19435 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19436 UNSPECV_STACK_PROBE)
19437 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19438 (clobber (match_scratch:DI 1 "=0"))
19439 (clobber (reg:CC FLAGS_REG))]
19440 "TARGET_64BIT && TARGET_STACK_PROBE"
19441 "call\t__alloca"
19442 [(set_attr "type" "multi")
19443 (set_attr "length" "5")])
19444
19445 (define_expand "allocate_stack_worker_rex64_postreload"
19446 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19447 UNSPECV_STACK_PROBE)
19448 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19449 (clobber (match_dup 0))
19450 (clobber (reg:CC FLAGS_REG))])]
19451 ""
19452 "")
19453
19454 (define_expand "allocate_stack"
19455 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19456 (minus:SI (reg:SI SP_REG)
19457 (match_operand:SI 1 "general_operand" "")))
19458 (clobber (reg:CC FLAGS_REG))])
19459 (parallel [(set (reg:SI SP_REG)
19460 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19461 (clobber (reg:CC FLAGS_REG))])]
19462 "TARGET_STACK_PROBE"
19463 {
19464 #ifdef CHECK_STACK_LIMIT
19465 if (GET_CODE (operands[1]) == CONST_INT
19466 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19467 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19468 operands[1]));
19469 else
19470 #endif
19471 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19472 operands[1])));
19473
19474 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19475 DONE;
19476 })
19477
19478 (define_expand "builtin_setjmp_receiver"
19479 [(label_ref (match_operand 0 "" ""))]
19480 "!TARGET_64BIT && flag_pic"
19481 {
19482 if (TARGET_MACHO)
19483 {
19484 rtx xops[3];
19485 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19486 rtx label_rtx = gen_label_rtx ();
19487 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19488 xops[0] = xops[1] = picreg;
19489 xops[2] = gen_rtx_CONST (SImode,
19490 gen_rtx_MINUS (SImode,
19491 gen_rtx_LABEL_REF (SImode, label_rtx),
19492 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19493 ix86_expand_binary_operator (MINUS, SImode, xops);
19494 }
19495 else
19496 emit_insn (gen_set_got (pic_offset_table_rtx));
19497 DONE;
19498 })
19499 \f
19500 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19501
19502 (define_split
19503 [(set (match_operand 0 "register_operand" "")
19504 (match_operator 3 "promotable_binary_operator"
19505 [(match_operand 1 "register_operand" "")
19506 (match_operand 2 "aligned_operand" "")]))
19507 (clobber (reg:CC FLAGS_REG))]
19508 "! TARGET_PARTIAL_REG_STALL && reload_completed
19509 && ((GET_MODE (operands[0]) == HImode
19510 && ((!optimize_size && !TARGET_FAST_PREFIX)
19511 /* ??? next two lines just !satisfies_constraint_K (...) */
19512 || GET_CODE (operands[2]) != CONST_INT
19513 || satisfies_constraint_K (operands[2])))
19514 || (GET_MODE (operands[0]) == QImode
19515 && (TARGET_PROMOTE_QImode || optimize_size)))"
19516 [(parallel [(set (match_dup 0)
19517 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19518 (clobber (reg:CC FLAGS_REG))])]
19519 "operands[0] = gen_lowpart (SImode, operands[0]);
19520 operands[1] = gen_lowpart (SImode, operands[1]);
19521 if (GET_CODE (operands[3]) != ASHIFT)
19522 operands[2] = gen_lowpart (SImode, operands[2]);
19523 PUT_MODE (operands[3], SImode);")
19524
19525 ; Promote the QImode tests, as i386 has encoding of the AND
19526 ; instruction with 32-bit sign-extended immediate and thus the
19527 ; instruction size is unchanged, except in the %eax case for
19528 ; which it is increased by one byte, hence the ! optimize_size.
19529 (define_split
19530 [(set (match_operand 0 "flags_reg_operand" "")
19531 (match_operator 2 "compare_operator"
19532 [(and (match_operand 3 "aligned_operand" "")
19533 (match_operand 4 "const_int_operand" ""))
19534 (const_int 0)]))
19535 (set (match_operand 1 "register_operand" "")
19536 (and (match_dup 3) (match_dup 4)))]
19537 "! TARGET_PARTIAL_REG_STALL && reload_completed
19538 /* Ensure that the operand will remain sign-extended immediate. */
19539 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19540 && ! optimize_size
19541 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19542 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19543 [(parallel [(set (match_dup 0)
19544 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19545 (const_int 0)]))
19546 (set (match_dup 1)
19547 (and:SI (match_dup 3) (match_dup 4)))])]
19548 {
19549 operands[4]
19550 = gen_int_mode (INTVAL (operands[4])
19551 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19552 operands[1] = gen_lowpart (SImode, operands[1]);
19553 operands[3] = gen_lowpart (SImode, operands[3]);
19554 })
19555
19556 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19557 ; the TEST instruction with 32-bit sign-extended immediate and thus
19558 ; the instruction size would at least double, which is not what we
19559 ; want even with ! optimize_size.
19560 (define_split
19561 [(set (match_operand 0 "flags_reg_operand" "")
19562 (match_operator 1 "compare_operator"
19563 [(and (match_operand:HI 2 "aligned_operand" "")
19564 (match_operand:HI 3 "const_int_operand" ""))
19565 (const_int 0)]))]
19566 "! TARGET_PARTIAL_REG_STALL && reload_completed
19567 /* Ensure that the operand will remain sign-extended immediate. */
19568 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19569 && ! TARGET_FAST_PREFIX
19570 && ! optimize_size"
19571 [(set (match_dup 0)
19572 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19573 (const_int 0)]))]
19574 {
19575 operands[3]
19576 = gen_int_mode (INTVAL (operands[3])
19577 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19578 operands[2] = gen_lowpart (SImode, operands[2]);
19579 })
19580
19581 (define_split
19582 [(set (match_operand 0 "register_operand" "")
19583 (neg (match_operand 1 "register_operand" "")))
19584 (clobber (reg:CC FLAGS_REG))]
19585 "! TARGET_PARTIAL_REG_STALL && reload_completed
19586 && (GET_MODE (operands[0]) == HImode
19587 || (GET_MODE (operands[0]) == QImode
19588 && (TARGET_PROMOTE_QImode || optimize_size)))"
19589 [(parallel [(set (match_dup 0)
19590 (neg:SI (match_dup 1)))
19591 (clobber (reg:CC FLAGS_REG))])]
19592 "operands[0] = gen_lowpart (SImode, operands[0]);
19593 operands[1] = gen_lowpart (SImode, operands[1]);")
19594
19595 (define_split
19596 [(set (match_operand 0 "register_operand" "")
19597 (not (match_operand 1 "register_operand" "")))]
19598 "! TARGET_PARTIAL_REG_STALL && reload_completed
19599 && (GET_MODE (operands[0]) == HImode
19600 || (GET_MODE (operands[0]) == QImode
19601 && (TARGET_PROMOTE_QImode || optimize_size)))"
19602 [(set (match_dup 0)
19603 (not:SI (match_dup 1)))]
19604 "operands[0] = gen_lowpart (SImode, operands[0]);
19605 operands[1] = gen_lowpart (SImode, operands[1]);")
19606
19607 (define_split
19608 [(set (match_operand 0 "register_operand" "")
19609 (if_then_else (match_operator 1 "comparison_operator"
19610 [(reg FLAGS_REG) (const_int 0)])
19611 (match_operand 2 "register_operand" "")
19612 (match_operand 3 "register_operand" "")))]
19613 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19614 && (GET_MODE (operands[0]) == HImode
19615 || (GET_MODE (operands[0]) == QImode
19616 && (TARGET_PROMOTE_QImode || optimize_size)))"
19617 [(set (match_dup 0)
19618 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19619 "operands[0] = gen_lowpart (SImode, operands[0]);
19620 operands[2] = gen_lowpart (SImode, operands[2]);
19621 operands[3] = gen_lowpart (SImode, operands[3]);")
19622
19623 \f
19624 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19625 ;; transform a complex memory operation into two memory to register operations.
19626
19627 ;; Don't push memory operands
19628 (define_peephole2
19629 [(set (match_operand:SI 0 "push_operand" "")
19630 (match_operand:SI 1 "memory_operand" ""))
19631 (match_scratch:SI 2 "r")]
19632 "!optimize_size && !TARGET_PUSH_MEMORY
19633 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19634 [(set (match_dup 2) (match_dup 1))
19635 (set (match_dup 0) (match_dup 2))]
19636 "")
19637
19638 (define_peephole2
19639 [(set (match_operand:DI 0 "push_operand" "")
19640 (match_operand:DI 1 "memory_operand" ""))
19641 (match_scratch:DI 2 "r")]
19642 "!optimize_size && !TARGET_PUSH_MEMORY
19643 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19644 [(set (match_dup 2) (match_dup 1))
19645 (set (match_dup 0) (match_dup 2))]
19646 "")
19647
19648 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19649 ;; SImode pushes.
19650 (define_peephole2
19651 [(set (match_operand:SF 0 "push_operand" "")
19652 (match_operand:SF 1 "memory_operand" ""))
19653 (match_scratch:SF 2 "r")]
19654 "!optimize_size && !TARGET_PUSH_MEMORY
19655 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19656 [(set (match_dup 2) (match_dup 1))
19657 (set (match_dup 0) (match_dup 2))]
19658 "")
19659
19660 (define_peephole2
19661 [(set (match_operand:HI 0 "push_operand" "")
19662 (match_operand:HI 1 "memory_operand" ""))
19663 (match_scratch:HI 2 "r")]
19664 "!optimize_size && !TARGET_PUSH_MEMORY
19665 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19666 [(set (match_dup 2) (match_dup 1))
19667 (set (match_dup 0) (match_dup 2))]
19668 "")
19669
19670 (define_peephole2
19671 [(set (match_operand:QI 0 "push_operand" "")
19672 (match_operand:QI 1 "memory_operand" ""))
19673 (match_scratch:QI 2 "q")]
19674 "!optimize_size && !TARGET_PUSH_MEMORY
19675 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19676 [(set (match_dup 2) (match_dup 1))
19677 (set (match_dup 0) (match_dup 2))]
19678 "")
19679
19680 ;; Don't move an immediate directly to memory when the instruction
19681 ;; gets too big.
19682 (define_peephole2
19683 [(match_scratch:SI 1 "r")
19684 (set (match_operand:SI 0 "memory_operand" "")
19685 (const_int 0))]
19686 "! optimize_size
19687 && ! TARGET_USE_MOV0
19688 && TARGET_SPLIT_LONG_MOVES
19689 && get_attr_length (insn) >= ix86_cost->large_insn
19690 && peep2_regno_dead_p (0, FLAGS_REG)"
19691 [(parallel [(set (match_dup 1) (const_int 0))
19692 (clobber (reg:CC FLAGS_REG))])
19693 (set (match_dup 0) (match_dup 1))]
19694 "")
19695
19696 (define_peephole2
19697 [(match_scratch:HI 1 "r")
19698 (set (match_operand:HI 0 "memory_operand" "")
19699 (const_int 0))]
19700 "! optimize_size
19701 && ! TARGET_USE_MOV0
19702 && TARGET_SPLIT_LONG_MOVES
19703 && get_attr_length (insn) >= ix86_cost->large_insn
19704 && peep2_regno_dead_p (0, FLAGS_REG)"
19705 [(parallel [(set (match_dup 2) (const_int 0))
19706 (clobber (reg:CC FLAGS_REG))])
19707 (set (match_dup 0) (match_dup 1))]
19708 "operands[2] = gen_lowpart (SImode, operands[1]);")
19709
19710 (define_peephole2
19711 [(match_scratch:QI 1 "q")
19712 (set (match_operand:QI 0 "memory_operand" "")
19713 (const_int 0))]
19714 "! optimize_size
19715 && ! TARGET_USE_MOV0
19716 && TARGET_SPLIT_LONG_MOVES
19717 && get_attr_length (insn) >= ix86_cost->large_insn
19718 && peep2_regno_dead_p (0, FLAGS_REG)"
19719 [(parallel [(set (match_dup 2) (const_int 0))
19720 (clobber (reg:CC FLAGS_REG))])
19721 (set (match_dup 0) (match_dup 1))]
19722 "operands[2] = gen_lowpart (SImode, operands[1]);")
19723
19724 (define_peephole2
19725 [(match_scratch:SI 2 "r")
19726 (set (match_operand:SI 0 "memory_operand" "")
19727 (match_operand:SI 1 "immediate_operand" ""))]
19728 "! optimize_size
19729 && get_attr_length (insn) >= ix86_cost->large_insn
19730 && TARGET_SPLIT_LONG_MOVES"
19731 [(set (match_dup 2) (match_dup 1))
19732 (set (match_dup 0) (match_dup 2))]
19733 "")
19734
19735 (define_peephole2
19736 [(match_scratch:HI 2 "r")
19737 (set (match_operand:HI 0 "memory_operand" "")
19738 (match_operand:HI 1 "immediate_operand" ""))]
19739 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19740 && TARGET_SPLIT_LONG_MOVES"
19741 [(set (match_dup 2) (match_dup 1))
19742 (set (match_dup 0) (match_dup 2))]
19743 "")
19744
19745 (define_peephole2
19746 [(match_scratch:QI 2 "q")
19747 (set (match_operand:QI 0 "memory_operand" "")
19748 (match_operand:QI 1 "immediate_operand" ""))]
19749 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19750 && TARGET_SPLIT_LONG_MOVES"
19751 [(set (match_dup 2) (match_dup 1))
19752 (set (match_dup 0) (match_dup 2))]
19753 "")
19754
19755 ;; Don't compare memory with zero, load and use a test instead.
19756 (define_peephole2
19757 [(set (match_operand 0 "flags_reg_operand" "")
19758 (match_operator 1 "compare_operator"
19759 [(match_operand:SI 2 "memory_operand" "")
19760 (const_int 0)]))
19761 (match_scratch:SI 3 "r")]
19762 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19763 [(set (match_dup 3) (match_dup 2))
19764 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19765 "")
19766
19767 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19768 ;; Don't split NOTs with a displacement operand, because resulting XOR
19769 ;; will not be pairable anyway.
19770 ;;
19771 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19772 ;; represented using a modRM byte. The XOR replacement is long decoded,
19773 ;; so this split helps here as well.
19774 ;;
19775 ;; Note: Can't do this as a regular split because we can't get proper
19776 ;; lifetime information then.
19777
19778 (define_peephole2
19779 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19780 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19781 "!optimize_size
19782 && peep2_regno_dead_p (0, FLAGS_REG)
19783 && ((TARGET_PENTIUM
19784 && (GET_CODE (operands[0]) != MEM
19785 || !memory_displacement_operand (operands[0], SImode)))
19786 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19787 [(parallel [(set (match_dup 0)
19788 (xor:SI (match_dup 1) (const_int -1)))
19789 (clobber (reg:CC FLAGS_REG))])]
19790 "")
19791
19792 (define_peephole2
19793 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19794 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19795 "!optimize_size
19796 && peep2_regno_dead_p (0, FLAGS_REG)
19797 && ((TARGET_PENTIUM
19798 && (GET_CODE (operands[0]) != MEM
19799 || !memory_displacement_operand (operands[0], HImode)))
19800 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19801 [(parallel [(set (match_dup 0)
19802 (xor:HI (match_dup 1) (const_int -1)))
19803 (clobber (reg:CC FLAGS_REG))])]
19804 "")
19805
19806 (define_peephole2
19807 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19808 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19809 "!optimize_size
19810 && peep2_regno_dead_p (0, FLAGS_REG)
19811 && ((TARGET_PENTIUM
19812 && (GET_CODE (operands[0]) != MEM
19813 || !memory_displacement_operand (operands[0], QImode)))
19814 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19815 [(parallel [(set (match_dup 0)
19816 (xor:QI (match_dup 1) (const_int -1)))
19817 (clobber (reg:CC FLAGS_REG))])]
19818 "")
19819
19820 ;; Non pairable "test imm, reg" instructions can be translated to
19821 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19822 ;; byte opcode instead of two, have a short form for byte operands),
19823 ;; so do it for other CPUs as well. Given that the value was dead,
19824 ;; this should not create any new dependencies. Pass on the sub-word
19825 ;; versions if we're concerned about partial register stalls.
19826
19827 (define_peephole2
19828 [(set (match_operand 0 "flags_reg_operand" "")
19829 (match_operator 1 "compare_operator"
19830 [(and:SI (match_operand:SI 2 "register_operand" "")
19831 (match_operand:SI 3 "immediate_operand" ""))
19832 (const_int 0)]))]
19833 "ix86_match_ccmode (insn, CCNOmode)
19834 && (true_regnum (operands[2]) != 0
19835 || satisfies_constraint_K (operands[3]))
19836 && peep2_reg_dead_p (1, operands[2])"
19837 [(parallel
19838 [(set (match_dup 0)
19839 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19840 (const_int 0)]))
19841 (set (match_dup 2)
19842 (and:SI (match_dup 2) (match_dup 3)))])]
19843 "")
19844
19845 ;; We don't need to handle HImode case, because it will be promoted to SImode
19846 ;; on ! TARGET_PARTIAL_REG_STALL
19847
19848 (define_peephole2
19849 [(set (match_operand 0 "flags_reg_operand" "")
19850 (match_operator 1 "compare_operator"
19851 [(and:QI (match_operand:QI 2 "register_operand" "")
19852 (match_operand:QI 3 "immediate_operand" ""))
19853 (const_int 0)]))]
19854 "! TARGET_PARTIAL_REG_STALL
19855 && ix86_match_ccmode (insn, CCNOmode)
19856 && true_regnum (operands[2]) != 0
19857 && peep2_reg_dead_p (1, operands[2])"
19858 [(parallel
19859 [(set (match_dup 0)
19860 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19861 (const_int 0)]))
19862 (set (match_dup 2)
19863 (and:QI (match_dup 2) (match_dup 3)))])]
19864 "")
19865
19866 (define_peephole2
19867 [(set (match_operand 0 "flags_reg_operand" "")
19868 (match_operator 1 "compare_operator"
19869 [(and:SI
19870 (zero_extract:SI
19871 (match_operand 2 "ext_register_operand" "")
19872 (const_int 8)
19873 (const_int 8))
19874 (match_operand 3 "const_int_operand" ""))
19875 (const_int 0)]))]
19876 "! TARGET_PARTIAL_REG_STALL
19877 && ix86_match_ccmode (insn, CCNOmode)
19878 && true_regnum (operands[2]) != 0
19879 && peep2_reg_dead_p (1, operands[2])"
19880 [(parallel [(set (match_dup 0)
19881 (match_op_dup 1
19882 [(and:SI
19883 (zero_extract:SI
19884 (match_dup 2)
19885 (const_int 8)
19886 (const_int 8))
19887 (match_dup 3))
19888 (const_int 0)]))
19889 (set (zero_extract:SI (match_dup 2)
19890 (const_int 8)
19891 (const_int 8))
19892 (and:SI
19893 (zero_extract:SI
19894 (match_dup 2)
19895 (const_int 8)
19896 (const_int 8))
19897 (match_dup 3)))])]
19898 "")
19899
19900 ;; Don't do logical operations with memory inputs.
19901 (define_peephole2
19902 [(match_scratch:SI 2 "r")
19903 (parallel [(set (match_operand:SI 0 "register_operand" "")
19904 (match_operator:SI 3 "arith_or_logical_operator"
19905 [(match_dup 0)
19906 (match_operand:SI 1 "memory_operand" "")]))
19907 (clobber (reg:CC FLAGS_REG))])]
19908 "! optimize_size && ! TARGET_READ_MODIFY"
19909 [(set (match_dup 2) (match_dup 1))
19910 (parallel [(set (match_dup 0)
19911 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19912 (clobber (reg:CC FLAGS_REG))])]
19913 "")
19914
19915 (define_peephole2
19916 [(match_scratch:SI 2 "r")
19917 (parallel [(set (match_operand:SI 0 "register_operand" "")
19918 (match_operator:SI 3 "arith_or_logical_operator"
19919 [(match_operand:SI 1 "memory_operand" "")
19920 (match_dup 0)]))
19921 (clobber (reg:CC FLAGS_REG))])]
19922 "! optimize_size && ! TARGET_READ_MODIFY"
19923 [(set (match_dup 2) (match_dup 1))
19924 (parallel [(set (match_dup 0)
19925 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19926 (clobber (reg:CC FLAGS_REG))])]
19927 "")
19928
19929 ; Don't do logical operations with memory outputs
19930 ;
19931 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19932 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19933 ; the same decoder scheduling characteristics as the original.
19934
19935 (define_peephole2
19936 [(match_scratch:SI 2 "r")
19937 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19938 (match_operator:SI 3 "arith_or_logical_operator"
19939 [(match_dup 0)
19940 (match_operand:SI 1 "nonmemory_operand" "")]))
19941 (clobber (reg:CC FLAGS_REG))])]
19942 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19943 [(set (match_dup 2) (match_dup 0))
19944 (parallel [(set (match_dup 2)
19945 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19946 (clobber (reg:CC FLAGS_REG))])
19947 (set (match_dup 0) (match_dup 2))]
19948 "")
19949
19950 (define_peephole2
19951 [(match_scratch:SI 2 "r")
19952 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19953 (match_operator:SI 3 "arith_or_logical_operator"
19954 [(match_operand:SI 1 "nonmemory_operand" "")
19955 (match_dup 0)]))
19956 (clobber (reg:CC FLAGS_REG))])]
19957 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19958 [(set (match_dup 2) (match_dup 0))
19959 (parallel [(set (match_dup 2)
19960 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19961 (clobber (reg:CC FLAGS_REG))])
19962 (set (match_dup 0) (match_dup 2))]
19963 "")
19964
19965 ;; Attempt to always use XOR for zeroing registers.
19966 (define_peephole2
19967 [(set (match_operand 0 "register_operand" "")
19968 (match_operand 1 "const0_operand" ""))]
19969 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19970 && (! TARGET_USE_MOV0 || optimize_size)
19971 && GENERAL_REG_P (operands[0])
19972 && peep2_regno_dead_p (0, FLAGS_REG)"
19973 [(parallel [(set (match_dup 0) (const_int 0))
19974 (clobber (reg:CC FLAGS_REG))])]
19975 {
19976 operands[0] = gen_lowpart (word_mode, operands[0]);
19977 })
19978
19979 (define_peephole2
19980 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19981 (const_int 0))]
19982 "(GET_MODE (operands[0]) == QImode
19983 || GET_MODE (operands[0]) == HImode)
19984 && (! TARGET_USE_MOV0 || optimize_size)
19985 && peep2_regno_dead_p (0, FLAGS_REG)"
19986 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19987 (clobber (reg:CC FLAGS_REG))])])
19988
19989 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19990 (define_peephole2
19991 [(set (match_operand 0 "register_operand" "")
19992 (const_int -1))]
19993 "(GET_MODE (operands[0]) == HImode
19994 || GET_MODE (operands[0]) == SImode
19995 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19996 && (optimize_size || TARGET_PENTIUM)
19997 && peep2_regno_dead_p (0, FLAGS_REG)"
19998 [(parallel [(set (match_dup 0) (const_int -1))
19999 (clobber (reg:CC FLAGS_REG))])]
20000 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20001 operands[0]);")
20002
20003 ;; Attempt to convert simple leas to adds. These can be created by
20004 ;; move expanders.
20005 (define_peephole2
20006 [(set (match_operand:SI 0 "register_operand" "")
20007 (plus:SI (match_dup 0)
20008 (match_operand:SI 1 "nonmemory_operand" "")))]
20009 "peep2_regno_dead_p (0, FLAGS_REG)"
20010 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20011 (clobber (reg:CC FLAGS_REG))])]
20012 "")
20013
20014 (define_peephole2
20015 [(set (match_operand:SI 0 "register_operand" "")
20016 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20017 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20018 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20019 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20020 (clobber (reg:CC FLAGS_REG))])]
20021 "operands[2] = gen_lowpart (SImode, operands[2]);")
20022
20023 (define_peephole2
20024 [(set (match_operand:DI 0 "register_operand" "")
20025 (plus:DI (match_dup 0)
20026 (match_operand:DI 1 "x86_64_general_operand" "")))]
20027 "peep2_regno_dead_p (0, FLAGS_REG)"
20028 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20029 (clobber (reg:CC FLAGS_REG))])]
20030 "")
20031
20032 (define_peephole2
20033 [(set (match_operand:SI 0 "register_operand" "")
20034 (mult:SI (match_dup 0)
20035 (match_operand:SI 1 "const_int_operand" "")))]
20036 "exact_log2 (INTVAL (operands[1])) >= 0
20037 && peep2_regno_dead_p (0, FLAGS_REG)"
20038 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20039 (clobber (reg:CC FLAGS_REG))])]
20040 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20041
20042 (define_peephole2
20043 [(set (match_operand:DI 0 "register_operand" "")
20044 (mult:DI (match_dup 0)
20045 (match_operand:DI 1 "const_int_operand" "")))]
20046 "exact_log2 (INTVAL (operands[1])) >= 0
20047 && peep2_regno_dead_p (0, FLAGS_REG)"
20048 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20049 (clobber (reg:CC FLAGS_REG))])]
20050 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20051
20052 (define_peephole2
20053 [(set (match_operand:SI 0 "register_operand" "")
20054 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20055 (match_operand:DI 2 "const_int_operand" "")) 0))]
20056 "exact_log2 (INTVAL (operands[2])) >= 0
20057 && REGNO (operands[0]) == REGNO (operands[1])
20058 && peep2_regno_dead_p (0, FLAGS_REG)"
20059 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20060 (clobber (reg:CC FLAGS_REG))])]
20061 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20062
20063 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20064 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20065 ;; many CPUs it is also faster, since special hardware to avoid esp
20066 ;; dependencies is present.
20067
20068 ;; While some of these conversions may be done using splitters, we use peepholes
20069 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20070
20071 ;; Convert prologue esp subtractions to push.
20072 ;; We need register to push. In order to keep verify_flow_info happy we have
20073 ;; two choices
20074 ;; - use scratch and clobber it in order to avoid dependencies
20075 ;; - use already live register
20076 ;; We can't use the second way right now, since there is no reliable way how to
20077 ;; verify that given register is live. First choice will also most likely in
20078 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20079 ;; call clobbered registers are dead. We may want to use base pointer as an
20080 ;; alternative when no register is available later.
20081
20082 (define_peephole2
20083 [(match_scratch:SI 0 "r")
20084 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20085 (clobber (reg:CC FLAGS_REG))
20086 (clobber (mem:BLK (scratch)))])]
20087 "optimize_size || !TARGET_SUB_ESP_4"
20088 [(clobber (match_dup 0))
20089 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20090 (clobber (mem:BLK (scratch)))])])
20091
20092 (define_peephole2
20093 [(match_scratch:SI 0 "r")
20094 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20095 (clobber (reg:CC FLAGS_REG))
20096 (clobber (mem:BLK (scratch)))])]
20097 "optimize_size || !TARGET_SUB_ESP_8"
20098 [(clobber (match_dup 0))
20099 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20100 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20101 (clobber (mem:BLK (scratch)))])])
20102
20103 ;; Convert esp subtractions to push.
20104 (define_peephole2
20105 [(match_scratch:SI 0 "r")
20106 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20107 (clobber (reg:CC FLAGS_REG))])]
20108 "optimize_size || !TARGET_SUB_ESP_4"
20109 [(clobber (match_dup 0))
20110 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20111
20112 (define_peephole2
20113 [(match_scratch:SI 0 "r")
20114 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20115 (clobber (reg:CC FLAGS_REG))])]
20116 "optimize_size || !TARGET_SUB_ESP_8"
20117 [(clobber (match_dup 0))
20118 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20119 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20120
20121 ;; Convert epilogue deallocator to pop.
20122 (define_peephole2
20123 [(match_scratch:SI 0 "r")
20124 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20125 (clobber (reg:CC FLAGS_REG))
20126 (clobber (mem:BLK (scratch)))])]
20127 "optimize_size || !TARGET_ADD_ESP_4"
20128 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20129 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20130 (clobber (mem:BLK (scratch)))])]
20131 "")
20132
20133 ;; Two pops case is tricky, since pop causes dependency on destination register.
20134 ;; We use two registers if available.
20135 (define_peephole2
20136 [(match_scratch:SI 0 "r")
20137 (match_scratch:SI 1 "r")
20138 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20139 (clobber (reg:CC FLAGS_REG))
20140 (clobber (mem:BLK (scratch)))])]
20141 "optimize_size || !TARGET_ADD_ESP_8"
20142 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20143 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20144 (clobber (mem:BLK (scratch)))])
20145 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20146 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20147 "")
20148
20149 (define_peephole2
20150 [(match_scratch:SI 0 "r")
20151 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20152 (clobber (reg:CC FLAGS_REG))
20153 (clobber (mem:BLK (scratch)))])]
20154 "optimize_size"
20155 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20156 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20157 (clobber (mem:BLK (scratch)))])
20158 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20159 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20160 "")
20161
20162 ;; Convert esp additions to pop.
20163 (define_peephole2
20164 [(match_scratch:SI 0 "r")
20165 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20166 (clobber (reg:CC FLAGS_REG))])]
20167 ""
20168 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20169 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20170 "")
20171
20172 ;; Two pops case is tricky, since pop causes dependency on destination register.
20173 ;; We use two registers if available.
20174 (define_peephole2
20175 [(match_scratch:SI 0 "r")
20176 (match_scratch:SI 1 "r")
20177 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20178 (clobber (reg:CC FLAGS_REG))])]
20179 ""
20180 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20181 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20182 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20183 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20184 "")
20185
20186 (define_peephole2
20187 [(match_scratch:SI 0 "r")
20188 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20189 (clobber (reg:CC FLAGS_REG))])]
20190 "optimize_size"
20191 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20192 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20193 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20194 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20195 "")
20196 \f
20197 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20198 ;; required and register dies. Similarly for 128 to plus -128.
20199 (define_peephole2
20200 [(set (match_operand 0 "flags_reg_operand" "")
20201 (match_operator 1 "compare_operator"
20202 [(match_operand 2 "register_operand" "")
20203 (match_operand 3 "const_int_operand" "")]))]
20204 "(INTVAL (operands[3]) == -1
20205 || INTVAL (operands[3]) == 1
20206 || INTVAL (operands[3]) == 128)
20207 && ix86_match_ccmode (insn, CCGCmode)
20208 && peep2_reg_dead_p (1, operands[2])"
20209 [(parallel [(set (match_dup 0)
20210 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20211 (clobber (match_dup 2))])]
20212 "")
20213 \f
20214 (define_peephole2
20215 [(match_scratch:DI 0 "r")
20216 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20217 (clobber (reg:CC FLAGS_REG))
20218 (clobber (mem:BLK (scratch)))])]
20219 "optimize_size || !TARGET_SUB_ESP_4"
20220 [(clobber (match_dup 0))
20221 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20222 (clobber (mem:BLK (scratch)))])])
20223
20224 (define_peephole2
20225 [(match_scratch:DI 0 "r")
20226 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20227 (clobber (reg:CC FLAGS_REG))
20228 (clobber (mem:BLK (scratch)))])]
20229 "optimize_size || !TARGET_SUB_ESP_8"
20230 [(clobber (match_dup 0))
20231 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20232 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20233 (clobber (mem:BLK (scratch)))])])
20234
20235 ;; Convert esp subtractions to push.
20236 (define_peephole2
20237 [(match_scratch:DI 0 "r")
20238 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20239 (clobber (reg:CC FLAGS_REG))])]
20240 "optimize_size || !TARGET_SUB_ESP_4"
20241 [(clobber (match_dup 0))
20242 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20243
20244 (define_peephole2
20245 [(match_scratch:DI 0 "r")
20246 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20247 (clobber (reg:CC FLAGS_REG))])]
20248 "optimize_size || !TARGET_SUB_ESP_8"
20249 [(clobber (match_dup 0))
20250 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20251 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20252
20253 ;; Convert epilogue deallocator to pop.
20254 (define_peephole2
20255 [(match_scratch:DI 0 "r")
20256 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20257 (clobber (reg:CC FLAGS_REG))
20258 (clobber (mem:BLK (scratch)))])]
20259 "optimize_size || !TARGET_ADD_ESP_4"
20260 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20261 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20262 (clobber (mem:BLK (scratch)))])]
20263 "")
20264
20265 ;; Two pops case is tricky, since pop causes dependency on destination register.
20266 ;; We use two registers if available.
20267 (define_peephole2
20268 [(match_scratch:DI 0 "r")
20269 (match_scratch:DI 1 "r")
20270 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20271 (clobber (reg:CC FLAGS_REG))
20272 (clobber (mem:BLK (scratch)))])]
20273 "optimize_size || !TARGET_ADD_ESP_8"
20274 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20275 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20276 (clobber (mem:BLK (scratch)))])
20277 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20278 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20279 "")
20280
20281 (define_peephole2
20282 [(match_scratch:DI 0 "r")
20283 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20284 (clobber (reg:CC FLAGS_REG))
20285 (clobber (mem:BLK (scratch)))])]
20286 "optimize_size"
20287 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20288 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20289 (clobber (mem:BLK (scratch)))])
20290 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20291 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20292 "")
20293
20294 ;; Convert esp additions to pop.
20295 (define_peephole2
20296 [(match_scratch:DI 0 "r")
20297 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20298 (clobber (reg:CC FLAGS_REG))])]
20299 ""
20300 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20301 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20302 "")
20303
20304 ;; Two pops case is tricky, since pop causes dependency on destination register.
20305 ;; We use two registers if available.
20306 (define_peephole2
20307 [(match_scratch:DI 0 "r")
20308 (match_scratch:DI 1 "r")
20309 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20310 (clobber (reg:CC FLAGS_REG))])]
20311 ""
20312 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20313 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20314 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20315 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20316 "")
20317
20318 (define_peephole2
20319 [(match_scratch:DI 0 "r")
20320 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20321 (clobber (reg:CC FLAGS_REG))])]
20322 "optimize_size"
20323 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20324 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20325 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20326 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20327 "")
20328 \f
20329 ;; Convert imul by three, five and nine into lea
20330 (define_peephole2
20331 [(parallel
20332 [(set (match_operand:SI 0 "register_operand" "")
20333 (mult:SI (match_operand:SI 1 "register_operand" "")
20334 (match_operand:SI 2 "const_int_operand" "")))
20335 (clobber (reg:CC FLAGS_REG))])]
20336 "INTVAL (operands[2]) == 3
20337 || INTVAL (operands[2]) == 5
20338 || INTVAL (operands[2]) == 9"
20339 [(set (match_dup 0)
20340 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20341 (match_dup 1)))]
20342 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20343
20344 (define_peephole2
20345 [(parallel
20346 [(set (match_operand:SI 0 "register_operand" "")
20347 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20348 (match_operand:SI 2 "const_int_operand" "")))
20349 (clobber (reg:CC FLAGS_REG))])]
20350 "!optimize_size
20351 && (INTVAL (operands[2]) == 3
20352 || INTVAL (operands[2]) == 5
20353 || INTVAL (operands[2]) == 9)"
20354 [(set (match_dup 0) (match_dup 1))
20355 (set (match_dup 0)
20356 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20357 (match_dup 0)))]
20358 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20359
20360 (define_peephole2
20361 [(parallel
20362 [(set (match_operand:DI 0 "register_operand" "")
20363 (mult:DI (match_operand:DI 1 "register_operand" "")
20364 (match_operand:DI 2 "const_int_operand" "")))
20365 (clobber (reg:CC FLAGS_REG))])]
20366 "TARGET_64BIT
20367 && (INTVAL (operands[2]) == 3
20368 || INTVAL (operands[2]) == 5
20369 || INTVAL (operands[2]) == 9)"
20370 [(set (match_dup 0)
20371 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20372 (match_dup 1)))]
20373 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20374
20375 (define_peephole2
20376 [(parallel
20377 [(set (match_operand:DI 0 "register_operand" "")
20378 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20379 (match_operand:DI 2 "const_int_operand" "")))
20380 (clobber (reg:CC FLAGS_REG))])]
20381 "TARGET_64BIT
20382 && !optimize_size
20383 && (INTVAL (operands[2]) == 3
20384 || INTVAL (operands[2]) == 5
20385 || INTVAL (operands[2]) == 9)"
20386 [(set (match_dup 0) (match_dup 1))
20387 (set (match_dup 0)
20388 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20389 (match_dup 0)))]
20390 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20391
20392 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20393 ;; imul $32bit_imm, reg, reg is direct decoded.
20394 (define_peephole2
20395 [(match_scratch:DI 3 "r")
20396 (parallel [(set (match_operand:DI 0 "register_operand" "")
20397 (mult:DI (match_operand:DI 1 "memory_operand" "")
20398 (match_operand:DI 2 "immediate_operand" "")))
20399 (clobber (reg:CC FLAGS_REG))])]
20400 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20401 && !satisfies_constraint_K (operands[2])"
20402 [(set (match_dup 3) (match_dup 1))
20403 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20404 (clobber (reg:CC FLAGS_REG))])]
20405 "")
20406
20407 (define_peephole2
20408 [(match_scratch:SI 3 "r")
20409 (parallel [(set (match_operand:SI 0 "register_operand" "")
20410 (mult:SI (match_operand:SI 1 "memory_operand" "")
20411 (match_operand:SI 2 "immediate_operand" "")))
20412 (clobber (reg:CC FLAGS_REG))])]
20413 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20414 && !satisfies_constraint_K (operands[2])"
20415 [(set (match_dup 3) (match_dup 1))
20416 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20417 (clobber (reg:CC FLAGS_REG))])]
20418 "")
20419
20420 (define_peephole2
20421 [(match_scratch:SI 3 "r")
20422 (parallel [(set (match_operand:DI 0 "register_operand" "")
20423 (zero_extend:DI
20424 (mult:SI (match_operand:SI 1 "memory_operand" "")
20425 (match_operand:SI 2 "immediate_operand" ""))))
20426 (clobber (reg:CC FLAGS_REG))])]
20427 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20428 && !satisfies_constraint_K (operands[2])"
20429 [(set (match_dup 3) (match_dup 1))
20430 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20431 (clobber (reg:CC FLAGS_REG))])]
20432 "")
20433
20434 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20435 ;; Convert it into imul reg, reg
20436 ;; It would be better to force assembler to encode instruction using long
20437 ;; immediate, but there is apparently no way to do so.
20438 (define_peephole2
20439 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20440 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20441 (match_operand:DI 2 "const_int_operand" "")))
20442 (clobber (reg:CC FLAGS_REG))])
20443 (match_scratch:DI 3 "r")]
20444 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20445 && satisfies_constraint_K (operands[2])"
20446 [(set (match_dup 3) (match_dup 2))
20447 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20448 (clobber (reg:CC FLAGS_REG))])]
20449 {
20450 if (!rtx_equal_p (operands[0], operands[1]))
20451 emit_move_insn (operands[0], operands[1]);
20452 })
20453
20454 (define_peephole2
20455 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20456 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20457 (match_operand:SI 2 "const_int_operand" "")))
20458 (clobber (reg:CC FLAGS_REG))])
20459 (match_scratch:SI 3 "r")]
20460 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20461 && satisfies_constraint_K (operands[2])"
20462 [(set (match_dup 3) (match_dup 2))
20463 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20464 (clobber (reg:CC FLAGS_REG))])]
20465 {
20466 if (!rtx_equal_p (operands[0], operands[1]))
20467 emit_move_insn (operands[0], operands[1]);
20468 })
20469
20470 (define_peephole2
20471 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20472 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20473 (match_operand:HI 2 "immediate_operand" "")))
20474 (clobber (reg:CC FLAGS_REG))])
20475 (match_scratch:HI 3 "r")]
20476 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20477 [(set (match_dup 3) (match_dup 2))
20478 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20479 (clobber (reg:CC FLAGS_REG))])]
20480 {
20481 if (!rtx_equal_p (operands[0], operands[1]))
20482 emit_move_insn (operands[0], operands[1]);
20483 })
20484
20485 ;; After splitting up read-modify operations, array accesses with memory
20486 ;; operands might end up in form:
20487 ;; sall $2, %eax
20488 ;; movl 4(%esp), %edx
20489 ;; addl %edx, %eax
20490 ;; instead of pre-splitting:
20491 ;; sall $2, %eax
20492 ;; addl 4(%esp), %eax
20493 ;; Turn it into:
20494 ;; movl 4(%esp), %edx
20495 ;; leal (%edx,%eax,4), %eax
20496
20497 (define_peephole2
20498 [(parallel [(set (match_operand 0 "register_operand" "")
20499 (ashift (match_operand 1 "register_operand" "")
20500 (match_operand 2 "const_int_operand" "")))
20501 (clobber (reg:CC FLAGS_REG))])
20502 (set (match_operand 3 "register_operand")
20503 (match_operand 4 "x86_64_general_operand" ""))
20504 (parallel [(set (match_operand 5 "register_operand" "")
20505 (plus (match_operand 6 "register_operand" "")
20506 (match_operand 7 "register_operand" "")))
20507 (clobber (reg:CC FLAGS_REG))])]
20508 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20509 /* Validate MODE for lea. */
20510 && ((!TARGET_PARTIAL_REG_STALL
20511 && (GET_MODE (operands[0]) == QImode
20512 || GET_MODE (operands[0]) == HImode))
20513 || GET_MODE (operands[0]) == SImode
20514 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20515 /* We reorder load and the shift. */
20516 && !rtx_equal_p (operands[1], operands[3])
20517 && !reg_overlap_mentioned_p (operands[0], operands[4])
20518 /* Last PLUS must consist of operand 0 and 3. */
20519 && !rtx_equal_p (operands[0], operands[3])
20520 && (rtx_equal_p (operands[3], operands[6])
20521 || rtx_equal_p (operands[3], operands[7]))
20522 && (rtx_equal_p (operands[0], operands[6])
20523 || rtx_equal_p (operands[0], operands[7]))
20524 /* The intermediate operand 0 must die or be same as output. */
20525 && (rtx_equal_p (operands[0], operands[5])
20526 || peep2_reg_dead_p (3, operands[0]))"
20527 [(set (match_dup 3) (match_dup 4))
20528 (set (match_dup 0) (match_dup 1))]
20529 {
20530 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20531 int scale = 1 << INTVAL (operands[2]);
20532 rtx index = gen_lowpart (Pmode, operands[1]);
20533 rtx base = gen_lowpart (Pmode, operands[3]);
20534 rtx dest = gen_lowpart (mode, operands[5]);
20535
20536 operands[1] = gen_rtx_PLUS (Pmode, base,
20537 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20538 if (mode != Pmode)
20539 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20540 operands[0] = dest;
20541 })
20542 \f
20543 ;; Call-value patterns last so that the wildcard operand does not
20544 ;; disrupt insn-recog's switch tables.
20545
20546 (define_insn "*call_value_pop_0"
20547 [(set (match_operand 0 "" "")
20548 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20549 (match_operand:SI 2 "" "")))
20550 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20551 (match_operand:SI 3 "immediate_operand" "")))]
20552 "!TARGET_64BIT"
20553 {
20554 if (SIBLING_CALL_P (insn))
20555 return "jmp\t%P1";
20556 else
20557 return "call\t%P1";
20558 }
20559 [(set_attr "type" "callv")])
20560
20561 (define_insn "*call_value_pop_1"
20562 [(set (match_operand 0 "" "")
20563 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20564 (match_operand:SI 2 "" "")))
20565 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20566 (match_operand:SI 3 "immediate_operand" "i")))]
20567 "!TARGET_64BIT"
20568 {
20569 if (constant_call_address_operand (operands[1], Pmode))
20570 {
20571 if (SIBLING_CALL_P (insn))
20572 return "jmp\t%P1";
20573 else
20574 return "call\t%P1";
20575 }
20576 if (SIBLING_CALL_P (insn))
20577 return "jmp\t%A1";
20578 else
20579 return "call\t%A1";
20580 }
20581 [(set_attr "type" "callv")])
20582
20583 (define_insn "*call_value_0"
20584 [(set (match_operand 0 "" "")
20585 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20586 (match_operand:SI 2 "" "")))]
20587 "!TARGET_64BIT"
20588 {
20589 if (SIBLING_CALL_P (insn))
20590 return "jmp\t%P1";
20591 else
20592 return "call\t%P1";
20593 }
20594 [(set_attr "type" "callv")])
20595
20596 (define_insn "*call_value_0_rex64"
20597 [(set (match_operand 0 "" "")
20598 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20599 (match_operand:DI 2 "const_int_operand" "")))]
20600 "TARGET_64BIT"
20601 {
20602 if (SIBLING_CALL_P (insn))
20603 return "jmp\t%P1";
20604 else
20605 return "call\t%P1";
20606 }
20607 [(set_attr "type" "callv")])
20608
20609 (define_insn "*call_value_1"
20610 [(set (match_operand 0 "" "")
20611 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20612 (match_operand:SI 2 "" "")))]
20613 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20614 {
20615 if (constant_call_address_operand (operands[1], Pmode))
20616 return "call\t%P1";
20617 return "call\t%A1";
20618 }
20619 [(set_attr "type" "callv")])
20620
20621 (define_insn "*sibcall_value_1"
20622 [(set (match_operand 0 "" "")
20623 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20624 (match_operand:SI 2 "" "")))]
20625 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20626 {
20627 if (constant_call_address_operand (operands[1], Pmode))
20628 return "jmp\t%P1";
20629 return "jmp\t%A1";
20630 }
20631 [(set_attr "type" "callv")])
20632
20633 (define_insn "*call_value_1_rex64"
20634 [(set (match_operand 0 "" "")
20635 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20636 (match_operand:DI 2 "" "")))]
20637 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20638 {
20639 if (constant_call_address_operand (operands[1], Pmode))
20640 return "call\t%P1";
20641 return "call\t%A1";
20642 }
20643 [(set_attr "type" "callv")])
20644
20645 (define_insn "*sibcall_value_1_rex64"
20646 [(set (match_operand 0 "" "")
20647 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20648 (match_operand:DI 2 "" "")))]
20649 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20650 "jmp\t%P1"
20651 [(set_attr "type" "callv")])
20652
20653 (define_insn "*sibcall_value_1_rex64_v"
20654 [(set (match_operand 0 "" "")
20655 (call (mem:QI (reg:DI 40))
20656 (match_operand:DI 1 "" "")))]
20657 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20658 "jmp\t*%%r11"
20659 [(set_attr "type" "callv")])
20660 \f
20661 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20662 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20663 ;; caught for use by garbage collectors and the like. Using an insn that
20664 ;; maps to SIGILL makes it more likely the program will rightfully die.
20665 ;; Keeping with tradition, "6" is in honor of #UD.
20666 (define_insn "trap"
20667 [(trap_if (const_int 1) (const_int 6))]
20668 ""
20669 { return ASM_SHORT "0x0b0f"; }
20670 [(set_attr "length" "2")])
20671
20672 (define_expand "sse_prologue_save"
20673 [(parallel [(set (match_operand:BLK 0 "" "")
20674 (unspec:BLK [(reg:DI 21)
20675 (reg:DI 22)
20676 (reg:DI 23)
20677 (reg:DI 24)
20678 (reg:DI 25)
20679 (reg:DI 26)
20680 (reg:DI 27)
20681 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20682 (use (match_operand:DI 1 "register_operand" ""))
20683 (use (match_operand:DI 2 "immediate_operand" ""))
20684 (use (label_ref:DI (match_operand 3 "" "")))])]
20685 "TARGET_64BIT"
20686 "")
20687
20688 (define_insn "*sse_prologue_save_insn"
20689 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20690 (match_operand:DI 4 "const_int_operand" "n")))
20691 (unspec:BLK [(reg:DI 21)
20692 (reg:DI 22)
20693 (reg:DI 23)
20694 (reg:DI 24)
20695 (reg:DI 25)
20696 (reg:DI 26)
20697 (reg:DI 27)
20698 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20699 (use (match_operand:DI 1 "register_operand" "r"))
20700 (use (match_operand:DI 2 "const_int_operand" "i"))
20701 (use (label_ref:DI (match_operand 3 "" "X")))]
20702 "TARGET_64BIT
20703 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20704 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20705 "*
20706 {
20707 int i;
20708 operands[0] = gen_rtx_MEM (Pmode,
20709 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20710 output_asm_insn (\"jmp\\t%A1\", operands);
20711 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20712 {
20713 operands[4] = adjust_address (operands[0], DImode, i*16);
20714 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20715 PUT_MODE (operands[4], TImode);
20716 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20717 output_asm_insn (\"rex\", operands);
20718 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20719 }
20720 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20721 CODE_LABEL_NUMBER (operands[3]));
20722 RET;
20723 }
20724 "
20725 [(set_attr "type" "other")
20726 (set_attr "length_immediate" "0")
20727 (set_attr "length_address" "0")
20728 (set_attr "length" "135")
20729 (set_attr "memory" "store")
20730 (set_attr "modrm" "0")
20731 (set_attr "mode" "DI")])
20732
20733 (define_expand "prefetch"
20734 [(prefetch (match_operand 0 "address_operand" "")
20735 (match_operand:SI 1 "const_int_operand" "")
20736 (match_operand:SI 2 "const_int_operand" ""))]
20737 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20738 {
20739 int rw = INTVAL (operands[1]);
20740 int locality = INTVAL (operands[2]);
20741
20742 gcc_assert (rw == 0 || rw == 1);
20743 gcc_assert (locality >= 0 && locality <= 3);
20744 gcc_assert (GET_MODE (operands[0]) == Pmode
20745 || GET_MODE (operands[0]) == VOIDmode);
20746
20747 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20748 supported by SSE counterpart or the SSE prefetch is not available
20749 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20750 of locality. */
20751 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20752 operands[2] = GEN_INT (3);
20753 else
20754 operands[1] = const0_rtx;
20755 })
20756
20757 (define_insn "*prefetch_sse"
20758 [(prefetch (match_operand:SI 0 "address_operand" "p")
20759 (const_int 0)
20760 (match_operand:SI 1 "const_int_operand" ""))]
20761 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20762 {
20763 static const char * const patterns[4] = {
20764 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20765 };
20766
20767 int locality = INTVAL (operands[1]);
20768 gcc_assert (locality >= 0 && locality <= 3);
20769
20770 return patterns[locality];
20771 }
20772 [(set_attr "type" "sse")
20773 (set_attr "memory" "none")])
20774
20775 (define_insn "*prefetch_sse_rex"
20776 [(prefetch (match_operand:DI 0 "address_operand" "p")
20777 (const_int 0)
20778 (match_operand:SI 1 "const_int_operand" ""))]
20779 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20780 {
20781 static const char * const patterns[4] = {
20782 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20783 };
20784
20785 int locality = INTVAL (operands[1]);
20786 gcc_assert (locality >= 0 && locality <= 3);
20787
20788 return patterns[locality];
20789 }
20790 [(set_attr "type" "sse")
20791 (set_attr "memory" "none")])
20792
20793 (define_insn "*prefetch_3dnow"
20794 [(prefetch (match_operand:SI 0 "address_operand" "p")
20795 (match_operand:SI 1 "const_int_operand" "n")
20796 (const_int 3))]
20797 "TARGET_3DNOW && !TARGET_64BIT"
20798 {
20799 if (INTVAL (operands[1]) == 0)
20800 return "prefetch\t%a0";
20801 else
20802 return "prefetchw\t%a0";
20803 }
20804 [(set_attr "type" "mmx")
20805 (set_attr "memory" "none")])
20806
20807 (define_insn "*prefetch_3dnow_rex"
20808 [(prefetch (match_operand:DI 0 "address_operand" "p")
20809 (match_operand:SI 1 "const_int_operand" "n")
20810 (const_int 3))]
20811 "TARGET_3DNOW && TARGET_64BIT"
20812 {
20813 if (INTVAL (operands[1]) == 0)
20814 return "prefetch\t%a0";
20815 else
20816 return "prefetchw\t%a0";
20817 }
20818 [(set_attr "type" "mmx")
20819 (set_attr "memory" "none")])
20820
20821 (define_expand "stack_protect_set"
20822 [(match_operand 0 "memory_operand" "")
20823 (match_operand 1 "memory_operand" "")]
20824 ""
20825 {
20826 #ifdef TARGET_THREAD_SSP_OFFSET
20827 if (TARGET_64BIT)
20828 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20829 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20830 else
20831 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20832 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20833 #else
20834 if (TARGET_64BIT)
20835 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20836 else
20837 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20838 #endif
20839 DONE;
20840 })
20841
20842 (define_insn "stack_protect_set_si"
20843 [(set (match_operand:SI 0 "memory_operand" "=m")
20844 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20845 (set (match_scratch:SI 2 "=&r") (const_int 0))
20846 (clobber (reg:CC FLAGS_REG))]
20847 ""
20848 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20849 [(set_attr "type" "multi")])
20850
20851 (define_insn "stack_protect_set_di"
20852 [(set (match_operand:DI 0 "memory_operand" "=m")
20853 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20854 (set (match_scratch:DI 2 "=&r") (const_int 0))
20855 (clobber (reg:CC FLAGS_REG))]
20856 "TARGET_64BIT"
20857 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20858 [(set_attr "type" "multi")])
20859
20860 (define_insn "stack_tls_protect_set_si"
20861 [(set (match_operand:SI 0 "memory_operand" "=m")
20862 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20863 (set (match_scratch:SI 2 "=&r") (const_int 0))
20864 (clobber (reg:CC FLAGS_REG))]
20865 ""
20866 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20867 [(set_attr "type" "multi")])
20868
20869 (define_insn "stack_tls_protect_set_di"
20870 [(set (match_operand:DI 0 "memory_operand" "=m")
20871 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20872 (set (match_scratch:DI 2 "=&r") (const_int 0))
20873 (clobber (reg:CC FLAGS_REG))]
20874 "TARGET_64BIT"
20875 {
20876 /* The kernel uses a different segment register for performance reasons; a
20877 system call would not have to trash the userspace segment register,
20878 which would be expensive */
20879 if (ix86_cmodel != CM_KERNEL)
20880 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20881 else
20882 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20883 }
20884 [(set_attr "type" "multi")])
20885
20886 (define_expand "stack_protect_test"
20887 [(match_operand 0 "memory_operand" "")
20888 (match_operand 1 "memory_operand" "")
20889 (match_operand 2 "" "")]
20890 ""
20891 {
20892 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20893 ix86_compare_op0 = operands[0];
20894 ix86_compare_op1 = operands[1];
20895 ix86_compare_emitted = flags;
20896
20897 #ifdef TARGET_THREAD_SSP_OFFSET
20898 if (TARGET_64BIT)
20899 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20900 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20901 else
20902 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20903 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20904 #else
20905 if (TARGET_64BIT)
20906 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20907 else
20908 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20909 #endif
20910 emit_jump_insn (gen_beq (operands[2]));
20911 DONE;
20912 })
20913
20914 (define_insn "stack_protect_test_si"
20915 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20916 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20917 (match_operand:SI 2 "memory_operand" "m")]
20918 UNSPEC_SP_TEST))
20919 (clobber (match_scratch:SI 3 "=&r"))]
20920 ""
20921 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20922 [(set_attr "type" "multi")])
20923
20924 (define_insn "stack_protect_test_di"
20925 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20926 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20927 (match_operand:DI 2 "memory_operand" "m")]
20928 UNSPEC_SP_TEST))
20929 (clobber (match_scratch:DI 3 "=&r"))]
20930 "TARGET_64BIT"
20931 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20932 [(set_attr "type" "multi")])
20933
20934 (define_insn "stack_tls_protect_test_si"
20935 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20936 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20937 (match_operand:SI 2 "const_int_operand" "i")]
20938 UNSPEC_SP_TLS_TEST))
20939 (clobber (match_scratch:SI 3 "=r"))]
20940 ""
20941 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20942 [(set_attr "type" "multi")])
20943
20944 (define_insn "stack_tls_protect_test_di"
20945 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20946 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20947 (match_operand:DI 2 "const_int_operand" "i")]
20948 UNSPEC_SP_TLS_TEST))
20949 (clobber (match_scratch:DI 3 "=r"))]
20950 "TARGET_64BIT"
20951 {
20952 /* The kernel uses a different segment register for performance reasons; a
20953 system call would not have to trash the userspace segment register,
20954 which would be expensive */
20955 if (ix86_cmodel != CM_KERNEL)
20956 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20957 else
20958 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20959 }
20960 [(set_attr "type" "multi")])
20961
20962 (include "mmx.md")
20963 (include "sse.md")
20964 (include "sync.md")