builtins.c (expand_builtin_int_interclass_roundingfn): New function to handle optabs...
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
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 (UNSPEC_TRUNC_NOOP 29)
89
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 30)
92 (UNSPEC_MASKMOV 31)
93 (UNSPEC_MOVMSK 32)
94 (UNSPEC_MOVNT 33)
95 (UNSPEC_MOVU 34)
96 (UNSPEC_RCP 35)
97 (UNSPEC_RSQRT 36)
98 (UNSPEC_SFENCE 37)
99 (UNSPEC_NOP 38) ; prevents combiner cleverness
100 (UNSPEC_PFRCP 39)
101 (UNSPEC_PFRCPIT1 40)
102 (UNSPEC_PFRCPIT2 41)
103 (UNSPEC_PFRSQRT 42)
104 (UNSPEC_PFRSQIT1 43)
105 (UNSPEC_MFENCE 44)
106 (UNSPEC_LFENCE 45)
107 (UNSPEC_PSADBW 46)
108 (UNSPEC_LDDQU 47)
109
110 ; Generic math support
111 (UNSPEC_COPYSIGN 50)
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
114
115 ; x87 Floating point
116 (UNSPEC_SIN 60)
117 (UNSPEC_COS 61)
118 (UNSPEC_FPATAN 62)
119 (UNSPEC_FYL2X 63)
120 (UNSPEC_FYL2XP1 64)
121 (UNSPEC_FRNDINT 65)
122 (UNSPEC_FIST 66)
123 (UNSPEC_F2XM1 67)
124 (UNSPEC_TAN 68)
125
126 ; x87 Rounding
127 (UNSPEC_FRNDINT_FLOOR 70)
128 (UNSPEC_FRNDINT_CEIL 71)
129 (UNSPEC_FRNDINT_TRUNC 72)
130 (UNSPEC_FRNDINT_MASK_PM 73)
131 (UNSPEC_FIST_FLOOR 74)
132 (UNSPEC_FIST_CEIL 75)
133
134 ; x87 Double output FP
135 (UNSPEC_SINCOS_COS 80)
136 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
141 (UNSPEC_FPREM_F 88)
142 (UNSPEC_FPREM_U 89)
143 (UNSPEC_FPREM1_F 90)
144 (UNSPEC_FPREM1_U 91)
145
146 ; 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 (FPCR_REG 19)
182 (R10_REG 39)
183 (R11_REG 40)
184 ])
185
186 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
187 ;; from i386.c.
188
189 ;; In C guard expressions, put expressions which may be compile-time
190 ;; constants first. This allows for better optimization. For
191 ;; example, write "TARGET_64BIT && reload_completed", not
192 ;; "reload_completed && TARGET_64BIT".
193
194 \f
195 ;; Processor type. This attribute must exactly match the processor_type
196 ;; enumeration in i386.h.
197 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
198 (const (symbol_ref "ix86_tune")))
199
200 ;; A basic instruction type. Refinements due to arguments to be
201 ;; provided in other attributes.
202 (define_attr "type"
203 "other,multi,
204 alu,alu1,negnot,imov,imovx,lea,
205 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
206 icmp,test,ibr,setcc,icmov,
207 push,pop,call,callv,leave,
208 str,
209 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
210 sselog,sselog1,sseiadd,sseishft,sseimul,
211 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
212 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
213 (const_string "other"))
214
215 ;; Main data type used by the insn
216 (define_attr "mode"
217 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
218 (const_string "unknown"))
219
220 ;; The CPU unit operations uses.
221 (define_attr "unit" "integer,i387,sse,mmx,unknown"
222 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
223 (const_string "i387")
224 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
225 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
226 (const_string "sse")
227 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
228 (const_string "mmx")
229 (eq_attr "type" "other")
230 (const_string "unknown")]
231 (const_string "integer")))
232
233 ;; The (bounding maximum) length of an instruction immediate.
234 (define_attr "length_immediate" ""
235 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave")
236 (const_int 0)
237 (eq_attr "unit" "i387,sse,mmx")
238 (const_int 0)
239 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
240 imul,icmp,push,pop")
241 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
242 (eq_attr "type" "imov,test")
243 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
244 (eq_attr "type" "call")
245 (if_then_else (match_operand 0 "constant_call_address_operand" "")
246 (const_int 4)
247 (const_int 0))
248 (eq_attr "type" "callv")
249 (if_then_else (match_operand 1 "constant_call_address_operand" "")
250 (const_int 4)
251 (const_int 0))
252 ;; We don't know the size before shorten_branches. Expect
253 ;; the instruction to fit for better scheduling.
254 (eq_attr "type" "ibr")
255 (const_int 1)
256 ]
257 (symbol_ref "/* Update immediate_length and other attributes! */
258 gcc_unreachable (),1")))
259
260 ;; The (bounding maximum) length of an instruction address.
261 (define_attr "length_address" ""
262 (cond [(eq_attr "type" "str,other,multi,fxch")
263 (const_int 0)
264 (and (eq_attr "type" "call")
265 (match_operand 0 "constant_call_address_operand" ""))
266 (const_int 0)
267 (and (eq_attr "type" "callv")
268 (match_operand 1 "constant_call_address_operand" ""))
269 (const_int 0)
270 ]
271 (symbol_ref "ix86_attr_length_address_default (insn)")))
272
273 ;; Set when length prefix is used.
274 (define_attr "prefix_data16" ""
275 (if_then_else (ior (eq_attr "mode" "HI")
276 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
277 (const_int 1)
278 (const_int 0)))
279
280 ;; Set when string REP prefix is used.
281 (define_attr "prefix_rep" ""
282 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
283 (const_int 1)
284 (const_int 0)))
285
286 ;; Set when 0f opcode prefix is used.
287 (define_attr "prefix_0f" ""
288 (if_then_else
289 (ior (eq_attr "type" "imovx,setcc,icmov")
290 (eq_attr "unit" "sse,mmx"))
291 (const_int 1)
292 (const_int 0)))
293
294 ;; Set when REX opcode prefix is used.
295 (define_attr "prefix_rex" ""
296 (cond [(and (eq_attr "mode" "DI")
297 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
298 (const_int 1)
299 (and (eq_attr "mode" "QI")
300 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
301 (const_int 0)))
302 (const_int 1)
303 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
304 (const_int 0))
305 (const_int 1)
306 ]
307 (const_int 0)))
308
309 ;; Set when modrm byte is used.
310 (define_attr "modrm" ""
311 (cond [(eq_attr "type" "str,leave")
312 (const_int 0)
313 (eq_attr "unit" "i387")
314 (const_int 0)
315 (and (eq_attr "type" "incdec")
316 (ior (match_operand:SI 1 "register_operand" "")
317 (match_operand:HI 1 "register_operand" "")))
318 (const_int 0)
319 (and (eq_attr "type" "push")
320 (not (match_operand 1 "memory_operand" "")))
321 (const_int 0)
322 (and (eq_attr "type" "pop")
323 (not (match_operand 0 "memory_operand" "")))
324 (const_int 0)
325 (and (eq_attr "type" "imov")
326 (ior (and (match_operand 0 "register_operand" "")
327 (match_operand 1 "immediate_operand" ""))
328 (ior (and (match_operand 0 "ax_reg_operand" "")
329 (match_operand 1 "memory_displacement_only_operand" ""))
330 (and (match_operand 0 "memory_displacement_only_operand" "")
331 (match_operand 1 "ax_reg_operand" "")))))
332 (const_int 0)
333 (and (eq_attr "type" "call")
334 (match_operand 0 "constant_call_address_operand" ""))
335 (const_int 0)
336 (and (eq_attr "type" "callv")
337 (match_operand 1 "constant_call_address_operand" ""))
338 (const_int 0)
339 ]
340 (const_int 1)))
341
342 ;; The (bounding maximum) length of an instruction in bytes.
343 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
344 ;; Later we may want to split them and compute proper length as for
345 ;; other insns.
346 (define_attr "length" ""
347 (cond [(eq_attr "type" "other,multi,fistp,frndint")
348 (const_int 16)
349 (eq_attr "type" "fcmp")
350 (const_int 4)
351 (eq_attr "unit" "i387")
352 (plus (const_int 2)
353 (plus (attr "prefix_data16")
354 (attr "length_address")))]
355 (plus (plus (attr "modrm")
356 (plus (attr "prefix_0f")
357 (plus (attr "prefix_rex")
358 (const_int 1))))
359 (plus (attr "prefix_rep")
360 (plus (attr "prefix_data16")
361 (plus (attr "length_immediate")
362 (attr "length_address")))))))
363
364 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
365 ;; `store' if there is a simple memory reference therein, or `unknown'
366 ;; if the instruction is complex.
367
368 (define_attr "memory" "none,load,store,both,unknown"
369 (cond [(eq_attr "type" "other,multi,str")
370 (const_string "unknown")
371 (eq_attr "type" "lea,fcmov,fpspc")
372 (const_string "none")
373 (eq_attr "type" "fistp,leave")
374 (const_string "both")
375 (eq_attr "type" "frndint")
376 (const_string "load")
377 (eq_attr "type" "push")
378 (if_then_else (match_operand 1 "memory_operand" "")
379 (const_string "both")
380 (const_string "store"))
381 (eq_attr "type" "pop")
382 (if_then_else (match_operand 0 "memory_operand" "")
383 (const_string "both")
384 (const_string "load"))
385 (eq_attr "type" "setcc")
386 (if_then_else (match_operand 0 "memory_operand" "")
387 (const_string "store")
388 (const_string "none"))
389 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
390 (if_then_else (ior (match_operand 0 "memory_operand" "")
391 (match_operand 1 "memory_operand" ""))
392 (const_string "load")
393 (const_string "none"))
394 (eq_attr "type" "ibr")
395 (if_then_else (match_operand 0 "memory_operand" "")
396 (const_string "load")
397 (const_string "none"))
398 (eq_attr "type" "call")
399 (if_then_else (match_operand 0 "constant_call_address_operand" "")
400 (const_string "none")
401 (const_string "load"))
402 (eq_attr "type" "callv")
403 (if_then_else (match_operand 1 "constant_call_address_operand" "")
404 (const_string "none")
405 (const_string "load"))
406 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
407 (match_operand 1 "memory_operand" ""))
408 (const_string "both")
409 (and (match_operand 0 "memory_operand" "")
410 (match_operand 1 "memory_operand" ""))
411 (const_string "both")
412 (match_operand 0 "memory_operand" "")
413 (const_string "store")
414 (match_operand 1 "memory_operand" "")
415 (const_string "load")
416 (and (eq_attr "type"
417 "!alu1,negnot,ishift1,
418 imov,imovx,icmp,test,
419 fmov,fcmp,fsgn,
420 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
421 mmx,mmxmov,mmxcmp,mmxcvt")
422 (match_operand 2 "memory_operand" ""))
423 (const_string "load")
424 (and (eq_attr "type" "icmov")
425 (match_operand 3 "memory_operand" ""))
426 (const_string "load")
427 ]
428 (const_string "none")))
429
430 ;; Indicates if an instruction has both an immediate and a displacement.
431
432 (define_attr "imm_disp" "false,true,unknown"
433 (cond [(eq_attr "type" "other,multi")
434 (const_string "unknown")
435 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
436 (and (match_operand 0 "memory_displacement_operand" "")
437 (match_operand 1 "immediate_operand" "")))
438 (const_string "true")
439 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
440 (and (match_operand 0 "memory_displacement_operand" "")
441 (match_operand 2 "immediate_operand" "")))
442 (const_string "true")
443 ]
444 (const_string "false")))
445
446 ;; Indicates if an FP operation has an integer source.
447
448 (define_attr "fp_int_src" "false,true"
449 (const_string "false"))
450
451 ;; Defines rounding mode of an FP operation.
452
453 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
454 (const_string "any"))
455
456 ;; Describe a user's asm statement.
457 (define_asm_attributes
458 [(set_attr "length" "128")
459 (set_attr "type" "multi")])
460
461 ;; All x87 floating point modes
462 (define_mode_macro X87MODEF [SF DF XF])
463
464 ;; x87 SFmode and DFMode floating point modes
465 (define_mode_macro X87MODEF12 [SF DF])
466
467 ;; All integer modes handled by x87 fisttp operator.
468 (define_mode_macro X87MODEI [HI SI DI])
469
470 ;; All integer modes handled by integer x87 operators.
471 (define_mode_macro X87MODEI12 [HI SI])
472
473 ;; All SSE floating point modes
474 (define_mode_macro SSEMODEF [SF DF])
475
476 ;; All integer modes handled by SSE cvtts?2si* operators.
477 (define_mode_macro SSEMODEI24 [SI DI])
478
479 ;; SSE asm suffix for floating point modes
480 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
481
482 \f
483 ;; Scheduling descriptions
484
485 (include "pentium.md")
486 (include "ppro.md")
487 (include "k6.md")
488 (include "athlon.md")
489 (include "geode.md")
490
491 \f
492 ;; Operand and operator predicates and constraints
493
494 (include "predicates.md")
495 (include "constraints.md")
496
497 \f
498 ;; Compare instructions.
499
500 ;; All compare insns have expanders that save the operands away without
501 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
502 ;; after the cmp) will actually emit the cmpM.
503
504 (define_expand "cmpti"
505 [(set (reg:CC FLAGS_REG)
506 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
507 (match_operand:TI 1 "x86_64_general_operand" "")))]
508 "TARGET_64BIT"
509 {
510 if (MEM_P (operands[0]) && MEM_P (operands[1]))
511 operands[0] = force_reg (TImode, operands[0]);
512 ix86_compare_op0 = operands[0];
513 ix86_compare_op1 = operands[1];
514 DONE;
515 })
516
517 (define_expand "cmpdi"
518 [(set (reg:CC FLAGS_REG)
519 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
520 (match_operand:DI 1 "x86_64_general_operand" "")))]
521 ""
522 {
523 if (MEM_P (operands[0]) && MEM_P (operands[1]))
524 operands[0] = force_reg (DImode, operands[0]);
525 ix86_compare_op0 = operands[0];
526 ix86_compare_op1 = operands[1];
527 DONE;
528 })
529
530 (define_expand "cmpsi"
531 [(set (reg:CC FLAGS_REG)
532 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
533 (match_operand:SI 1 "general_operand" "")))]
534 ""
535 {
536 if (MEM_P (operands[0]) && MEM_P (operands[1]))
537 operands[0] = force_reg (SImode, operands[0]);
538 ix86_compare_op0 = operands[0];
539 ix86_compare_op1 = operands[1];
540 DONE;
541 })
542
543 (define_expand "cmphi"
544 [(set (reg:CC FLAGS_REG)
545 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
546 (match_operand:HI 1 "general_operand" "")))]
547 ""
548 {
549 if (MEM_P (operands[0]) && MEM_P (operands[1]))
550 operands[0] = force_reg (HImode, operands[0]);
551 ix86_compare_op0 = operands[0];
552 ix86_compare_op1 = operands[1];
553 DONE;
554 })
555
556 (define_expand "cmpqi"
557 [(set (reg:CC FLAGS_REG)
558 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
559 (match_operand:QI 1 "general_operand" "")))]
560 "TARGET_QIMODE_MATH"
561 {
562 if (MEM_P (operands[0]) && MEM_P (operands[1]))
563 operands[0] = force_reg (QImode, operands[0]);
564 ix86_compare_op0 = operands[0];
565 ix86_compare_op1 = operands[1];
566 DONE;
567 })
568
569 (define_insn "cmpdi_ccno_1_rex64"
570 [(set (reg FLAGS_REG)
571 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
572 (match_operand:DI 1 "const0_operand" "n,n")))]
573 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
574 "@
575 test{q}\t{%0, %0|%0, %0}
576 cmp{q}\t{%1, %0|%0, %1}"
577 [(set_attr "type" "test,icmp")
578 (set_attr "length_immediate" "0,1")
579 (set_attr "mode" "DI")])
580
581 (define_insn "*cmpdi_minus_1_rex64"
582 [(set (reg FLAGS_REG)
583 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
584 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
585 (const_int 0)))]
586 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
587 "cmp{q}\t{%1, %0|%0, %1}"
588 [(set_attr "type" "icmp")
589 (set_attr "mode" "DI")])
590
591 (define_expand "cmpdi_1_rex64"
592 [(set (reg:CC FLAGS_REG)
593 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
594 (match_operand:DI 1 "general_operand" "")))]
595 "TARGET_64BIT"
596 "")
597
598 (define_insn "cmpdi_1_insn_rex64"
599 [(set (reg FLAGS_REG)
600 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
601 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
602 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
603 "cmp{q}\t{%1, %0|%0, %1}"
604 [(set_attr "type" "icmp")
605 (set_attr "mode" "DI")])
606
607
608 (define_insn "*cmpsi_ccno_1"
609 [(set (reg FLAGS_REG)
610 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
611 (match_operand:SI 1 "const0_operand" "n,n")))]
612 "ix86_match_ccmode (insn, CCNOmode)"
613 "@
614 test{l}\t{%0, %0|%0, %0}
615 cmp{l}\t{%1, %0|%0, %1}"
616 [(set_attr "type" "test,icmp")
617 (set_attr "length_immediate" "0,1")
618 (set_attr "mode" "SI")])
619
620 (define_insn "*cmpsi_minus_1"
621 [(set (reg FLAGS_REG)
622 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623 (match_operand:SI 1 "general_operand" "ri,mr"))
624 (const_int 0)))]
625 "ix86_match_ccmode (insn, CCGOCmode)"
626 "cmp{l}\t{%1, %0|%0, %1}"
627 [(set_attr "type" "icmp")
628 (set_attr "mode" "SI")])
629
630 (define_expand "cmpsi_1"
631 [(set (reg:CC FLAGS_REG)
632 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
633 (match_operand:SI 1 "general_operand" "ri,mr")))]
634 ""
635 "")
636
637 (define_insn "*cmpsi_1_insn"
638 [(set (reg FLAGS_REG)
639 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
640 (match_operand:SI 1 "general_operand" "ri,mr")))]
641 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
642 && ix86_match_ccmode (insn, CCmode)"
643 "cmp{l}\t{%1, %0|%0, %1}"
644 [(set_attr "type" "icmp")
645 (set_attr "mode" "SI")])
646
647 (define_insn "*cmphi_ccno_1"
648 [(set (reg FLAGS_REG)
649 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
650 (match_operand:HI 1 "const0_operand" "n,n")))]
651 "ix86_match_ccmode (insn, CCNOmode)"
652 "@
653 test{w}\t{%0, %0|%0, %0}
654 cmp{w}\t{%1, %0|%0, %1}"
655 [(set_attr "type" "test,icmp")
656 (set_attr "length_immediate" "0,1")
657 (set_attr "mode" "HI")])
658
659 (define_insn "*cmphi_minus_1"
660 [(set (reg FLAGS_REG)
661 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
662 (match_operand:HI 1 "general_operand" "ri,mr"))
663 (const_int 0)))]
664 "ix86_match_ccmode (insn, CCGOCmode)"
665 "cmp{w}\t{%1, %0|%0, %1}"
666 [(set_attr "type" "icmp")
667 (set_attr "mode" "HI")])
668
669 (define_insn "*cmphi_1"
670 [(set (reg FLAGS_REG)
671 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
672 (match_operand:HI 1 "general_operand" "ri,mr")))]
673 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
674 && ix86_match_ccmode (insn, CCmode)"
675 "cmp{w}\t{%1, %0|%0, %1}"
676 [(set_attr "type" "icmp")
677 (set_attr "mode" "HI")])
678
679 (define_insn "*cmpqi_ccno_1"
680 [(set (reg FLAGS_REG)
681 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
682 (match_operand:QI 1 "const0_operand" "n,n")))]
683 "ix86_match_ccmode (insn, CCNOmode)"
684 "@
685 test{b}\t{%0, %0|%0, %0}
686 cmp{b}\t{$0, %0|%0, 0}"
687 [(set_attr "type" "test,icmp")
688 (set_attr "length_immediate" "0,1")
689 (set_attr "mode" "QI")])
690
691 (define_insn "*cmpqi_1"
692 [(set (reg FLAGS_REG)
693 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
694 (match_operand:QI 1 "general_operand" "qi,mq")))]
695 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
696 && ix86_match_ccmode (insn, CCmode)"
697 "cmp{b}\t{%1, %0|%0, %1}"
698 [(set_attr "type" "icmp")
699 (set_attr "mode" "QI")])
700
701 (define_insn "*cmpqi_minus_1"
702 [(set (reg FLAGS_REG)
703 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
704 (match_operand:QI 1 "general_operand" "qi,mq"))
705 (const_int 0)))]
706 "ix86_match_ccmode (insn, CCGOCmode)"
707 "cmp{b}\t{%1, %0|%0, %1}"
708 [(set_attr "type" "icmp")
709 (set_attr "mode" "QI")])
710
711 (define_insn "*cmpqi_ext_1"
712 [(set (reg FLAGS_REG)
713 (compare
714 (match_operand:QI 0 "general_operand" "Qm")
715 (subreg:QI
716 (zero_extract:SI
717 (match_operand 1 "ext_register_operand" "Q")
718 (const_int 8)
719 (const_int 8)) 0)))]
720 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721 "cmp{b}\t{%h1, %0|%0, %h1}"
722 [(set_attr "type" "icmp")
723 (set_attr "mode" "QI")])
724
725 (define_insn "*cmpqi_ext_1_rex64"
726 [(set (reg FLAGS_REG)
727 (compare
728 (match_operand:QI 0 "register_operand" "Q")
729 (subreg:QI
730 (zero_extract:SI
731 (match_operand 1 "ext_register_operand" "Q")
732 (const_int 8)
733 (const_int 8)) 0)))]
734 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735 "cmp{b}\t{%h1, %0|%0, %h1}"
736 [(set_attr "type" "icmp")
737 (set_attr "mode" "QI")])
738
739 (define_insn "*cmpqi_ext_2"
740 [(set (reg FLAGS_REG)
741 (compare
742 (subreg:QI
743 (zero_extract:SI
744 (match_operand 0 "ext_register_operand" "Q")
745 (const_int 8)
746 (const_int 8)) 0)
747 (match_operand:QI 1 "const0_operand" "n")))]
748 "ix86_match_ccmode (insn, CCNOmode)"
749 "test{b}\t%h0, %h0"
750 [(set_attr "type" "test")
751 (set_attr "length_immediate" "0")
752 (set_attr "mode" "QI")])
753
754 (define_expand "cmpqi_ext_3"
755 [(set (reg:CC FLAGS_REG)
756 (compare:CC
757 (subreg:QI
758 (zero_extract:SI
759 (match_operand 0 "ext_register_operand" "")
760 (const_int 8)
761 (const_int 8)) 0)
762 (match_operand:QI 1 "general_operand" "")))]
763 ""
764 "")
765
766 (define_insn "cmpqi_ext_3_insn"
767 [(set (reg FLAGS_REG)
768 (compare
769 (subreg:QI
770 (zero_extract:SI
771 (match_operand 0 "ext_register_operand" "Q")
772 (const_int 8)
773 (const_int 8)) 0)
774 (match_operand:QI 1 "general_operand" "Qmn")))]
775 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776 "cmp{b}\t{%1, %h0|%h0, %1}"
777 [(set_attr "type" "icmp")
778 (set_attr "mode" "QI")])
779
780 (define_insn "cmpqi_ext_3_insn_rex64"
781 [(set (reg FLAGS_REG)
782 (compare
783 (subreg:QI
784 (zero_extract:SI
785 (match_operand 0 "ext_register_operand" "Q")
786 (const_int 8)
787 (const_int 8)) 0)
788 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
789 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
790 "cmp{b}\t{%1, %h0|%h0, %1}"
791 [(set_attr "type" "icmp")
792 (set_attr "mode" "QI")])
793
794 (define_insn "*cmpqi_ext_4"
795 [(set (reg FLAGS_REG)
796 (compare
797 (subreg:QI
798 (zero_extract:SI
799 (match_operand 0 "ext_register_operand" "Q")
800 (const_int 8)
801 (const_int 8)) 0)
802 (subreg:QI
803 (zero_extract:SI
804 (match_operand 1 "ext_register_operand" "Q")
805 (const_int 8)
806 (const_int 8)) 0)))]
807 "ix86_match_ccmode (insn, CCmode)"
808 "cmp{b}\t{%h1, %h0|%h0, %h1}"
809 [(set_attr "type" "icmp")
810 (set_attr "mode" "QI")])
811
812 ;; These implement float point compares.
813 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
814 ;; which would allow mix and match FP modes on the compares. Which is what
815 ;; the old patterns did, but with many more of them.
816
817 (define_expand "cmpxf"
818 [(set (reg:CC FLAGS_REG)
819 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
820 (match_operand:XF 1 "nonmemory_operand" "")))]
821 "TARGET_80387"
822 {
823 ix86_compare_op0 = operands[0];
824 ix86_compare_op1 = operands[1];
825 DONE;
826 })
827
828 (define_expand "cmpdf"
829 [(set (reg:CC FLAGS_REG)
830 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
831 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
832 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
833 {
834 ix86_compare_op0 = operands[0];
835 ix86_compare_op1 = operands[1];
836 DONE;
837 })
838
839 (define_expand "cmpsf"
840 [(set (reg:CC FLAGS_REG)
841 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
842 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
843 "TARGET_80387 || TARGET_SSE_MATH"
844 {
845 ix86_compare_op0 = operands[0];
846 ix86_compare_op1 = operands[1];
847 DONE;
848 })
849
850 ;; FP compares, step 1:
851 ;; Set the FP condition codes.
852 ;;
853 ;; CCFPmode compare with exceptions
854 ;; CCFPUmode compare with no exceptions
855
856 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
857 ;; used to manage the reg stack popping would not be preserved.
858
859 (define_insn "*cmpfp_0"
860 [(set (match_operand:HI 0 "register_operand" "=a")
861 (unspec:HI
862 [(compare:CCFP
863 (match_operand 1 "register_operand" "f")
864 (match_operand 2 "const0_operand" "X"))]
865 UNSPEC_FNSTSW))]
866 "TARGET_80387
867 && FLOAT_MODE_P (GET_MODE (operands[1]))
868 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
869 "* return output_fp_compare (insn, operands, 0, 0);"
870 [(set_attr "type" "multi")
871 (set_attr "unit" "i387")
872 (set (attr "mode")
873 (cond [(match_operand:SF 1 "" "")
874 (const_string "SF")
875 (match_operand:DF 1 "" "")
876 (const_string "DF")
877 ]
878 (const_string "XF")))])
879
880 (define_insn "*cmpfp_sf"
881 [(set (match_operand:HI 0 "register_operand" "=a")
882 (unspec:HI
883 [(compare:CCFP
884 (match_operand:SF 1 "register_operand" "f")
885 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
886 UNSPEC_FNSTSW))]
887 "TARGET_80387"
888 "* return output_fp_compare (insn, operands, 0, 0);"
889 [(set_attr "type" "multi")
890 (set_attr "unit" "i387")
891 (set_attr "mode" "SF")])
892
893 (define_insn "*cmpfp_df"
894 [(set (match_operand:HI 0 "register_operand" "=a")
895 (unspec:HI
896 [(compare:CCFP
897 (match_operand:DF 1 "register_operand" "f")
898 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
899 UNSPEC_FNSTSW))]
900 "TARGET_80387"
901 "* return output_fp_compare (insn, operands, 0, 0);"
902 [(set_attr "type" "multi")
903 (set_attr "unit" "i387")
904 (set_attr "mode" "DF")])
905
906 (define_insn "*cmpfp_xf"
907 [(set (match_operand:HI 0 "register_operand" "=a")
908 (unspec:HI
909 [(compare:CCFP
910 (match_operand:XF 1 "register_operand" "f")
911 (match_operand:XF 2 "register_operand" "f"))]
912 UNSPEC_FNSTSW))]
913 "TARGET_80387"
914 "* return output_fp_compare (insn, operands, 0, 0);"
915 [(set_attr "type" "multi")
916 (set_attr "unit" "i387")
917 (set_attr "mode" "XF")])
918
919 (define_insn "*cmpfp_u"
920 [(set (match_operand:HI 0 "register_operand" "=a")
921 (unspec:HI
922 [(compare:CCFPU
923 (match_operand 1 "register_operand" "f")
924 (match_operand 2 "register_operand" "f"))]
925 UNSPEC_FNSTSW))]
926 "TARGET_80387
927 && FLOAT_MODE_P (GET_MODE (operands[1]))
928 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
929 "* return output_fp_compare (insn, operands, 0, 1);"
930 [(set_attr "type" "multi")
931 (set_attr "unit" "i387")
932 (set (attr "mode")
933 (cond [(match_operand:SF 1 "" "")
934 (const_string "SF")
935 (match_operand:DF 1 "" "")
936 (const_string "DF")
937 ]
938 (const_string "XF")))])
939
940 (define_insn "*cmpfp_<mode>"
941 [(set (match_operand:HI 0 "register_operand" "=a")
942 (unspec:HI
943 [(compare:CCFP
944 (match_operand 1 "register_operand" "f")
945 (match_operator 3 "float_operator"
946 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
947 UNSPEC_FNSTSW))]
948 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
949 && FLOAT_MODE_P (GET_MODE (operands[1]))
950 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
951 "* return output_fp_compare (insn, operands, 0, 0);"
952 [(set_attr "type" "multi")
953 (set_attr "unit" "i387")
954 (set_attr "fp_int_src" "true")
955 (set_attr "mode" "<MODE>")])
956
957 ;; FP compares, step 2
958 ;; Move the fpsw to ax.
959
960 (define_insn "x86_fnstsw_1"
961 [(set (match_operand:HI 0 "register_operand" "=a")
962 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
963 "TARGET_80387"
964 "fnstsw\t%0"
965 [(set_attr "length" "2")
966 (set_attr "mode" "SI")
967 (set_attr "unit" "i387")])
968
969 ;; FP compares, step 3
970 ;; Get ax into flags, general case.
971
972 (define_insn "x86_sahf_1"
973 [(set (reg:CC FLAGS_REG)
974 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
975 "!TARGET_64BIT"
976 "sahf"
977 [(set_attr "length" "1")
978 (set_attr "athlon_decode" "vector")
979 (set_attr "mode" "SI")])
980
981 ;; Pentium Pro can do steps 1 through 3 in one go.
982
983 (define_insn "*cmpfp_i_mixed"
984 [(set (reg:CCFP FLAGS_REG)
985 (compare:CCFP (match_operand 0 "register_operand" "f,x")
986 (match_operand 1 "nonimmediate_operand" "f,xm")))]
987 "TARGET_MIX_SSE_I387
988 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
990 "* return output_fp_compare (insn, operands, 1, 0);"
991 [(set_attr "type" "fcmp,ssecomi")
992 (set (attr "mode")
993 (if_then_else (match_operand:SF 1 "" "")
994 (const_string "SF")
995 (const_string "DF")))
996 (set_attr "athlon_decode" "vector")])
997
998 (define_insn "*cmpfp_i_sse"
999 [(set (reg:CCFP FLAGS_REG)
1000 (compare:CCFP (match_operand 0 "register_operand" "x")
1001 (match_operand 1 "nonimmediate_operand" "xm")))]
1002 "TARGET_SSE_MATH
1003 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1004 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1005 "* return output_fp_compare (insn, operands, 1, 0);"
1006 [(set_attr "type" "ssecomi")
1007 (set (attr "mode")
1008 (if_then_else (match_operand:SF 1 "" "")
1009 (const_string "SF")
1010 (const_string "DF")))
1011 (set_attr "athlon_decode" "vector")])
1012
1013 (define_insn "*cmpfp_i_i387"
1014 [(set (reg:CCFP FLAGS_REG)
1015 (compare:CCFP (match_operand 0 "register_operand" "f")
1016 (match_operand 1 "register_operand" "f")))]
1017 "TARGET_80387 && TARGET_CMOVE
1018 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1019 && FLOAT_MODE_P (GET_MODE (operands[0]))
1020 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1021 "* return output_fp_compare (insn, operands, 1, 0);"
1022 [(set_attr "type" "fcmp")
1023 (set (attr "mode")
1024 (cond [(match_operand:SF 1 "" "")
1025 (const_string "SF")
1026 (match_operand:DF 1 "" "")
1027 (const_string "DF")
1028 ]
1029 (const_string "XF")))
1030 (set_attr "athlon_decode" "vector")])
1031
1032 (define_insn "*cmpfp_iu_mixed"
1033 [(set (reg:CCFPU FLAGS_REG)
1034 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1035 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1036 "TARGET_MIX_SSE_I387
1037 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039 "* return output_fp_compare (insn, operands, 1, 1);"
1040 [(set_attr "type" "fcmp,ssecomi")
1041 (set (attr "mode")
1042 (if_then_else (match_operand:SF 1 "" "")
1043 (const_string "SF")
1044 (const_string "DF")))
1045 (set_attr "athlon_decode" "vector")])
1046
1047 (define_insn "*cmpfp_iu_sse"
1048 [(set (reg:CCFPU FLAGS_REG)
1049 (compare:CCFPU (match_operand 0 "register_operand" "x")
1050 (match_operand 1 "nonimmediate_operand" "xm")))]
1051 "TARGET_SSE_MATH
1052 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1053 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1054 "* return output_fp_compare (insn, operands, 1, 1);"
1055 [(set_attr "type" "ssecomi")
1056 (set (attr "mode")
1057 (if_then_else (match_operand:SF 1 "" "")
1058 (const_string "SF")
1059 (const_string "DF")))
1060 (set_attr "athlon_decode" "vector")])
1061
1062 (define_insn "*cmpfp_iu_387"
1063 [(set (reg:CCFPU FLAGS_REG)
1064 (compare:CCFPU (match_operand 0 "register_operand" "f")
1065 (match_operand 1 "register_operand" "f")))]
1066 "TARGET_80387 && TARGET_CMOVE
1067 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1068 && FLOAT_MODE_P (GET_MODE (operands[0]))
1069 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1070 "* return output_fp_compare (insn, operands, 1, 1);"
1071 [(set_attr "type" "fcmp")
1072 (set (attr "mode")
1073 (cond [(match_operand:SF 1 "" "")
1074 (const_string "SF")
1075 (match_operand:DF 1 "" "")
1076 (const_string "DF")
1077 ]
1078 (const_string "XF")))
1079 (set_attr "athlon_decode" "vector")])
1080 \f
1081 ;; Move instructions.
1082
1083 ;; General case of fullword move.
1084
1085 (define_expand "movsi"
1086 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1087 (match_operand:SI 1 "general_operand" ""))]
1088 ""
1089 "ix86_expand_move (SImode, operands); DONE;")
1090
1091 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1092 ;; general_operand.
1093 ;;
1094 ;; %%% We don't use a post-inc memory reference because x86 is not a
1095 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1096 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1097 ;; targets without our curiosities, and it is just as easy to represent
1098 ;; this differently.
1099
1100 (define_insn "*pushsi2"
1101 [(set (match_operand:SI 0 "push_operand" "=<")
1102 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1103 "!TARGET_64BIT"
1104 "push{l}\t%1"
1105 [(set_attr "type" "push")
1106 (set_attr "mode" "SI")])
1107
1108 ;; For 64BIT abi we always round up to 8 bytes.
1109 (define_insn "*pushsi2_rex64"
1110 [(set (match_operand:SI 0 "push_operand" "=X")
1111 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1112 "TARGET_64BIT"
1113 "push{q}\t%q1"
1114 [(set_attr "type" "push")
1115 (set_attr "mode" "SI")])
1116
1117 (define_insn "*pushsi2_prologue"
1118 [(set (match_operand:SI 0 "push_operand" "=<")
1119 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1120 (clobber (mem:BLK (scratch)))]
1121 "!TARGET_64BIT"
1122 "push{l}\t%1"
1123 [(set_attr "type" "push")
1124 (set_attr "mode" "SI")])
1125
1126 (define_insn "*popsi1_epilogue"
1127 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1128 (mem:SI (reg:SI SP_REG)))
1129 (set (reg:SI SP_REG)
1130 (plus:SI (reg:SI SP_REG) (const_int 4)))
1131 (clobber (mem:BLK (scratch)))]
1132 "!TARGET_64BIT"
1133 "pop{l}\t%0"
1134 [(set_attr "type" "pop")
1135 (set_attr "mode" "SI")])
1136
1137 (define_insn "popsi1"
1138 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1139 (mem:SI (reg:SI SP_REG)))
1140 (set (reg:SI SP_REG)
1141 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1142 "!TARGET_64BIT"
1143 "pop{l}\t%0"
1144 [(set_attr "type" "pop")
1145 (set_attr "mode" "SI")])
1146
1147 (define_insn "*movsi_xor"
1148 [(set (match_operand:SI 0 "register_operand" "=r")
1149 (match_operand:SI 1 "const0_operand" "i"))
1150 (clobber (reg:CC FLAGS_REG))]
1151 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1152 "xor{l}\t{%0, %0|%0, %0}"
1153 [(set_attr "type" "alu1")
1154 (set_attr "mode" "SI")
1155 (set_attr "length_immediate" "0")])
1156
1157 (define_insn "*movsi_or"
1158 [(set (match_operand:SI 0 "register_operand" "=r")
1159 (match_operand:SI 1 "immediate_operand" "i"))
1160 (clobber (reg:CC FLAGS_REG))]
1161 "reload_completed
1162 && operands[1] == constm1_rtx
1163 && (TARGET_PENTIUM || optimize_size)"
1164 {
1165 operands[1] = constm1_rtx;
1166 return "or{l}\t{%1, %0|%0, %1}";
1167 }
1168 [(set_attr "type" "alu1")
1169 (set_attr "mode" "SI")
1170 (set_attr "length_immediate" "1")])
1171
1172 (define_insn "*movsi_1"
1173 [(set (match_operand:SI 0 "nonimmediate_operand"
1174 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1175 (match_operand:SI 1 "general_operand"
1176 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1177 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1178 {
1179 switch (get_attr_type (insn))
1180 {
1181 case TYPE_SSELOG1:
1182 if (get_attr_mode (insn) == MODE_TI)
1183 return "pxor\t%0, %0";
1184 return "xorps\t%0, %0";
1185
1186 case TYPE_SSEMOV:
1187 switch (get_attr_mode (insn))
1188 {
1189 case MODE_TI:
1190 return "movdqa\t{%1, %0|%0, %1}";
1191 case MODE_V4SF:
1192 return "movaps\t{%1, %0|%0, %1}";
1193 case MODE_SI:
1194 return "movd\t{%1, %0|%0, %1}";
1195 case MODE_SF:
1196 return "movss\t{%1, %0|%0, %1}";
1197 default:
1198 gcc_unreachable ();
1199 }
1200
1201 case TYPE_MMXADD:
1202 return "pxor\t%0, %0";
1203
1204 case TYPE_MMXMOV:
1205 if (get_attr_mode (insn) == MODE_DI)
1206 return "movq\t{%1, %0|%0, %1}";
1207 return "movd\t{%1, %0|%0, %1}";
1208
1209 case TYPE_LEA:
1210 return "lea{l}\t{%1, %0|%0, %1}";
1211
1212 default:
1213 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1214 return "mov{l}\t{%1, %0|%0, %1}";
1215 }
1216 }
1217 [(set (attr "type")
1218 (cond [(eq_attr "alternative" "2")
1219 (const_string "mmxadd")
1220 (eq_attr "alternative" "3,4,5")
1221 (const_string "mmxmov")
1222 (eq_attr "alternative" "6")
1223 (const_string "sselog1")
1224 (eq_attr "alternative" "7,8,9,10,11")
1225 (const_string "ssemov")
1226 (match_operand:DI 1 "pic_32bit_operand" "")
1227 (const_string "lea")
1228 ]
1229 (const_string "imov")))
1230 (set (attr "mode")
1231 (cond [(eq_attr "alternative" "2,3")
1232 (const_string "DI")
1233 (eq_attr "alternative" "6,7")
1234 (if_then_else
1235 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1236 (const_string "V4SF")
1237 (const_string "TI"))
1238 (and (eq_attr "alternative" "8,9,10,11")
1239 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1240 (const_string "SF")
1241 ]
1242 (const_string "SI")))])
1243
1244 ;; Stores and loads of ax to arbitrary constant address.
1245 ;; We fake an second form of instruction to force reload to load address
1246 ;; into register when rax is not available
1247 (define_insn "*movabssi_1_rex64"
1248 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1249 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1250 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1251 "@
1252 movabs{l}\t{%1, %P0|%P0, %1}
1253 mov{l}\t{%1, %a0|%a0, %1}"
1254 [(set_attr "type" "imov")
1255 (set_attr "modrm" "0,*")
1256 (set_attr "length_address" "8,0")
1257 (set_attr "length_immediate" "0,*")
1258 (set_attr "memory" "store")
1259 (set_attr "mode" "SI")])
1260
1261 (define_insn "*movabssi_2_rex64"
1262 [(set (match_operand:SI 0 "register_operand" "=a,r")
1263 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1264 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1265 "@
1266 movabs{l}\t{%P1, %0|%0, %P1}
1267 mov{l}\t{%a1, %0|%0, %a1}"
1268 [(set_attr "type" "imov")
1269 (set_attr "modrm" "0,*")
1270 (set_attr "length_address" "8,0")
1271 (set_attr "length_immediate" "0")
1272 (set_attr "memory" "load")
1273 (set_attr "mode" "SI")])
1274
1275 (define_insn "*swapsi"
1276 [(set (match_operand:SI 0 "register_operand" "+r")
1277 (match_operand:SI 1 "register_operand" "+r"))
1278 (set (match_dup 1)
1279 (match_dup 0))]
1280 ""
1281 "xchg{l}\t%1, %0"
1282 [(set_attr "type" "imov")
1283 (set_attr "mode" "SI")
1284 (set_attr "pent_pair" "np")
1285 (set_attr "athlon_decode" "vector")])
1286
1287 (define_expand "movhi"
1288 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1289 (match_operand:HI 1 "general_operand" ""))]
1290 ""
1291 "ix86_expand_move (HImode, operands); DONE;")
1292
1293 (define_insn "*pushhi2"
1294 [(set (match_operand:HI 0 "push_operand" "=X")
1295 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1296 "!TARGET_64BIT"
1297 "push{l}\t%k1"
1298 [(set_attr "type" "push")
1299 (set_attr "mode" "SI")])
1300
1301 ;; For 64BIT abi we always round up to 8 bytes.
1302 (define_insn "*pushhi2_rex64"
1303 [(set (match_operand:HI 0 "push_operand" "=X")
1304 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1305 "TARGET_64BIT"
1306 "push{q}\t%q1"
1307 [(set_attr "type" "push")
1308 (set_attr "mode" "DI")])
1309
1310 (define_insn "*movhi_1"
1311 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1312 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1313 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1314 {
1315 switch (get_attr_type (insn))
1316 {
1317 case TYPE_IMOVX:
1318 /* movzwl is faster than movw on p2 due to partial word stalls,
1319 though not as fast as an aligned movl. */
1320 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1321 default:
1322 if (get_attr_mode (insn) == MODE_SI)
1323 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1324 else
1325 return "mov{w}\t{%1, %0|%0, %1}";
1326 }
1327 }
1328 [(set (attr "type")
1329 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1330 (const_string "imov")
1331 (and (eq_attr "alternative" "0")
1332 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1333 (const_int 0))
1334 (eq (symbol_ref "TARGET_HIMODE_MATH")
1335 (const_int 0))))
1336 (const_string "imov")
1337 (and (eq_attr "alternative" "1,2")
1338 (match_operand:HI 1 "aligned_operand" ""))
1339 (const_string "imov")
1340 (and (ne (symbol_ref "TARGET_MOVX")
1341 (const_int 0))
1342 (eq_attr "alternative" "0,2"))
1343 (const_string "imovx")
1344 ]
1345 (const_string "imov")))
1346 (set (attr "mode")
1347 (cond [(eq_attr "type" "imovx")
1348 (const_string "SI")
1349 (and (eq_attr "alternative" "1,2")
1350 (match_operand:HI 1 "aligned_operand" ""))
1351 (const_string "SI")
1352 (and (eq_attr "alternative" "0")
1353 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1354 (const_int 0))
1355 (eq (symbol_ref "TARGET_HIMODE_MATH")
1356 (const_int 0))))
1357 (const_string "SI")
1358 ]
1359 (const_string "HI")))])
1360
1361 ;; Stores and loads of ax to arbitrary constant address.
1362 ;; We fake an second form of instruction to force reload to load address
1363 ;; into register when rax is not available
1364 (define_insn "*movabshi_1_rex64"
1365 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1366 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1367 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1368 "@
1369 movabs{w}\t{%1, %P0|%P0, %1}
1370 mov{w}\t{%1, %a0|%a0, %1}"
1371 [(set_attr "type" "imov")
1372 (set_attr "modrm" "0,*")
1373 (set_attr "length_address" "8,0")
1374 (set_attr "length_immediate" "0,*")
1375 (set_attr "memory" "store")
1376 (set_attr "mode" "HI")])
1377
1378 (define_insn "*movabshi_2_rex64"
1379 [(set (match_operand:HI 0 "register_operand" "=a,r")
1380 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1381 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1382 "@
1383 movabs{w}\t{%P1, %0|%0, %P1}
1384 mov{w}\t{%a1, %0|%0, %a1}"
1385 [(set_attr "type" "imov")
1386 (set_attr "modrm" "0,*")
1387 (set_attr "length_address" "8,0")
1388 (set_attr "length_immediate" "0")
1389 (set_attr "memory" "load")
1390 (set_attr "mode" "HI")])
1391
1392 (define_insn "*swaphi_1"
1393 [(set (match_operand:HI 0 "register_operand" "+r")
1394 (match_operand:HI 1 "register_operand" "+r"))
1395 (set (match_dup 1)
1396 (match_dup 0))]
1397 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1398 "xchg{l}\t%k1, %k0"
1399 [(set_attr "type" "imov")
1400 (set_attr "mode" "SI")
1401 (set_attr "pent_pair" "np")
1402 (set_attr "athlon_decode" "vector")])
1403
1404 (define_insn "*swaphi_2"
1405 [(set (match_operand:HI 0 "register_operand" "+r")
1406 (match_operand:HI 1 "register_operand" "+r"))
1407 (set (match_dup 1)
1408 (match_dup 0))]
1409 "TARGET_PARTIAL_REG_STALL"
1410 "xchg{w}\t%1, %0"
1411 [(set_attr "type" "imov")
1412 (set_attr "mode" "HI")
1413 (set_attr "pent_pair" "np")
1414 (set_attr "athlon_decode" "vector")])
1415
1416 (define_expand "movstricthi"
1417 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1418 (match_operand:HI 1 "general_operand" ""))]
1419 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1420 {
1421 /* Don't generate memory->memory moves, go through a register */
1422 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1423 operands[1] = force_reg (HImode, operands[1]);
1424 })
1425
1426 (define_insn "*movstricthi_1"
1427 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1428 (match_operand:HI 1 "general_operand" "rn,m"))]
1429 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1430 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1431 "mov{w}\t{%1, %0|%0, %1}"
1432 [(set_attr "type" "imov")
1433 (set_attr "mode" "HI")])
1434
1435 (define_insn "*movstricthi_xor"
1436 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1437 (match_operand:HI 1 "const0_operand" "i"))
1438 (clobber (reg:CC FLAGS_REG))]
1439 "reload_completed
1440 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1441 "xor{w}\t{%0, %0|%0, %0}"
1442 [(set_attr "type" "alu1")
1443 (set_attr "mode" "HI")
1444 (set_attr "length_immediate" "0")])
1445
1446 (define_expand "movqi"
1447 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1448 (match_operand:QI 1 "general_operand" ""))]
1449 ""
1450 "ix86_expand_move (QImode, operands); DONE;")
1451
1452 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1453 ;; "push a byte". But actually we use pushl, which has the effect
1454 ;; of rounding the amount pushed up to a word.
1455
1456 (define_insn "*pushqi2"
1457 [(set (match_operand:QI 0 "push_operand" "=X")
1458 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1459 "!TARGET_64BIT"
1460 "push{l}\t%k1"
1461 [(set_attr "type" "push")
1462 (set_attr "mode" "SI")])
1463
1464 ;; For 64BIT abi we always round up to 8 bytes.
1465 (define_insn "*pushqi2_rex64"
1466 [(set (match_operand:QI 0 "push_operand" "=X")
1467 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1468 "TARGET_64BIT"
1469 "push{q}\t%q1"
1470 [(set_attr "type" "push")
1471 (set_attr "mode" "DI")])
1472
1473 ;; Situation is quite tricky about when to choose full sized (SImode) move
1474 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1475 ;; partial register dependency machines (such as AMD Athlon), where QImode
1476 ;; moves issue extra dependency and for partial register stalls machines
1477 ;; that don't use QImode patterns (and QImode move cause stall on the next
1478 ;; instruction).
1479 ;;
1480 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1481 ;; register stall machines with, where we use QImode instructions, since
1482 ;; partial register stall can be caused there. Then we use movzx.
1483 (define_insn "*movqi_1"
1484 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1485 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1486 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1487 {
1488 switch (get_attr_type (insn))
1489 {
1490 case TYPE_IMOVX:
1491 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1492 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1493 default:
1494 if (get_attr_mode (insn) == MODE_SI)
1495 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1496 else
1497 return "mov{b}\t{%1, %0|%0, %1}";
1498 }
1499 }
1500 [(set (attr "type")
1501 (cond [(and (eq_attr "alternative" "5")
1502 (not (match_operand:QI 1 "aligned_operand" "")))
1503 (const_string "imovx")
1504 (ne (symbol_ref "optimize_size") (const_int 0))
1505 (const_string "imov")
1506 (and (eq_attr "alternative" "3")
1507 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1508 (const_int 0))
1509 (eq (symbol_ref "TARGET_QIMODE_MATH")
1510 (const_int 0))))
1511 (const_string "imov")
1512 (eq_attr "alternative" "3,5")
1513 (const_string "imovx")
1514 (and (ne (symbol_ref "TARGET_MOVX")
1515 (const_int 0))
1516 (eq_attr "alternative" "2"))
1517 (const_string "imovx")
1518 ]
1519 (const_string "imov")))
1520 (set (attr "mode")
1521 (cond [(eq_attr "alternative" "3,4,5")
1522 (const_string "SI")
1523 (eq_attr "alternative" "6")
1524 (const_string "QI")
1525 (eq_attr "type" "imovx")
1526 (const_string "SI")
1527 (and (eq_attr "type" "imov")
1528 (and (eq_attr "alternative" "0,1")
1529 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1530 (const_int 0))
1531 (and (eq (symbol_ref "optimize_size")
1532 (const_int 0))
1533 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1534 (const_int 0))))))
1535 (const_string "SI")
1536 ;; Avoid partial register stalls when not using QImode arithmetic
1537 (and (eq_attr "type" "imov")
1538 (and (eq_attr "alternative" "0,1")
1539 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1540 (const_int 0))
1541 (eq (symbol_ref "TARGET_QIMODE_MATH")
1542 (const_int 0)))))
1543 (const_string "SI")
1544 ]
1545 (const_string "QI")))])
1546
1547 (define_expand "reload_outqi"
1548 [(parallel [(match_operand:QI 0 "" "=m")
1549 (match_operand:QI 1 "register_operand" "r")
1550 (match_operand:QI 2 "register_operand" "=&q")])]
1551 ""
1552 {
1553 rtx op0, op1, op2;
1554 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1555
1556 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1557 if (! q_regs_operand (op1, QImode))
1558 {
1559 emit_insn (gen_movqi (op2, op1));
1560 op1 = op2;
1561 }
1562 emit_insn (gen_movqi (op0, op1));
1563 DONE;
1564 })
1565
1566 (define_insn "*swapqi_1"
1567 [(set (match_operand:QI 0 "register_operand" "+r")
1568 (match_operand:QI 1 "register_operand" "+r"))
1569 (set (match_dup 1)
1570 (match_dup 0))]
1571 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1572 "xchg{l}\t%k1, %k0"
1573 [(set_attr "type" "imov")
1574 (set_attr "mode" "SI")
1575 (set_attr "pent_pair" "np")
1576 (set_attr "athlon_decode" "vector")])
1577
1578 (define_insn "*swapqi_2"
1579 [(set (match_operand:QI 0 "register_operand" "+q")
1580 (match_operand:QI 1 "register_operand" "+q"))
1581 (set (match_dup 1)
1582 (match_dup 0))]
1583 "TARGET_PARTIAL_REG_STALL"
1584 "xchg{b}\t%1, %0"
1585 [(set_attr "type" "imov")
1586 (set_attr "mode" "QI")
1587 (set_attr "pent_pair" "np")
1588 (set_attr "athlon_decode" "vector")])
1589
1590 (define_expand "movstrictqi"
1591 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1592 (match_operand:QI 1 "general_operand" ""))]
1593 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1594 {
1595 /* Don't generate memory->memory moves, go through a register. */
1596 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1597 operands[1] = force_reg (QImode, operands[1]);
1598 })
1599
1600 (define_insn "*movstrictqi_1"
1601 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1602 (match_operand:QI 1 "general_operand" "*qn,m"))]
1603 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1604 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1605 "mov{b}\t{%1, %0|%0, %1}"
1606 [(set_attr "type" "imov")
1607 (set_attr "mode" "QI")])
1608
1609 (define_insn "*movstrictqi_xor"
1610 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1611 (match_operand:QI 1 "const0_operand" "i"))
1612 (clobber (reg:CC FLAGS_REG))]
1613 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1614 "xor{b}\t{%0, %0|%0, %0}"
1615 [(set_attr "type" "alu1")
1616 (set_attr "mode" "QI")
1617 (set_attr "length_immediate" "0")])
1618
1619 (define_insn "*movsi_extv_1"
1620 [(set (match_operand:SI 0 "register_operand" "=R")
1621 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1622 (const_int 8)
1623 (const_int 8)))]
1624 ""
1625 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1626 [(set_attr "type" "imovx")
1627 (set_attr "mode" "SI")])
1628
1629 (define_insn "*movhi_extv_1"
1630 [(set (match_operand:HI 0 "register_operand" "=R")
1631 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1632 (const_int 8)
1633 (const_int 8)))]
1634 ""
1635 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1636 [(set_attr "type" "imovx")
1637 (set_attr "mode" "SI")])
1638
1639 (define_insn "*movqi_extv_1"
1640 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1641 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1642 (const_int 8)
1643 (const_int 8)))]
1644 "!TARGET_64BIT"
1645 {
1646 switch (get_attr_type (insn))
1647 {
1648 case TYPE_IMOVX:
1649 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1650 default:
1651 return "mov{b}\t{%h1, %0|%0, %h1}";
1652 }
1653 }
1654 [(set (attr "type")
1655 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1656 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1657 (ne (symbol_ref "TARGET_MOVX")
1658 (const_int 0))))
1659 (const_string "imovx")
1660 (const_string "imov")))
1661 (set (attr "mode")
1662 (if_then_else (eq_attr "type" "imovx")
1663 (const_string "SI")
1664 (const_string "QI")))])
1665
1666 (define_insn "*movqi_extv_1_rex64"
1667 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1668 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1669 (const_int 8)
1670 (const_int 8)))]
1671 "TARGET_64BIT"
1672 {
1673 switch (get_attr_type (insn))
1674 {
1675 case TYPE_IMOVX:
1676 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1677 default:
1678 return "mov{b}\t{%h1, %0|%0, %h1}";
1679 }
1680 }
1681 [(set (attr "type")
1682 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1683 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1684 (ne (symbol_ref "TARGET_MOVX")
1685 (const_int 0))))
1686 (const_string "imovx")
1687 (const_string "imov")))
1688 (set (attr "mode")
1689 (if_then_else (eq_attr "type" "imovx")
1690 (const_string "SI")
1691 (const_string "QI")))])
1692
1693 ;; Stores and loads of ax to arbitrary constant address.
1694 ;; We fake an second form of instruction to force reload to load address
1695 ;; into register when rax is not available
1696 (define_insn "*movabsqi_1_rex64"
1697 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1698 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1699 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1700 "@
1701 movabs{b}\t{%1, %P0|%P0, %1}
1702 mov{b}\t{%1, %a0|%a0, %1}"
1703 [(set_attr "type" "imov")
1704 (set_attr "modrm" "0,*")
1705 (set_attr "length_address" "8,0")
1706 (set_attr "length_immediate" "0,*")
1707 (set_attr "memory" "store")
1708 (set_attr "mode" "QI")])
1709
1710 (define_insn "*movabsqi_2_rex64"
1711 [(set (match_operand:QI 0 "register_operand" "=a,r")
1712 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1713 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1714 "@
1715 movabs{b}\t{%P1, %0|%0, %P1}
1716 mov{b}\t{%a1, %0|%0, %a1}"
1717 [(set_attr "type" "imov")
1718 (set_attr "modrm" "0,*")
1719 (set_attr "length_address" "8,0")
1720 (set_attr "length_immediate" "0")
1721 (set_attr "memory" "load")
1722 (set_attr "mode" "QI")])
1723
1724 (define_insn "*movdi_extzv_1"
1725 [(set (match_operand:DI 0 "register_operand" "=R")
1726 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1727 (const_int 8)
1728 (const_int 8)))]
1729 "TARGET_64BIT"
1730 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1731 [(set_attr "type" "imovx")
1732 (set_attr "mode" "DI")])
1733
1734 (define_insn "*movsi_extzv_1"
1735 [(set (match_operand:SI 0 "register_operand" "=R")
1736 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1737 (const_int 8)
1738 (const_int 8)))]
1739 ""
1740 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1741 [(set_attr "type" "imovx")
1742 (set_attr "mode" "SI")])
1743
1744 (define_insn "*movqi_extzv_2"
1745 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1746 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1747 (const_int 8)
1748 (const_int 8)) 0))]
1749 "!TARGET_64BIT"
1750 {
1751 switch (get_attr_type (insn))
1752 {
1753 case TYPE_IMOVX:
1754 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1755 default:
1756 return "mov{b}\t{%h1, %0|%0, %h1}";
1757 }
1758 }
1759 [(set (attr "type")
1760 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1761 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1762 (ne (symbol_ref "TARGET_MOVX")
1763 (const_int 0))))
1764 (const_string "imovx")
1765 (const_string "imov")))
1766 (set (attr "mode")
1767 (if_then_else (eq_attr "type" "imovx")
1768 (const_string "SI")
1769 (const_string "QI")))])
1770
1771 (define_insn "*movqi_extzv_2_rex64"
1772 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1773 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1774 (const_int 8)
1775 (const_int 8)) 0))]
1776 "TARGET_64BIT"
1777 {
1778 switch (get_attr_type (insn))
1779 {
1780 case TYPE_IMOVX:
1781 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1782 default:
1783 return "mov{b}\t{%h1, %0|%0, %h1}";
1784 }
1785 }
1786 [(set (attr "type")
1787 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1788 (ne (symbol_ref "TARGET_MOVX")
1789 (const_int 0)))
1790 (const_string "imovx")
1791 (const_string "imov")))
1792 (set (attr "mode")
1793 (if_then_else (eq_attr "type" "imovx")
1794 (const_string "SI")
1795 (const_string "QI")))])
1796
1797 (define_insn "movsi_insv_1"
1798 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1799 (const_int 8)
1800 (const_int 8))
1801 (match_operand:SI 1 "general_operand" "Qmn"))]
1802 "!TARGET_64BIT"
1803 "mov{b}\t{%b1, %h0|%h0, %b1}"
1804 [(set_attr "type" "imov")
1805 (set_attr "mode" "QI")])
1806
1807 (define_insn "*movsi_insv_1_rex64"
1808 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1809 (const_int 8)
1810 (const_int 8))
1811 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1812 "TARGET_64BIT"
1813 "mov{b}\t{%b1, %h0|%h0, %b1}"
1814 [(set_attr "type" "imov")
1815 (set_attr "mode" "QI")])
1816
1817 (define_insn "movdi_insv_1_rex64"
1818 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1819 (const_int 8)
1820 (const_int 8))
1821 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1822 "TARGET_64BIT"
1823 "mov{b}\t{%b1, %h0|%h0, %b1}"
1824 [(set_attr "type" "imov")
1825 (set_attr "mode" "QI")])
1826
1827 (define_insn "*movqi_insv_2"
1828 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1829 (const_int 8)
1830 (const_int 8))
1831 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1832 (const_int 8)))]
1833 ""
1834 "mov{b}\t{%h1, %h0|%h0, %h1}"
1835 [(set_attr "type" "imov")
1836 (set_attr "mode" "QI")])
1837
1838 (define_expand "movdi"
1839 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1840 (match_operand:DI 1 "general_operand" ""))]
1841 ""
1842 "ix86_expand_move (DImode, operands); DONE;")
1843
1844 (define_insn "*pushdi"
1845 [(set (match_operand:DI 0 "push_operand" "=<")
1846 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1847 "!TARGET_64BIT"
1848 "#")
1849
1850 (define_insn "*pushdi2_rex64"
1851 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1852 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1853 "TARGET_64BIT"
1854 "@
1855 push{q}\t%1
1856 #"
1857 [(set_attr "type" "push,multi")
1858 (set_attr "mode" "DI")])
1859
1860 ;; Convert impossible pushes of immediate to existing instructions.
1861 ;; First try to get scratch register and go through it. In case this
1862 ;; fails, push sign extended lower part first and then overwrite
1863 ;; upper part by 32bit move.
1864 (define_peephole2
1865 [(match_scratch:DI 2 "r")
1866 (set (match_operand:DI 0 "push_operand" "")
1867 (match_operand:DI 1 "immediate_operand" ""))]
1868 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1869 && !x86_64_immediate_operand (operands[1], DImode)"
1870 [(set (match_dup 2) (match_dup 1))
1871 (set (match_dup 0) (match_dup 2))]
1872 "")
1873
1874 ;; We need to define this as both peepholer and splitter for case
1875 ;; peephole2 pass is not run.
1876 ;; "&& 1" is needed to keep it from matching the previous pattern.
1877 (define_peephole2
1878 [(set (match_operand:DI 0 "push_operand" "")
1879 (match_operand:DI 1 "immediate_operand" ""))]
1880 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1881 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1882 [(set (match_dup 0) (match_dup 1))
1883 (set (match_dup 2) (match_dup 3))]
1884 "split_di (operands + 1, 1, operands + 2, operands + 3);
1885 operands[1] = gen_lowpart (DImode, operands[2]);
1886 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1887 GEN_INT (4)));
1888 ")
1889
1890 (define_split
1891 [(set (match_operand:DI 0 "push_operand" "")
1892 (match_operand:DI 1 "immediate_operand" ""))]
1893 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1894 ? flow2_completed : reload_completed)
1895 && !symbolic_operand (operands[1], DImode)
1896 && !x86_64_immediate_operand (operands[1], DImode)"
1897 [(set (match_dup 0) (match_dup 1))
1898 (set (match_dup 2) (match_dup 3))]
1899 "split_di (operands + 1, 1, operands + 2, operands + 3);
1900 operands[1] = gen_lowpart (DImode, operands[2]);
1901 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1902 GEN_INT (4)));
1903 ")
1904
1905 (define_insn "*pushdi2_prologue_rex64"
1906 [(set (match_operand:DI 0 "push_operand" "=<")
1907 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1908 (clobber (mem:BLK (scratch)))]
1909 "TARGET_64BIT"
1910 "push{q}\t%1"
1911 [(set_attr "type" "push")
1912 (set_attr "mode" "DI")])
1913
1914 (define_insn "*popdi1_epilogue_rex64"
1915 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1916 (mem:DI (reg:DI SP_REG)))
1917 (set (reg:DI SP_REG)
1918 (plus:DI (reg:DI SP_REG) (const_int 8)))
1919 (clobber (mem:BLK (scratch)))]
1920 "TARGET_64BIT"
1921 "pop{q}\t%0"
1922 [(set_attr "type" "pop")
1923 (set_attr "mode" "DI")])
1924
1925 (define_insn "popdi1"
1926 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1927 (mem:DI (reg:DI SP_REG)))
1928 (set (reg:DI SP_REG)
1929 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1930 "TARGET_64BIT"
1931 "pop{q}\t%0"
1932 [(set_attr "type" "pop")
1933 (set_attr "mode" "DI")])
1934
1935 (define_insn "*movdi_xor_rex64"
1936 [(set (match_operand:DI 0 "register_operand" "=r")
1937 (match_operand:DI 1 "const0_operand" "i"))
1938 (clobber (reg:CC FLAGS_REG))]
1939 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1940 && reload_completed"
1941 "xor{l}\t{%k0, %k0|%k0, %k0}"
1942 [(set_attr "type" "alu1")
1943 (set_attr "mode" "SI")
1944 (set_attr "length_immediate" "0")])
1945
1946 (define_insn "*movdi_or_rex64"
1947 [(set (match_operand:DI 0 "register_operand" "=r")
1948 (match_operand:DI 1 "const_int_operand" "i"))
1949 (clobber (reg:CC FLAGS_REG))]
1950 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1951 && reload_completed
1952 && operands[1] == constm1_rtx"
1953 {
1954 operands[1] = constm1_rtx;
1955 return "or{q}\t{%1, %0|%0, %1}";
1956 }
1957 [(set_attr "type" "alu1")
1958 (set_attr "mode" "DI")
1959 (set_attr "length_immediate" "1")])
1960
1961 (define_insn "*movdi_2"
1962 [(set (match_operand:DI 0 "nonimmediate_operand"
1963 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1964 (match_operand:DI 1 "general_operand"
1965 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1966 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1967 "@
1968 #
1969 #
1970 pxor\t%0, %0
1971 movq\t{%1, %0|%0, %1}
1972 movq\t{%1, %0|%0, %1}
1973 pxor\t%0, %0
1974 movq\t{%1, %0|%0, %1}
1975 movdqa\t{%1, %0|%0, %1}
1976 movq\t{%1, %0|%0, %1}
1977 xorps\t%0, %0
1978 movlps\t{%1, %0|%0, %1}
1979 movaps\t{%1, %0|%0, %1}
1980 movlps\t{%1, %0|%0, %1}"
1981 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1982 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1983
1984 (define_split
1985 [(set (match_operand:DI 0 "push_operand" "")
1986 (match_operand:DI 1 "general_operand" ""))]
1987 "!TARGET_64BIT && reload_completed
1988 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1989 [(const_int 0)]
1990 "ix86_split_long_move (operands); DONE;")
1991
1992 ;; %%% This multiword shite has got to go.
1993 (define_split
1994 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1995 (match_operand:DI 1 "general_operand" ""))]
1996 "!TARGET_64BIT && reload_completed
1997 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1998 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1999 [(const_int 0)]
2000 "ix86_split_long_move (operands); DONE;")
2001
2002 (define_insn "*movdi_1_rex64"
2003 [(set (match_operand:DI 0 "nonimmediate_operand"
2004 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2005 (match_operand:DI 1 "general_operand"
2006 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2007 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2008 {
2009 switch (get_attr_type (insn))
2010 {
2011 case TYPE_SSECVT:
2012 if (which_alternative == 13)
2013 return "movq2dq\t{%1, %0|%0, %1}";
2014 else
2015 return "movdq2q\t{%1, %0|%0, %1}";
2016 case TYPE_SSEMOV:
2017 if (get_attr_mode (insn) == MODE_TI)
2018 return "movdqa\t{%1, %0|%0, %1}";
2019 /* FALLTHRU */
2020 case TYPE_MMXMOV:
2021 /* Moves from and into integer register is done using movd opcode with
2022 REX prefix. */
2023 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2024 return "movd\t{%1, %0|%0, %1}";
2025 return "movq\t{%1, %0|%0, %1}";
2026 case TYPE_SSELOG1:
2027 case TYPE_MMXADD:
2028 return "pxor\t%0, %0";
2029 case TYPE_MULTI:
2030 return "#";
2031 case TYPE_LEA:
2032 return "lea{q}\t{%a1, %0|%0, %a1}";
2033 default:
2034 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2035 if (get_attr_mode (insn) == MODE_SI)
2036 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2037 else if (which_alternative == 2)
2038 return "movabs{q}\t{%1, %0|%0, %1}";
2039 else
2040 return "mov{q}\t{%1, %0|%0, %1}";
2041 }
2042 }
2043 [(set (attr "type")
2044 (cond [(eq_attr "alternative" "5")
2045 (const_string "mmxadd")
2046 (eq_attr "alternative" "6,7,8")
2047 (const_string "mmxmov")
2048 (eq_attr "alternative" "9")
2049 (const_string "sselog1")
2050 (eq_attr "alternative" "10,11,12")
2051 (const_string "ssemov")
2052 (eq_attr "alternative" "13,14")
2053 (const_string "ssecvt")
2054 (eq_attr "alternative" "4")
2055 (const_string "multi")
2056 (match_operand:DI 1 "pic_32bit_operand" "")
2057 (const_string "lea")
2058 ]
2059 (const_string "imov")))
2060 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2061 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2062 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2063
2064 ;; Stores and loads of ax to arbitrary constant address.
2065 ;; We fake an second form of instruction to force reload to load address
2066 ;; into register when rax is not available
2067 (define_insn "*movabsdi_1_rex64"
2068 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2069 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2070 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2071 "@
2072 movabs{q}\t{%1, %P0|%P0, %1}
2073 mov{q}\t{%1, %a0|%a0, %1}"
2074 [(set_attr "type" "imov")
2075 (set_attr "modrm" "0,*")
2076 (set_attr "length_address" "8,0")
2077 (set_attr "length_immediate" "0,*")
2078 (set_attr "memory" "store")
2079 (set_attr "mode" "DI")])
2080
2081 (define_insn "*movabsdi_2_rex64"
2082 [(set (match_operand:DI 0 "register_operand" "=a,r")
2083 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2084 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2085 "@
2086 movabs{q}\t{%P1, %0|%0, %P1}
2087 mov{q}\t{%a1, %0|%0, %a1}"
2088 [(set_attr "type" "imov")
2089 (set_attr "modrm" "0,*")
2090 (set_attr "length_address" "8,0")
2091 (set_attr "length_immediate" "0")
2092 (set_attr "memory" "load")
2093 (set_attr "mode" "DI")])
2094
2095 ;; Convert impossible stores of immediate to existing instructions.
2096 ;; First try to get scratch register and go through it. In case this
2097 ;; fails, move by 32bit parts.
2098 (define_peephole2
2099 [(match_scratch:DI 2 "r")
2100 (set (match_operand:DI 0 "memory_operand" "")
2101 (match_operand:DI 1 "immediate_operand" ""))]
2102 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2103 && !x86_64_immediate_operand (operands[1], DImode)"
2104 [(set (match_dup 2) (match_dup 1))
2105 (set (match_dup 0) (match_dup 2))]
2106 "")
2107
2108 ;; We need to define this as both peepholer and splitter for case
2109 ;; peephole2 pass is not run.
2110 ;; "&& 1" is needed to keep it from matching the previous pattern.
2111 (define_peephole2
2112 [(set (match_operand:DI 0 "memory_operand" "")
2113 (match_operand:DI 1 "immediate_operand" ""))]
2114 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2115 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2116 [(set (match_dup 2) (match_dup 3))
2117 (set (match_dup 4) (match_dup 5))]
2118 "split_di (operands, 2, operands + 2, operands + 4);")
2119
2120 (define_split
2121 [(set (match_operand:DI 0 "memory_operand" "")
2122 (match_operand:DI 1 "immediate_operand" ""))]
2123 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2124 ? flow2_completed : reload_completed)
2125 && !symbolic_operand (operands[1], DImode)
2126 && !x86_64_immediate_operand (operands[1], DImode)"
2127 [(set (match_dup 2) (match_dup 3))
2128 (set (match_dup 4) (match_dup 5))]
2129 "split_di (operands, 2, operands + 2, operands + 4);")
2130
2131 (define_insn "*swapdi_rex64"
2132 [(set (match_operand:DI 0 "register_operand" "+r")
2133 (match_operand:DI 1 "register_operand" "+r"))
2134 (set (match_dup 1)
2135 (match_dup 0))]
2136 "TARGET_64BIT"
2137 "xchg{q}\t%1, %0"
2138 [(set_attr "type" "imov")
2139 (set_attr "mode" "DI")
2140 (set_attr "pent_pair" "np")
2141 (set_attr "athlon_decode" "vector")])
2142
2143 (define_expand "movti"
2144 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2145 (match_operand:TI 1 "nonimmediate_operand" ""))]
2146 "TARGET_SSE || TARGET_64BIT"
2147 {
2148 if (TARGET_64BIT)
2149 ix86_expand_move (TImode, operands);
2150 else
2151 ix86_expand_vector_move (TImode, operands);
2152 DONE;
2153 })
2154
2155 (define_insn "*movti_internal"
2156 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2157 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2158 "TARGET_SSE && !TARGET_64BIT
2159 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2160 {
2161 switch (which_alternative)
2162 {
2163 case 0:
2164 if (get_attr_mode (insn) == MODE_V4SF)
2165 return "xorps\t%0, %0";
2166 else
2167 return "pxor\t%0, %0";
2168 case 1:
2169 case 2:
2170 if (get_attr_mode (insn) == MODE_V4SF)
2171 return "movaps\t{%1, %0|%0, %1}";
2172 else
2173 return "movdqa\t{%1, %0|%0, %1}";
2174 default:
2175 gcc_unreachable ();
2176 }
2177 }
2178 [(set_attr "type" "sselog1,ssemov,ssemov")
2179 (set (attr "mode")
2180 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2181 (ne (symbol_ref "optimize_size") (const_int 0)))
2182 (const_string "V4SF")
2183 (and (eq_attr "alternative" "2")
2184 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2185 (const_int 0)))
2186 (const_string "V4SF")]
2187 (const_string "TI")))])
2188
2189 (define_insn "*movti_rex64"
2190 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2191 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2192 "TARGET_64BIT
2193 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2194 {
2195 switch (which_alternative)
2196 {
2197 case 0:
2198 case 1:
2199 return "#";
2200 case 2:
2201 if (get_attr_mode (insn) == MODE_V4SF)
2202 return "xorps\t%0, %0";
2203 else
2204 return "pxor\t%0, %0";
2205 case 3:
2206 case 4:
2207 if (get_attr_mode (insn) == MODE_V4SF)
2208 return "movaps\t{%1, %0|%0, %1}";
2209 else
2210 return "movdqa\t{%1, %0|%0, %1}";
2211 default:
2212 gcc_unreachable ();
2213 }
2214 }
2215 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2216 (set (attr "mode")
2217 (cond [(eq_attr "alternative" "2,3")
2218 (if_then_else
2219 (ne (symbol_ref "optimize_size")
2220 (const_int 0))
2221 (const_string "V4SF")
2222 (const_string "TI"))
2223 (eq_attr "alternative" "4")
2224 (if_then_else
2225 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2226 (const_int 0))
2227 (ne (symbol_ref "optimize_size")
2228 (const_int 0)))
2229 (const_string "V4SF")
2230 (const_string "TI"))]
2231 (const_string "DI")))])
2232
2233 (define_split
2234 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2235 (match_operand:TI 1 "general_operand" ""))]
2236 "reload_completed && !SSE_REG_P (operands[0])
2237 && !SSE_REG_P (operands[1])"
2238 [(const_int 0)]
2239 "ix86_split_long_move (operands); DONE;")
2240
2241 (define_expand "movsf"
2242 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2243 (match_operand:SF 1 "general_operand" ""))]
2244 ""
2245 "ix86_expand_move (SFmode, operands); DONE;")
2246
2247 (define_insn "*pushsf"
2248 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2249 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2250 "!TARGET_64BIT"
2251 {
2252 /* Anything else should be already split before reg-stack. */
2253 gcc_assert (which_alternative == 1);
2254 return "push{l}\t%1";
2255 }
2256 [(set_attr "type" "multi,push,multi")
2257 (set_attr "unit" "i387,*,*")
2258 (set_attr "mode" "SF,SI,SF")])
2259
2260 (define_insn "*pushsf_rex64"
2261 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2262 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2263 "TARGET_64BIT"
2264 {
2265 /* Anything else should be already split before reg-stack. */
2266 gcc_assert (which_alternative == 1);
2267 return "push{q}\t%q1";
2268 }
2269 [(set_attr "type" "multi,push,multi")
2270 (set_attr "unit" "i387,*,*")
2271 (set_attr "mode" "SF,DI,SF")])
2272
2273 (define_split
2274 [(set (match_operand:SF 0 "push_operand" "")
2275 (match_operand:SF 1 "memory_operand" ""))]
2276 "reload_completed
2277 && MEM_P (operands[1])
2278 && constant_pool_reference_p (operands[1])"
2279 [(set (match_dup 0)
2280 (match_dup 1))]
2281 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2282
2283
2284 ;; %%% Kill this when call knows how to work this out.
2285 (define_split
2286 [(set (match_operand:SF 0 "push_operand" "")
2287 (match_operand:SF 1 "any_fp_register_operand" ""))]
2288 "!TARGET_64BIT"
2289 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2290 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2291
2292 (define_split
2293 [(set (match_operand:SF 0 "push_operand" "")
2294 (match_operand:SF 1 "any_fp_register_operand" ""))]
2295 "TARGET_64BIT"
2296 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2297 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2298
2299 (define_insn "*movsf_1"
2300 [(set (match_operand:SF 0 "nonimmediate_operand"
2301 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2302 (match_operand:SF 1 "general_operand"
2303 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2304 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2305 && (reload_in_progress || reload_completed
2306 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2307 || (!TARGET_SSE_MATH && optimize_size
2308 && standard_80387_constant_p (operands[1]))
2309 || GET_CODE (operands[1]) != CONST_DOUBLE
2310 || memory_operand (operands[0], SFmode))"
2311 {
2312 switch (which_alternative)
2313 {
2314 case 0:
2315 return output_387_reg_move (insn, operands);
2316
2317 case 1:
2318 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2319 return "fstp%z0\t%y0";
2320 else
2321 return "fst%z0\t%y0";
2322
2323 case 2:
2324 return standard_80387_constant_opcode (operands[1]);
2325
2326 case 3:
2327 case 4:
2328 return "mov{l}\t{%1, %0|%0, %1}";
2329 case 5:
2330 if (get_attr_mode (insn) == MODE_TI)
2331 return "pxor\t%0, %0";
2332 else
2333 return "xorps\t%0, %0";
2334 case 6:
2335 if (get_attr_mode (insn) == MODE_V4SF)
2336 return "movaps\t{%1, %0|%0, %1}";
2337 else
2338 return "movss\t{%1, %0|%0, %1}";
2339 case 7:
2340 case 8:
2341 return "movss\t{%1, %0|%0, %1}";
2342
2343 case 9:
2344 case 10:
2345 return "movd\t{%1, %0|%0, %1}";
2346
2347 case 11:
2348 return "movq\t{%1, %0|%0, %1}";
2349
2350 default:
2351 gcc_unreachable ();
2352 }
2353 }
2354 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2355 (set (attr "mode")
2356 (cond [(eq_attr "alternative" "3,4,9,10")
2357 (const_string "SI")
2358 (eq_attr "alternative" "5")
2359 (if_then_else
2360 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2361 (const_int 0))
2362 (ne (symbol_ref "TARGET_SSE2")
2363 (const_int 0)))
2364 (eq (symbol_ref "optimize_size")
2365 (const_int 0)))
2366 (const_string "TI")
2367 (const_string "V4SF"))
2368 /* For architectures resolving dependencies on
2369 whole SSE registers use APS move to break dependency
2370 chains, otherwise use short move to avoid extra work.
2371
2372 Do the same for architectures resolving dependencies on
2373 the parts. While in DF mode it is better to always handle
2374 just register parts, the SF mode is different due to lack
2375 of instructions to load just part of the register. It is
2376 better to maintain the whole registers in single format
2377 to avoid problems on using packed logical operations. */
2378 (eq_attr "alternative" "6")
2379 (if_then_else
2380 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2381 (const_int 0))
2382 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2383 (const_int 0)))
2384 (const_string "V4SF")
2385 (const_string "SF"))
2386 (eq_attr "alternative" "11")
2387 (const_string "DI")]
2388 (const_string "SF")))])
2389
2390 (define_insn "*swapsf"
2391 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2392 (match_operand:SF 1 "fp_register_operand" "+f"))
2393 (set (match_dup 1)
2394 (match_dup 0))]
2395 "reload_completed || TARGET_80387"
2396 {
2397 if (STACK_TOP_P (operands[0]))
2398 return "fxch\t%1";
2399 else
2400 return "fxch\t%0";
2401 }
2402 [(set_attr "type" "fxch")
2403 (set_attr "mode" "SF")])
2404
2405 (define_expand "movdf"
2406 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2407 (match_operand:DF 1 "general_operand" ""))]
2408 ""
2409 "ix86_expand_move (DFmode, operands); DONE;")
2410
2411 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2412 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2413 ;; On the average, pushdf using integers can be still shorter. Allow this
2414 ;; pattern for optimize_size too.
2415
2416 (define_insn "*pushdf_nointeger"
2417 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2418 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2419 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2420 {
2421 /* This insn should be already split before reg-stack. */
2422 gcc_unreachable ();
2423 }
2424 [(set_attr "type" "multi")
2425 (set_attr "unit" "i387,*,*,*")
2426 (set_attr "mode" "DF,SI,SI,DF")])
2427
2428 (define_insn "*pushdf_integer"
2429 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2430 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2431 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2432 {
2433 /* This insn should be already split before reg-stack. */
2434 gcc_unreachable ();
2435 }
2436 [(set_attr "type" "multi")
2437 (set_attr "unit" "i387,*,*")
2438 (set_attr "mode" "DF,SI,DF")])
2439
2440 ;; %%% Kill this when call knows how to work this out.
2441 (define_split
2442 [(set (match_operand:DF 0 "push_operand" "")
2443 (match_operand:DF 1 "any_fp_register_operand" ""))]
2444 "!TARGET_64BIT && reload_completed"
2445 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2446 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2447 "")
2448
2449 (define_split
2450 [(set (match_operand:DF 0 "push_operand" "")
2451 (match_operand:DF 1 "any_fp_register_operand" ""))]
2452 "TARGET_64BIT && reload_completed"
2453 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2454 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2455 "")
2456
2457 (define_split
2458 [(set (match_operand:DF 0 "push_operand" "")
2459 (match_operand:DF 1 "general_operand" ""))]
2460 "reload_completed"
2461 [(const_int 0)]
2462 "ix86_split_long_move (operands); DONE;")
2463
2464 ;; Moving is usually shorter when only FP registers are used. This separate
2465 ;; movdf pattern avoids the use of integer registers for FP operations
2466 ;; when optimizing for size.
2467
2468 (define_insn "*movdf_nointeger"
2469 [(set (match_operand:DF 0 "nonimmediate_operand"
2470 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2471 (match_operand:DF 1 "general_operand"
2472 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2473 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2474 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2475 && (reload_in_progress || reload_completed
2476 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2477 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2478 && standard_80387_constant_p (operands[1]))
2479 || GET_CODE (operands[1]) != CONST_DOUBLE
2480 || memory_operand (operands[0], DFmode))"
2481 {
2482 switch (which_alternative)
2483 {
2484 case 0:
2485 return output_387_reg_move (insn, operands);
2486
2487 case 1:
2488 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2489 return "fstp%z0\t%y0";
2490 else
2491 return "fst%z0\t%y0";
2492
2493 case 2:
2494 return standard_80387_constant_opcode (operands[1]);
2495
2496 case 3:
2497 case 4:
2498 return "#";
2499 case 5:
2500 switch (get_attr_mode (insn))
2501 {
2502 case MODE_V4SF:
2503 return "xorps\t%0, %0";
2504 case MODE_V2DF:
2505 return "xorpd\t%0, %0";
2506 case MODE_TI:
2507 return "pxor\t%0, %0";
2508 default:
2509 gcc_unreachable ();
2510 }
2511 case 6:
2512 case 7:
2513 case 8:
2514 switch (get_attr_mode (insn))
2515 {
2516 case MODE_V4SF:
2517 return "movaps\t{%1, %0|%0, %1}";
2518 case MODE_V2DF:
2519 return "movapd\t{%1, %0|%0, %1}";
2520 case MODE_TI:
2521 return "movdqa\t{%1, %0|%0, %1}";
2522 case MODE_DI:
2523 return "movq\t{%1, %0|%0, %1}";
2524 case MODE_DF:
2525 return "movsd\t{%1, %0|%0, %1}";
2526 case MODE_V1DF:
2527 return "movlpd\t{%1, %0|%0, %1}";
2528 case MODE_V2SF:
2529 return "movlps\t{%1, %0|%0, %1}";
2530 default:
2531 gcc_unreachable ();
2532 }
2533
2534 default:
2535 gcc_unreachable ();
2536 }
2537 }
2538 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2539 (set (attr "mode")
2540 (cond [(eq_attr "alternative" "0,1,2")
2541 (const_string "DF")
2542 (eq_attr "alternative" "3,4")
2543 (const_string "SI")
2544
2545 /* For SSE1, we have many fewer alternatives. */
2546 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2547 (cond [(eq_attr "alternative" "5,6")
2548 (const_string "V4SF")
2549 ]
2550 (const_string "V2SF"))
2551
2552 /* xorps is one byte shorter. */
2553 (eq_attr "alternative" "5")
2554 (cond [(ne (symbol_ref "optimize_size")
2555 (const_int 0))
2556 (const_string "V4SF")
2557 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2558 (const_int 0))
2559 (const_string "TI")
2560 ]
2561 (const_string "V2DF"))
2562
2563 /* For architectures resolving dependencies on
2564 whole SSE registers use APD move to break dependency
2565 chains, otherwise use short move to avoid extra work.
2566
2567 movaps encodes one byte shorter. */
2568 (eq_attr "alternative" "6")
2569 (cond
2570 [(ne (symbol_ref "optimize_size")
2571 (const_int 0))
2572 (const_string "V4SF")
2573 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2574 (const_int 0))
2575 (const_string "V2DF")
2576 ]
2577 (const_string "DF"))
2578 /* For architectures resolving dependencies on register
2579 parts we may avoid extra work to zero out upper part
2580 of register. */
2581 (eq_attr "alternative" "7")
2582 (if_then_else
2583 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2584 (const_int 0))
2585 (const_string "V1DF")
2586 (const_string "DF"))
2587 ]
2588 (const_string "DF")))])
2589
2590 (define_insn "*movdf_integer"
2591 [(set (match_operand:DF 0 "nonimmediate_operand"
2592 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2593 (match_operand:DF 1 "general_operand"
2594 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2595 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2596 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2597 && (reload_in_progress || reload_completed
2598 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2599 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2600 && standard_80387_constant_p (operands[1]))
2601 || GET_CODE (operands[1]) != CONST_DOUBLE
2602 || memory_operand (operands[0], DFmode))"
2603 {
2604 switch (which_alternative)
2605 {
2606 case 0:
2607 return output_387_reg_move (insn, operands);
2608
2609 case 1:
2610 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2611 return "fstp%z0\t%y0";
2612 else
2613 return "fst%z0\t%y0";
2614
2615 case 2:
2616 return standard_80387_constant_opcode (operands[1]);
2617
2618 case 3:
2619 case 4:
2620 return "#";
2621
2622 case 5:
2623 switch (get_attr_mode (insn))
2624 {
2625 case MODE_V4SF:
2626 return "xorps\t%0, %0";
2627 case MODE_V2DF:
2628 return "xorpd\t%0, %0";
2629 case MODE_TI:
2630 return "pxor\t%0, %0";
2631 default:
2632 gcc_unreachable ();
2633 }
2634 case 6:
2635 case 7:
2636 case 8:
2637 switch (get_attr_mode (insn))
2638 {
2639 case MODE_V4SF:
2640 return "movaps\t{%1, %0|%0, %1}";
2641 case MODE_V2DF:
2642 return "movapd\t{%1, %0|%0, %1}";
2643 case MODE_TI:
2644 return "movdqa\t{%1, %0|%0, %1}";
2645 case MODE_DI:
2646 return "movq\t{%1, %0|%0, %1}";
2647 case MODE_DF:
2648 return "movsd\t{%1, %0|%0, %1}";
2649 case MODE_V1DF:
2650 return "movlpd\t{%1, %0|%0, %1}";
2651 case MODE_V2SF:
2652 return "movlps\t{%1, %0|%0, %1}";
2653 default:
2654 gcc_unreachable ();
2655 }
2656
2657 default:
2658 gcc_unreachable();
2659 }
2660 }
2661 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2662 (set (attr "mode")
2663 (cond [(eq_attr "alternative" "0,1,2")
2664 (const_string "DF")
2665 (eq_attr "alternative" "3,4")
2666 (const_string "SI")
2667
2668 /* For SSE1, we have many fewer alternatives. */
2669 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2670 (cond [(eq_attr "alternative" "5,6")
2671 (const_string "V4SF")
2672 ]
2673 (const_string "V2SF"))
2674
2675 /* xorps is one byte shorter. */
2676 (eq_attr "alternative" "5")
2677 (cond [(ne (symbol_ref "optimize_size")
2678 (const_int 0))
2679 (const_string "V4SF")
2680 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2681 (const_int 0))
2682 (const_string "TI")
2683 ]
2684 (const_string "V2DF"))
2685
2686 /* For architectures resolving dependencies on
2687 whole SSE registers use APD move to break dependency
2688 chains, otherwise use short move to avoid extra work.
2689
2690 movaps encodes one byte shorter. */
2691 (eq_attr "alternative" "6")
2692 (cond
2693 [(ne (symbol_ref "optimize_size")
2694 (const_int 0))
2695 (const_string "V4SF")
2696 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2697 (const_int 0))
2698 (const_string "V2DF")
2699 ]
2700 (const_string "DF"))
2701 /* For architectures resolving dependencies on register
2702 parts we may avoid extra work to zero out upper part
2703 of register. */
2704 (eq_attr "alternative" "7")
2705 (if_then_else
2706 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2707 (const_int 0))
2708 (const_string "V1DF")
2709 (const_string "DF"))
2710 ]
2711 (const_string "DF")))])
2712
2713 (define_split
2714 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2715 (match_operand:DF 1 "general_operand" ""))]
2716 "reload_completed
2717 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2718 && ! (ANY_FP_REG_P (operands[0]) ||
2719 (GET_CODE (operands[0]) == SUBREG
2720 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2721 && ! (ANY_FP_REG_P (operands[1]) ||
2722 (GET_CODE (operands[1]) == SUBREG
2723 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2724 [(const_int 0)]
2725 "ix86_split_long_move (operands); DONE;")
2726
2727 (define_insn "*swapdf"
2728 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2729 (match_operand:DF 1 "fp_register_operand" "+f"))
2730 (set (match_dup 1)
2731 (match_dup 0))]
2732 "reload_completed || TARGET_80387"
2733 {
2734 if (STACK_TOP_P (operands[0]))
2735 return "fxch\t%1";
2736 else
2737 return "fxch\t%0";
2738 }
2739 [(set_attr "type" "fxch")
2740 (set_attr "mode" "DF")])
2741
2742 (define_expand "movxf"
2743 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2744 (match_operand:XF 1 "general_operand" ""))]
2745 ""
2746 "ix86_expand_move (XFmode, operands); DONE;")
2747
2748 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2749 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2750 ;; Pushing using integer instructions is longer except for constants
2751 ;; and direct memory references.
2752 ;; (assuming that any given constant is pushed only once, but this ought to be
2753 ;; handled elsewhere).
2754
2755 (define_insn "*pushxf_nointeger"
2756 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2757 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2758 "optimize_size"
2759 {
2760 /* This insn should be already split before reg-stack. */
2761 gcc_unreachable ();
2762 }
2763 [(set_attr "type" "multi")
2764 (set_attr "unit" "i387,*,*")
2765 (set_attr "mode" "XF,SI,SI")])
2766
2767 (define_insn "*pushxf_integer"
2768 [(set (match_operand:XF 0 "push_operand" "=<,<")
2769 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2770 "!optimize_size"
2771 {
2772 /* This insn should be already split before reg-stack. */
2773 gcc_unreachable ();
2774 }
2775 [(set_attr "type" "multi")
2776 (set_attr "unit" "i387,*")
2777 (set_attr "mode" "XF,SI")])
2778
2779 (define_split
2780 [(set (match_operand 0 "push_operand" "")
2781 (match_operand 1 "general_operand" ""))]
2782 "reload_completed
2783 && (GET_MODE (operands[0]) == XFmode
2784 || GET_MODE (operands[0]) == DFmode)
2785 && !ANY_FP_REG_P (operands[1])"
2786 [(const_int 0)]
2787 "ix86_split_long_move (operands); DONE;")
2788
2789 (define_split
2790 [(set (match_operand:XF 0 "push_operand" "")
2791 (match_operand:XF 1 "any_fp_register_operand" ""))]
2792 "!TARGET_64BIT"
2793 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2794 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2795 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2796
2797 (define_split
2798 [(set (match_operand:XF 0 "push_operand" "")
2799 (match_operand:XF 1 "any_fp_register_operand" ""))]
2800 "TARGET_64BIT"
2801 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2802 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2803 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2804
2805 ;; Do not use integer registers when optimizing for size
2806 (define_insn "*movxf_nointeger"
2807 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2808 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2809 "optimize_size
2810 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2811 && (reload_in_progress || reload_completed
2812 || (optimize_size && standard_80387_constant_p (operands[1]))
2813 || GET_CODE (operands[1]) != CONST_DOUBLE
2814 || memory_operand (operands[0], XFmode))"
2815 {
2816 switch (which_alternative)
2817 {
2818 case 0:
2819 return output_387_reg_move (insn, operands);
2820
2821 case 1:
2822 /* There is no non-popping store to memory for XFmode. So if
2823 we need one, follow the store with a load. */
2824 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2825 return "fstp%z0\t%y0\;fld%z0\t%y0";
2826 else
2827 return "fstp%z0\t%y0";
2828
2829 case 2:
2830 return standard_80387_constant_opcode (operands[1]);
2831
2832 case 3: case 4:
2833 return "#";
2834 default:
2835 gcc_unreachable ();
2836 }
2837 }
2838 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839 (set_attr "mode" "XF,XF,XF,SI,SI")])
2840
2841 (define_insn "*movxf_integer"
2842 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2843 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2844 "!optimize_size
2845 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2846 && (reload_in_progress || reload_completed
2847 || (optimize_size && standard_80387_constant_p (operands[1]))
2848 || GET_CODE (operands[1]) != CONST_DOUBLE
2849 || memory_operand (operands[0], XFmode))"
2850 {
2851 switch (which_alternative)
2852 {
2853 case 0:
2854 return output_387_reg_move (insn, operands);
2855
2856 case 1:
2857 /* There is no non-popping store to memory for XFmode. So if
2858 we need one, follow the store with a load. */
2859 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2860 return "fstp%z0\t%y0\;fld%z0\t%y0";
2861 else
2862 return "fstp%z0\t%y0";
2863
2864 case 2:
2865 return standard_80387_constant_opcode (operands[1]);
2866
2867 case 3: case 4:
2868 return "#";
2869
2870 default:
2871 gcc_unreachable ();
2872 }
2873 }
2874 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2875 (set_attr "mode" "XF,XF,XF,SI,SI")])
2876
2877 (define_split
2878 [(set (match_operand 0 "nonimmediate_operand" "")
2879 (match_operand 1 "general_operand" ""))]
2880 "reload_completed
2881 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2882 && GET_MODE (operands[0]) == XFmode
2883 && ! (ANY_FP_REG_P (operands[0]) ||
2884 (GET_CODE (operands[0]) == SUBREG
2885 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2886 && ! (ANY_FP_REG_P (operands[1]) ||
2887 (GET_CODE (operands[1]) == SUBREG
2888 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2889 [(const_int 0)]
2890 "ix86_split_long_move (operands); DONE;")
2891
2892 (define_split
2893 [(set (match_operand 0 "register_operand" "")
2894 (match_operand 1 "memory_operand" ""))]
2895 "reload_completed
2896 && MEM_P (operands[1])
2897 && (GET_MODE (operands[0]) == XFmode
2898 || GET_MODE (operands[0]) == SFmode
2899 || GET_MODE (operands[0]) == DFmode)
2900 && constant_pool_reference_p (operands[1])"
2901 [(set (match_dup 0) (match_dup 1))]
2902 {
2903 rtx c = avoid_constant_pool_reference (operands[1]);
2904 rtx r = operands[0];
2905
2906 if (GET_CODE (r) == SUBREG)
2907 r = SUBREG_REG (r);
2908
2909 if (SSE_REG_P (r))
2910 {
2911 if (!standard_sse_constant_p (c))
2912 FAIL;
2913 }
2914 else if (FP_REG_P (r))
2915 {
2916 if (!standard_80387_constant_p (c))
2917 FAIL;
2918 }
2919 else if (MMX_REG_P (r))
2920 FAIL;
2921
2922 operands[1] = c;
2923 })
2924
2925 (define_split
2926 [(set (match_operand 0 "register_operand" "")
2927 (float_extend (match_operand 1 "memory_operand" "")))]
2928 "reload_completed
2929 && MEM_P (operands[1])
2930 && (GET_MODE (operands[0]) == XFmode
2931 || GET_MODE (operands[0]) == SFmode
2932 || GET_MODE (operands[0]) == DFmode)
2933 && constant_pool_reference_p (operands[1])"
2934 [(set (match_dup 0) (match_dup 1))]
2935 {
2936 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2937 rtx r = operands[0];
2938
2939 if (GET_CODE (r) == SUBREG)
2940 r = SUBREG_REG (r);
2941
2942 if (SSE_REG_P (r))
2943 {
2944 if (!standard_sse_constant_p (c))
2945 FAIL;
2946 }
2947 else if (FP_REG_P (r))
2948 {
2949 if (!standard_80387_constant_p (c))
2950 FAIL;
2951 }
2952 else if (MMX_REG_P (r))
2953 FAIL;
2954
2955 operands[1] = c;
2956 })
2957
2958 (define_insn "swapxf"
2959 [(set (match_operand:XF 0 "register_operand" "+f")
2960 (match_operand:XF 1 "register_operand" "+f"))
2961 (set (match_dup 1)
2962 (match_dup 0))]
2963 "TARGET_80387"
2964 {
2965 if (STACK_TOP_P (operands[0]))
2966 return "fxch\t%1";
2967 else
2968 return "fxch\t%0";
2969 }
2970 [(set_attr "type" "fxch")
2971 (set_attr "mode" "XF")])
2972
2973 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2974 (define_split
2975 [(set (match_operand:X87MODEF 0 "register_operand" "")
2976 (match_operand:X87MODEF 1 "immediate_operand" ""))]
2977 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2978 && (standard_80387_constant_p (operands[1]) == 8
2979 || standard_80387_constant_p (operands[1]) == 9)"
2980 [(set (match_dup 0)(match_dup 1))
2981 (set (match_dup 0)
2982 (neg:X87MODEF (match_dup 0)))]
2983 {
2984 REAL_VALUE_TYPE r;
2985
2986 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2987 if (real_isnegzero (&r))
2988 operands[1] = CONST0_RTX (<MODE>mode);
2989 else
2990 operands[1] = CONST1_RTX (<MODE>mode);
2991 })
2992
2993 (define_expand "movtf"
2994 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2995 (match_operand:TF 1 "nonimmediate_operand" ""))]
2996 "TARGET_64BIT"
2997 {
2998 ix86_expand_move (TFmode, operands);
2999 DONE;
3000 })
3001
3002 (define_insn "*movtf_internal"
3003 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3004 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3005 "TARGET_64BIT
3006 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3007 {
3008 switch (which_alternative)
3009 {
3010 case 0:
3011 case 1:
3012 return "#";
3013 case 2:
3014 if (get_attr_mode (insn) == MODE_V4SF)
3015 return "xorps\t%0, %0";
3016 else
3017 return "pxor\t%0, %0";
3018 case 3:
3019 case 4:
3020 if (get_attr_mode (insn) == MODE_V4SF)
3021 return "movaps\t{%1, %0|%0, %1}";
3022 else
3023 return "movdqa\t{%1, %0|%0, %1}";
3024 default:
3025 gcc_unreachable ();
3026 }
3027 }
3028 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3029 (set (attr "mode")
3030 (cond [(eq_attr "alternative" "2,3")
3031 (if_then_else
3032 (ne (symbol_ref "optimize_size")
3033 (const_int 0))
3034 (const_string "V4SF")
3035 (const_string "TI"))
3036 (eq_attr "alternative" "4")
3037 (if_then_else
3038 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3039 (const_int 0))
3040 (ne (symbol_ref "optimize_size")
3041 (const_int 0)))
3042 (const_string "V4SF")
3043 (const_string "TI"))]
3044 (const_string "DI")))])
3045
3046 (define_split
3047 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3048 (match_operand:TF 1 "general_operand" ""))]
3049 "reload_completed && !SSE_REG_P (operands[0])
3050 && !SSE_REG_P (operands[1])"
3051 [(const_int 0)]
3052 "ix86_split_long_move (operands); DONE;")
3053 \f
3054 ;; Zero extension instructions
3055
3056 (define_expand "zero_extendhisi2"
3057 [(set (match_operand:SI 0 "register_operand" "")
3058 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3059 ""
3060 {
3061 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3062 {
3063 operands[1] = force_reg (HImode, operands[1]);
3064 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3065 DONE;
3066 }
3067 })
3068
3069 (define_insn "zero_extendhisi2_and"
3070 [(set (match_operand:SI 0 "register_operand" "=r")
3071 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3072 (clobber (reg:CC FLAGS_REG))]
3073 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3074 "#"
3075 [(set_attr "type" "alu1")
3076 (set_attr "mode" "SI")])
3077
3078 (define_split
3079 [(set (match_operand:SI 0 "register_operand" "")
3080 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3081 (clobber (reg:CC FLAGS_REG))]
3082 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3083 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3084 (clobber (reg:CC FLAGS_REG))])]
3085 "")
3086
3087 (define_insn "*zero_extendhisi2_movzwl"
3088 [(set (match_operand:SI 0 "register_operand" "=r")
3089 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3090 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3091 "movz{wl|x}\t{%1, %0|%0, %1}"
3092 [(set_attr "type" "imovx")
3093 (set_attr "mode" "SI")])
3094
3095 (define_expand "zero_extendqihi2"
3096 [(parallel
3097 [(set (match_operand:HI 0 "register_operand" "")
3098 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3099 (clobber (reg:CC FLAGS_REG))])]
3100 ""
3101 "")
3102
3103 (define_insn "*zero_extendqihi2_and"
3104 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3105 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3106 (clobber (reg:CC FLAGS_REG))]
3107 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3108 "#"
3109 [(set_attr "type" "alu1")
3110 (set_attr "mode" "HI")])
3111
3112 (define_insn "*zero_extendqihi2_movzbw_and"
3113 [(set (match_operand:HI 0 "register_operand" "=r,r")
3114 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3115 (clobber (reg:CC FLAGS_REG))]
3116 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3117 "#"
3118 [(set_attr "type" "imovx,alu1")
3119 (set_attr "mode" "HI")])
3120
3121 ; zero extend to SImode here to avoid partial register stalls
3122 (define_insn "*zero_extendqihi2_movzbl"
3123 [(set (match_operand:HI 0 "register_operand" "=r")
3124 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3125 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3126 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3127 [(set_attr "type" "imovx")
3128 (set_attr "mode" "SI")])
3129
3130 ;; For the movzbw case strip only the clobber
3131 (define_split
3132 [(set (match_operand:HI 0 "register_operand" "")
3133 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3134 (clobber (reg:CC FLAGS_REG))]
3135 "reload_completed
3136 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3137 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3138 [(set (match_operand:HI 0 "register_operand" "")
3139 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3140
3141 ;; When source and destination does not overlap, clear destination
3142 ;; first and then do the movb
3143 (define_split
3144 [(set (match_operand:HI 0 "register_operand" "")
3145 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3146 (clobber (reg:CC FLAGS_REG))]
3147 "reload_completed
3148 && ANY_QI_REG_P (operands[0])
3149 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3150 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3151 [(set (match_dup 0) (const_int 0))
3152 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3153 "operands[2] = gen_lowpart (QImode, operands[0]);")
3154
3155 ;; Rest is handled by single and.
3156 (define_split
3157 [(set (match_operand:HI 0 "register_operand" "")
3158 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3159 (clobber (reg:CC FLAGS_REG))]
3160 "reload_completed
3161 && true_regnum (operands[0]) == true_regnum (operands[1])"
3162 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3163 (clobber (reg:CC FLAGS_REG))])]
3164 "")
3165
3166 (define_expand "zero_extendqisi2"
3167 [(parallel
3168 [(set (match_operand:SI 0 "register_operand" "")
3169 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3170 (clobber (reg:CC FLAGS_REG))])]
3171 ""
3172 "")
3173
3174 (define_insn "*zero_extendqisi2_and"
3175 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3176 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3177 (clobber (reg:CC FLAGS_REG))]
3178 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3179 "#"
3180 [(set_attr "type" "alu1")
3181 (set_attr "mode" "SI")])
3182
3183 (define_insn "*zero_extendqisi2_movzbw_and"
3184 [(set (match_operand:SI 0 "register_operand" "=r,r")
3185 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3186 (clobber (reg:CC FLAGS_REG))]
3187 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3188 "#"
3189 [(set_attr "type" "imovx,alu1")
3190 (set_attr "mode" "SI")])
3191
3192 (define_insn "*zero_extendqisi2_movzbw"
3193 [(set (match_operand:SI 0 "register_operand" "=r")
3194 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3195 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3196 "movz{bl|x}\t{%1, %0|%0, %1}"
3197 [(set_attr "type" "imovx")
3198 (set_attr "mode" "SI")])
3199
3200 ;; For the movzbl case strip only the clobber
3201 (define_split
3202 [(set (match_operand:SI 0 "register_operand" "")
3203 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3204 (clobber (reg:CC FLAGS_REG))]
3205 "reload_completed
3206 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3207 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3208 [(set (match_dup 0)
3209 (zero_extend:SI (match_dup 1)))])
3210
3211 ;; When source and destination does not overlap, clear destination
3212 ;; first and then do the movb
3213 (define_split
3214 [(set (match_operand:SI 0 "register_operand" "")
3215 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3216 (clobber (reg:CC FLAGS_REG))]
3217 "reload_completed
3218 && ANY_QI_REG_P (operands[0])
3219 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3220 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3221 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3222 [(set (match_dup 0) (const_int 0))
3223 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3224 "operands[2] = gen_lowpart (QImode, operands[0]);")
3225
3226 ;; Rest is handled by single and.
3227 (define_split
3228 [(set (match_operand:SI 0 "register_operand" "")
3229 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3230 (clobber (reg:CC FLAGS_REG))]
3231 "reload_completed
3232 && true_regnum (operands[0]) == true_regnum (operands[1])"
3233 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3234 (clobber (reg:CC FLAGS_REG))])]
3235 "")
3236
3237 ;; %%% Kill me once multi-word ops are sane.
3238 (define_expand "zero_extendsidi2"
3239 [(set (match_operand:DI 0 "register_operand" "=r")
3240 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3241 ""
3242 "if (!TARGET_64BIT)
3243 {
3244 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3245 DONE;
3246 }
3247 ")
3248
3249 (define_insn "zero_extendsidi2_32"
3250 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3251 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3252 (clobber (reg:CC FLAGS_REG))]
3253 "!TARGET_64BIT"
3254 "@
3255 #
3256 #
3257 #
3258 movd\t{%1, %0|%0, %1}
3259 movd\t{%1, %0|%0, %1}"
3260 [(set_attr "mode" "SI,SI,SI,DI,TI")
3261 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3262
3263 (define_insn "zero_extendsidi2_rex64"
3264 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3265 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3266 "TARGET_64BIT"
3267 "@
3268 mov\t{%k1, %k0|%k0, %k1}
3269 #
3270 movd\t{%1, %0|%0, %1}
3271 movd\t{%1, %0|%0, %1}"
3272 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3273 (set_attr "mode" "SI,DI,SI,SI")])
3274
3275 (define_split
3276 [(set (match_operand:DI 0 "memory_operand" "")
3277 (zero_extend:DI (match_dup 0)))]
3278 "TARGET_64BIT"
3279 [(set (match_dup 4) (const_int 0))]
3280 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3281
3282 (define_split
3283 [(set (match_operand:DI 0 "register_operand" "")
3284 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3285 (clobber (reg:CC FLAGS_REG))]
3286 "!TARGET_64BIT && reload_completed
3287 && true_regnum (operands[0]) == true_regnum (operands[1])"
3288 [(set (match_dup 4) (const_int 0))]
3289 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3290
3291 (define_split
3292 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3293 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3294 (clobber (reg:CC FLAGS_REG))]
3295 "!TARGET_64BIT && reload_completed
3296 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3297 [(set (match_dup 3) (match_dup 1))
3298 (set (match_dup 4) (const_int 0))]
3299 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3300
3301 (define_insn "zero_extendhidi2"
3302 [(set (match_operand:DI 0 "register_operand" "=r")
3303 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3304 "TARGET_64BIT"
3305 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3306 [(set_attr "type" "imovx")
3307 (set_attr "mode" "DI")])
3308
3309 (define_insn "zero_extendqidi2"
3310 [(set (match_operand:DI 0 "register_operand" "=r")
3311 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3312 "TARGET_64BIT"
3313 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3314 [(set_attr "type" "imovx")
3315 (set_attr "mode" "DI")])
3316 \f
3317 ;; Sign extension instructions
3318
3319 (define_expand "extendsidi2"
3320 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3321 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3322 (clobber (reg:CC FLAGS_REG))
3323 (clobber (match_scratch:SI 2 ""))])]
3324 ""
3325 {
3326 if (TARGET_64BIT)
3327 {
3328 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3329 DONE;
3330 }
3331 })
3332
3333 (define_insn "*extendsidi2_1"
3334 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3335 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3336 (clobber (reg:CC FLAGS_REG))
3337 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3338 "!TARGET_64BIT"
3339 "#")
3340
3341 (define_insn "extendsidi2_rex64"
3342 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3343 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3344 "TARGET_64BIT"
3345 "@
3346 {cltq|cdqe}
3347 movs{lq|x}\t{%1,%0|%0, %1}"
3348 [(set_attr "type" "imovx")
3349 (set_attr "mode" "DI")
3350 (set_attr "prefix_0f" "0")
3351 (set_attr "modrm" "0,1")])
3352
3353 (define_insn "extendhidi2"
3354 [(set (match_operand:DI 0 "register_operand" "=r")
3355 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3356 "TARGET_64BIT"
3357 "movs{wq|x}\t{%1,%0|%0, %1}"
3358 [(set_attr "type" "imovx")
3359 (set_attr "mode" "DI")])
3360
3361 (define_insn "extendqidi2"
3362 [(set (match_operand:DI 0 "register_operand" "=r")
3363 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3364 "TARGET_64BIT"
3365 "movs{bq|x}\t{%1,%0|%0, %1}"
3366 [(set_attr "type" "imovx")
3367 (set_attr "mode" "DI")])
3368
3369 ;; Extend to memory case when source register does die.
3370 (define_split
3371 [(set (match_operand:DI 0 "memory_operand" "")
3372 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3373 (clobber (reg:CC FLAGS_REG))
3374 (clobber (match_operand:SI 2 "register_operand" ""))]
3375 "(reload_completed
3376 && dead_or_set_p (insn, operands[1])
3377 && !reg_mentioned_p (operands[1], operands[0]))"
3378 [(set (match_dup 3) (match_dup 1))
3379 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3380 (clobber (reg:CC FLAGS_REG))])
3381 (set (match_dup 4) (match_dup 1))]
3382 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3383
3384 ;; Extend to memory case when source register does not die.
3385 (define_split
3386 [(set (match_operand:DI 0 "memory_operand" "")
3387 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3388 (clobber (reg:CC FLAGS_REG))
3389 (clobber (match_operand:SI 2 "register_operand" ""))]
3390 "reload_completed"
3391 [(const_int 0)]
3392 {
3393 split_di (&operands[0], 1, &operands[3], &operands[4]);
3394
3395 emit_move_insn (operands[3], operands[1]);
3396
3397 /* Generate a cltd if possible and doing so it profitable. */
3398 if (true_regnum (operands[1]) == 0
3399 && true_regnum (operands[2]) == 1
3400 && (optimize_size || TARGET_USE_CLTD))
3401 {
3402 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3403 }
3404 else
3405 {
3406 emit_move_insn (operands[2], operands[1]);
3407 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3408 }
3409 emit_move_insn (operands[4], operands[2]);
3410 DONE;
3411 })
3412
3413 ;; Extend to register case. Optimize case where source and destination
3414 ;; registers match and cases where we can use cltd.
3415 (define_split
3416 [(set (match_operand:DI 0 "register_operand" "")
3417 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3418 (clobber (reg:CC FLAGS_REG))
3419 (clobber (match_scratch:SI 2 ""))]
3420 "reload_completed"
3421 [(const_int 0)]
3422 {
3423 split_di (&operands[0], 1, &operands[3], &operands[4]);
3424
3425 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3426 emit_move_insn (operands[3], operands[1]);
3427
3428 /* Generate a cltd if possible and doing so it profitable. */
3429 if (true_regnum (operands[3]) == 0
3430 && (optimize_size || TARGET_USE_CLTD))
3431 {
3432 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3433 DONE;
3434 }
3435
3436 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3437 emit_move_insn (operands[4], operands[1]);
3438
3439 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3440 DONE;
3441 })
3442
3443 (define_insn "extendhisi2"
3444 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3445 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3446 ""
3447 {
3448 switch (get_attr_prefix_0f (insn))
3449 {
3450 case 0:
3451 return "{cwtl|cwde}";
3452 default:
3453 return "movs{wl|x}\t{%1,%0|%0, %1}";
3454 }
3455 }
3456 [(set_attr "type" "imovx")
3457 (set_attr "mode" "SI")
3458 (set (attr "prefix_0f")
3459 ;; movsx is short decodable while cwtl is vector decoded.
3460 (if_then_else (and (eq_attr "cpu" "!k6")
3461 (eq_attr "alternative" "0"))
3462 (const_string "0")
3463 (const_string "1")))
3464 (set (attr "modrm")
3465 (if_then_else (eq_attr "prefix_0f" "0")
3466 (const_string "0")
3467 (const_string "1")))])
3468
3469 (define_insn "*extendhisi2_zext"
3470 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3471 (zero_extend:DI
3472 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3473 "TARGET_64BIT"
3474 {
3475 switch (get_attr_prefix_0f (insn))
3476 {
3477 case 0:
3478 return "{cwtl|cwde}";
3479 default:
3480 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3481 }
3482 }
3483 [(set_attr "type" "imovx")
3484 (set_attr "mode" "SI")
3485 (set (attr "prefix_0f")
3486 ;; movsx is short decodable while cwtl is vector decoded.
3487 (if_then_else (and (eq_attr "cpu" "!k6")
3488 (eq_attr "alternative" "0"))
3489 (const_string "0")
3490 (const_string "1")))
3491 (set (attr "modrm")
3492 (if_then_else (eq_attr "prefix_0f" "0")
3493 (const_string "0")
3494 (const_string "1")))])
3495
3496 (define_insn "extendqihi2"
3497 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3498 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3499 ""
3500 {
3501 switch (get_attr_prefix_0f (insn))
3502 {
3503 case 0:
3504 return "{cbtw|cbw}";
3505 default:
3506 return "movs{bw|x}\t{%1,%0|%0, %1}";
3507 }
3508 }
3509 [(set_attr "type" "imovx")
3510 (set_attr "mode" "HI")
3511 (set (attr "prefix_0f")
3512 ;; movsx is short decodable while cwtl is vector decoded.
3513 (if_then_else (and (eq_attr "cpu" "!k6")
3514 (eq_attr "alternative" "0"))
3515 (const_string "0")
3516 (const_string "1")))
3517 (set (attr "modrm")
3518 (if_then_else (eq_attr "prefix_0f" "0")
3519 (const_string "0")
3520 (const_string "1")))])
3521
3522 (define_insn "extendqisi2"
3523 [(set (match_operand:SI 0 "register_operand" "=r")
3524 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3525 ""
3526 "movs{bl|x}\t{%1,%0|%0, %1}"
3527 [(set_attr "type" "imovx")
3528 (set_attr "mode" "SI")])
3529
3530 (define_insn "*extendqisi2_zext"
3531 [(set (match_operand:DI 0 "register_operand" "=r")
3532 (zero_extend:DI
3533 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3534 "TARGET_64BIT"
3535 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3536 [(set_attr "type" "imovx")
3537 (set_attr "mode" "SI")])
3538 \f
3539 ;; Conversions between float and double.
3540
3541 ;; These are all no-ops in the model used for the 80387. So just
3542 ;; emit moves.
3543
3544 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3545 (define_insn "*dummy_extendsfdf2"
3546 [(set (match_operand:DF 0 "push_operand" "=<")
3547 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3548 "0"
3549 "#")
3550
3551 (define_split
3552 [(set (match_operand:DF 0 "push_operand" "")
3553 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3554 "!TARGET_64BIT"
3555 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3556 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3557
3558 (define_split
3559 [(set (match_operand:DF 0 "push_operand" "")
3560 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3561 "TARGET_64BIT"
3562 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3563 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3564
3565 (define_insn "*dummy_extendsfxf2"
3566 [(set (match_operand:XF 0 "push_operand" "=<")
3567 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3568 "0"
3569 "#")
3570
3571 (define_split
3572 [(set (match_operand:XF 0 "push_operand" "")
3573 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3574 ""
3575 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3576 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3577 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3578
3579 (define_split
3580 [(set (match_operand:XF 0 "push_operand" "")
3581 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3582 "TARGET_64BIT"
3583 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3584 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3585 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3586
3587 (define_split
3588 [(set (match_operand:XF 0 "push_operand" "")
3589 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3590 ""
3591 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3592 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3593 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3594
3595 (define_split
3596 [(set (match_operand:XF 0 "push_operand" "")
3597 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3598 "TARGET_64BIT"
3599 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3600 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3601 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3602
3603 (define_expand "extendsfdf2"
3604 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3605 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3606 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3607 {
3608 /* ??? Needed for compress_float_constant since all fp constants
3609 are LEGITIMATE_CONSTANT_P. */
3610 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3611 {
3612 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3613 && standard_80387_constant_p (operands[1]) > 0)
3614 {
3615 operands[1] = simplify_const_unary_operation
3616 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3617 emit_move_insn_1 (operands[0], operands[1]);
3618 DONE;
3619 }
3620 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3621 }
3622 })
3623
3624 (define_insn "*extendsfdf2_mixed"
3625 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3626 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3627 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3628 {
3629 switch (which_alternative)
3630 {
3631 case 0:
3632 return output_387_reg_move (insn, operands);
3633
3634 case 1:
3635 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3636 return "fstp%z0\t%y0";
3637 else
3638 return "fst%z0\t%y0";
3639
3640 case 2:
3641 return "cvtss2sd\t{%1, %0|%0, %1}";
3642
3643 default:
3644 gcc_unreachable ();
3645 }
3646 }
3647 [(set_attr "type" "fmov,fmov,ssecvt")
3648 (set_attr "mode" "SF,XF,DF")])
3649
3650 (define_insn "*extendsfdf2_sse"
3651 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3652 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3653 "TARGET_SSE2 && TARGET_SSE_MATH"
3654 "cvtss2sd\t{%1, %0|%0, %1}"
3655 [(set_attr "type" "ssecvt")
3656 (set_attr "mode" "DF")])
3657
3658 (define_insn "*extendsfdf2_i387"
3659 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3660 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3661 "TARGET_80387"
3662 {
3663 switch (which_alternative)
3664 {
3665 case 0:
3666 return output_387_reg_move (insn, operands);
3667
3668 case 1:
3669 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3670 return "fstp%z0\t%y0";
3671 else
3672 return "fst%z0\t%y0";
3673
3674 default:
3675 gcc_unreachable ();
3676 }
3677 }
3678 [(set_attr "type" "fmov")
3679 (set_attr "mode" "SF,XF")])
3680
3681 (define_expand "extendsfxf2"
3682 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3683 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3684 "TARGET_80387"
3685 {
3686 /* ??? Needed for compress_float_constant since all fp constants
3687 are LEGITIMATE_CONSTANT_P. */
3688 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3689 {
3690 if (standard_80387_constant_p (operands[1]) > 0)
3691 {
3692 operands[1] = simplify_const_unary_operation
3693 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3694 emit_move_insn_1 (operands[0], operands[1]);
3695 DONE;
3696 }
3697 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3698 }
3699 })
3700
3701 (define_insn "*extendsfxf2_i387"
3702 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3703 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3704 "TARGET_80387"
3705 {
3706 switch (which_alternative)
3707 {
3708 case 0:
3709 return output_387_reg_move (insn, operands);
3710
3711 case 1:
3712 /* There is no non-popping store to memory for XFmode. So if
3713 we need one, follow the store with a load. */
3714 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3715 return "fstp%z0\t%y0";
3716 else
3717 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3718
3719 default:
3720 gcc_unreachable ();
3721 }
3722 }
3723 [(set_attr "type" "fmov")
3724 (set_attr "mode" "SF,XF")])
3725
3726 (define_expand "extenddfxf2"
3727 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3728 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3729 "TARGET_80387"
3730 {
3731 /* ??? Needed for compress_float_constant since all fp constants
3732 are LEGITIMATE_CONSTANT_P. */
3733 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3734 {
3735 if (standard_80387_constant_p (operands[1]) > 0)
3736 {
3737 operands[1] = simplify_const_unary_operation
3738 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3739 emit_move_insn_1 (operands[0], operands[1]);
3740 DONE;
3741 }
3742 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3743 }
3744 })
3745
3746 (define_insn "*extenddfxf2_i387"
3747 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3748 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3749 "TARGET_80387"
3750 {
3751 switch (which_alternative)
3752 {
3753 case 0:
3754 return output_387_reg_move (insn, operands);
3755
3756 case 1:
3757 /* There is no non-popping store to memory for XFmode. So if
3758 we need one, follow the store with a load. */
3759 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3760 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3761 else
3762 return "fstp%z0\t%y0";
3763
3764 default:
3765 gcc_unreachable ();
3766 }
3767 }
3768 [(set_attr "type" "fmov")
3769 (set_attr "mode" "DF,XF")])
3770
3771 ;; %%% This seems bad bad news.
3772 ;; This cannot output into an f-reg because there is no way to be sure
3773 ;; of truncating in that case. Otherwise this is just like a simple move
3774 ;; insn. So we pretend we can output to a reg in order to get better
3775 ;; register preferencing, but we really use a stack slot.
3776
3777 ;; Conversion from DFmode to SFmode.
3778
3779 (define_expand "truncdfsf2"
3780 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3781 (float_truncate:SF
3782 (match_operand:DF 1 "nonimmediate_operand" "")))]
3783 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3784 {
3785 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3786 ;
3787 else if (flag_unsafe_math_optimizations)
3788 ;
3789 else
3790 {
3791 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3792 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3793 DONE;
3794 }
3795 })
3796
3797 (define_expand "truncdfsf2_with_temp"
3798 [(parallel [(set (match_operand:SF 0 "" "")
3799 (float_truncate:SF (match_operand:DF 1 "" "")))
3800 (clobber (match_operand:SF 2 "" ""))])]
3801 "")
3802
3803 (define_insn "*truncdfsf_fast_mixed"
3804 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3805 (float_truncate:SF
3806 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3807 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3808 {
3809 switch (which_alternative)
3810 {
3811 case 0:
3812 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3813 return "fstp%z0\t%y0";
3814 else
3815 return "fst%z0\t%y0";
3816 case 1:
3817 return output_387_reg_move (insn, operands);
3818 case 2:
3819 return "cvtsd2ss\t{%1, %0|%0, %1}";
3820 default:
3821 gcc_unreachable ();
3822 }
3823 }
3824 [(set_attr "type" "fmov,fmov,ssecvt")
3825 (set_attr "mode" "SF")])
3826
3827 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3828 ;; because nothing we do here is unsafe.
3829 (define_insn "*truncdfsf_fast_sse"
3830 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3831 (float_truncate:SF
3832 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3833 "TARGET_SSE2 && TARGET_SSE_MATH"
3834 "cvtsd2ss\t{%1, %0|%0, %1}"
3835 [(set_attr "type" "ssecvt")
3836 (set_attr "mode" "SF")])
3837
3838 (define_insn "*truncdfsf_fast_i387"
3839 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3840 (float_truncate:SF
3841 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3842 "TARGET_80387 && flag_unsafe_math_optimizations"
3843 "* return output_387_reg_move (insn, operands);"
3844 [(set_attr "type" "fmov")
3845 (set_attr "mode" "SF")])
3846
3847 (define_insn "*truncdfsf_mixed"
3848 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3849 (float_truncate:SF
3850 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3851 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3852 "TARGET_MIX_SSE_I387"
3853 {
3854 switch (which_alternative)
3855 {
3856 case 0:
3857 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3858 return "fstp%z0\t%y0";
3859 else
3860 return "fst%z0\t%y0";
3861 case 1:
3862 return "#";
3863 case 2:
3864 return "cvtsd2ss\t{%1, %0|%0, %1}";
3865 default:
3866 gcc_unreachable ();
3867 }
3868 }
3869 [(set_attr "type" "fmov,multi,ssecvt")
3870 (set_attr "unit" "*,i387,*")
3871 (set_attr "mode" "SF")])
3872
3873 (define_insn "*truncdfsf_i387"
3874 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3875 (float_truncate:SF
3876 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3877 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3878 "TARGET_80387"
3879 {
3880 switch (which_alternative)
3881 {
3882 case 0:
3883 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3884 return "fstp%z0\t%y0";
3885 else
3886 return "fst%z0\t%y0";
3887 case 1:
3888 return "#";
3889 default:
3890 gcc_unreachable ();
3891 }
3892 }
3893 [(set_attr "type" "fmov,multi")
3894 (set_attr "unit" "*,i387")
3895 (set_attr "mode" "SF")])
3896
3897 (define_insn "*truncdfsf2_i387_1"
3898 [(set (match_operand:SF 0 "memory_operand" "=m")
3899 (float_truncate:SF
3900 (match_operand:DF 1 "register_operand" "f")))]
3901 "TARGET_80387
3902 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3903 && !TARGET_MIX_SSE_I387"
3904 {
3905 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3906 return "fstp%z0\t%y0";
3907 else
3908 return "fst%z0\t%y0";
3909 }
3910 [(set_attr "type" "fmov")
3911 (set_attr "mode" "SF")])
3912
3913 (define_split
3914 [(set (match_operand:SF 0 "register_operand" "")
3915 (float_truncate:SF
3916 (match_operand:DF 1 "fp_register_operand" "")))
3917 (clobber (match_operand 2 "" ""))]
3918 "reload_completed"
3919 [(set (match_dup 2) (match_dup 1))
3920 (set (match_dup 0) (match_dup 2))]
3921 {
3922 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3923 })
3924
3925 ;; Conversion from XFmode to SFmode.
3926
3927 (define_expand "truncxfsf2"
3928 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3929 (float_truncate:SF
3930 (match_operand:XF 1 "register_operand" "")))
3931 (clobber (match_dup 2))])]
3932 "TARGET_80387"
3933 {
3934 if (flag_unsafe_math_optimizations)
3935 {
3936 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3937 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3938 if (reg != operands[0])
3939 emit_move_insn (operands[0], reg);
3940 DONE;
3941 }
3942 else
3943 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3944 })
3945
3946 (define_insn "*truncxfsf2_mixed"
3947 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3948 (float_truncate:SF
3949 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3950 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3951 "TARGET_80387"
3952 {
3953 gcc_assert (!which_alternative);
3954 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3955 return "fstp%z0\t%y0";
3956 else
3957 return "fst%z0\t%y0";
3958 }
3959 [(set_attr "type" "fmov,multi,multi,multi")
3960 (set_attr "unit" "*,i387,i387,i387")
3961 (set_attr "mode" "SF")])
3962
3963 (define_insn "truncxfsf2_i387_noop"
3964 [(set (match_operand:SF 0 "register_operand" "=f")
3965 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3966 "TARGET_80387 && flag_unsafe_math_optimizations"
3967 "* return output_387_reg_move (insn, operands);"
3968 [(set_attr "type" "fmov")
3969 (set_attr "mode" "SF")])
3970
3971 (define_insn "*truncxfsf2_i387"
3972 [(set (match_operand:SF 0 "memory_operand" "=m")
3973 (float_truncate:SF
3974 (match_operand:XF 1 "register_operand" "f")))]
3975 "TARGET_80387"
3976 {
3977 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3978 return "fstp%z0\t%y0";
3979 else
3980 return "fst%z0\t%y0";
3981 }
3982 [(set_attr "type" "fmov")
3983 (set_attr "mode" "SF")])
3984
3985 (define_split
3986 [(set (match_operand:SF 0 "register_operand" "")
3987 (float_truncate:SF
3988 (match_operand:XF 1 "register_operand" "")))
3989 (clobber (match_operand:SF 2 "memory_operand" ""))]
3990 "TARGET_80387 && reload_completed"
3991 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3992 (set (match_dup 0) (match_dup 2))]
3993 "")
3994
3995 (define_split
3996 [(set (match_operand:SF 0 "memory_operand" "")
3997 (float_truncate:SF
3998 (match_operand:XF 1 "register_operand" "")))
3999 (clobber (match_operand:SF 2 "memory_operand" ""))]
4000 "TARGET_80387"
4001 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4002 "")
4003
4004 ;; Conversion from XFmode to DFmode.
4005
4006 (define_expand "truncxfdf2"
4007 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4008 (float_truncate:DF
4009 (match_operand:XF 1 "register_operand" "")))
4010 (clobber (match_dup 2))])]
4011 "TARGET_80387"
4012 {
4013 if (flag_unsafe_math_optimizations)
4014 {
4015 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4016 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4017 if (reg != operands[0])
4018 emit_move_insn (operands[0], reg);
4019 DONE;
4020 }
4021 else
4022 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4023 })
4024
4025 (define_insn "*truncxfdf2_mixed"
4026 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4027 (float_truncate:DF
4028 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4029 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4030 "TARGET_80387"
4031 {
4032 gcc_assert (!which_alternative);
4033 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4034 return "fstp%z0\t%y0";
4035 else
4036 return "fst%z0\t%y0";
4037 }
4038 [(set_attr "type" "fmov,multi,multi,multi")
4039 (set_attr "unit" "*,i387,i387,i387")
4040 (set_attr "mode" "DF")])
4041
4042 (define_insn "truncxfdf2_i387_noop"
4043 [(set (match_operand:DF 0 "register_operand" "=f")
4044 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4045 "TARGET_80387 && flag_unsafe_math_optimizations"
4046 "* return output_387_reg_move (insn, operands);"
4047 [(set_attr "type" "fmov")
4048 (set_attr "mode" "DF")])
4049
4050 (define_insn "*truncxfdf2_i387"
4051 [(set (match_operand:DF 0 "memory_operand" "=m")
4052 (float_truncate:DF
4053 (match_operand:XF 1 "register_operand" "f")))]
4054 "TARGET_80387"
4055 {
4056 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4057 return "fstp%z0\t%y0";
4058 else
4059 return "fst%z0\t%y0";
4060 }
4061 [(set_attr "type" "fmov")
4062 (set_attr "mode" "DF")])
4063
4064 (define_split
4065 [(set (match_operand:DF 0 "register_operand" "")
4066 (float_truncate:DF
4067 (match_operand:XF 1 "register_operand" "")))
4068 (clobber (match_operand:DF 2 "memory_operand" ""))]
4069 "TARGET_80387 && reload_completed"
4070 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4071 (set (match_dup 0) (match_dup 2))]
4072 "")
4073
4074 (define_split
4075 [(set (match_operand:DF 0 "memory_operand" "")
4076 (float_truncate:DF
4077 (match_operand:XF 1 "register_operand" "")))
4078 (clobber (match_operand:DF 2 "memory_operand" ""))]
4079 "TARGET_80387"
4080 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4081 "")
4082 \f
4083 ;; Signed conversion to DImode.
4084
4085 (define_expand "fix_truncxfdi2"
4086 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4087 (fix:DI (match_operand:XF 1 "register_operand" "")))
4088 (clobber (reg:CC FLAGS_REG))])]
4089 "TARGET_80387"
4090 {
4091 if (TARGET_FISTTP)
4092 {
4093 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4094 DONE;
4095 }
4096 })
4097
4098 (define_expand "fix_trunc<mode>di2"
4099 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4100 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4101 (clobber (reg:CC FLAGS_REG))])]
4102 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4103 {
4104 if (TARGET_FISTTP
4105 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4106 {
4107 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4108 DONE;
4109 }
4110 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4111 {
4112 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4113 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4114 if (out != operands[0])
4115 emit_move_insn (operands[0], out);
4116 DONE;
4117 }
4118 })
4119
4120 ;; Signed conversion to SImode.
4121
4122 (define_expand "fix_truncxfsi2"
4123 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4124 (fix:SI (match_operand:XF 1 "register_operand" "")))
4125 (clobber (reg:CC FLAGS_REG))])]
4126 "TARGET_80387"
4127 {
4128 if (TARGET_FISTTP)
4129 {
4130 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4131 DONE;
4132 }
4133 })
4134
4135 (define_expand "fix_trunc<mode>si2"
4136 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4137 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4138 (clobber (reg:CC FLAGS_REG))])]
4139 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4140 {
4141 if (TARGET_FISTTP
4142 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4143 {
4144 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4145 DONE;
4146 }
4147 if (SSE_FLOAT_MODE_P (<MODE>mode))
4148 {
4149 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4150 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4151 if (out != operands[0])
4152 emit_move_insn (operands[0], out);
4153 DONE;
4154 }
4155 })
4156
4157 ;; Signed conversion to HImode.
4158
4159 (define_expand "fix_trunc<mode>hi2"
4160 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4161 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4162 (clobber (reg:CC FLAGS_REG))])]
4163 "TARGET_80387
4164 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4165 {
4166 if (TARGET_FISTTP)
4167 {
4168 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4169 DONE;
4170 }
4171 })
4172
4173 ;; When SSE is available, it is always faster to use it!
4174 (define_insn "fix_truncsfdi_sse"
4175 [(set (match_operand:DI 0 "register_operand" "=r,r")
4176 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4177 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4178 "cvttss2si{q}\t{%1, %0|%0, %1}"
4179 [(set_attr "type" "sseicvt")
4180 (set_attr "mode" "SF")
4181 (set_attr "athlon_decode" "double,vector")])
4182
4183 (define_insn "fix_truncdfdi_sse"
4184 [(set (match_operand:DI 0 "register_operand" "=r,r")
4185 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4186 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4187 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4188 [(set_attr "type" "sseicvt")
4189 (set_attr "mode" "DF")
4190 (set_attr "athlon_decode" "double,vector")])
4191
4192 (define_insn "fix_truncsfsi_sse"
4193 [(set (match_operand:SI 0 "register_operand" "=r,r")
4194 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4195 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4196 "cvttss2si\t{%1, %0|%0, %1}"
4197 [(set_attr "type" "sseicvt")
4198 (set_attr "mode" "DF")
4199 (set_attr "athlon_decode" "double,vector")])
4200
4201 (define_insn "fix_truncdfsi_sse"
4202 [(set (match_operand:SI 0 "register_operand" "=r,r")
4203 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4204 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4205 "cvttsd2si\t{%1, %0|%0, %1}"
4206 [(set_attr "type" "sseicvt")
4207 (set_attr "mode" "DF")
4208 (set_attr "athlon_decode" "double,vector")])
4209
4210 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4211 (define_peephole2
4212 [(set (match_operand:DF 0 "register_operand" "")
4213 (match_operand:DF 1 "memory_operand" ""))
4214 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4215 (fix:SSEMODEI24 (match_dup 0)))]
4216 "!TARGET_K8
4217 && peep2_reg_dead_p (2, operands[0])"
4218 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4219 "")
4220
4221 (define_peephole2
4222 [(set (match_operand:SF 0 "register_operand" "")
4223 (match_operand:SF 1 "memory_operand" ""))
4224 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4225 (fix:SSEMODEI24 (match_dup 0)))]
4226 "!TARGET_K8
4227 && peep2_reg_dead_p (2, operands[0])"
4228 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4229 "")
4230
4231 ;; Avoid vector decoded forms of the instruction.
4232 (define_peephole2
4233 [(match_scratch:DF 2 "Y")
4234 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4235 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4236 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4237 [(set (match_dup 2) (match_dup 1))
4238 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4239 "")
4240
4241 (define_peephole2
4242 [(match_scratch:SF 2 "x")
4243 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4244 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4245 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4246 [(set (match_dup 2) (match_dup 1))
4247 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4248 "")
4249
4250 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4251 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4252 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4253 "TARGET_FISTTP
4254 && FLOAT_MODE_P (GET_MODE (operands[1]))
4255 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4256 && (TARGET_64BIT || <MODE>mode != DImode))
4257 && TARGET_SSE_MATH)
4258 && !(reload_completed || reload_in_progress)"
4259 "#"
4260 "&& 1"
4261 [(const_int 0)]
4262 {
4263 if (memory_operand (operands[0], VOIDmode))
4264 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4265 else
4266 {
4267 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4268 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4269 operands[1],
4270 operands[2]));
4271 }
4272 DONE;
4273 }
4274 [(set_attr "type" "fisttp")
4275 (set_attr "mode" "<MODE>")])
4276
4277 (define_insn "fix_trunc<mode>_i387_fisttp"
4278 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4279 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4280 (clobber (match_scratch:XF 2 "=&1f"))]
4281 "TARGET_FISTTP
4282 && FLOAT_MODE_P (GET_MODE (operands[1]))
4283 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4284 && (TARGET_64BIT || <MODE>mode != DImode))
4285 && TARGET_SSE_MATH)"
4286 "* return output_fix_trunc (insn, operands, 1);"
4287 [(set_attr "type" "fisttp")
4288 (set_attr "mode" "<MODE>")])
4289
4290 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4291 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4292 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4293 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4294 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4295 "TARGET_FISTTP
4296 && FLOAT_MODE_P (GET_MODE (operands[1]))
4297 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4298 && (TARGET_64BIT || <MODE>mode != DImode))
4299 && TARGET_SSE_MATH)"
4300 "#"
4301 [(set_attr "type" "fisttp")
4302 (set_attr "mode" "<MODE>")])
4303
4304 (define_split
4305 [(set (match_operand:X87MODEI 0 "register_operand" "")
4306 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4307 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4308 (clobber (match_scratch 3 ""))]
4309 "reload_completed"
4310 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4311 (clobber (match_dup 3))])
4312 (set (match_dup 0) (match_dup 2))]
4313 "")
4314
4315 (define_split
4316 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4317 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4318 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4319 (clobber (match_scratch 3 ""))]
4320 "reload_completed"
4321 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4322 (clobber (match_dup 3))])]
4323 "")
4324
4325 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4326 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4327 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4328 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4329 ;; function in i386.c.
4330 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4331 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4332 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4333 (clobber (reg:CC FLAGS_REG))]
4334 "TARGET_80387 && !TARGET_FISTTP
4335 && FLOAT_MODE_P (GET_MODE (operands[1]))
4336 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4337 && (TARGET_64BIT || <MODE>mode != DImode))
4338 && !(reload_completed || reload_in_progress)"
4339 "#"
4340 "&& 1"
4341 [(const_int 0)]
4342 {
4343 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4344
4345 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4346 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4347 if (memory_operand (operands[0], VOIDmode))
4348 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4349 operands[2], operands[3]));
4350 else
4351 {
4352 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4353 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4354 operands[2], operands[3],
4355 operands[4]));
4356 }
4357 DONE;
4358 }
4359 [(set_attr "type" "fistp")
4360 (set_attr "i387_cw" "trunc")
4361 (set_attr "mode" "<MODE>")])
4362
4363 (define_insn "fix_truncdi_i387"
4364 [(set (match_operand:DI 0 "memory_operand" "=m")
4365 (fix:DI (match_operand 1 "register_operand" "f")))
4366 (use (match_operand:HI 2 "memory_operand" "m"))
4367 (use (match_operand:HI 3 "memory_operand" "m"))
4368 (clobber (match_scratch:XF 4 "=&1f"))]
4369 "TARGET_80387 && !TARGET_FISTTP
4370 && FLOAT_MODE_P (GET_MODE (operands[1]))
4371 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4372 "* return output_fix_trunc (insn, operands, 0);"
4373 [(set_attr "type" "fistp")
4374 (set_attr "i387_cw" "trunc")
4375 (set_attr "mode" "DI")])
4376
4377 (define_insn "fix_truncdi_i387_with_temp"
4378 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4379 (fix:DI (match_operand 1 "register_operand" "f,f")))
4380 (use (match_operand:HI 2 "memory_operand" "m,m"))
4381 (use (match_operand:HI 3 "memory_operand" "m,m"))
4382 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4383 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4384 "TARGET_80387 && !TARGET_FISTTP
4385 && FLOAT_MODE_P (GET_MODE (operands[1]))
4386 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4387 "#"
4388 [(set_attr "type" "fistp")
4389 (set_attr "i387_cw" "trunc")
4390 (set_attr "mode" "DI")])
4391
4392 (define_split
4393 [(set (match_operand:DI 0 "register_operand" "")
4394 (fix:DI (match_operand 1 "register_operand" "")))
4395 (use (match_operand:HI 2 "memory_operand" ""))
4396 (use (match_operand:HI 3 "memory_operand" ""))
4397 (clobber (match_operand:DI 4 "memory_operand" ""))
4398 (clobber (match_scratch 5 ""))]
4399 "reload_completed"
4400 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4401 (use (match_dup 2))
4402 (use (match_dup 3))
4403 (clobber (match_dup 5))])
4404 (set (match_dup 0) (match_dup 4))]
4405 "")
4406
4407 (define_split
4408 [(set (match_operand:DI 0 "memory_operand" "")
4409 (fix:DI (match_operand 1 "register_operand" "")))
4410 (use (match_operand:HI 2 "memory_operand" ""))
4411 (use (match_operand:HI 3 "memory_operand" ""))
4412 (clobber (match_operand:DI 4 "memory_operand" ""))
4413 (clobber (match_scratch 5 ""))]
4414 "reload_completed"
4415 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4416 (use (match_dup 2))
4417 (use (match_dup 3))
4418 (clobber (match_dup 5))])]
4419 "")
4420
4421 (define_insn "fix_trunc<mode>_i387"
4422 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4423 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4424 (use (match_operand:HI 2 "memory_operand" "m"))
4425 (use (match_operand:HI 3 "memory_operand" "m"))]
4426 "TARGET_80387 && !TARGET_FISTTP
4427 && FLOAT_MODE_P (GET_MODE (operands[1]))
4428 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4429 "* return output_fix_trunc (insn, operands, 0);"
4430 [(set_attr "type" "fistp")
4431 (set_attr "i387_cw" "trunc")
4432 (set_attr "mode" "<MODE>")])
4433
4434 (define_insn "fix_trunc<mode>_i387_with_temp"
4435 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4436 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4437 (use (match_operand:HI 2 "memory_operand" "m,m"))
4438 (use (match_operand:HI 3 "memory_operand" "m,m"))
4439 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4440 "TARGET_80387 && !TARGET_FISTTP
4441 && FLOAT_MODE_P (GET_MODE (operands[1]))
4442 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4443 "#"
4444 [(set_attr "type" "fistp")
4445 (set_attr "i387_cw" "trunc")
4446 (set_attr "mode" "<MODE>")])
4447
4448 (define_split
4449 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4450 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4451 (use (match_operand:HI 2 "memory_operand" ""))
4452 (use (match_operand:HI 3 "memory_operand" ""))
4453 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4454 "reload_completed"
4455 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4456 (use (match_dup 2))
4457 (use (match_dup 3))])
4458 (set (match_dup 0) (match_dup 4))]
4459 "")
4460
4461 (define_split
4462 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4463 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4464 (use (match_operand:HI 2 "memory_operand" ""))
4465 (use (match_operand:HI 3 "memory_operand" ""))
4466 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4467 "reload_completed"
4468 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4469 (use (match_dup 2))
4470 (use (match_dup 3))])]
4471 "")
4472
4473 (define_insn "x86_fnstcw_1"
4474 [(set (match_operand:HI 0 "memory_operand" "=m")
4475 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4476 "TARGET_80387"
4477 "fnstcw\t%0"
4478 [(set_attr "length" "2")
4479 (set_attr "mode" "HI")
4480 (set_attr "unit" "i387")])
4481
4482 (define_insn "x86_fldcw_1"
4483 [(set (reg:HI FPCR_REG)
4484 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4485 "TARGET_80387"
4486 "fldcw\t%0"
4487 [(set_attr "length" "2")
4488 (set_attr "mode" "HI")
4489 (set_attr "unit" "i387")
4490 (set_attr "athlon_decode" "vector")])
4491 \f
4492 ;; Conversion between fixed point and floating point.
4493
4494 ;; Even though we only accept memory inputs, the backend _really_
4495 ;; wants to be able to do this between registers.
4496
4497 (define_expand "floathisf2"
4498 [(set (match_operand:SF 0 "register_operand" "")
4499 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4500 "TARGET_80387 || TARGET_SSE_MATH"
4501 {
4502 if (TARGET_SSE_MATH)
4503 {
4504 emit_insn (gen_floatsisf2 (operands[0],
4505 convert_to_mode (SImode, operands[1], 0)));
4506 DONE;
4507 }
4508 })
4509
4510 (define_insn "*floathisf2_i387"
4511 [(set (match_operand:SF 0 "register_operand" "=f,f")
4512 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4513 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
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 "floatsisf2"
4523 [(set (match_operand:SF 0 "register_operand" "")
4524 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4525 "TARGET_80387 || TARGET_SSE_MATH"
4526 "")
4527
4528 (define_insn "*floatsisf2_mixed"
4529 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4530 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4531 "TARGET_MIX_SSE_I387"
4532 "@
4533 fild%z1\t%1
4534 #
4535 cvtsi2ss\t{%1, %0|%0, %1}
4536 cvtsi2ss\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 "*floatsisf2_sse"
4544 [(set (match_operand:SF 0 "register_operand" "=x,x")
4545 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4546 "TARGET_SSE_MATH"
4547 "cvtsi2ss\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 "*floatsisf2_i387"
4554 [(set (match_operand:SF 0 "register_operand" "=f,f")
4555 (float:SF (match_operand:SI 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 "floatdisf2"
4566 [(set (match_operand:SF 0 "register_operand" "")
4567 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4568 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4569 "")
4570
4571 (define_insn "*floatdisf2_mixed"
4572 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4573 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4574 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4575 "@
4576 fild%z1\t%1
4577 #
4578 cvtsi2ss{q}\t{%1, %0|%0, %1}
4579 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4580 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4581 (set_attr "mode" "SF")
4582 (set_attr "unit" "*,i387,*,*")
4583 (set_attr "athlon_decode" "*,*,vector,double")
4584 (set_attr "fp_int_src" "true")])
4585
4586 (define_insn "*floatdisf2_sse"
4587 [(set (match_operand:SF 0 "register_operand" "=x,x")
4588 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4589 "TARGET_64BIT && TARGET_SSE_MATH"
4590 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4591 [(set_attr "type" "sseicvt")
4592 (set_attr "mode" "SF")
4593 (set_attr "athlon_decode" "vector,double")
4594 (set_attr "fp_int_src" "true")])
4595
4596 (define_insn "*floatdisf2_i387"
4597 [(set (match_operand:SF 0 "register_operand" "=f,f")
4598 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4599 "TARGET_80387"
4600 "@
4601 fild%z1\t%1
4602 #"
4603 [(set_attr "type" "fmov,multi")
4604 (set_attr "mode" "SF")
4605 (set_attr "unit" "*,i387")
4606 (set_attr "fp_int_src" "true")])
4607
4608 (define_expand "floathidf2"
4609 [(set (match_operand:DF 0 "register_operand" "")
4610 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4611 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4612 {
4613 if (TARGET_SSE2 && TARGET_SSE_MATH)
4614 {
4615 emit_insn (gen_floatsidf2 (operands[0],
4616 convert_to_mode (SImode, operands[1], 0)));
4617 DONE;
4618 }
4619 })
4620
4621 (define_insn "*floathidf2_i387"
4622 [(set (match_operand:DF 0 "register_operand" "=f,f")
4623 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4624 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
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 "floatsidf2"
4634 [(set (match_operand:DF 0 "register_operand" "")
4635 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4636 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4637 "")
4638
4639 (define_insn "*floatsidf2_mixed"
4640 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4641 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4642 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4643 "@
4644 fild%z1\t%1
4645 #
4646 cvtsi2sd\t{%1, %0|%0, %1}
4647 cvtsi2sd\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 "*floatsidf2_sse"
4655 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4656 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4657 "TARGET_SSE2 && TARGET_SSE_MATH"
4658 "cvtsi2sd\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 "*floatsidf2_i387"
4665 [(set (match_operand:DF 0 "register_operand" "=f,f")
4666 (float:DF (match_operand:SI 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_expand "floatdidf2"
4677 [(set (match_operand:DF 0 "register_operand" "")
4678 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4679 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4680 "")
4681
4682 (define_insn "*floatdidf2_mixed"
4683 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4684 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4685 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4686 "@
4687 fild%z1\t%1
4688 #
4689 cvtsi2sd{q}\t{%1, %0|%0, %1}
4690 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4691 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4692 (set_attr "mode" "DF")
4693 (set_attr "unit" "*,i387,*,*")
4694 (set_attr "athlon_decode" "*,*,double,direct")
4695 (set_attr "fp_int_src" "true")])
4696
4697 (define_insn "*floatdidf2_sse"
4698 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4699 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4700 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4701 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4702 [(set_attr "type" "sseicvt")
4703 (set_attr "mode" "DF")
4704 (set_attr "athlon_decode" "double,direct")
4705 (set_attr "fp_int_src" "true")])
4706
4707 (define_insn "*floatdidf2_i387"
4708 [(set (match_operand:DF 0 "register_operand" "=f,f")
4709 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4710 "TARGET_80387"
4711 "@
4712 fild%z1\t%1
4713 #"
4714 [(set_attr "type" "fmov,multi")
4715 (set_attr "mode" "DF")
4716 (set_attr "unit" "*,i387")
4717 (set_attr "fp_int_src" "true")])
4718
4719 (define_insn "floathixf2"
4720 [(set (match_operand:XF 0 "register_operand" "=f,f")
4721 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4722 "TARGET_80387"
4723 "@
4724 fild%z1\t%1
4725 #"
4726 [(set_attr "type" "fmov,multi")
4727 (set_attr "mode" "XF")
4728 (set_attr "unit" "*,i387")
4729 (set_attr "fp_int_src" "true")])
4730
4731 (define_insn "floatsixf2"
4732 [(set (match_operand:XF 0 "register_operand" "=f,f")
4733 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4734 "TARGET_80387"
4735 "@
4736 fild%z1\t%1
4737 #"
4738 [(set_attr "type" "fmov,multi")
4739 (set_attr "mode" "XF")
4740 (set_attr "unit" "*,i387")
4741 (set_attr "fp_int_src" "true")])
4742
4743 (define_insn "floatdixf2"
4744 [(set (match_operand:XF 0 "register_operand" "=f,f")
4745 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4746 "TARGET_80387"
4747 "@
4748 fild%z1\t%1
4749 #"
4750 [(set_attr "type" "fmov,multi")
4751 (set_attr "mode" "XF")
4752 (set_attr "unit" "*,i387")
4753 (set_attr "fp_int_src" "true")])
4754
4755 ;; %%% Kill these when reload knows how to do it.
4756 (define_split
4757 [(set (match_operand 0 "fp_register_operand" "")
4758 (float (match_operand 1 "register_operand" "")))]
4759 "reload_completed
4760 && TARGET_80387
4761 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4762 [(const_int 0)]
4763 {
4764 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4765 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4766 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4767 ix86_free_from_memory (GET_MODE (operands[1]));
4768 DONE;
4769 })
4770
4771 (define_expand "floatunssisf2"
4772 [(use (match_operand:SF 0 "register_operand" ""))
4773 (use (match_operand:SI 1 "register_operand" ""))]
4774 "!TARGET_64BIT && TARGET_SSE_MATH"
4775 "x86_emit_floatuns (operands); DONE;")
4776
4777 (define_expand "floatunsdisf2"
4778 [(use (match_operand:SF 0 "register_operand" ""))
4779 (use (match_operand:DI 1 "register_operand" ""))]
4780 "TARGET_64BIT && TARGET_SSE_MATH"
4781 "x86_emit_floatuns (operands); DONE;")
4782
4783 (define_expand "floatunsdidf2"
4784 [(use (match_operand:DF 0 "register_operand" ""))
4785 (use (match_operand:DI 1 "register_operand" ""))]
4786 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4787 "x86_emit_floatuns (operands); DONE;")
4788 \f
4789 ;; SSE extract/set expanders
4790
4791 \f
4792 ;; Add instructions
4793
4794 ;; %%% splits for addditi3
4795
4796 (define_expand "addti3"
4797 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4798 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4799 (match_operand:TI 2 "x86_64_general_operand" "")))
4800 (clobber (reg:CC FLAGS_REG))]
4801 "TARGET_64BIT"
4802 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4803
4804 (define_insn "*addti3_1"
4805 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4806 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4807 (match_operand:TI 2 "general_operand" "roiF,riF")))
4808 (clobber (reg:CC FLAGS_REG))]
4809 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4810 "#")
4811
4812 (define_split
4813 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4814 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4815 (match_operand:TI 2 "general_operand" "")))
4816 (clobber (reg:CC FLAGS_REG))]
4817 "TARGET_64BIT && reload_completed"
4818 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4819 UNSPEC_ADD_CARRY))
4820 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4821 (parallel [(set (match_dup 3)
4822 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4823 (match_dup 4))
4824 (match_dup 5)))
4825 (clobber (reg:CC FLAGS_REG))])]
4826 "split_ti (operands+0, 1, operands+0, operands+3);
4827 split_ti (operands+1, 1, operands+1, operands+4);
4828 split_ti (operands+2, 1, operands+2, operands+5);")
4829
4830 ;; %%% splits for addsidi3
4831 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4832 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4833 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4834
4835 (define_expand "adddi3"
4836 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4837 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4838 (match_operand:DI 2 "x86_64_general_operand" "")))
4839 (clobber (reg:CC FLAGS_REG))]
4840 ""
4841 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4842
4843 (define_insn "*adddi3_1"
4844 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4845 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4846 (match_operand:DI 2 "general_operand" "roiF,riF")))
4847 (clobber (reg:CC FLAGS_REG))]
4848 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4849 "#")
4850
4851 (define_split
4852 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4853 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4854 (match_operand:DI 2 "general_operand" "")))
4855 (clobber (reg:CC FLAGS_REG))]
4856 "!TARGET_64BIT && reload_completed"
4857 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4858 UNSPEC_ADD_CARRY))
4859 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4860 (parallel [(set (match_dup 3)
4861 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4862 (match_dup 4))
4863 (match_dup 5)))
4864 (clobber (reg:CC FLAGS_REG))])]
4865 "split_di (operands+0, 1, operands+0, operands+3);
4866 split_di (operands+1, 1, operands+1, operands+4);
4867 split_di (operands+2, 1, operands+2, operands+5);")
4868
4869 (define_insn "adddi3_carry_rex64"
4870 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4871 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4872 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4873 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4874 (clobber (reg:CC FLAGS_REG))]
4875 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4876 "adc{q}\t{%2, %0|%0, %2}"
4877 [(set_attr "type" "alu")
4878 (set_attr "pent_pair" "pu")
4879 (set_attr "mode" "DI")])
4880
4881 (define_insn "*adddi3_cc_rex64"
4882 [(set (reg:CC FLAGS_REG)
4883 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4884 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4885 UNSPEC_ADD_CARRY))
4886 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4887 (plus:DI (match_dup 1) (match_dup 2)))]
4888 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4889 "add{q}\t{%2, %0|%0, %2}"
4890 [(set_attr "type" "alu")
4891 (set_attr "mode" "DI")])
4892
4893 (define_insn "addqi3_carry"
4894 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4895 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4896 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4897 (match_operand:QI 2 "general_operand" "qi,qm")))
4898 (clobber (reg:CC FLAGS_REG))]
4899 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4900 "adc{b}\t{%2, %0|%0, %2}"
4901 [(set_attr "type" "alu")
4902 (set_attr "pent_pair" "pu")
4903 (set_attr "mode" "QI")])
4904
4905 (define_insn "addhi3_carry"
4906 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4907 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4908 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4909 (match_operand:HI 2 "general_operand" "ri,rm")))
4910 (clobber (reg:CC FLAGS_REG))]
4911 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4912 "adc{w}\t{%2, %0|%0, %2}"
4913 [(set_attr "type" "alu")
4914 (set_attr "pent_pair" "pu")
4915 (set_attr "mode" "HI")])
4916
4917 (define_insn "addsi3_carry"
4918 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4919 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4920 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4921 (match_operand:SI 2 "general_operand" "ri,rm")))
4922 (clobber (reg:CC FLAGS_REG))]
4923 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4924 "adc{l}\t{%2, %0|%0, %2}"
4925 [(set_attr "type" "alu")
4926 (set_attr "pent_pair" "pu")
4927 (set_attr "mode" "SI")])
4928
4929 (define_insn "*addsi3_carry_zext"
4930 [(set (match_operand:DI 0 "register_operand" "=r")
4931 (zero_extend:DI
4932 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4933 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4934 (match_operand:SI 2 "general_operand" "rim"))))
4935 (clobber (reg:CC FLAGS_REG))]
4936 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4937 "adc{l}\t{%2, %k0|%k0, %2}"
4938 [(set_attr "type" "alu")
4939 (set_attr "pent_pair" "pu")
4940 (set_attr "mode" "SI")])
4941
4942 (define_insn "*addsi3_cc"
4943 [(set (reg:CC FLAGS_REG)
4944 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4945 (match_operand:SI 2 "general_operand" "ri,rm")]
4946 UNSPEC_ADD_CARRY))
4947 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4948 (plus:SI (match_dup 1) (match_dup 2)))]
4949 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4950 "add{l}\t{%2, %0|%0, %2}"
4951 [(set_attr "type" "alu")
4952 (set_attr "mode" "SI")])
4953
4954 (define_insn "addqi3_cc"
4955 [(set (reg:CC FLAGS_REG)
4956 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4957 (match_operand:QI 2 "general_operand" "qi,qm")]
4958 UNSPEC_ADD_CARRY))
4959 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4960 (plus:QI (match_dup 1) (match_dup 2)))]
4961 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4962 "add{b}\t{%2, %0|%0, %2}"
4963 [(set_attr "type" "alu")
4964 (set_attr "mode" "QI")])
4965
4966 (define_expand "addsi3"
4967 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4968 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4969 (match_operand:SI 2 "general_operand" "")))
4970 (clobber (reg:CC FLAGS_REG))])]
4971 ""
4972 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4973
4974 (define_insn "*lea_1"
4975 [(set (match_operand:SI 0 "register_operand" "=r")
4976 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4977 "!TARGET_64BIT"
4978 "lea{l}\t{%a1, %0|%0, %a1}"
4979 [(set_attr "type" "lea")
4980 (set_attr "mode" "SI")])
4981
4982 (define_insn "*lea_1_rex64"
4983 [(set (match_operand:SI 0 "register_operand" "=r")
4984 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4985 "TARGET_64BIT"
4986 "lea{l}\t{%a1, %0|%0, %a1}"
4987 [(set_attr "type" "lea")
4988 (set_attr "mode" "SI")])
4989
4990 (define_insn "*lea_1_zext"
4991 [(set (match_operand:DI 0 "register_operand" "=r")
4992 (zero_extend:DI
4993 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4994 "TARGET_64BIT"
4995 "lea{l}\t{%a1, %k0|%k0, %a1}"
4996 [(set_attr "type" "lea")
4997 (set_attr "mode" "SI")])
4998
4999 (define_insn "*lea_2_rex64"
5000 [(set (match_operand:DI 0 "register_operand" "=r")
5001 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5002 "TARGET_64BIT"
5003 "lea{q}\t{%a1, %0|%0, %a1}"
5004 [(set_attr "type" "lea")
5005 (set_attr "mode" "DI")])
5006
5007 ;; The lea patterns for non-Pmodes needs to be matched by several
5008 ;; insns converted to real lea by splitters.
5009
5010 (define_insn_and_split "*lea_general_1"
5011 [(set (match_operand 0 "register_operand" "=r")
5012 (plus (plus (match_operand 1 "index_register_operand" "l")
5013 (match_operand 2 "register_operand" "r"))
5014 (match_operand 3 "immediate_operand" "i")))]
5015 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5016 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5017 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5018 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5019 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5020 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5021 || GET_MODE (operands[3]) == VOIDmode)"
5022 "#"
5023 "&& reload_completed"
5024 [(const_int 0)]
5025 {
5026 rtx pat;
5027 operands[0] = gen_lowpart (SImode, operands[0]);
5028 operands[1] = gen_lowpart (Pmode, operands[1]);
5029 operands[2] = gen_lowpart (Pmode, operands[2]);
5030 operands[3] = gen_lowpart (Pmode, operands[3]);
5031 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5032 operands[3]);
5033 if (Pmode != SImode)
5034 pat = gen_rtx_SUBREG (SImode, pat, 0);
5035 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5036 DONE;
5037 }
5038 [(set_attr "type" "lea")
5039 (set_attr "mode" "SI")])
5040
5041 (define_insn_and_split "*lea_general_1_zext"
5042 [(set (match_operand:DI 0 "register_operand" "=r")
5043 (zero_extend:DI
5044 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5045 (match_operand:SI 2 "register_operand" "r"))
5046 (match_operand:SI 3 "immediate_operand" "i"))))]
5047 "TARGET_64BIT"
5048 "#"
5049 "&& reload_completed"
5050 [(set (match_dup 0)
5051 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5052 (match_dup 2))
5053 (match_dup 3)) 0)))]
5054 {
5055 operands[1] = gen_lowpart (Pmode, operands[1]);
5056 operands[2] = gen_lowpart (Pmode, operands[2]);
5057 operands[3] = gen_lowpart (Pmode, operands[3]);
5058 }
5059 [(set_attr "type" "lea")
5060 (set_attr "mode" "SI")])
5061
5062 (define_insn_and_split "*lea_general_2"
5063 [(set (match_operand 0 "register_operand" "=r")
5064 (plus (mult (match_operand 1 "index_register_operand" "l")
5065 (match_operand 2 "const248_operand" "i"))
5066 (match_operand 3 "nonmemory_operand" "ri")))]
5067 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5068 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5069 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5070 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5071 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5072 || GET_MODE (operands[3]) == VOIDmode)"
5073 "#"
5074 "&& reload_completed"
5075 [(const_int 0)]
5076 {
5077 rtx pat;
5078 operands[0] = gen_lowpart (SImode, operands[0]);
5079 operands[1] = gen_lowpart (Pmode, operands[1]);
5080 operands[3] = gen_lowpart (Pmode, operands[3]);
5081 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5082 operands[3]);
5083 if (Pmode != SImode)
5084 pat = gen_rtx_SUBREG (SImode, pat, 0);
5085 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5086 DONE;
5087 }
5088 [(set_attr "type" "lea")
5089 (set_attr "mode" "SI")])
5090
5091 (define_insn_and_split "*lea_general_2_zext"
5092 [(set (match_operand:DI 0 "register_operand" "=r")
5093 (zero_extend:DI
5094 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5095 (match_operand:SI 2 "const248_operand" "n"))
5096 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5097 "TARGET_64BIT"
5098 "#"
5099 "&& reload_completed"
5100 [(set (match_dup 0)
5101 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5102 (match_dup 2))
5103 (match_dup 3)) 0)))]
5104 {
5105 operands[1] = gen_lowpart (Pmode, operands[1]);
5106 operands[3] = gen_lowpart (Pmode, operands[3]);
5107 }
5108 [(set_attr "type" "lea")
5109 (set_attr "mode" "SI")])
5110
5111 (define_insn_and_split "*lea_general_3"
5112 [(set (match_operand 0 "register_operand" "=r")
5113 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5114 (match_operand 2 "const248_operand" "i"))
5115 (match_operand 3 "register_operand" "r"))
5116 (match_operand 4 "immediate_operand" "i")))]
5117 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5118 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5119 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5120 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5121 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5122 "#"
5123 "&& reload_completed"
5124 [(const_int 0)]
5125 {
5126 rtx pat;
5127 operands[0] = gen_lowpart (SImode, operands[0]);
5128 operands[1] = gen_lowpart (Pmode, operands[1]);
5129 operands[3] = gen_lowpart (Pmode, operands[3]);
5130 operands[4] = gen_lowpart (Pmode, operands[4]);
5131 pat = gen_rtx_PLUS (Pmode,
5132 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5133 operands[2]),
5134 operands[3]),
5135 operands[4]);
5136 if (Pmode != SImode)
5137 pat = gen_rtx_SUBREG (SImode, pat, 0);
5138 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5139 DONE;
5140 }
5141 [(set_attr "type" "lea")
5142 (set_attr "mode" "SI")])
5143
5144 (define_insn_and_split "*lea_general_3_zext"
5145 [(set (match_operand:DI 0 "register_operand" "=r")
5146 (zero_extend:DI
5147 (plus:SI (plus:SI (mult:SI
5148 (match_operand:SI 1 "index_register_operand" "l")
5149 (match_operand:SI 2 "const248_operand" "n"))
5150 (match_operand:SI 3 "register_operand" "r"))
5151 (match_operand:SI 4 "immediate_operand" "i"))))]
5152 "TARGET_64BIT"
5153 "#"
5154 "&& reload_completed"
5155 [(set (match_dup 0)
5156 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5157 (match_dup 2))
5158 (match_dup 3))
5159 (match_dup 4)) 0)))]
5160 {
5161 operands[1] = gen_lowpart (Pmode, operands[1]);
5162 operands[3] = gen_lowpart (Pmode, operands[3]);
5163 operands[4] = gen_lowpart (Pmode, operands[4]);
5164 }
5165 [(set_attr "type" "lea")
5166 (set_attr "mode" "SI")])
5167
5168 (define_insn "*adddi_1_rex64"
5169 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5170 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5171 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5172 (clobber (reg:CC FLAGS_REG))]
5173 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5174 {
5175 switch (get_attr_type (insn))
5176 {
5177 case TYPE_LEA:
5178 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5179 return "lea{q}\t{%a2, %0|%0, %a2}";
5180
5181 case TYPE_INCDEC:
5182 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5183 if (operands[2] == const1_rtx)
5184 return "inc{q}\t%0";
5185 else
5186 {
5187 gcc_assert (operands[2] == constm1_rtx);
5188 return "dec{q}\t%0";
5189 }
5190
5191 default:
5192 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5193
5194 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5195 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5196 if (CONST_INT_P (operands[2])
5197 /* Avoid overflows. */
5198 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5199 && (INTVAL (operands[2]) == 128
5200 || (INTVAL (operands[2]) < 0
5201 && INTVAL (operands[2]) != -128)))
5202 {
5203 operands[2] = GEN_INT (-INTVAL (operands[2]));
5204 return "sub{q}\t{%2, %0|%0, %2}";
5205 }
5206 return "add{q}\t{%2, %0|%0, %2}";
5207 }
5208 }
5209 [(set (attr "type")
5210 (cond [(eq_attr "alternative" "2")
5211 (const_string "lea")
5212 ; Current assemblers are broken and do not allow @GOTOFF in
5213 ; ought but a memory context.
5214 (match_operand:DI 2 "pic_symbolic_operand" "")
5215 (const_string "lea")
5216 (match_operand:DI 2 "incdec_operand" "")
5217 (const_string "incdec")
5218 ]
5219 (const_string "alu")))
5220 (set_attr "mode" "DI")])
5221
5222 ;; Convert lea to the lea pattern to avoid flags dependency.
5223 (define_split
5224 [(set (match_operand:DI 0 "register_operand" "")
5225 (plus:DI (match_operand:DI 1 "register_operand" "")
5226 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5227 (clobber (reg:CC FLAGS_REG))]
5228 "TARGET_64BIT && reload_completed
5229 && true_regnum (operands[0]) != true_regnum (operands[1])"
5230 [(set (match_dup 0)
5231 (plus:DI (match_dup 1)
5232 (match_dup 2)))]
5233 "")
5234
5235 (define_insn "*adddi_2_rex64"
5236 [(set (reg FLAGS_REG)
5237 (compare
5238 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5239 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5240 (const_int 0)))
5241 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5242 (plus:DI (match_dup 1) (match_dup 2)))]
5243 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5244 && ix86_binary_operator_ok (PLUS, DImode, operands)
5245 /* Current assemblers are broken and do not allow @GOTOFF in
5246 ought but a memory context. */
5247 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5248 {
5249 switch (get_attr_type (insn))
5250 {
5251 case TYPE_INCDEC:
5252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5253 if (operands[2] == const1_rtx)
5254 return "inc{q}\t%0";
5255 else
5256 {
5257 gcc_assert (operands[2] == constm1_rtx);
5258 return "dec{q}\t%0";
5259 }
5260
5261 default:
5262 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5263 /* ???? We ought to handle there the 32bit case too
5264 - do we need new constraint? */
5265 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5266 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5267 if (CONST_INT_P (operands[2])
5268 /* Avoid overflows. */
5269 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5270 && (INTVAL (operands[2]) == 128
5271 || (INTVAL (operands[2]) < 0
5272 && INTVAL (operands[2]) != -128)))
5273 {
5274 operands[2] = GEN_INT (-INTVAL (operands[2]));
5275 return "sub{q}\t{%2, %0|%0, %2}";
5276 }
5277 return "add{q}\t{%2, %0|%0, %2}";
5278 }
5279 }
5280 [(set (attr "type")
5281 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5282 (const_string "incdec")
5283 (const_string "alu")))
5284 (set_attr "mode" "DI")])
5285
5286 (define_insn "*adddi_3_rex64"
5287 [(set (reg FLAGS_REG)
5288 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5289 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5290 (clobber (match_scratch:DI 0 "=r"))]
5291 "TARGET_64BIT
5292 && ix86_match_ccmode (insn, CCZmode)
5293 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5294 /* Current assemblers are broken and do not allow @GOTOFF in
5295 ought but a memory context. */
5296 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5297 {
5298 switch (get_attr_type (insn))
5299 {
5300 case TYPE_INCDEC:
5301 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5302 if (operands[2] == const1_rtx)
5303 return "inc{q}\t%0";
5304 else
5305 {
5306 gcc_assert (operands[2] == constm1_rtx);
5307 return "dec{q}\t%0";
5308 }
5309
5310 default:
5311 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5312 /* ???? We ought to handle there the 32bit case too
5313 - do we need new constraint? */
5314 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5315 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5316 if (CONST_INT_P (operands[2])
5317 /* Avoid overflows. */
5318 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5319 && (INTVAL (operands[2]) == 128
5320 || (INTVAL (operands[2]) < 0
5321 && INTVAL (operands[2]) != -128)))
5322 {
5323 operands[2] = GEN_INT (-INTVAL (operands[2]));
5324 return "sub{q}\t{%2, %0|%0, %2}";
5325 }
5326 return "add{q}\t{%2, %0|%0, %2}";
5327 }
5328 }
5329 [(set (attr "type")
5330 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5331 (const_string "incdec")
5332 (const_string "alu")))
5333 (set_attr "mode" "DI")])
5334
5335 ; For comparisons against 1, -1 and 128, we may generate better code
5336 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5337 ; is matched then. We can't accept general immediate, because for
5338 ; case of overflows, the result is messed up.
5339 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5340 ; when negated.
5341 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5342 ; only for comparisons not depending on it.
5343 (define_insn "*adddi_4_rex64"
5344 [(set (reg FLAGS_REG)
5345 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5346 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5347 (clobber (match_scratch:DI 0 "=rm"))]
5348 "TARGET_64BIT
5349 && ix86_match_ccmode (insn, CCGCmode)"
5350 {
5351 switch (get_attr_type (insn))
5352 {
5353 case TYPE_INCDEC:
5354 if (operands[2] == constm1_rtx)
5355 return "inc{q}\t%0";
5356 else
5357 {
5358 gcc_assert (operands[2] == const1_rtx);
5359 return "dec{q}\t%0";
5360 }
5361
5362 default:
5363 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5364 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5365 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5366 if ((INTVAL (operands[2]) == -128
5367 || (INTVAL (operands[2]) > 0
5368 && INTVAL (operands[2]) != 128))
5369 /* Avoid overflows. */
5370 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5371 return "sub{q}\t{%2, %0|%0, %2}";
5372 operands[2] = GEN_INT (-INTVAL (operands[2]));
5373 return "add{q}\t{%2, %0|%0, %2}";
5374 }
5375 }
5376 [(set (attr "type")
5377 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378 (const_string "incdec")
5379 (const_string "alu")))
5380 (set_attr "mode" "DI")])
5381
5382 (define_insn "*adddi_5_rex64"
5383 [(set (reg FLAGS_REG)
5384 (compare
5385 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5386 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5387 (const_int 0)))
5388 (clobber (match_scratch:DI 0 "=r"))]
5389 "TARGET_64BIT
5390 && ix86_match_ccmode (insn, CCGOCmode)
5391 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5392 /* Current assemblers are broken and do not allow @GOTOFF in
5393 ought but a memory context. */
5394 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5395 {
5396 switch (get_attr_type (insn))
5397 {
5398 case TYPE_INCDEC:
5399 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5400 if (operands[2] == const1_rtx)
5401 return "inc{q}\t%0";
5402 else
5403 {
5404 gcc_assert (operands[2] == constm1_rtx);
5405 return "dec{q}\t%0";
5406 }
5407
5408 default:
5409 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5410 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5411 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5412 if (CONST_INT_P (operands[2])
5413 /* Avoid overflows. */
5414 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5415 && (INTVAL (operands[2]) == 128
5416 || (INTVAL (operands[2]) < 0
5417 && INTVAL (operands[2]) != -128)))
5418 {
5419 operands[2] = GEN_INT (-INTVAL (operands[2]));
5420 return "sub{q}\t{%2, %0|%0, %2}";
5421 }
5422 return "add{q}\t{%2, %0|%0, %2}";
5423 }
5424 }
5425 [(set (attr "type")
5426 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5427 (const_string "incdec")
5428 (const_string "alu")))
5429 (set_attr "mode" "DI")])
5430
5431
5432 (define_insn "*addsi_1"
5433 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5434 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5435 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5436 (clobber (reg:CC FLAGS_REG))]
5437 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5438 {
5439 switch (get_attr_type (insn))
5440 {
5441 case TYPE_LEA:
5442 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5443 return "lea{l}\t{%a2, %0|%0, %a2}";
5444
5445 case TYPE_INCDEC:
5446 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5447 if (operands[2] == const1_rtx)
5448 return "inc{l}\t%0";
5449 else
5450 {
5451 gcc_assert (operands[2] == constm1_rtx);
5452 return "dec{l}\t%0";
5453 }
5454
5455 default:
5456 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5457
5458 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5459 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5460 if (CONST_INT_P (operands[2])
5461 && (INTVAL (operands[2]) == 128
5462 || (INTVAL (operands[2]) < 0
5463 && INTVAL (operands[2]) != -128)))
5464 {
5465 operands[2] = GEN_INT (-INTVAL (operands[2]));
5466 return "sub{l}\t{%2, %0|%0, %2}";
5467 }
5468 return "add{l}\t{%2, %0|%0, %2}";
5469 }
5470 }
5471 [(set (attr "type")
5472 (cond [(eq_attr "alternative" "2")
5473 (const_string "lea")
5474 ; Current assemblers are broken and do not allow @GOTOFF in
5475 ; ought but a memory context.
5476 (match_operand:SI 2 "pic_symbolic_operand" "")
5477 (const_string "lea")
5478 (match_operand:SI 2 "incdec_operand" "")
5479 (const_string "incdec")
5480 ]
5481 (const_string "alu")))
5482 (set_attr "mode" "SI")])
5483
5484 ;; Convert lea to the lea pattern to avoid flags dependency.
5485 (define_split
5486 [(set (match_operand 0 "register_operand" "")
5487 (plus (match_operand 1 "register_operand" "")
5488 (match_operand 2 "nonmemory_operand" "")))
5489 (clobber (reg:CC FLAGS_REG))]
5490 "reload_completed
5491 && true_regnum (operands[0]) != true_regnum (operands[1])"
5492 [(const_int 0)]
5493 {
5494 rtx pat;
5495 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5496 may confuse gen_lowpart. */
5497 if (GET_MODE (operands[0]) != Pmode)
5498 {
5499 operands[1] = gen_lowpart (Pmode, operands[1]);
5500 operands[2] = gen_lowpart (Pmode, operands[2]);
5501 }
5502 operands[0] = gen_lowpart (SImode, operands[0]);
5503 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5504 if (Pmode != SImode)
5505 pat = gen_rtx_SUBREG (SImode, pat, 0);
5506 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5507 DONE;
5508 })
5509
5510 ;; It may seem that nonimmediate operand is proper one for operand 1.
5511 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5512 ;; we take care in ix86_binary_operator_ok to not allow two memory
5513 ;; operands so proper swapping will be done in reload. This allow
5514 ;; patterns constructed from addsi_1 to match.
5515 (define_insn "addsi_1_zext"
5516 [(set (match_operand:DI 0 "register_operand" "=r,r")
5517 (zero_extend:DI
5518 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5519 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5520 (clobber (reg:CC FLAGS_REG))]
5521 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5522 {
5523 switch (get_attr_type (insn))
5524 {
5525 case TYPE_LEA:
5526 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5527 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5528
5529 case TYPE_INCDEC:
5530 if (operands[2] == const1_rtx)
5531 return "inc{l}\t%k0";
5532 else
5533 {
5534 gcc_assert (operands[2] == constm1_rtx);
5535 return "dec{l}\t%k0";
5536 }
5537
5538 default:
5539 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5540 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5541 if (CONST_INT_P (operands[2])
5542 && (INTVAL (operands[2]) == 128
5543 || (INTVAL (operands[2]) < 0
5544 && INTVAL (operands[2]) != -128)))
5545 {
5546 operands[2] = GEN_INT (-INTVAL (operands[2]));
5547 return "sub{l}\t{%2, %k0|%k0, %2}";
5548 }
5549 return "add{l}\t{%2, %k0|%k0, %2}";
5550 }
5551 }
5552 [(set (attr "type")
5553 (cond [(eq_attr "alternative" "1")
5554 (const_string "lea")
5555 ; Current assemblers are broken and do not allow @GOTOFF in
5556 ; ought but a memory context.
5557 (match_operand:SI 2 "pic_symbolic_operand" "")
5558 (const_string "lea")
5559 (match_operand:SI 2 "incdec_operand" "")
5560 (const_string "incdec")
5561 ]
5562 (const_string "alu")))
5563 (set_attr "mode" "SI")])
5564
5565 ;; Convert lea to the lea pattern to avoid flags dependency.
5566 (define_split
5567 [(set (match_operand:DI 0 "register_operand" "")
5568 (zero_extend:DI
5569 (plus:SI (match_operand:SI 1 "register_operand" "")
5570 (match_operand:SI 2 "nonmemory_operand" ""))))
5571 (clobber (reg:CC FLAGS_REG))]
5572 "TARGET_64BIT && reload_completed
5573 && true_regnum (operands[0]) != true_regnum (operands[1])"
5574 [(set (match_dup 0)
5575 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5576 {
5577 operands[1] = gen_lowpart (Pmode, operands[1]);
5578 operands[2] = gen_lowpart (Pmode, operands[2]);
5579 })
5580
5581 (define_insn "*addsi_2"
5582 [(set (reg FLAGS_REG)
5583 (compare
5584 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5585 (match_operand:SI 2 "general_operand" "rmni,rni"))
5586 (const_int 0)))
5587 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5588 (plus:SI (match_dup 1) (match_dup 2)))]
5589 "ix86_match_ccmode (insn, CCGOCmode)
5590 && ix86_binary_operator_ok (PLUS, SImode, operands)
5591 /* Current assemblers are broken and do not allow @GOTOFF in
5592 ought but a memory context. */
5593 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5594 {
5595 switch (get_attr_type (insn))
5596 {
5597 case TYPE_INCDEC:
5598 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599 if (operands[2] == const1_rtx)
5600 return "inc{l}\t%0";
5601 else
5602 {
5603 gcc_assert (operands[2] == constm1_rtx);
5604 return "dec{l}\t%0";
5605 }
5606
5607 default:
5608 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5610 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5611 if (CONST_INT_P (operands[2])
5612 && (INTVAL (operands[2]) == 128
5613 || (INTVAL (operands[2]) < 0
5614 && INTVAL (operands[2]) != -128)))
5615 {
5616 operands[2] = GEN_INT (-INTVAL (operands[2]));
5617 return "sub{l}\t{%2, %0|%0, %2}";
5618 }
5619 return "add{l}\t{%2, %0|%0, %2}";
5620 }
5621 }
5622 [(set (attr "type")
5623 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5624 (const_string "incdec")
5625 (const_string "alu")))
5626 (set_attr "mode" "SI")])
5627
5628 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5629 (define_insn "*addsi_2_zext"
5630 [(set (reg FLAGS_REG)
5631 (compare
5632 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5633 (match_operand:SI 2 "general_operand" "rmni"))
5634 (const_int 0)))
5635 (set (match_operand:DI 0 "register_operand" "=r")
5636 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5637 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5638 && ix86_binary_operator_ok (PLUS, SImode, operands)
5639 /* Current assemblers are broken and do not allow @GOTOFF in
5640 ought but a memory context. */
5641 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5642 {
5643 switch (get_attr_type (insn))
5644 {
5645 case TYPE_INCDEC:
5646 if (operands[2] == const1_rtx)
5647 return "inc{l}\t%k0";
5648 else
5649 {
5650 gcc_assert (operands[2] == constm1_rtx);
5651 return "dec{l}\t%k0";
5652 }
5653
5654 default:
5655 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5657 if (CONST_INT_P (operands[2])
5658 && (INTVAL (operands[2]) == 128
5659 || (INTVAL (operands[2]) < 0
5660 && INTVAL (operands[2]) != -128)))
5661 {
5662 operands[2] = GEN_INT (-INTVAL (operands[2]));
5663 return "sub{l}\t{%2, %k0|%k0, %2}";
5664 }
5665 return "add{l}\t{%2, %k0|%k0, %2}";
5666 }
5667 }
5668 [(set (attr "type")
5669 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670 (const_string "incdec")
5671 (const_string "alu")))
5672 (set_attr "mode" "SI")])
5673
5674 (define_insn "*addsi_3"
5675 [(set (reg FLAGS_REG)
5676 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5677 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5678 (clobber (match_scratch:SI 0 "=r"))]
5679 "ix86_match_ccmode (insn, CCZmode)
5680 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5681 /* Current assemblers are broken and do not allow @GOTOFF in
5682 ought but a memory context. */
5683 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5684 {
5685 switch (get_attr_type (insn))
5686 {
5687 case TYPE_INCDEC:
5688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689 if (operands[2] == const1_rtx)
5690 return "inc{l}\t%0";
5691 else
5692 {
5693 gcc_assert (operands[2] == constm1_rtx);
5694 return "dec{l}\t%0";
5695 }
5696
5697 default:
5698 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5700 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5701 if (CONST_INT_P (operands[2])
5702 && (INTVAL (operands[2]) == 128
5703 || (INTVAL (operands[2]) < 0
5704 && INTVAL (operands[2]) != -128)))
5705 {
5706 operands[2] = GEN_INT (-INTVAL (operands[2]));
5707 return "sub{l}\t{%2, %0|%0, %2}";
5708 }
5709 return "add{l}\t{%2, %0|%0, %2}";
5710 }
5711 }
5712 [(set (attr "type")
5713 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5714 (const_string "incdec")
5715 (const_string "alu")))
5716 (set_attr "mode" "SI")])
5717
5718 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5719 (define_insn "*addsi_3_zext"
5720 [(set (reg FLAGS_REG)
5721 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5722 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5723 (set (match_operand:DI 0 "register_operand" "=r")
5724 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5725 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5726 && ix86_binary_operator_ok (PLUS, SImode, operands)
5727 /* Current assemblers are broken and do not allow @GOTOFF in
5728 ought but a memory context. */
5729 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5730 {
5731 switch (get_attr_type (insn))
5732 {
5733 case TYPE_INCDEC:
5734 if (operands[2] == const1_rtx)
5735 return "inc{l}\t%k0";
5736 else
5737 {
5738 gcc_assert (operands[2] == constm1_rtx);
5739 return "dec{l}\t%k0";
5740 }
5741
5742 default:
5743 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5744 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5745 if (CONST_INT_P (operands[2])
5746 && (INTVAL (operands[2]) == 128
5747 || (INTVAL (operands[2]) < 0
5748 && INTVAL (operands[2]) != -128)))
5749 {
5750 operands[2] = GEN_INT (-INTVAL (operands[2]));
5751 return "sub{l}\t{%2, %k0|%k0, %2}";
5752 }
5753 return "add{l}\t{%2, %k0|%k0, %2}";
5754 }
5755 }
5756 [(set (attr "type")
5757 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5758 (const_string "incdec")
5759 (const_string "alu")))
5760 (set_attr "mode" "SI")])
5761
5762 ; For comparisons against 1, -1 and 128, we may generate better code
5763 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5764 ; is matched then. We can't accept general immediate, because for
5765 ; case of overflows, the result is messed up.
5766 ; This pattern also don't hold of 0x80000000, since the value overflows
5767 ; when negated.
5768 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5769 ; only for comparisons not depending on it.
5770 (define_insn "*addsi_4"
5771 [(set (reg FLAGS_REG)
5772 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5773 (match_operand:SI 2 "const_int_operand" "n")))
5774 (clobber (match_scratch:SI 0 "=rm"))]
5775 "ix86_match_ccmode (insn, CCGCmode)
5776 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5777 {
5778 switch (get_attr_type (insn))
5779 {
5780 case TYPE_INCDEC:
5781 if (operands[2] == constm1_rtx)
5782 return "inc{l}\t%0";
5783 else
5784 {
5785 gcc_assert (operands[2] == const1_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 ((INTVAL (operands[2]) == -128
5794 || (INTVAL (operands[2]) > 0
5795 && INTVAL (operands[2]) != 128)))
5796 return "sub{l}\t{%2, %0|%0, %2}";
5797 operands[2] = GEN_INT (-INTVAL (operands[2]));
5798 return "add{l}\t{%2, %0|%0, %2}";
5799 }
5800 }
5801 [(set (attr "type")
5802 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5803 (const_string "incdec")
5804 (const_string "alu")))
5805 (set_attr "mode" "SI")])
5806
5807 (define_insn "*addsi_5"
5808 [(set (reg FLAGS_REG)
5809 (compare
5810 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5811 (match_operand:SI 2 "general_operand" "rmni"))
5812 (const_int 0)))
5813 (clobber (match_scratch:SI 0 "=r"))]
5814 "ix86_match_ccmode (insn, CCGOCmode)
5815 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5816 /* Current assemblers are broken and do not allow @GOTOFF in
5817 ought but a memory context. */
5818 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5819 {
5820 switch (get_attr_type (insn))
5821 {
5822 case TYPE_INCDEC:
5823 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5824 if (operands[2] == const1_rtx)
5825 return "inc{l}\t%0";
5826 else
5827 {
5828 gcc_assert (operands[2] == constm1_rtx);
5829 return "dec{l}\t%0";
5830 }
5831
5832 default:
5833 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5834 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5835 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5836 if (CONST_INT_P (operands[2])
5837 && (INTVAL (operands[2]) == 128
5838 || (INTVAL (operands[2]) < 0
5839 && INTVAL (operands[2]) != -128)))
5840 {
5841 operands[2] = GEN_INT (-INTVAL (operands[2]));
5842 return "sub{l}\t{%2, %0|%0, %2}";
5843 }
5844 return "add{l}\t{%2, %0|%0, %2}";
5845 }
5846 }
5847 [(set (attr "type")
5848 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5849 (const_string "incdec")
5850 (const_string "alu")))
5851 (set_attr "mode" "SI")])
5852
5853 (define_expand "addhi3"
5854 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5855 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5856 (match_operand:HI 2 "general_operand" "")))
5857 (clobber (reg:CC FLAGS_REG))])]
5858 "TARGET_HIMODE_MATH"
5859 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5860
5861 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5862 ;; type optimizations enabled by define-splits. This is not important
5863 ;; for PII, and in fact harmful because of partial register stalls.
5864
5865 (define_insn "*addhi_1_lea"
5866 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5867 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5868 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
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_LEA:
5876 return "#";
5877 case TYPE_INCDEC:
5878 if (operands[2] == const1_rtx)
5879 return "inc{w}\t%0";
5880 else
5881 {
5882 gcc_assert (operands[2] == constm1_rtx);
5883 return "dec{w}\t%0";
5884 }
5885
5886 default:
5887 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5888 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5889 if (CONST_INT_P (operands[2])
5890 && (INTVAL (operands[2]) == 128
5891 || (INTVAL (operands[2]) < 0
5892 && INTVAL (operands[2]) != -128)))
5893 {
5894 operands[2] = GEN_INT (-INTVAL (operands[2]));
5895 return "sub{w}\t{%2, %0|%0, %2}";
5896 }
5897 return "add{w}\t{%2, %0|%0, %2}";
5898 }
5899 }
5900 [(set (attr "type")
5901 (if_then_else (eq_attr "alternative" "2")
5902 (const_string "lea")
5903 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5904 (const_string "incdec")
5905 (const_string "alu"))))
5906 (set_attr "mode" "HI,HI,SI")])
5907
5908 (define_insn "*addhi_1"
5909 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5910 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5911 (match_operand:HI 2 "general_operand" "ri,rm")))
5912 (clobber (reg:CC FLAGS_REG))]
5913 "TARGET_PARTIAL_REG_STALL
5914 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5915 {
5916 switch (get_attr_type (insn))
5917 {
5918 case TYPE_INCDEC:
5919 if (operands[2] == const1_rtx)
5920 return "inc{w}\t%0";
5921 else
5922 {
5923 gcc_assert (operands[2] == constm1_rtx);
5924 return "dec{w}\t%0";
5925 }
5926
5927 default:
5928 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5929 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5930 if (CONST_INT_P (operands[2])
5931 && (INTVAL (operands[2]) == 128
5932 || (INTVAL (operands[2]) < 0
5933 && INTVAL (operands[2]) != -128)))
5934 {
5935 operands[2] = GEN_INT (-INTVAL (operands[2]));
5936 return "sub{w}\t{%2, %0|%0, %2}";
5937 }
5938 return "add{w}\t{%2, %0|%0, %2}";
5939 }
5940 }
5941 [(set (attr "type")
5942 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5943 (const_string "incdec")
5944 (const_string "alu")))
5945 (set_attr "mode" "HI")])
5946
5947 (define_insn "*addhi_2"
5948 [(set (reg FLAGS_REG)
5949 (compare
5950 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5951 (match_operand:HI 2 "general_operand" "rmni,rni"))
5952 (const_int 0)))
5953 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5954 (plus:HI (match_dup 1) (match_dup 2)))]
5955 "ix86_match_ccmode (insn, CCGOCmode)
5956 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5957 {
5958 switch (get_attr_type (insn))
5959 {
5960 case TYPE_INCDEC:
5961 if (operands[2] == const1_rtx)
5962 return "inc{w}\t%0";
5963 else
5964 {
5965 gcc_assert (operands[2] == constm1_rtx);
5966 return "dec{w}\t%0";
5967 }
5968
5969 default:
5970 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5971 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5972 if (CONST_INT_P (operands[2])
5973 && (INTVAL (operands[2]) == 128
5974 || (INTVAL (operands[2]) < 0
5975 && INTVAL (operands[2]) != -128)))
5976 {
5977 operands[2] = GEN_INT (-INTVAL (operands[2]));
5978 return "sub{w}\t{%2, %0|%0, %2}";
5979 }
5980 return "add{w}\t{%2, %0|%0, %2}";
5981 }
5982 }
5983 [(set (attr "type")
5984 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5985 (const_string "incdec")
5986 (const_string "alu")))
5987 (set_attr "mode" "HI")])
5988
5989 (define_insn "*addhi_3"
5990 [(set (reg FLAGS_REG)
5991 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5992 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5993 (clobber (match_scratch:HI 0 "=r"))]
5994 "ix86_match_ccmode (insn, CCZmode)
5995 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5996 {
5997 switch (get_attr_type (insn))
5998 {
5999 case TYPE_INCDEC:
6000 if (operands[2] == const1_rtx)
6001 return "inc{w}\t%0";
6002 else
6003 {
6004 gcc_assert (operands[2] == constm1_rtx);
6005 return "dec{w}\t%0";
6006 }
6007
6008 default:
6009 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6011 if (CONST_INT_P (operands[2])
6012 && (INTVAL (operands[2]) == 128
6013 || (INTVAL (operands[2]) < 0
6014 && INTVAL (operands[2]) != -128)))
6015 {
6016 operands[2] = GEN_INT (-INTVAL (operands[2]));
6017 return "sub{w}\t{%2, %0|%0, %2}";
6018 }
6019 return "add{w}\t{%2, %0|%0, %2}";
6020 }
6021 }
6022 [(set (attr "type")
6023 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6024 (const_string "incdec")
6025 (const_string "alu")))
6026 (set_attr "mode" "HI")])
6027
6028 ; See comments above addsi_4 for details.
6029 (define_insn "*addhi_4"
6030 [(set (reg FLAGS_REG)
6031 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6032 (match_operand:HI 2 "const_int_operand" "n")))
6033 (clobber (match_scratch:HI 0 "=rm"))]
6034 "ix86_match_ccmode (insn, CCGCmode)
6035 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6036 {
6037 switch (get_attr_type (insn))
6038 {
6039 case TYPE_INCDEC:
6040 if (operands[2] == constm1_rtx)
6041 return "inc{w}\t%0";
6042 else
6043 {
6044 gcc_assert (operands[2] == const1_rtx);
6045 return "dec{w}\t%0";
6046 }
6047
6048 default:
6049 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6050 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6051 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6052 if ((INTVAL (operands[2]) == -128
6053 || (INTVAL (operands[2]) > 0
6054 && INTVAL (operands[2]) != 128)))
6055 return "sub{w}\t{%2, %0|%0, %2}";
6056 operands[2] = GEN_INT (-INTVAL (operands[2]));
6057 return "add{w}\t{%2, %0|%0, %2}";
6058 }
6059 }
6060 [(set (attr "type")
6061 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6062 (const_string "incdec")
6063 (const_string "alu")))
6064 (set_attr "mode" "SI")])
6065
6066
6067 (define_insn "*addhi_5"
6068 [(set (reg FLAGS_REG)
6069 (compare
6070 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6071 (match_operand:HI 2 "general_operand" "rmni"))
6072 (const_int 0)))
6073 (clobber (match_scratch:HI 0 "=r"))]
6074 "ix86_match_ccmode (insn, CCGOCmode)
6075 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6076 {
6077 switch (get_attr_type (insn))
6078 {
6079 case TYPE_INCDEC:
6080 if (operands[2] == const1_rtx)
6081 return "inc{w}\t%0";
6082 else
6083 {
6084 gcc_assert (operands[2] == constm1_rtx);
6085 return "dec{w}\t%0";
6086 }
6087
6088 default:
6089 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6090 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6091 if (CONST_INT_P (operands[2])
6092 && (INTVAL (operands[2]) == 128
6093 || (INTVAL (operands[2]) < 0
6094 && INTVAL (operands[2]) != -128)))
6095 {
6096 operands[2] = GEN_INT (-INTVAL (operands[2]));
6097 return "sub{w}\t{%2, %0|%0, %2}";
6098 }
6099 return "add{w}\t{%2, %0|%0, %2}";
6100 }
6101 }
6102 [(set (attr "type")
6103 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6104 (const_string "incdec")
6105 (const_string "alu")))
6106 (set_attr "mode" "HI")])
6107
6108 (define_expand "addqi3"
6109 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6110 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6111 (match_operand:QI 2 "general_operand" "")))
6112 (clobber (reg:CC FLAGS_REG))])]
6113 "TARGET_QIMODE_MATH"
6114 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6115
6116 ;; %%% Potential partial reg stall on alternative 2. What to do?
6117 (define_insn "*addqi_1_lea"
6118 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6119 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6120 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6121 (clobber (reg:CC FLAGS_REG))]
6122 "!TARGET_PARTIAL_REG_STALL
6123 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6124 {
6125 int widen = (which_alternative == 2);
6126 switch (get_attr_type (insn))
6127 {
6128 case TYPE_LEA:
6129 return "#";
6130 case TYPE_INCDEC:
6131 if (operands[2] == const1_rtx)
6132 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6133 else
6134 {
6135 gcc_assert (operands[2] == constm1_rtx);
6136 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6137 }
6138
6139 default:
6140 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6141 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6142 if (CONST_INT_P (operands[2])
6143 && (INTVAL (operands[2]) == 128
6144 || (INTVAL (operands[2]) < 0
6145 && INTVAL (operands[2]) != -128)))
6146 {
6147 operands[2] = GEN_INT (-INTVAL (operands[2]));
6148 if (widen)
6149 return "sub{l}\t{%2, %k0|%k0, %2}";
6150 else
6151 return "sub{b}\t{%2, %0|%0, %2}";
6152 }
6153 if (widen)
6154 return "add{l}\t{%k2, %k0|%k0, %k2}";
6155 else
6156 return "add{b}\t{%2, %0|%0, %2}";
6157 }
6158 }
6159 [(set (attr "type")
6160 (if_then_else (eq_attr "alternative" "3")
6161 (const_string "lea")
6162 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6163 (const_string "incdec")
6164 (const_string "alu"))))
6165 (set_attr "mode" "QI,QI,SI,SI")])
6166
6167 (define_insn "*addqi_1"
6168 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6169 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6170 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6171 (clobber (reg:CC FLAGS_REG))]
6172 "TARGET_PARTIAL_REG_STALL
6173 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6174 {
6175 int widen = (which_alternative == 2);
6176 switch (get_attr_type (insn))
6177 {
6178 case TYPE_INCDEC:
6179 if (operands[2] == const1_rtx)
6180 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6181 else
6182 {
6183 gcc_assert (operands[2] == constm1_rtx);
6184 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6185 }
6186
6187 default:
6188 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6189 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6190 if (CONST_INT_P (operands[2])
6191 && (INTVAL (operands[2]) == 128
6192 || (INTVAL (operands[2]) < 0
6193 && INTVAL (operands[2]) != -128)))
6194 {
6195 operands[2] = GEN_INT (-INTVAL (operands[2]));
6196 if (widen)
6197 return "sub{l}\t{%2, %k0|%k0, %2}";
6198 else
6199 return "sub{b}\t{%2, %0|%0, %2}";
6200 }
6201 if (widen)
6202 return "add{l}\t{%k2, %k0|%k0, %k2}";
6203 else
6204 return "add{b}\t{%2, %0|%0, %2}";
6205 }
6206 }
6207 [(set (attr "type")
6208 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6209 (const_string "incdec")
6210 (const_string "alu")))
6211 (set_attr "mode" "QI,QI,SI")])
6212
6213 (define_insn "*addqi_1_slp"
6214 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6215 (plus:QI (match_dup 0)
6216 (match_operand:QI 1 "general_operand" "qn,qnm")))
6217 (clobber (reg:CC FLAGS_REG))]
6218 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6219 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6220 {
6221 switch (get_attr_type (insn))
6222 {
6223 case TYPE_INCDEC:
6224 if (operands[1] == const1_rtx)
6225 return "inc{b}\t%0";
6226 else
6227 {
6228 gcc_assert (operands[1] == constm1_rtx);
6229 return "dec{b}\t%0";
6230 }
6231
6232 default:
6233 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6234 if (CONST_INT_P (operands[1])
6235 && INTVAL (operands[1]) < 0)
6236 {
6237 operands[1] = GEN_INT (-INTVAL (operands[1]));
6238 return "sub{b}\t{%1, %0|%0, %1}";
6239 }
6240 return "add{b}\t{%1, %0|%0, %1}";
6241 }
6242 }
6243 [(set (attr "type")
6244 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6245 (const_string "incdec")
6246 (const_string "alu1")))
6247 (set (attr "memory")
6248 (if_then_else (match_operand 1 "memory_operand" "")
6249 (const_string "load")
6250 (const_string "none")))
6251 (set_attr "mode" "QI")])
6252
6253 (define_insn "*addqi_2"
6254 [(set (reg FLAGS_REG)
6255 (compare
6256 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6257 (match_operand:QI 2 "general_operand" "qmni,qni"))
6258 (const_int 0)))
6259 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6260 (plus:QI (match_dup 1) (match_dup 2)))]
6261 "ix86_match_ccmode (insn, CCGOCmode)
6262 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6263 {
6264 switch (get_attr_type (insn))
6265 {
6266 case TYPE_INCDEC:
6267 if (operands[2] == const1_rtx)
6268 return "inc{b}\t%0";
6269 else
6270 {
6271 gcc_assert (operands[2] == constm1_rtx
6272 || (CONST_INT_P (operands[2])
6273 && INTVAL (operands[2]) == 255));
6274 return "dec{b}\t%0";
6275 }
6276
6277 default:
6278 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6279 if (CONST_INT_P (operands[2])
6280 && INTVAL (operands[2]) < 0)
6281 {
6282 operands[2] = GEN_INT (-INTVAL (operands[2]));
6283 return "sub{b}\t{%2, %0|%0, %2}";
6284 }
6285 return "add{b}\t{%2, %0|%0, %2}";
6286 }
6287 }
6288 [(set (attr "type")
6289 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6290 (const_string "incdec")
6291 (const_string "alu")))
6292 (set_attr "mode" "QI")])
6293
6294 (define_insn "*addqi_3"
6295 [(set (reg FLAGS_REG)
6296 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6297 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6298 (clobber (match_scratch:QI 0 "=q"))]
6299 "ix86_match_ccmode (insn, CCZmode)
6300 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6301 {
6302 switch (get_attr_type (insn))
6303 {
6304 case TYPE_INCDEC:
6305 if (operands[2] == const1_rtx)
6306 return "inc{b}\t%0";
6307 else
6308 {
6309 gcc_assert (operands[2] == constm1_rtx
6310 || (CONST_INT_P (operands[2])
6311 && INTVAL (operands[2]) == 255));
6312 return "dec{b}\t%0";
6313 }
6314
6315 default:
6316 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6317 if (CONST_INT_P (operands[2])
6318 && INTVAL (operands[2]) < 0)
6319 {
6320 operands[2] = GEN_INT (-INTVAL (operands[2]));
6321 return "sub{b}\t{%2, %0|%0, %2}";
6322 }
6323 return "add{b}\t{%2, %0|%0, %2}";
6324 }
6325 }
6326 [(set (attr "type")
6327 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6328 (const_string "incdec")
6329 (const_string "alu")))
6330 (set_attr "mode" "QI")])
6331
6332 ; See comments above addsi_4 for details.
6333 (define_insn "*addqi_4"
6334 [(set (reg FLAGS_REG)
6335 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6336 (match_operand:QI 2 "const_int_operand" "n")))
6337 (clobber (match_scratch:QI 0 "=qm"))]
6338 "ix86_match_ccmode (insn, CCGCmode)
6339 && (INTVAL (operands[2]) & 0xff) != 0x80"
6340 {
6341 switch (get_attr_type (insn))
6342 {
6343 case TYPE_INCDEC:
6344 if (operands[2] == constm1_rtx
6345 || (CONST_INT_P (operands[2])
6346 && INTVAL (operands[2]) == 255))
6347 return "inc{b}\t%0";
6348 else
6349 {
6350 gcc_assert (operands[2] == const1_rtx);
6351 return "dec{b}\t%0";
6352 }
6353
6354 default:
6355 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6356 if (INTVAL (operands[2]) < 0)
6357 {
6358 operands[2] = GEN_INT (-INTVAL (operands[2]));
6359 return "add{b}\t{%2, %0|%0, %2}";
6360 }
6361 return "sub{b}\t{%2, %0|%0, %2}";
6362 }
6363 }
6364 [(set (attr "type")
6365 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6366 (const_string "incdec")
6367 (const_string "alu")))
6368 (set_attr "mode" "QI")])
6369
6370
6371 (define_insn "*addqi_5"
6372 [(set (reg FLAGS_REG)
6373 (compare
6374 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6375 (match_operand:QI 2 "general_operand" "qmni"))
6376 (const_int 0)))
6377 (clobber (match_scratch:QI 0 "=q"))]
6378 "ix86_match_ccmode (insn, CCGOCmode)
6379 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6380 {
6381 switch (get_attr_type (insn))
6382 {
6383 case TYPE_INCDEC:
6384 if (operands[2] == const1_rtx)
6385 return "inc{b}\t%0";
6386 else
6387 {
6388 gcc_assert (operands[2] == constm1_rtx
6389 || (CONST_INT_P (operands[2])
6390 && INTVAL (operands[2]) == 255));
6391 return "dec{b}\t%0";
6392 }
6393
6394 default:
6395 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6396 if (CONST_INT_P (operands[2])
6397 && INTVAL (operands[2]) < 0)
6398 {
6399 operands[2] = GEN_INT (-INTVAL (operands[2]));
6400 return "sub{b}\t{%2, %0|%0, %2}";
6401 }
6402 return "add{b}\t{%2, %0|%0, %2}";
6403 }
6404 }
6405 [(set (attr "type")
6406 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407 (const_string "incdec")
6408 (const_string "alu")))
6409 (set_attr "mode" "QI")])
6410
6411
6412 (define_insn "addqi_ext_1"
6413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6414 (const_int 8)
6415 (const_int 8))
6416 (plus:SI
6417 (zero_extract:SI
6418 (match_operand 1 "ext_register_operand" "0")
6419 (const_int 8)
6420 (const_int 8))
6421 (match_operand:QI 2 "general_operand" "Qmn")))
6422 (clobber (reg:CC FLAGS_REG))]
6423 "!TARGET_64BIT"
6424 {
6425 switch (get_attr_type (insn))
6426 {
6427 case TYPE_INCDEC:
6428 if (operands[2] == const1_rtx)
6429 return "inc{b}\t%h0";
6430 else
6431 {
6432 gcc_assert (operands[2] == constm1_rtx
6433 || (CONST_INT_P (operands[2])
6434 && INTVAL (operands[2]) == 255));
6435 return "dec{b}\t%h0";
6436 }
6437
6438 default:
6439 return "add{b}\t{%2, %h0|%h0, %2}";
6440 }
6441 }
6442 [(set (attr "type")
6443 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6444 (const_string "incdec")
6445 (const_string "alu")))
6446 (set_attr "mode" "QI")])
6447
6448 (define_insn "*addqi_ext_1_rex64"
6449 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6450 (const_int 8)
6451 (const_int 8))
6452 (plus:SI
6453 (zero_extract:SI
6454 (match_operand 1 "ext_register_operand" "0")
6455 (const_int 8)
6456 (const_int 8))
6457 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6458 (clobber (reg:CC FLAGS_REG))]
6459 "TARGET_64BIT"
6460 {
6461 switch (get_attr_type (insn))
6462 {
6463 case TYPE_INCDEC:
6464 if (operands[2] == const1_rtx)
6465 return "inc{b}\t%h0";
6466 else
6467 {
6468 gcc_assert (operands[2] == constm1_rtx
6469 || (CONST_INT_P (operands[2])
6470 && INTVAL (operands[2]) == 255));
6471 return "dec{b}\t%h0";
6472 }
6473
6474 default:
6475 return "add{b}\t{%2, %h0|%h0, %2}";
6476 }
6477 }
6478 [(set (attr "type")
6479 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6480 (const_string "incdec")
6481 (const_string "alu")))
6482 (set_attr "mode" "QI")])
6483
6484 (define_insn "*addqi_ext_2"
6485 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6486 (const_int 8)
6487 (const_int 8))
6488 (plus:SI
6489 (zero_extract:SI
6490 (match_operand 1 "ext_register_operand" "%0")
6491 (const_int 8)
6492 (const_int 8))
6493 (zero_extract:SI
6494 (match_operand 2 "ext_register_operand" "Q")
6495 (const_int 8)
6496 (const_int 8))))
6497 (clobber (reg:CC FLAGS_REG))]
6498 ""
6499 "add{b}\t{%h2, %h0|%h0, %h2}"
6500 [(set_attr "type" "alu")
6501 (set_attr "mode" "QI")])
6502
6503 ;; The patterns that match these are at the end of this file.
6504
6505 (define_expand "addxf3"
6506 [(set (match_operand:XF 0 "register_operand" "")
6507 (plus:XF (match_operand:XF 1 "register_operand" "")
6508 (match_operand:XF 2 "register_operand" "")))]
6509 "TARGET_80387"
6510 "")
6511
6512 (define_expand "adddf3"
6513 [(set (match_operand:DF 0 "register_operand" "")
6514 (plus:DF (match_operand:DF 1 "register_operand" "")
6515 (match_operand:DF 2 "nonimmediate_operand" "")))]
6516 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6517 "")
6518
6519 (define_expand "addsf3"
6520 [(set (match_operand:SF 0 "register_operand" "")
6521 (plus:SF (match_operand:SF 1 "register_operand" "")
6522 (match_operand:SF 2 "nonimmediate_operand" "")))]
6523 "TARGET_80387 || TARGET_SSE_MATH"
6524 "")
6525 \f
6526 ;; Subtract instructions
6527
6528 ;; %%% splits for subditi3
6529
6530 (define_expand "subti3"
6531 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6532 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6533 (match_operand:TI 2 "x86_64_general_operand" "")))
6534 (clobber (reg:CC FLAGS_REG))])]
6535 "TARGET_64BIT"
6536 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6537
6538 (define_insn "*subti3_1"
6539 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6540 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6541 (match_operand:TI 2 "general_operand" "roiF,riF")))
6542 (clobber (reg:CC FLAGS_REG))]
6543 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6544 "#")
6545
6546 (define_split
6547 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6548 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6549 (match_operand:TI 2 "general_operand" "")))
6550 (clobber (reg:CC FLAGS_REG))]
6551 "TARGET_64BIT && reload_completed"
6552 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6553 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6554 (parallel [(set (match_dup 3)
6555 (minus:DI (match_dup 4)
6556 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6557 (match_dup 5))))
6558 (clobber (reg:CC FLAGS_REG))])]
6559 "split_ti (operands+0, 1, operands+0, operands+3);
6560 split_ti (operands+1, 1, operands+1, operands+4);
6561 split_ti (operands+2, 1, operands+2, operands+5);")
6562
6563 ;; %%% splits for subsidi3
6564
6565 (define_expand "subdi3"
6566 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6567 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6568 (match_operand:DI 2 "x86_64_general_operand" "")))
6569 (clobber (reg:CC FLAGS_REG))])]
6570 ""
6571 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6572
6573 (define_insn "*subdi3_1"
6574 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6575 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6576 (match_operand:DI 2 "general_operand" "roiF,riF")))
6577 (clobber (reg:CC FLAGS_REG))]
6578 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6579 "#")
6580
6581 (define_split
6582 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6583 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6584 (match_operand:DI 2 "general_operand" "")))
6585 (clobber (reg:CC FLAGS_REG))]
6586 "!TARGET_64BIT && reload_completed"
6587 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6588 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6589 (parallel [(set (match_dup 3)
6590 (minus:SI (match_dup 4)
6591 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6592 (match_dup 5))))
6593 (clobber (reg:CC FLAGS_REG))])]
6594 "split_di (operands+0, 1, operands+0, operands+3);
6595 split_di (operands+1, 1, operands+1, operands+4);
6596 split_di (operands+2, 1, operands+2, operands+5);")
6597
6598 (define_insn "subdi3_carry_rex64"
6599 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6600 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6601 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6602 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6603 (clobber (reg:CC FLAGS_REG))]
6604 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6605 "sbb{q}\t{%2, %0|%0, %2}"
6606 [(set_attr "type" "alu")
6607 (set_attr "pent_pair" "pu")
6608 (set_attr "mode" "DI")])
6609
6610 (define_insn "*subdi_1_rex64"
6611 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6612 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6613 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6614 (clobber (reg:CC FLAGS_REG))]
6615 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6616 "sub{q}\t{%2, %0|%0, %2}"
6617 [(set_attr "type" "alu")
6618 (set_attr "mode" "DI")])
6619
6620 (define_insn "*subdi_2_rex64"
6621 [(set (reg FLAGS_REG)
6622 (compare
6623 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6624 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6625 (const_int 0)))
6626 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6627 (minus:DI (match_dup 1) (match_dup 2)))]
6628 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6629 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6630 "sub{q}\t{%2, %0|%0, %2}"
6631 [(set_attr "type" "alu")
6632 (set_attr "mode" "DI")])
6633
6634 (define_insn "*subdi_3_rex63"
6635 [(set (reg FLAGS_REG)
6636 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6637 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6638 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6639 (minus:DI (match_dup 1) (match_dup 2)))]
6640 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6641 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6642 "sub{q}\t{%2, %0|%0, %2}"
6643 [(set_attr "type" "alu")
6644 (set_attr "mode" "DI")])
6645
6646 (define_insn "subqi3_carry"
6647 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6648 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6649 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6650 (match_operand:QI 2 "general_operand" "qi,qm"))))
6651 (clobber (reg:CC FLAGS_REG))]
6652 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6653 "sbb{b}\t{%2, %0|%0, %2}"
6654 [(set_attr "type" "alu")
6655 (set_attr "pent_pair" "pu")
6656 (set_attr "mode" "QI")])
6657
6658 (define_insn "subhi3_carry"
6659 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6660 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6661 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6662 (match_operand:HI 2 "general_operand" "ri,rm"))))
6663 (clobber (reg:CC FLAGS_REG))]
6664 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6665 "sbb{w}\t{%2, %0|%0, %2}"
6666 [(set_attr "type" "alu")
6667 (set_attr "pent_pair" "pu")
6668 (set_attr "mode" "HI")])
6669
6670 (define_insn "subsi3_carry"
6671 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6672 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6674 (match_operand:SI 2 "general_operand" "ri,rm"))))
6675 (clobber (reg:CC FLAGS_REG))]
6676 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6677 "sbb{l}\t{%2, %0|%0, %2}"
6678 [(set_attr "type" "alu")
6679 (set_attr "pent_pair" "pu")
6680 (set_attr "mode" "SI")])
6681
6682 (define_insn "subsi3_carry_zext"
6683 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6684 (zero_extend:DI
6685 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6686 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6687 (match_operand:SI 2 "general_operand" "ri,rm")))))
6688 (clobber (reg:CC FLAGS_REG))]
6689 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6690 "sbb{l}\t{%2, %k0|%k0, %2}"
6691 [(set_attr "type" "alu")
6692 (set_attr "pent_pair" "pu")
6693 (set_attr "mode" "SI")])
6694
6695 (define_expand "subsi3"
6696 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6697 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6698 (match_operand:SI 2 "general_operand" "")))
6699 (clobber (reg:CC FLAGS_REG))])]
6700 ""
6701 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6702
6703 (define_insn "*subsi_1"
6704 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6705 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6706 (match_operand:SI 2 "general_operand" "ri,rm")))
6707 (clobber (reg:CC FLAGS_REG))]
6708 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6709 "sub{l}\t{%2, %0|%0, %2}"
6710 [(set_attr "type" "alu")
6711 (set_attr "mode" "SI")])
6712
6713 (define_insn "*subsi_1_zext"
6714 [(set (match_operand:DI 0 "register_operand" "=r")
6715 (zero_extend:DI
6716 (minus:SI (match_operand:SI 1 "register_operand" "0")
6717 (match_operand:SI 2 "general_operand" "rim"))))
6718 (clobber (reg:CC FLAGS_REG))]
6719 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6720 "sub{l}\t{%2, %k0|%k0, %2}"
6721 [(set_attr "type" "alu")
6722 (set_attr "mode" "SI")])
6723
6724 (define_insn "*subsi_2"
6725 [(set (reg FLAGS_REG)
6726 (compare
6727 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6728 (match_operand:SI 2 "general_operand" "ri,rm"))
6729 (const_int 0)))
6730 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6731 (minus:SI (match_dup 1) (match_dup 2)))]
6732 "ix86_match_ccmode (insn, CCGOCmode)
6733 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6734 "sub{l}\t{%2, %0|%0, %2}"
6735 [(set_attr "type" "alu")
6736 (set_attr "mode" "SI")])
6737
6738 (define_insn "*subsi_2_zext"
6739 [(set (reg FLAGS_REG)
6740 (compare
6741 (minus:SI (match_operand:SI 1 "register_operand" "0")
6742 (match_operand:SI 2 "general_operand" "rim"))
6743 (const_int 0)))
6744 (set (match_operand:DI 0 "register_operand" "=r")
6745 (zero_extend:DI
6746 (minus:SI (match_dup 1)
6747 (match_dup 2))))]
6748 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6749 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6750 "sub{l}\t{%2, %k0|%k0, %2}"
6751 [(set_attr "type" "alu")
6752 (set_attr "mode" "SI")])
6753
6754 (define_insn "*subsi_3"
6755 [(set (reg FLAGS_REG)
6756 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6757 (match_operand:SI 2 "general_operand" "ri,rm")))
6758 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6759 (minus:SI (match_dup 1) (match_dup 2)))]
6760 "ix86_match_ccmode (insn, CCmode)
6761 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6762 "sub{l}\t{%2, %0|%0, %2}"
6763 [(set_attr "type" "alu")
6764 (set_attr "mode" "SI")])
6765
6766 (define_insn "*subsi_3_zext"
6767 [(set (reg FLAGS_REG)
6768 (compare (match_operand:SI 1 "register_operand" "0")
6769 (match_operand:SI 2 "general_operand" "rim")))
6770 (set (match_operand:DI 0 "register_operand" "=r")
6771 (zero_extend:DI
6772 (minus:SI (match_dup 1)
6773 (match_dup 2))))]
6774 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6775 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6776 "sub{l}\t{%2, %1|%1, %2}"
6777 [(set_attr "type" "alu")
6778 (set_attr "mode" "DI")])
6779
6780 (define_expand "subhi3"
6781 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6782 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6783 (match_operand:HI 2 "general_operand" "")))
6784 (clobber (reg:CC FLAGS_REG))])]
6785 "TARGET_HIMODE_MATH"
6786 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6787
6788 (define_insn "*subhi_1"
6789 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6790 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6791 (match_operand:HI 2 "general_operand" "ri,rm")))
6792 (clobber (reg:CC FLAGS_REG))]
6793 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6794 "sub{w}\t{%2, %0|%0, %2}"
6795 [(set_attr "type" "alu")
6796 (set_attr "mode" "HI")])
6797
6798 (define_insn "*subhi_2"
6799 [(set (reg FLAGS_REG)
6800 (compare
6801 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6802 (match_operand:HI 2 "general_operand" "ri,rm"))
6803 (const_int 0)))
6804 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6805 (minus:HI (match_dup 1) (match_dup 2)))]
6806 "ix86_match_ccmode (insn, CCGOCmode)
6807 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6808 "sub{w}\t{%2, %0|%0, %2}"
6809 [(set_attr "type" "alu")
6810 (set_attr "mode" "HI")])
6811
6812 (define_insn "*subhi_3"
6813 [(set (reg FLAGS_REG)
6814 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6815 (match_operand:HI 2 "general_operand" "ri,rm")))
6816 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6817 (minus:HI (match_dup 1) (match_dup 2)))]
6818 "ix86_match_ccmode (insn, CCmode)
6819 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6820 "sub{w}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "mode" "HI")])
6823
6824 (define_expand "subqi3"
6825 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6826 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6827 (match_operand:QI 2 "general_operand" "")))
6828 (clobber (reg:CC FLAGS_REG))])]
6829 "TARGET_QIMODE_MATH"
6830 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6831
6832 (define_insn "*subqi_1"
6833 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6834 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6835 (match_operand:QI 2 "general_operand" "qn,qmn")))
6836 (clobber (reg:CC FLAGS_REG))]
6837 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6838 "sub{b}\t{%2, %0|%0, %2}"
6839 [(set_attr "type" "alu")
6840 (set_attr "mode" "QI")])
6841
6842 (define_insn "*subqi_1_slp"
6843 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6844 (minus:QI (match_dup 0)
6845 (match_operand:QI 1 "general_operand" "qn,qmn")))
6846 (clobber (reg:CC FLAGS_REG))]
6847 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6848 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6849 "sub{b}\t{%1, %0|%0, %1}"
6850 [(set_attr "type" "alu1")
6851 (set_attr "mode" "QI")])
6852
6853 (define_insn "*subqi_2"
6854 [(set (reg FLAGS_REG)
6855 (compare
6856 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6857 (match_operand:QI 2 "general_operand" "qi,qm"))
6858 (const_int 0)))
6859 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6860 (minus:HI (match_dup 1) (match_dup 2)))]
6861 "ix86_match_ccmode (insn, CCGOCmode)
6862 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6863 "sub{b}\t{%2, %0|%0, %2}"
6864 [(set_attr "type" "alu")
6865 (set_attr "mode" "QI")])
6866
6867 (define_insn "*subqi_3"
6868 [(set (reg FLAGS_REG)
6869 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6870 (match_operand:QI 2 "general_operand" "qi,qm")))
6871 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6872 (minus:HI (match_dup 1) (match_dup 2)))]
6873 "ix86_match_ccmode (insn, CCmode)
6874 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6875 "sub{b}\t{%2, %0|%0, %2}"
6876 [(set_attr "type" "alu")
6877 (set_attr "mode" "QI")])
6878
6879 ;; The patterns that match these are at the end of this file.
6880
6881 (define_expand "subxf3"
6882 [(set (match_operand:XF 0 "register_operand" "")
6883 (minus:XF (match_operand:XF 1 "register_operand" "")
6884 (match_operand:XF 2 "register_operand" "")))]
6885 "TARGET_80387"
6886 "")
6887
6888 (define_expand "subdf3"
6889 [(set (match_operand:DF 0 "register_operand" "")
6890 (minus:DF (match_operand:DF 1 "register_operand" "")
6891 (match_operand:DF 2 "nonimmediate_operand" "")))]
6892 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6893 "")
6894
6895 (define_expand "subsf3"
6896 [(set (match_operand:SF 0 "register_operand" "")
6897 (minus:SF (match_operand:SF 1 "register_operand" "")
6898 (match_operand:SF 2 "nonimmediate_operand" "")))]
6899 "TARGET_80387 || TARGET_SSE_MATH"
6900 "")
6901 \f
6902 ;; Multiply instructions
6903
6904 (define_expand "muldi3"
6905 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6906 (mult:DI (match_operand:DI 1 "register_operand" "")
6907 (match_operand:DI 2 "x86_64_general_operand" "")))
6908 (clobber (reg:CC FLAGS_REG))])]
6909 "TARGET_64BIT"
6910 "")
6911
6912 (define_insn "*muldi3_1_rex64"
6913 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6914 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6915 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6916 (clobber (reg:CC FLAGS_REG))]
6917 "TARGET_64BIT
6918 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6919 "@
6920 imul{q}\t{%2, %1, %0|%0, %1, %2}
6921 imul{q}\t{%2, %1, %0|%0, %1, %2}
6922 imul{q}\t{%2, %0|%0, %2}"
6923 [(set_attr "type" "imul")
6924 (set_attr "prefix_0f" "0,0,1")
6925 (set (attr "athlon_decode")
6926 (cond [(eq_attr "cpu" "athlon")
6927 (const_string "vector")
6928 (eq_attr "alternative" "1")
6929 (const_string "vector")
6930 (and (eq_attr "alternative" "2")
6931 (match_operand 1 "memory_operand" ""))
6932 (const_string "vector")]
6933 (const_string "direct")))
6934 (set_attr "mode" "DI")])
6935
6936 (define_expand "mulsi3"
6937 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6938 (mult:SI (match_operand:SI 1 "register_operand" "")
6939 (match_operand:SI 2 "general_operand" "")))
6940 (clobber (reg:CC FLAGS_REG))])]
6941 ""
6942 "")
6943
6944 (define_insn "*mulsi3_1"
6945 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6946 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6947 (match_operand:SI 2 "general_operand" "K,i,mr")))
6948 (clobber (reg:CC FLAGS_REG))]
6949 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950 "@
6951 imul{l}\t{%2, %1, %0|%0, %1, %2}
6952 imul{l}\t{%2, %1, %0|%0, %1, %2}
6953 imul{l}\t{%2, %0|%0, %2}"
6954 [(set_attr "type" "imul")
6955 (set_attr "prefix_0f" "0,0,1")
6956 (set (attr "athlon_decode")
6957 (cond [(eq_attr "cpu" "athlon")
6958 (const_string "vector")
6959 (eq_attr "alternative" "1")
6960 (const_string "vector")
6961 (and (eq_attr "alternative" "2")
6962 (match_operand 1 "memory_operand" ""))
6963 (const_string "vector")]
6964 (const_string "direct")))
6965 (set_attr "mode" "SI")])
6966
6967 (define_insn "*mulsi3_1_zext"
6968 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6969 (zero_extend:DI
6970 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6971 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6972 (clobber (reg:CC FLAGS_REG))]
6973 "TARGET_64BIT
6974 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6975 "@
6976 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6977 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6978 imul{l}\t{%2, %k0|%k0, %2}"
6979 [(set_attr "type" "imul")
6980 (set_attr "prefix_0f" "0,0,1")
6981 (set (attr "athlon_decode")
6982 (cond [(eq_attr "cpu" "athlon")
6983 (const_string "vector")
6984 (eq_attr "alternative" "1")
6985 (const_string "vector")
6986 (and (eq_attr "alternative" "2")
6987 (match_operand 1 "memory_operand" ""))
6988 (const_string "vector")]
6989 (const_string "direct")))
6990 (set_attr "mode" "SI")])
6991
6992 (define_expand "mulhi3"
6993 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6994 (mult:HI (match_operand:HI 1 "register_operand" "")
6995 (match_operand:HI 2 "general_operand" "")))
6996 (clobber (reg:CC FLAGS_REG))])]
6997 "TARGET_HIMODE_MATH"
6998 "")
6999
7000 (define_insn "*mulhi3_1"
7001 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7002 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7003 (match_operand:HI 2 "general_operand" "K,i,mr")))
7004 (clobber (reg:CC FLAGS_REG))]
7005 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7006 "@
7007 imul{w}\t{%2, %1, %0|%0, %1, %2}
7008 imul{w}\t{%2, %1, %0|%0, %1, %2}
7009 imul{w}\t{%2, %0|%0, %2}"
7010 [(set_attr "type" "imul")
7011 (set_attr "prefix_0f" "0,0,1")
7012 (set (attr "athlon_decode")
7013 (cond [(eq_attr "cpu" "athlon")
7014 (const_string "vector")
7015 (eq_attr "alternative" "1,2")
7016 (const_string "vector")]
7017 (const_string "direct")))
7018 (set_attr "mode" "HI")])
7019
7020 (define_expand "mulqi3"
7021 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7022 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7023 (match_operand:QI 2 "register_operand" "")))
7024 (clobber (reg:CC FLAGS_REG))])]
7025 "TARGET_QIMODE_MATH"
7026 "")
7027
7028 (define_insn "*mulqi3_1"
7029 [(set (match_operand:QI 0 "register_operand" "=a")
7030 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7031 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7032 (clobber (reg:CC FLAGS_REG))]
7033 "TARGET_QIMODE_MATH
7034 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7035 "mul{b}\t%2"
7036 [(set_attr "type" "imul")
7037 (set_attr "length_immediate" "0")
7038 (set (attr "athlon_decode")
7039 (if_then_else (eq_attr "cpu" "athlon")
7040 (const_string "vector")
7041 (const_string "direct")))
7042 (set_attr "mode" "QI")])
7043
7044 (define_expand "umulqihi3"
7045 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7046 (mult:HI (zero_extend:HI
7047 (match_operand:QI 1 "nonimmediate_operand" ""))
7048 (zero_extend:HI
7049 (match_operand:QI 2 "register_operand" ""))))
7050 (clobber (reg:CC FLAGS_REG))])]
7051 "TARGET_QIMODE_MATH"
7052 "")
7053
7054 (define_insn "*umulqihi3_1"
7055 [(set (match_operand:HI 0 "register_operand" "=a")
7056 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7057 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7058 (clobber (reg:CC FLAGS_REG))]
7059 "TARGET_QIMODE_MATH
7060 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7061 "mul{b}\t%2"
7062 [(set_attr "type" "imul")
7063 (set_attr "length_immediate" "0")
7064 (set (attr "athlon_decode")
7065 (if_then_else (eq_attr "cpu" "athlon")
7066 (const_string "vector")
7067 (const_string "direct")))
7068 (set_attr "mode" "QI")])
7069
7070 (define_expand "mulqihi3"
7071 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7072 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7073 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7074 (clobber (reg:CC FLAGS_REG))])]
7075 "TARGET_QIMODE_MATH"
7076 "")
7077
7078 (define_insn "*mulqihi3_insn"
7079 [(set (match_operand:HI 0 "register_operand" "=a")
7080 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7081 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7082 (clobber (reg:CC FLAGS_REG))]
7083 "TARGET_QIMODE_MATH
7084 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7085 "imul{b}\t%2"
7086 [(set_attr "type" "imul")
7087 (set_attr "length_immediate" "0")
7088 (set (attr "athlon_decode")
7089 (if_then_else (eq_attr "cpu" "athlon")
7090 (const_string "vector")
7091 (const_string "direct")))
7092 (set_attr "mode" "QI")])
7093
7094 (define_expand "umulditi3"
7095 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7096 (mult:TI (zero_extend:TI
7097 (match_operand:DI 1 "nonimmediate_operand" ""))
7098 (zero_extend:TI
7099 (match_operand:DI 2 "register_operand" ""))))
7100 (clobber (reg:CC FLAGS_REG))])]
7101 "TARGET_64BIT"
7102 "")
7103
7104 (define_insn "*umulditi3_insn"
7105 [(set (match_operand:TI 0 "register_operand" "=A")
7106 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7107 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7108 (clobber (reg:CC FLAGS_REG))]
7109 "TARGET_64BIT
7110 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7111 "mul{q}\t%2"
7112 [(set_attr "type" "imul")
7113 (set_attr "length_immediate" "0")
7114 (set (attr "athlon_decode")
7115 (if_then_else (eq_attr "cpu" "athlon")
7116 (const_string "vector")
7117 (const_string "double")))
7118 (set_attr "mode" "DI")])
7119
7120 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7121 (define_expand "umulsidi3"
7122 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7123 (mult:DI (zero_extend:DI
7124 (match_operand:SI 1 "nonimmediate_operand" ""))
7125 (zero_extend:DI
7126 (match_operand:SI 2 "register_operand" ""))))
7127 (clobber (reg:CC FLAGS_REG))])]
7128 "!TARGET_64BIT"
7129 "")
7130
7131 (define_insn "*umulsidi3_insn"
7132 [(set (match_operand:DI 0 "register_operand" "=A")
7133 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7134 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7135 (clobber (reg:CC FLAGS_REG))]
7136 "!TARGET_64BIT
7137 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7138 "mul{l}\t%2"
7139 [(set_attr "type" "imul")
7140 (set_attr "length_immediate" "0")
7141 (set (attr "athlon_decode")
7142 (if_then_else (eq_attr "cpu" "athlon")
7143 (const_string "vector")
7144 (const_string "double")))
7145 (set_attr "mode" "SI")])
7146
7147 (define_expand "mulditi3"
7148 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7149 (mult:TI (sign_extend:TI
7150 (match_operand:DI 1 "nonimmediate_operand" ""))
7151 (sign_extend:TI
7152 (match_operand:DI 2 "register_operand" ""))))
7153 (clobber (reg:CC FLAGS_REG))])]
7154 "TARGET_64BIT"
7155 "")
7156
7157 (define_insn "*mulditi3_insn"
7158 [(set (match_operand:TI 0 "register_operand" "=A")
7159 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7160 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7161 (clobber (reg:CC FLAGS_REG))]
7162 "TARGET_64BIT
7163 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7164 "imul{q}\t%2"
7165 [(set_attr "type" "imul")
7166 (set_attr "length_immediate" "0")
7167 (set (attr "athlon_decode")
7168 (if_then_else (eq_attr "cpu" "athlon")
7169 (const_string "vector")
7170 (const_string "double")))
7171 (set_attr "mode" "DI")])
7172
7173 (define_expand "mulsidi3"
7174 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7175 (mult:DI (sign_extend:DI
7176 (match_operand:SI 1 "nonimmediate_operand" ""))
7177 (sign_extend:DI
7178 (match_operand:SI 2 "register_operand" ""))))
7179 (clobber (reg:CC FLAGS_REG))])]
7180 "!TARGET_64BIT"
7181 "")
7182
7183 (define_insn "*mulsidi3_insn"
7184 [(set (match_operand:DI 0 "register_operand" "=A")
7185 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7186 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7187 (clobber (reg:CC FLAGS_REG))]
7188 "!TARGET_64BIT
7189 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7190 "imul{l}\t%2"
7191 [(set_attr "type" "imul")
7192 (set_attr "length_immediate" "0")
7193 (set (attr "athlon_decode")
7194 (if_then_else (eq_attr "cpu" "athlon")
7195 (const_string "vector")
7196 (const_string "double")))
7197 (set_attr "mode" "SI")])
7198
7199 (define_expand "umuldi3_highpart"
7200 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7201 (truncate:DI
7202 (lshiftrt:TI
7203 (mult:TI (zero_extend:TI
7204 (match_operand:DI 1 "nonimmediate_operand" ""))
7205 (zero_extend:TI
7206 (match_operand:DI 2 "register_operand" "")))
7207 (const_int 64))))
7208 (clobber (match_scratch:DI 3 ""))
7209 (clobber (reg:CC FLAGS_REG))])]
7210 "TARGET_64BIT"
7211 "")
7212
7213 (define_insn "*umuldi3_highpart_rex64"
7214 [(set (match_operand:DI 0 "register_operand" "=d")
7215 (truncate:DI
7216 (lshiftrt:TI
7217 (mult:TI (zero_extend:TI
7218 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7219 (zero_extend:TI
7220 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7221 (const_int 64))))
7222 (clobber (match_scratch:DI 3 "=1"))
7223 (clobber (reg:CC FLAGS_REG))]
7224 "TARGET_64BIT
7225 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7226 "mul{q}\t%2"
7227 [(set_attr "type" "imul")
7228 (set_attr "length_immediate" "0")
7229 (set (attr "athlon_decode")
7230 (if_then_else (eq_attr "cpu" "athlon")
7231 (const_string "vector")
7232 (const_string "double")))
7233 (set_attr "mode" "DI")])
7234
7235 (define_expand "umulsi3_highpart"
7236 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7237 (truncate:SI
7238 (lshiftrt:DI
7239 (mult:DI (zero_extend:DI
7240 (match_operand:SI 1 "nonimmediate_operand" ""))
7241 (zero_extend:DI
7242 (match_operand:SI 2 "register_operand" "")))
7243 (const_int 32))))
7244 (clobber (match_scratch:SI 3 ""))
7245 (clobber (reg:CC FLAGS_REG))])]
7246 ""
7247 "")
7248
7249 (define_insn "*umulsi3_highpart_insn"
7250 [(set (match_operand:SI 0 "register_operand" "=d")
7251 (truncate:SI
7252 (lshiftrt:DI
7253 (mult:DI (zero_extend:DI
7254 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7255 (zero_extend:DI
7256 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7257 (const_int 32))))
7258 (clobber (match_scratch:SI 3 "=1"))
7259 (clobber (reg:CC FLAGS_REG))]
7260 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7261 "mul{l}\t%2"
7262 [(set_attr "type" "imul")
7263 (set_attr "length_immediate" "0")
7264 (set (attr "athlon_decode")
7265 (if_then_else (eq_attr "cpu" "athlon")
7266 (const_string "vector")
7267 (const_string "double")))
7268 (set_attr "mode" "SI")])
7269
7270 (define_insn "*umulsi3_highpart_zext"
7271 [(set (match_operand:DI 0 "register_operand" "=d")
7272 (zero_extend:DI (truncate:SI
7273 (lshiftrt:DI
7274 (mult:DI (zero_extend:DI
7275 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7276 (zero_extend:DI
7277 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7278 (const_int 32)))))
7279 (clobber (match_scratch:SI 3 "=1"))
7280 (clobber (reg:CC FLAGS_REG))]
7281 "TARGET_64BIT
7282 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7283 "mul{l}\t%2"
7284 [(set_attr "type" "imul")
7285 (set_attr "length_immediate" "0")
7286 (set (attr "athlon_decode")
7287 (if_then_else (eq_attr "cpu" "athlon")
7288 (const_string "vector")
7289 (const_string "double")))
7290 (set_attr "mode" "SI")])
7291
7292 (define_expand "smuldi3_highpart"
7293 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7294 (truncate:DI
7295 (lshiftrt:TI
7296 (mult:TI (sign_extend:TI
7297 (match_operand:DI 1 "nonimmediate_operand" ""))
7298 (sign_extend:TI
7299 (match_operand:DI 2 "register_operand" "")))
7300 (const_int 64))))
7301 (clobber (match_scratch:DI 3 ""))
7302 (clobber (reg:CC FLAGS_REG))])]
7303 "TARGET_64BIT"
7304 "")
7305
7306 (define_insn "*smuldi3_highpart_rex64"
7307 [(set (match_operand:DI 0 "register_operand" "=d")
7308 (truncate:DI
7309 (lshiftrt:TI
7310 (mult:TI (sign_extend:TI
7311 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7312 (sign_extend:TI
7313 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7314 (const_int 64))))
7315 (clobber (match_scratch:DI 3 "=1"))
7316 (clobber (reg:CC FLAGS_REG))]
7317 "TARGET_64BIT
7318 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7319 "imul{q}\t%2"
7320 [(set_attr "type" "imul")
7321 (set (attr "athlon_decode")
7322 (if_then_else (eq_attr "cpu" "athlon")
7323 (const_string "vector")
7324 (const_string "double")))
7325 (set_attr "mode" "DI")])
7326
7327 (define_expand "smulsi3_highpart"
7328 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7329 (truncate:SI
7330 (lshiftrt:DI
7331 (mult:DI (sign_extend:DI
7332 (match_operand:SI 1 "nonimmediate_operand" ""))
7333 (sign_extend:DI
7334 (match_operand:SI 2 "register_operand" "")))
7335 (const_int 32))))
7336 (clobber (match_scratch:SI 3 ""))
7337 (clobber (reg:CC FLAGS_REG))])]
7338 ""
7339 "")
7340
7341 (define_insn "*smulsi3_highpart_insn"
7342 [(set (match_operand:SI 0 "register_operand" "=d")
7343 (truncate:SI
7344 (lshiftrt:DI
7345 (mult:DI (sign_extend:DI
7346 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7347 (sign_extend:DI
7348 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7349 (const_int 32))))
7350 (clobber (match_scratch:SI 3 "=1"))
7351 (clobber (reg:CC FLAGS_REG))]
7352 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7353 "imul{l}\t%2"
7354 [(set_attr "type" "imul")
7355 (set (attr "athlon_decode")
7356 (if_then_else (eq_attr "cpu" "athlon")
7357 (const_string "vector")
7358 (const_string "double")))
7359 (set_attr "mode" "SI")])
7360
7361 (define_insn "*smulsi3_highpart_zext"
7362 [(set (match_operand:DI 0 "register_operand" "=d")
7363 (zero_extend:DI (truncate:SI
7364 (lshiftrt:DI
7365 (mult:DI (sign_extend:DI
7366 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7367 (sign_extend:DI
7368 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7369 (const_int 32)))))
7370 (clobber (match_scratch:SI 3 "=1"))
7371 (clobber (reg:CC FLAGS_REG))]
7372 "TARGET_64BIT
7373 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7374 "imul{l}\t%2"
7375 [(set_attr "type" "imul")
7376 (set (attr "athlon_decode")
7377 (if_then_else (eq_attr "cpu" "athlon")
7378 (const_string "vector")
7379 (const_string "double")))
7380 (set_attr "mode" "SI")])
7381
7382 ;; The patterns that match these are at the end of this file.
7383
7384 (define_expand "mulxf3"
7385 [(set (match_operand:XF 0 "register_operand" "")
7386 (mult:XF (match_operand:XF 1 "register_operand" "")
7387 (match_operand:XF 2 "register_operand" "")))]
7388 "TARGET_80387"
7389 "")
7390
7391 (define_expand "muldf3"
7392 [(set (match_operand:DF 0 "register_operand" "")
7393 (mult:DF (match_operand:DF 1 "register_operand" "")
7394 (match_operand:DF 2 "nonimmediate_operand" "")))]
7395 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7396 "")
7397
7398 (define_expand "mulsf3"
7399 [(set (match_operand:SF 0 "register_operand" "")
7400 (mult:SF (match_operand:SF 1 "register_operand" "")
7401 (match_operand:SF 2 "nonimmediate_operand" "")))]
7402 "TARGET_80387 || TARGET_SSE_MATH"
7403 "")
7404 \f
7405 ;; Divide instructions
7406
7407 (define_insn "divqi3"
7408 [(set (match_operand:QI 0 "register_operand" "=a")
7409 (div:QI (match_operand:HI 1 "register_operand" "0")
7410 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7411 (clobber (reg:CC FLAGS_REG))]
7412 "TARGET_QIMODE_MATH"
7413 "idiv{b}\t%2"
7414 [(set_attr "type" "idiv")
7415 (set_attr "mode" "QI")])
7416
7417 (define_insn "udivqi3"
7418 [(set (match_operand:QI 0 "register_operand" "=a")
7419 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7420 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7421 (clobber (reg:CC FLAGS_REG))]
7422 "TARGET_QIMODE_MATH"
7423 "div{b}\t%2"
7424 [(set_attr "type" "idiv")
7425 (set_attr "mode" "QI")])
7426
7427 ;; The patterns that match these are at the end of this file.
7428
7429 (define_expand "divxf3"
7430 [(set (match_operand:XF 0 "register_operand" "")
7431 (div:XF (match_operand:XF 1 "register_operand" "")
7432 (match_operand:XF 2 "register_operand" "")))]
7433 "TARGET_80387"
7434 "")
7435
7436 (define_expand "divdf3"
7437 [(set (match_operand:DF 0 "register_operand" "")
7438 (div:DF (match_operand:DF 1 "register_operand" "")
7439 (match_operand:DF 2 "nonimmediate_operand" "")))]
7440 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7441 "")
7442
7443 (define_expand "divsf3"
7444 [(set (match_operand:SF 0 "register_operand" "")
7445 (div:SF (match_operand:SF 1 "register_operand" "")
7446 (match_operand:SF 2 "nonimmediate_operand" "")))]
7447 "TARGET_80387 || TARGET_SSE_MATH"
7448 "")
7449 \f
7450 ;; Remainder instructions.
7451
7452 (define_expand "divmoddi4"
7453 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7454 (div:DI (match_operand:DI 1 "register_operand" "")
7455 (match_operand:DI 2 "nonimmediate_operand" "")))
7456 (set (match_operand:DI 3 "register_operand" "")
7457 (mod:DI (match_dup 1) (match_dup 2)))
7458 (clobber (reg:CC FLAGS_REG))])]
7459 "TARGET_64BIT"
7460 "")
7461
7462 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7463 ;; Penalize eax case slightly because it results in worse scheduling
7464 ;; of code.
7465 (define_insn "*divmoddi4_nocltd_rex64"
7466 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7467 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7468 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7469 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7470 (mod:DI (match_dup 2) (match_dup 3)))
7471 (clobber (reg:CC FLAGS_REG))]
7472 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7473 "#"
7474 [(set_attr "type" "multi")])
7475
7476 (define_insn "*divmoddi4_cltd_rex64"
7477 [(set (match_operand:DI 0 "register_operand" "=a")
7478 (div:DI (match_operand:DI 2 "register_operand" "a")
7479 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7480 (set (match_operand:DI 1 "register_operand" "=&d")
7481 (mod:DI (match_dup 2) (match_dup 3)))
7482 (clobber (reg:CC FLAGS_REG))]
7483 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7484 "#"
7485 [(set_attr "type" "multi")])
7486
7487 (define_insn "*divmoddi_noext_rex64"
7488 [(set (match_operand:DI 0 "register_operand" "=a")
7489 (div:DI (match_operand:DI 1 "register_operand" "0")
7490 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7491 (set (match_operand:DI 3 "register_operand" "=d")
7492 (mod:DI (match_dup 1) (match_dup 2)))
7493 (use (match_operand:DI 4 "register_operand" "3"))
7494 (clobber (reg:CC FLAGS_REG))]
7495 "TARGET_64BIT"
7496 "idiv{q}\t%2"
7497 [(set_attr "type" "idiv")
7498 (set_attr "mode" "DI")])
7499
7500 (define_split
7501 [(set (match_operand:DI 0 "register_operand" "")
7502 (div:DI (match_operand:DI 1 "register_operand" "")
7503 (match_operand:DI 2 "nonimmediate_operand" "")))
7504 (set (match_operand:DI 3 "register_operand" "")
7505 (mod:DI (match_dup 1) (match_dup 2)))
7506 (clobber (reg:CC FLAGS_REG))]
7507 "TARGET_64BIT && reload_completed"
7508 [(parallel [(set (match_dup 3)
7509 (ashiftrt:DI (match_dup 4) (const_int 63)))
7510 (clobber (reg:CC FLAGS_REG))])
7511 (parallel [(set (match_dup 0)
7512 (div:DI (reg:DI 0) (match_dup 2)))
7513 (set (match_dup 3)
7514 (mod:DI (reg:DI 0) (match_dup 2)))
7515 (use (match_dup 3))
7516 (clobber (reg:CC FLAGS_REG))])]
7517 {
7518 /* Avoid use of cltd in favor of a mov+shift. */
7519 if (!TARGET_USE_CLTD && !optimize_size)
7520 {
7521 if (true_regnum (operands[1]))
7522 emit_move_insn (operands[0], operands[1]);
7523 else
7524 emit_move_insn (operands[3], operands[1]);
7525 operands[4] = operands[3];
7526 }
7527 else
7528 {
7529 gcc_assert (!true_regnum (operands[1]));
7530 operands[4] = operands[1];
7531 }
7532 })
7533
7534
7535 (define_expand "divmodsi4"
7536 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7537 (div:SI (match_operand:SI 1 "register_operand" "")
7538 (match_operand:SI 2 "nonimmediate_operand" "")))
7539 (set (match_operand:SI 3 "register_operand" "")
7540 (mod:SI (match_dup 1) (match_dup 2)))
7541 (clobber (reg:CC FLAGS_REG))])]
7542 ""
7543 "")
7544
7545 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7546 ;; Penalize eax case slightly because it results in worse scheduling
7547 ;; of code.
7548 (define_insn "*divmodsi4_nocltd"
7549 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7550 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7551 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7552 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7553 (mod:SI (match_dup 2) (match_dup 3)))
7554 (clobber (reg:CC FLAGS_REG))]
7555 "!optimize_size && !TARGET_USE_CLTD"
7556 "#"
7557 [(set_attr "type" "multi")])
7558
7559 (define_insn "*divmodsi4_cltd"
7560 [(set (match_operand:SI 0 "register_operand" "=a")
7561 (div:SI (match_operand:SI 2 "register_operand" "a")
7562 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7563 (set (match_operand:SI 1 "register_operand" "=&d")
7564 (mod:SI (match_dup 2) (match_dup 3)))
7565 (clobber (reg:CC FLAGS_REG))]
7566 "optimize_size || TARGET_USE_CLTD"
7567 "#"
7568 [(set_attr "type" "multi")])
7569
7570 (define_insn "*divmodsi_noext"
7571 [(set (match_operand:SI 0 "register_operand" "=a")
7572 (div:SI (match_operand:SI 1 "register_operand" "0")
7573 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7574 (set (match_operand:SI 3 "register_operand" "=d")
7575 (mod:SI (match_dup 1) (match_dup 2)))
7576 (use (match_operand:SI 4 "register_operand" "3"))
7577 (clobber (reg:CC FLAGS_REG))]
7578 ""
7579 "idiv{l}\t%2"
7580 [(set_attr "type" "idiv")
7581 (set_attr "mode" "SI")])
7582
7583 (define_split
7584 [(set (match_operand:SI 0 "register_operand" "")
7585 (div:SI (match_operand:SI 1 "register_operand" "")
7586 (match_operand:SI 2 "nonimmediate_operand" "")))
7587 (set (match_operand:SI 3 "register_operand" "")
7588 (mod:SI (match_dup 1) (match_dup 2)))
7589 (clobber (reg:CC FLAGS_REG))]
7590 "reload_completed"
7591 [(parallel [(set (match_dup 3)
7592 (ashiftrt:SI (match_dup 4) (const_int 31)))
7593 (clobber (reg:CC FLAGS_REG))])
7594 (parallel [(set (match_dup 0)
7595 (div:SI (reg:SI 0) (match_dup 2)))
7596 (set (match_dup 3)
7597 (mod:SI (reg:SI 0) (match_dup 2)))
7598 (use (match_dup 3))
7599 (clobber (reg:CC FLAGS_REG))])]
7600 {
7601 /* Avoid use of cltd in favor of a mov+shift. */
7602 if (!TARGET_USE_CLTD && !optimize_size)
7603 {
7604 if (true_regnum (operands[1]))
7605 emit_move_insn (operands[0], operands[1]);
7606 else
7607 emit_move_insn (operands[3], operands[1]);
7608 operands[4] = operands[3];
7609 }
7610 else
7611 {
7612 gcc_assert (!true_regnum (operands[1]));
7613 operands[4] = operands[1];
7614 }
7615 })
7616 ;; %%% Split me.
7617 (define_insn "divmodhi4"
7618 [(set (match_operand:HI 0 "register_operand" "=a")
7619 (div:HI (match_operand:HI 1 "register_operand" "0")
7620 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7621 (set (match_operand:HI 3 "register_operand" "=&d")
7622 (mod:HI (match_dup 1) (match_dup 2)))
7623 (clobber (reg:CC FLAGS_REG))]
7624 "TARGET_HIMODE_MATH"
7625 "cwtd\;idiv{w}\t%2"
7626 [(set_attr "type" "multi")
7627 (set_attr "length_immediate" "0")
7628 (set_attr "mode" "SI")])
7629
7630 (define_insn "udivmoddi4"
7631 [(set (match_operand:DI 0 "register_operand" "=a")
7632 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7633 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7634 (set (match_operand:DI 3 "register_operand" "=&d")
7635 (umod:DI (match_dup 1) (match_dup 2)))
7636 (clobber (reg:CC FLAGS_REG))]
7637 "TARGET_64BIT"
7638 "xor{q}\t%3, %3\;div{q}\t%2"
7639 [(set_attr "type" "multi")
7640 (set_attr "length_immediate" "0")
7641 (set_attr "mode" "DI")])
7642
7643 (define_insn "*udivmoddi4_noext"
7644 [(set (match_operand:DI 0 "register_operand" "=a")
7645 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7646 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7647 (set (match_operand:DI 3 "register_operand" "=d")
7648 (umod:DI (match_dup 1) (match_dup 2)))
7649 (use (match_dup 3))
7650 (clobber (reg:CC FLAGS_REG))]
7651 "TARGET_64BIT"
7652 "div{q}\t%2"
7653 [(set_attr "type" "idiv")
7654 (set_attr "mode" "DI")])
7655
7656 (define_split
7657 [(set (match_operand:DI 0 "register_operand" "")
7658 (udiv:DI (match_operand:DI 1 "register_operand" "")
7659 (match_operand:DI 2 "nonimmediate_operand" "")))
7660 (set (match_operand:DI 3 "register_operand" "")
7661 (umod:DI (match_dup 1) (match_dup 2)))
7662 (clobber (reg:CC FLAGS_REG))]
7663 "TARGET_64BIT && reload_completed"
7664 [(set (match_dup 3) (const_int 0))
7665 (parallel [(set (match_dup 0)
7666 (udiv:DI (match_dup 1) (match_dup 2)))
7667 (set (match_dup 3)
7668 (umod:DI (match_dup 1) (match_dup 2)))
7669 (use (match_dup 3))
7670 (clobber (reg:CC FLAGS_REG))])]
7671 "")
7672
7673 (define_insn "udivmodsi4"
7674 [(set (match_operand:SI 0 "register_operand" "=a")
7675 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7676 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7677 (set (match_operand:SI 3 "register_operand" "=&d")
7678 (umod:SI (match_dup 1) (match_dup 2)))
7679 (clobber (reg:CC FLAGS_REG))]
7680 ""
7681 "xor{l}\t%3, %3\;div{l}\t%2"
7682 [(set_attr "type" "multi")
7683 (set_attr "length_immediate" "0")
7684 (set_attr "mode" "SI")])
7685
7686 (define_insn "*udivmodsi4_noext"
7687 [(set (match_operand:SI 0 "register_operand" "=a")
7688 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7689 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7690 (set (match_operand:SI 3 "register_operand" "=d")
7691 (umod:SI (match_dup 1) (match_dup 2)))
7692 (use (match_dup 3))
7693 (clobber (reg:CC FLAGS_REG))]
7694 ""
7695 "div{l}\t%2"
7696 [(set_attr "type" "idiv")
7697 (set_attr "mode" "SI")])
7698
7699 (define_split
7700 [(set (match_operand:SI 0 "register_operand" "")
7701 (udiv:SI (match_operand:SI 1 "register_operand" "")
7702 (match_operand:SI 2 "nonimmediate_operand" "")))
7703 (set (match_operand:SI 3 "register_operand" "")
7704 (umod:SI (match_dup 1) (match_dup 2)))
7705 (clobber (reg:CC FLAGS_REG))]
7706 "reload_completed"
7707 [(set (match_dup 3) (const_int 0))
7708 (parallel [(set (match_dup 0)
7709 (udiv:SI (match_dup 1) (match_dup 2)))
7710 (set (match_dup 3)
7711 (umod:SI (match_dup 1) (match_dup 2)))
7712 (use (match_dup 3))
7713 (clobber (reg:CC FLAGS_REG))])]
7714 "")
7715
7716 (define_expand "udivmodhi4"
7717 [(set (match_dup 4) (const_int 0))
7718 (parallel [(set (match_operand:HI 0 "register_operand" "")
7719 (udiv:HI (match_operand:HI 1 "register_operand" "")
7720 (match_operand:HI 2 "nonimmediate_operand" "")))
7721 (set (match_operand:HI 3 "register_operand" "")
7722 (umod:HI (match_dup 1) (match_dup 2)))
7723 (use (match_dup 4))
7724 (clobber (reg:CC FLAGS_REG))])]
7725 "TARGET_HIMODE_MATH"
7726 "operands[4] = gen_reg_rtx (HImode);")
7727
7728 (define_insn "*udivmodhi_noext"
7729 [(set (match_operand:HI 0 "register_operand" "=a")
7730 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7731 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7732 (set (match_operand:HI 3 "register_operand" "=d")
7733 (umod:HI (match_dup 1) (match_dup 2)))
7734 (use (match_operand:HI 4 "register_operand" "3"))
7735 (clobber (reg:CC FLAGS_REG))]
7736 ""
7737 "div{w}\t%2"
7738 [(set_attr "type" "idiv")
7739 (set_attr "mode" "HI")])
7740
7741 ;; We cannot use div/idiv for double division, because it causes
7742 ;; "division by zero" on the overflow and that's not what we expect
7743 ;; from truncate. Because true (non truncating) double division is
7744 ;; never generated, we can't create this insn anyway.
7745 ;
7746 ;(define_insn ""
7747 ; [(set (match_operand:SI 0 "register_operand" "=a")
7748 ; (truncate:SI
7749 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7750 ; (zero_extend:DI
7751 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7752 ; (set (match_operand:SI 3 "register_operand" "=d")
7753 ; (truncate:SI
7754 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7755 ; (clobber (reg:CC FLAGS_REG))]
7756 ; ""
7757 ; "div{l}\t{%2, %0|%0, %2}"
7758 ; [(set_attr "type" "idiv")])
7759 \f
7760 ;;- Logical AND instructions
7761
7762 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7763 ;; Note that this excludes ah.
7764
7765 (define_insn "*testdi_1_rex64"
7766 [(set (reg FLAGS_REG)
7767 (compare
7768 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7769 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7770 (const_int 0)))]
7771 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7772 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7773 "@
7774 test{l}\t{%k1, %k0|%k0, %k1}
7775 test{l}\t{%k1, %k0|%k0, %k1}
7776 test{q}\t{%1, %0|%0, %1}
7777 test{q}\t{%1, %0|%0, %1}
7778 test{q}\t{%1, %0|%0, %1}"
7779 [(set_attr "type" "test")
7780 (set_attr "modrm" "0,1,0,1,1")
7781 (set_attr "mode" "SI,SI,DI,DI,DI")
7782 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7783
7784 (define_insn "testsi_1"
7785 [(set (reg FLAGS_REG)
7786 (compare
7787 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7788 (match_operand:SI 1 "general_operand" "in,in,rin"))
7789 (const_int 0)))]
7790 "ix86_match_ccmode (insn, CCNOmode)
7791 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7792 "test{l}\t{%1, %0|%0, %1}"
7793 [(set_attr "type" "test")
7794 (set_attr "modrm" "0,1,1")
7795 (set_attr "mode" "SI")
7796 (set_attr "pent_pair" "uv,np,uv")])
7797
7798 (define_expand "testsi_ccno_1"
7799 [(set (reg:CCNO FLAGS_REG)
7800 (compare:CCNO
7801 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7802 (match_operand:SI 1 "nonmemory_operand" ""))
7803 (const_int 0)))]
7804 ""
7805 "")
7806
7807 (define_insn "*testhi_1"
7808 [(set (reg FLAGS_REG)
7809 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7810 (match_operand:HI 1 "general_operand" "n,n,rn"))
7811 (const_int 0)))]
7812 "ix86_match_ccmode (insn, CCNOmode)
7813 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7814 "test{w}\t{%1, %0|%0, %1}"
7815 [(set_attr "type" "test")
7816 (set_attr "modrm" "0,1,1")
7817 (set_attr "mode" "HI")
7818 (set_attr "pent_pair" "uv,np,uv")])
7819
7820 (define_expand "testqi_ccz_1"
7821 [(set (reg:CCZ FLAGS_REG)
7822 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7823 (match_operand:QI 1 "nonmemory_operand" ""))
7824 (const_int 0)))]
7825 ""
7826 "")
7827
7828 (define_insn "*testqi_1_maybe_si"
7829 [(set (reg FLAGS_REG)
7830 (compare
7831 (and:QI
7832 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7833 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7834 (const_int 0)))]
7835 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7836 && ix86_match_ccmode (insn,
7837 CONST_INT_P (operands[1])
7838 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7839 {
7840 if (which_alternative == 3)
7841 {
7842 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7843 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7844 return "test{l}\t{%1, %k0|%k0, %1}";
7845 }
7846 return "test{b}\t{%1, %0|%0, %1}";
7847 }
7848 [(set_attr "type" "test")
7849 (set_attr "modrm" "0,1,1,1")
7850 (set_attr "mode" "QI,QI,QI,SI")
7851 (set_attr "pent_pair" "uv,np,uv,np")])
7852
7853 (define_insn "*testqi_1"
7854 [(set (reg FLAGS_REG)
7855 (compare
7856 (and:QI
7857 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7858 (match_operand:QI 1 "general_operand" "n,n,qn"))
7859 (const_int 0)))]
7860 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7861 && ix86_match_ccmode (insn, CCNOmode)"
7862 "test{b}\t{%1, %0|%0, %1}"
7863 [(set_attr "type" "test")
7864 (set_attr "modrm" "0,1,1")
7865 (set_attr "mode" "QI")
7866 (set_attr "pent_pair" "uv,np,uv")])
7867
7868 (define_expand "testqi_ext_ccno_0"
7869 [(set (reg:CCNO FLAGS_REG)
7870 (compare:CCNO
7871 (and:SI
7872 (zero_extract:SI
7873 (match_operand 0 "ext_register_operand" "")
7874 (const_int 8)
7875 (const_int 8))
7876 (match_operand 1 "const_int_operand" ""))
7877 (const_int 0)))]
7878 ""
7879 "")
7880
7881 (define_insn "*testqi_ext_0"
7882 [(set (reg FLAGS_REG)
7883 (compare
7884 (and:SI
7885 (zero_extract:SI
7886 (match_operand 0 "ext_register_operand" "Q")
7887 (const_int 8)
7888 (const_int 8))
7889 (match_operand 1 "const_int_operand" "n"))
7890 (const_int 0)))]
7891 "ix86_match_ccmode (insn, CCNOmode)"
7892 "test{b}\t{%1, %h0|%h0, %1}"
7893 [(set_attr "type" "test")
7894 (set_attr "mode" "QI")
7895 (set_attr "length_immediate" "1")
7896 (set_attr "pent_pair" "np")])
7897
7898 (define_insn "*testqi_ext_1"
7899 [(set (reg FLAGS_REG)
7900 (compare
7901 (and:SI
7902 (zero_extract:SI
7903 (match_operand 0 "ext_register_operand" "Q")
7904 (const_int 8)
7905 (const_int 8))
7906 (zero_extend:SI
7907 (match_operand:QI 1 "general_operand" "Qm")))
7908 (const_int 0)))]
7909 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7910 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7911 "test{b}\t{%1, %h0|%h0, %1}"
7912 [(set_attr "type" "test")
7913 (set_attr "mode" "QI")])
7914
7915 (define_insn "*testqi_ext_1_rex64"
7916 [(set (reg FLAGS_REG)
7917 (compare
7918 (and:SI
7919 (zero_extract:SI
7920 (match_operand 0 "ext_register_operand" "Q")
7921 (const_int 8)
7922 (const_int 8))
7923 (zero_extend:SI
7924 (match_operand:QI 1 "register_operand" "Q")))
7925 (const_int 0)))]
7926 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7927 "test{b}\t{%1, %h0|%h0, %1}"
7928 [(set_attr "type" "test")
7929 (set_attr "mode" "QI")])
7930
7931 (define_insn "*testqi_ext_2"
7932 [(set (reg FLAGS_REG)
7933 (compare
7934 (and:SI
7935 (zero_extract:SI
7936 (match_operand 0 "ext_register_operand" "Q")
7937 (const_int 8)
7938 (const_int 8))
7939 (zero_extract:SI
7940 (match_operand 1 "ext_register_operand" "Q")
7941 (const_int 8)
7942 (const_int 8)))
7943 (const_int 0)))]
7944 "ix86_match_ccmode (insn, CCNOmode)"
7945 "test{b}\t{%h1, %h0|%h0, %h1}"
7946 [(set_attr "type" "test")
7947 (set_attr "mode" "QI")])
7948
7949 ;; Combine likes to form bit extractions for some tests. Humor it.
7950 (define_insn "*testqi_ext_3"
7951 [(set (reg FLAGS_REG)
7952 (compare (zero_extract:SI
7953 (match_operand 0 "nonimmediate_operand" "rm")
7954 (match_operand:SI 1 "const_int_operand" "")
7955 (match_operand:SI 2 "const_int_operand" ""))
7956 (const_int 0)))]
7957 "ix86_match_ccmode (insn, CCNOmode)
7958 && INTVAL (operands[1]) > 0
7959 && INTVAL (operands[2]) >= 0
7960 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7961 && (GET_MODE (operands[0]) == SImode
7962 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7963 || GET_MODE (operands[0]) == HImode
7964 || GET_MODE (operands[0]) == QImode)"
7965 "#")
7966
7967 (define_insn "*testqi_ext_3_rex64"
7968 [(set (reg FLAGS_REG)
7969 (compare (zero_extract:DI
7970 (match_operand 0 "nonimmediate_operand" "rm")
7971 (match_operand:DI 1 "const_int_operand" "")
7972 (match_operand:DI 2 "const_int_operand" ""))
7973 (const_int 0)))]
7974 "TARGET_64BIT
7975 && ix86_match_ccmode (insn, CCNOmode)
7976 && INTVAL (operands[1]) > 0
7977 && INTVAL (operands[2]) >= 0
7978 /* Ensure that resulting mask is zero or sign extended operand. */
7979 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7980 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7981 && INTVAL (operands[1]) > 32))
7982 && (GET_MODE (operands[0]) == SImode
7983 || GET_MODE (operands[0]) == DImode
7984 || GET_MODE (operands[0]) == HImode
7985 || GET_MODE (operands[0]) == QImode)"
7986 "#")
7987
7988 (define_split
7989 [(set (match_operand 0 "flags_reg_operand" "")
7990 (match_operator 1 "compare_operator"
7991 [(zero_extract
7992 (match_operand 2 "nonimmediate_operand" "")
7993 (match_operand 3 "const_int_operand" "")
7994 (match_operand 4 "const_int_operand" ""))
7995 (const_int 0)]))]
7996 "ix86_match_ccmode (insn, CCNOmode)"
7997 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7998 {
7999 rtx val = operands[2];
8000 HOST_WIDE_INT len = INTVAL (operands[3]);
8001 HOST_WIDE_INT pos = INTVAL (operands[4]);
8002 HOST_WIDE_INT mask;
8003 enum machine_mode mode, submode;
8004
8005 mode = GET_MODE (val);
8006 if (MEM_P (val))
8007 {
8008 /* ??? Combine likes to put non-volatile mem extractions in QImode
8009 no matter the size of the test. So find a mode that works. */
8010 if (! MEM_VOLATILE_P (val))
8011 {
8012 mode = smallest_mode_for_size (pos + len, MODE_INT);
8013 val = adjust_address (val, mode, 0);
8014 }
8015 }
8016 else if (GET_CODE (val) == SUBREG
8017 && (submode = GET_MODE (SUBREG_REG (val)),
8018 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8019 && pos + len <= GET_MODE_BITSIZE (submode))
8020 {
8021 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8022 mode = submode;
8023 val = SUBREG_REG (val);
8024 }
8025 else if (mode == HImode && pos + len <= 8)
8026 {
8027 /* Small HImode tests can be converted to QImode. */
8028 mode = QImode;
8029 val = gen_lowpart (QImode, val);
8030 }
8031
8032 if (len == HOST_BITS_PER_WIDE_INT)
8033 mask = -1;
8034 else
8035 mask = ((HOST_WIDE_INT)1 << len) - 1;
8036 mask <<= pos;
8037
8038 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8039 })
8040
8041 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8042 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8043 ;; this is relatively important trick.
8044 ;; Do the conversion only post-reload to avoid limiting of the register class
8045 ;; to QI regs.
8046 (define_split
8047 [(set (match_operand 0 "flags_reg_operand" "")
8048 (match_operator 1 "compare_operator"
8049 [(and (match_operand 2 "register_operand" "")
8050 (match_operand 3 "const_int_operand" ""))
8051 (const_int 0)]))]
8052 "reload_completed
8053 && QI_REG_P (operands[2])
8054 && GET_MODE (operands[2]) != QImode
8055 && ((ix86_match_ccmode (insn, CCZmode)
8056 && !(INTVAL (operands[3]) & ~(255 << 8)))
8057 || (ix86_match_ccmode (insn, CCNOmode)
8058 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8059 [(set (match_dup 0)
8060 (match_op_dup 1
8061 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8062 (match_dup 3))
8063 (const_int 0)]))]
8064 "operands[2] = gen_lowpart (SImode, operands[2]);
8065 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8066
8067 (define_split
8068 [(set (match_operand 0 "flags_reg_operand" "")
8069 (match_operator 1 "compare_operator"
8070 [(and (match_operand 2 "nonimmediate_operand" "")
8071 (match_operand 3 "const_int_operand" ""))
8072 (const_int 0)]))]
8073 "reload_completed
8074 && GET_MODE (operands[2]) != QImode
8075 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8076 && ((ix86_match_ccmode (insn, CCZmode)
8077 && !(INTVAL (operands[3]) & ~255))
8078 || (ix86_match_ccmode (insn, CCNOmode)
8079 && !(INTVAL (operands[3]) & ~127)))"
8080 [(set (match_dup 0)
8081 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8082 (const_int 0)]))]
8083 "operands[2] = gen_lowpart (QImode, operands[2]);
8084 operands[3] = gen_lowpart (QImode, operands[3]);")
8085
8086
8087 ;; %%% This used to optimize known byte-wide and operations to memory,
8088 ;; and sometimes to QImode registers. If this is considered useful,
8089 ;; it should be done with splitters.
8090
8091 (define_expand "anddi3"
8092 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8093 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8094 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8095 (clobber (reg:CC FLAGS_REG))]
8096 "TARGET_64BIT"
8097 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8098
8099 (define_insn "*anddi_1_rex64"
8100 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8101 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8102 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8103 (clobber (reg:CC FLAGS_REG))]
8104 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8105 {
8106 switch (get_attr_type (insn))
8107 {
8108 case TYPE_IMOVX:
8109 {
8110 enum machine_mode mode;
8111
8112 gcc_assert (CONST_INT_P (operands[2]));
8113 if (INTVAL (operands[2]) == 0xff)
8114 mode = QImode;
8115 else
8116 {
8117 gcc_assert (INTVAL (operands[2]) == 0xffff);
8118 mode = HImode;
8119 }
8120
8121 operands[1] = gen_lowpart (mode, operands[1]);
8122 if (mode == QImode)
8123 return "movz{bq|x}\t{%1,%0|%0, %1}";
8124 else
8125 return "movz{wq|x}\t{%1,%0|%0, %1}";
8126 }
8127
8128 default:
8129 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8130 if (get_attr_mode (insn) == MODE_SI)
8131 return "and{l}\t{%k2, %k0|%k0, %k2}";
8132 else
8133 return "and{q}\t{%2, %0|%0, %2}";
8134 }
8135 }
8136 [(set_attr "type" "alu,alu,alu,imovx")
8137 (set_attr "length_immediate" "*,*,*,0")
8138 (set_attr "mode" "SI,DI,DI,DI")])
8139
8140 (define_insn "*anddi_2"
8141 [(set (reg FLAGS_REG)
8142 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8143 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8144 (const_int 0)))
8145 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8146 (and:DI (match_dup 1) (match_dup 2)))]
8147 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8148 && ix86_binary_operator_ok (AND, DImode, operands)"
8149 "@
8150 and{l}\t{%k2, %k0|%k0, %k2}
8151 and{q}\t{%2, %0|%0, %2}
8152 and{q}\t{%2, %0|%0, %2}"
8153 [(set_attr "type" "alu")
8154 (set_attr "mode" "SI,DI,DI")])
8155
8156 (define_expand "andsi3"
8157 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8158 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8159 (match_operand:SI 2 "general_operand" "")))
8160 (clobber (reg:CC FLAGS_REG))]
8161 ""
8162 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8163
8164 (define_insn "*andsi_1"
8165 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8166 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8167 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8168 (clobber (reg:CC FLAGS_REG))]
8169 "ix86_binary_operator_ok (AND, SImode, operands)"
8170 {
8171 switch (get_attr_type (insn))
8172 {
8173 case TYPE_IMOVX:
8174 {
8175 enum machine_mode mode;
8176
8177 gcc_assert (CONST_INT_P (operands[2]));
8178 if (INTVAL (operands[2]) == 0xff)
8179 mode = QImode;
8180 else
8181 {
8182 gcc_assert (INTVAL (operands[2]) == 0xffff);
8183 mode = HImode;
8184 }
8185
8186 operands[1] = gen_lowpart (mode, operands[1]);
8187 if (mode == QImode)
8188 return "movz{bl|x}\t{%1,%0|%0, %1}";
8189 else
8190 return "movz{wl|x}\t{%1,%0|%0, %1}";
8191 }
8192
8193 default:
8194 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8195 return "and{l}\t{%2, %0|%0, %2}";
8196 }
8197 }
8198 [(set_attr "type" "alu,alu,imovx")
8199 (set_attr "length_immediate" "*,*,0")
8200 (set_attr "mode" "SI")])
8201
8202 (define_split
8203 [(set (match_operand 0 "register_operand" "")
8204 (and (match_dup 0)
8205 (const_int -65536)))
8206 (clobber (reg:CC FLAGS_REG))]
8207 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8208 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8209 "operands[1] = gen_lowpart (HImode, operands[0]);")
8210
8211 (define_split
8212 [(set (match_operand 0 "ext_register_operand" "")
8213 (and (match_dup 0)
8214 (const_int -256)))
8215 (clobber (reg:CC FLAGS_REG))]
8216 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8217 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8218 "operands[1] = gen_lowpart (QImode, operands[0]);")
8219
8220 (define_split
8221 [(set (match_operand 0 "ext_register_operand" "")
8222 (and (match_dup 0)
8223 (const_int -65281)))
8224 (clobber (reg:CC FLAGS_REG))]
8225 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8226 [(parallel [(set (zero_extract:SI (match_dup 0)
8227 (const_int 8)
8228 (const_int 8))
8229 (xor:SI
8230 (zero_extract:SI (match_dup 0)
8231 (const_int 8)
8232 (const_int 8))
8233 (zero_extract:SI (match_dup 0)
8234 (const_int 8)
8235 (const_int 8))))
8236 (clobber (reg:CC FLAGS_REG))])]
8237 "operands[0] = gen_lowpart (SImode, operands[0]);")
8238
8239 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8240 (define_insn "*andsi_1_zext"
8241 [(set (match_operand:DI 0 "register_operand" "=r")
8242 (zero_extend:DI
8243 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8244 (match_operand:SI 2 "general_operand" "rim"))))
8245 (clobber (reg:CC FLAGS_REG))]
8246 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8247 "and{l}\t{%2, %k0|%k0, %2}"
8248 [(set_attr "type" "alu")
8249 (set_attr "mode" "SI")])
8250
8251 (define_insn "*andsi_2"
8252 [(set (reg FLAGS_REG)
8253 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8254 (match_operand:SI 2 "general_operand" "rim,ri"))
8255 (const_int 0)))
8256 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8257 (and:SI (match_dup 1) (match_dup 2)))]
8258 "ix86_match_ccmode (insn, CCNOmode)
8259 && ix86_binary_operator_ok (AND, SImode, operands)"
8260 "and{l}\t{%2, %0|%0, %2}"
8261 [(set_attr "type" "alu")
8262 (set_attr "mode" "SI")])
8263
8264 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8265 (define_insn "*andsi_2_zext"
8266 [(set (reg FLAGS_REG)
8267 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8268 (match_operand:SI 2 "general_operand" "rim"))
8269 (const_int 0)))
8270 (set (match_operand:DI 0 "register_operand" "=r")
8271 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8272 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8273 && ix86_binary_operator_ok (AND, SImode, operands)"
8274 "and{l}\t{%2, %k0|%k0, %2}"
8275 [(set_attr "type" "alu")
8276 (set_attr "mode" "SI")])
8277
8278 (define_expand "andhi3"
8279 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8280 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8281 (match_operand:HI 2 "general_operand" "")))
8282 (clobber (reg:CC FLAGS_REG))]
8283 "TARGET_HIMODE_MATH"
8284 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8285
8286 (define_insn "*andhi_1"
8287 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8288 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8289 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8290 (clobber (reg:CC FLAGS_REG))]
8291 "ix86_binary_operator_ok (AND, HImode, operands)"
8292 {
8293 switch (get_attr_type (insn))
8294 {
8295 case TYPE_IMOVX:
8296 gcc_assert (CONST_INT_P (operands[2]));
8297 gcc_assert (INTVAL (operands[2]) == 0xff);
8298 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8299
8300 default:
8301 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8302
8303 return "and{w}\t{%2, %0|%0, %2}";
8304 }
8305 }
8306 [(set_attr "type" "alu,alu,imovx")
8307 (set_attr "length_immediate" "*,*,0")
8308 (set_attr "mode" "HI,HI,SI")])
8309
8310 (define_insn "*andhi_2"
8311 [(set (reg FLAGS_REG)
8312 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8313 (match_operand:HI 2 "general_operand" "rim,ri"))
8314 (const_int 0)))
8315 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8316 (and:HI (match_dup 1) (match_dup 2)))]
8317 "ix86_match_ccmode (insn, CCNOmode)
8318 && ix86_binary_operator_ok (AND, HImode, operands)"
8319 "and{w}\t{%2, %0|%0, %2}"
8320 [(set_attr "type" "alu")
8321 (set_attr "mode" "HI")])
8322
8323 (define_expand "andqi3"
8324 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8325 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8326 (match_operand:QI 2 "general_operand" "")))
8327 (clobber (reg:CC FLAGS_REG))]
8328 "TARGET_QIMODE_MATH"
8329 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8330
8331 ;; %%% Potential partial reg stall on alternative 2. What to do?
8332 (define_insn "*andqi_1"
8333 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8334 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8335 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8336 (clobber (reg:CC FLAGS_REG))]
8337 "ix86_binary_operator_ok (AND, QImode, operands)"
8338 "@
8339 and{b}\t{%2, %0|%0, %2}
8340 and{b}\t{%2, %0|%0, %2}
8341 and{l}\t{%k2, %k0|%k0, %k2}"
8342 [(set_attr "type" "alu")
8343 (set_attr "mode" "QI,QI,SI")])
8344
8345 (define_insn "*andqi_1_slp"
8346 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8347 (and:QI (match_dup 0)
8348 (match_operand:QI 1 "general_operand" "qi,qmi")))
8349 (clobber (reg:CC FLAGS_REG))]
8350 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8351 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8352 "and{b}\t{%1, %0|%0, %1}"
8353 [(set_attr "type" "alu1")
8354 (set_attr "mode" "QI")])
8355
8356 (define_insn "*andqi_2_maybe_si"
8357 [(set (reg FLAGS_REG)
8358 (compare (and:QI
8359 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8360 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8361 (const_int 0)))
8362 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8363 (and:QI (match_dup 1) (match_dup 2)))]
8364 "ix86_binary_operator_ok (AND, QImode, operands)
8365 && ix86_match_ccmode (insn,
8366 CONST_INT_P (operands[2])
8367 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8368 {
8369 if (which_alternative == 2)
8370 {
8371 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8372 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8373 return "and{l}\t{%2, %k0|%k0, %2}";
8374 }
8375 return "and{b}\t{%2, %0|%0, %2}";
8376 }
8377 [(set_attr "type" "alu")
8378 (set_attr "mode" "QI,QI,SI")])
8379
8380 (define_insn "*andqi_2"
8381 [(set (reg FLAGS_REG)
8382 (compare (and:QI
8383 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8384 (match_operand:QI 2 "general_operand" "qim,qi"))
8385 (const_int 0)))
8386 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8387 (and:QI (match_dup 1) (match_dup 2)))]
8388 "ix86_match_ccmode (insn, CCNOmode)
8389 && ix86_binary_operator_ok (AND, QImode, operands)"
8390 "and{b}\t{%2, %0|%0, %2}"
8391 [(set_attr "type" "alu")
8392 (set_attr "mode" "QI")])
8393
8394 (define_insn "*andqi_2_slp"
8395 [(set (reg FLAGS_REG)
8396 (compare (and:QI
8397 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8398 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8399 (const_int 0)))
8400 (set (strict_low_part (match_dup 0))
8401 (and:QI (match_dup 0) (match_dup 1)))]
8402 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8403 && ix86_match_ccmode (insn, CCNOmode)
8404 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8405 "and{b}\t{%1, %0|%0, %1}"
8406 [(set_attr "type" "alu1")
8407 (set_attr "mode" "QI")])
8408
8409 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8410 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8411 ;; for a QImode operand, which of course failed.
8412
8413 (define_insn "andqi_ext_0"
8414 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8415 (const_int 8)
8416 (const_int 8))
8417 (and:SI
8418 (zero_extract:SI
8419 (match_operand 1 "ext_register_operand" "0")
8420 (const_int 8)
8421 (const_int 8))
8422 (match_operand 2 "const_int_operand" "n")))
8423 (clobber (reg:CC FLAGS_REG))]
8424 ""
8425 "and{b}\t{%2, %h0|%h0, %2}"
8426 [(set_attr "type" "alu")
8427 (set_attr "length_immediate" "1")
8428 (set_attr "mode" "QI")])
8429
8430 ;; Generated by peephole translating test to and. This shows up
8431 ;; often in fp comparisons.
8432
8433 (define_insn "*andqi_ext_0_cc"
8434 [(set (reg FLAGS_REG)
8435 (compare
8436 (and:SI
8437 (zero_extract:SI
8438 (match_operand 1 "ext_register_operand" "0")
8439 (const_int 8)
8440 (const_int 8))
8441 (match_operand 2 "const_int_operand" "n"))
8442 (const_int 0)))
8443 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8444 (const_int 8)
8445 (const_int 8))
8446 (and:SI
8447 (zero_extract:SI
8448 (match_dup 1)
8449 (const_int 8)
8450 (const_int 8))
8451 (match_dup 2)))]
8452 "ix86_match_ccmode (insn, CCNOmode)"
8453 "and{b}\t{%2, %h0|%h0, %2}"
8454 [(set_attr "type" "alu")
8455 (set_attr "length_immediate" "1")
8456 (set_attr "mode" "QI")])
8457
8458 (define_insn "*andqi_ext_1"
8459 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8460 (const_int 8)
8461 (const_int 8))
8462 (and:SI
8463 (zero_extract:SI
8464 (match_operand 1 "ext_register_operand" "0")
8465 (const_int 8)
8466 (const_int 8))
8467 (zero_extend:SI
8468 (match_operand:QI 2 "general_operand" "Qm"))))
8469 (clobber (reg:CC FLAGS_REG))]
8470 "!TARGET_64BIT"
8471 "and{b}\t{%2, %h0|%h0, %2}"
8472 [(set_attr "type" "alu")
8473 (set_attr "length_immediate" "0")
8474 (set_attr "mode" "QI")])
8475
8476 (define_insn "*andqi_ext_1_rex64"
8477 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8478 (const_int 8)
8479 (const_int 8))
8480 (and:SI
8481 (zero_extract:SI
8482 (match_operand 1 "ext_register_operand" "0")
8483 (const_int 8)
8484 (const_int 8))
8485 (zero_extend:SI
8486 (match_operand 2 "ext_register_operand" "Q"))))
8487 (clobber (reg:CC FLAGS_REG))]
8488 "TARGET_64BIT"
8489 "and{b}\t{%2, %h0|%h0, %2}"
8490 [(set_attr "type" "alu")
8491 (set_attr "length_immediate" "0")
8492 (set_attr "mode" "QI")])
8493
8494 (define_insn "*andqi_ext_2"
8495 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8496 (const_int 8)
8497 (const_int 8))
8498 (and:SI
8499 (zero_extract:SI
8500 (match_operand 1 "ext_register_operand" "%0")
8501 (const_int 8)
8502 (const_int 8))
8503 (zero_extract:SI
8504 (match_operand 2 "ext_register_operand" "Q")
8505 (const_int 8)
8506 (const_int 8))))
8507 (clobber (reg:CC FLAGS_REG))]
8508 ""
8509 "and{b}\t{%h2, %h0|%h0, %h2}"
8510 [(set_attr "type" "alu")
8511 (set_attr "length_immediate" "0")
8512 (set_attr "mode" "QI")])
8513
8514 ;; Convert wide AND instructions with immediate operand to shorter QImode
8515 ;; equivalents when possible.
8516 ;; Don't do the splitting with memory operands, since it introduces risk
8517 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8518 ;; for size, but that can (should?) be handled by generic code instead.
8519 (define_split
8520 [(set (match_operand 0 "register_operand" "")
8521 (and (match_operand 1 "register_operand" "")
8522 (match_operand 2 "const_int_operand" "")))
8523 (clobber (reg:CC FLAGS_REG))]
8524 "reload_completed
8525 && QI_REG_P (operands[0])
8526 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8527 && !(~INTVAL (operands[2]) & ~(255 << 8))
8528 && GET_MODE (operands[0]) != QImode"
8529 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8530 (and:SI (zero_extract:SI (match_dup 1)
8531 (const_int 8) (const_int 8))
8532 (match_dup 2)))
8533 (clobber (reg:CC FLAGS_REG))])]
8534 "operands[0] = gen_lowpart (SImode, operands[0]);
8535 operands[1] = gen_lowpart (SImode, operands[1]);
8536 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8537
8538 ;; Since AND can be encoded with sign extended immediate, this is only
8539 ;; profitable when 7th bit is not set.
8540 (define_split
8541 [(set (match_operand 0 "register_operand" "")
8542 (and (match_operand 1 "general_operand" "")
8543 (match_operand 2 "const_int_operand" "")))
8544 (clobber (reg:CC FLAGS_REG))]
8545 "reload_completed
8546 && ANY_QI_REG_P (operands[0])
8547 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8548 && !(~INTVAL (operands[2]) & ~255)
8549 && !(INTVAL (operands[2]) & 128)
8550 && GET_MODE (operands[0]) != QImode"
8551 [(parallel [(set (strict_low_part (match_dup 0))
8552 (and:QI (match_dup 1)
8553 (match_dup 2)))
8554 (clobber (reg:CC FLAGS_REG))])]
8555 "operands[0] = gen_lowpart (QImode, operands[0]);
8556 operands[1] = gen_lowpart (QImode, operands[1]);
8557 operands[2] = gen_lowpart (QImode, operands[2]);")
8558 \f
8559 ;; Logical inclusive OR instructions
8560
8561 ;; %%% This used to optimize known byte-wide and operations to memory.
8562 ;; If this is considered useful, it should be done with splitters.
8563
8564 (define_expand "iordi3"
8565 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8566 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8567 (match_operand:DI 2 "x86_64_general_operand" "")))
8568 (clobber (reg:CC FLAGS_REG))]
8569 "TARGET_64BIT"
8570 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8571
8572 (define_insn "*iordi_1_rex64"
8573 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8574 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8575 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8576 (clobber (reg:CC FLAGS_REG))]
8577 "TARGET_64BIT
8578 && ix86_binary_operator_ok (IOR, DImode, operands)"
8579 "or{q}\t{%2, %0|%0, %2}"
8580 [(set_attr "type" "alu")
8581 (set_attr "mode" "DI")])
8582
8583 (define_insn "*iordi_2_rex64"
8584 [(set (reg FLAGS_REG)
8585 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8586 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8587 (const_int 0)))
8588 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8589 (ior:DI (match_dup 1) (match_dup 2)))]
8590 "TARGET_64BIT
8591 && ix86_match_ccmode (insn, CCNOmode)
8592 && ix86_binary_operator_ok (IOR, DImode, operands)"
8593 "or{q}\t{%2, %0|%0, %2}"
8594 [(set_attr "type" "alu")
8595 (set_attr "mode" "DI")])
8596
8597 (define_insn "*iordi_3_rex64"
8598 [(set (reg FLAGS_REG)
8599 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8600 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8601 (const_int 0)))
8602 (clobber (match_scratch:DI 0 "=r"))]
8603 "TARGET_64BIT
8604 && ix86_match_ccmode (insn, CCNOmode)
8605 && ix86_binary_operator_ok (IOR, DImode, operands)"
8606 "or{q}\t{%2, %0|%0, %2}"
8607 [(set_attr "type" "alu")
8608 (set_attr "mode" "DI")])
8609
8610
8611 (define_expand "iorsi3"
8612 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8613 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8614 (match_operand:SI 2 "general_operand" "")))
8615 (clobber (reg:CC FLAGS_REG))]
8616 ""
8617 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8618
8619 (define_insn "*iorsi_1"
8620 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8621 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8622 (match_operand:SI 2 "general_operand" "ri,rmi")))
8623 (clobber (reg:CC FLAGS_REG))]
8624 "ix86_binary_operator_ok (IOR, SImode, operands)"
8625 "or{l}\t{%2, %0|%0, %2}"
8626 [(set_attr "type" "alu")
8627 (set_attr "mode" "SI")])
8628
8629 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8630 (define_insn "*iorsi_1_zext"
8631 [(set (match_operand:DI 0 "register_operand" "=rm")
8632 (zero_extend:DI
8633 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8634 (match_operand:SI 2 "general_operand" "rim"))))
8635 (clobber (reg:CC FLAGS_REG))]
8636 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8637 "or{l}\t{%2, %k0|%k0, %2}"
8638 [(set_attr "type" "alu")
8639 (set_attr "mode" "SI")])
8640
8641 (define_insn "*iorsi_1_zext_imm"
8642 [(set (match_operand:DI 0 "register_operand" "=rm")
8643 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8644 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8645 (clobber (reg:CC FLAGS_REG))]
8646 "TARGET_64BIT"
8647 "or{l}\t{%2, %k0|%k0, %2}"
8648 [(set_attr "type" "alu")
8649 (set_attr "mode" "SI")])
8650
8651 (define_insn "*iorsi_2"
8652 [(set (reg FLAGS_REG)
8653 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8654 (match_operand:SI 2 "general_operand" "rim,ri"))
8655 (const_int 0)))
8656 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8657 (ior:SI (match_dup 1) (match_dup 2)))]
8658 "ix86_match_ccmode (insn, CCNOmode)
8659 && ix86_binary_operator_ok (IOR, SImode, operands)"
8660 "or{l}\t{%2, %0|%0, %2}"
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
8663
8664 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8665 ;; ??? Special case for immediate operand is missing - it is tricky.
8666 (define_insn "*iorsi_2_zext"
8667 [(set (reg FLAGS_REG)
8668 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8669 (match_operand:SI 2 "general_operand" "rim"))
8670 (const_int 0)))
8671 (set (match_operand:DI 0 "register_operand" "=r")
8672 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8673 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8674 && ix86_binary_operator_ok (IOR, SImode, operands)"
8675 "or{l}\t{%2, %k0|%k0, %2}"
8676 [(set_attr "type" "alu")
8677 (set_attr "mode" "SI")])
8678
8679 (define_insn "*iorsi_2_zext_imm"
8680 [(set (reg FLAGS_REG)
8681 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8682 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8683 (const_int 0)))
8684 (set (match_operand:DI 0 "register_operand" "=r")
8685 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8686 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8687 && ix86_binary_operator_ok (IOR, SImode, operands)"
8688 "or{l}\t{%2, %k0|%k0, %2}"
8689 [(set_attr "type" "alu")
8690 (set_attr "mode" "SI")])
8691
8692 (define_insn "*iorsi_3"
8693 [(set (reg FLAGS_REG)
8694 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8695 (match_operand:SI 2 "general_operand" "rim"))
8696 (const_int 0)))
8697 (clobber (match_scratch:SI 0 "=r"))]
8698 "ix86_match_ccmode (insn, CCNOmode)
8699 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8700 "or{l}\t{%2, %0|%0, %2}"
8701 [(set_attr "type" "alu")
8702 (set_attr "mode" "SI")])
8703
8704 (define_expand "iorhi3"
8705 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8706 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8707 (match_operand:HI 2 "general_operand" "")))
8708 (clobber (reg:CC FLAGS_REG))]
8709 "TARGET_HIMODE_MATH"
8710 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8711
8712 (define_insn "*iorhi_1"
8713 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8714 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8715 (match_operand:HI 2 "general_operand" "rmi,ri")))
8716 (clobber (reg:CC FLAGS_REG))]
8717 "ix86_binary_operator_ok (IOR, HImode, operands)"
8718 "or{w}\t{%2, %0|%0, %2}"
8719 [(set_attr "type" "alu")
8720 (set_attr "mode" "HI")])
8721
8722 (define_insn "*iorhi_2"
8723 [(set (reg FLAGS_REG)
8724 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8725 (match_operand:HI 2 "general_operand" "rim,ri"))
8726 (const_int 0)))
8727 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8728 (ior:HI (match_dup 1) (match_dup 2)))]
8729 "ix86_match_ccmode (insn, CCNOmode)
8730 && ix86_binary_operator_ok (IOR, HImode, operands)"
8731 "or{w}\t{%2, %0|%0, %2}"
8732 [(set_attr "type" "alu")
8733 (set_attr "mode" "HI")])
8734
8735 (define_insn "*iorhi_3"
8736 [(set (reg FLAGS_REG)
8737 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8738 (match_operand:HI 2 "general_operand" "rim"))
8739 (const_int 0)))
8740 (clobber (match_scratch:HI 0 "=r"))]
8741 "ix86_match_ccmode (insn, CCNOmode)
8742 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8743 "or{w}\t{%2, %0|%0, %2}"
8744 [(set_attr "type" "alu")
8745 (set_attr "mode" "HI")])
8746
8747 (define_expand "iorqi3"
8748 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8749 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8750 (match_operand:QI 2 "general_operand" "")))
8751 (clobber (reg:CC FLAGS_REG))]
8752 "TARGET_QIMODE_MATH"
8753 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8754
8755 ;; %%% Potential partial reg stall on alternative 2. What to do?
8756 (define_insn "*iorqi_1"
8757 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8758 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8759 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8760 (clobber (reg:CC FLAGS_REG))]
8761 "ix86_binary_operator_ok (IOR, QImode, operands)"
8762 "@
8763 or{b}\t{%2, %0|%0, %2}
8764 or{b}\t{%2, %0|%0, %2}
8765 or{l}\t{%k2, %k0|%k0, %k2}"
8766 [(set_attr "type" "alu")
8767 (set_attr "mode" "QI,QI,SI")])
8768
8769 (define_insn "*iorqi_1_slp"
8770 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8771 (ior:QI (match_dup 0)
8772 (match_operand:QI 1 "general_operand" "qmi,qi")))
8773 (clobber (reg:CC FLAGS_REG))]
8774 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8775 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8776 "or{b}\t{%1, %0|%0, %1}"
8777 [(set_attr "type" "alu1")
8778 (set_attr "mode" "QI")])
8779
8780 (define_insn "*iorqi_2"
8781 [(set (reg FLAGS_REG)
8782 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8783 (match_operand:QI 2 "general_operand" "qim,qi"))
8784 (const_int 0)))
8785 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8786 (ior:QI (match_dup 1) (match_dup 2)))]
8787 "ix86_match_ccmode (insn, CCNOmode)
8788 && ix86_binary_operator_ok (IOR, QImode, operands)"
8789 "or{b}\t{%2, %0|%0, %2}"
8790 [(set_attr "type" "alu")
8791 (set_attr "mode" "QI")])
8792
8793 (define_insn "*iorqi_2_slp"
8794 [(set (reg FLAGS_REG)
8795 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8796 (match_operand:QI 1 "general_operand" "qim,qi"))
8797 (const_int 0)))
8798 (set (strict_low_part (match_dup 0))
8799 (ior:QI (match_dup 0) (match_dup 1)))]
8800 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8801 && ix86_match_ccmode (insn, CCNOmode)
8802 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8803 "or{b}\t{%1, %0|%0, %1}"
8804 [(set_attr "type" "alu1")
8805 (set_attr "mode" "QI")])
8806
8807 (define_insn "*iorqi_3"
8808 [(set (reg FLAGS_REG)
8809 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8810 (match_operand:QI 2 "general_operand" "qim"))
8811 (const_int 0)))
8812 (clobber (match_scratch:QI 0 "=q"))]
8813 "ix86_match_ccmode (insn, CCNOmode)
8814 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8815 "or{b}\t{%2, %0|%0, %2}"
8816 [(set_attr "type" "alu")
8817 (set_attr "mode" "QI")])
8818
8819 (define_insn "iorqi_ext_0"
8820 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8821 (const_int 8)
8822 (const_int 8))
8823 (ior:SI
8824 (zero_extract:SI
8825 (match_operand 1 "ext_register_operand" "0")
8826 (const_int 8)
8827 (const_int 8))
8828 (match_operand 2 "const_int_operand" "n")))
8829 (clobber (reg:CC FLAGS_REG))]
8830 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8831 "or{b}\t{%2, %h0|%h0, %2}"
8832 [(set_attr "type" "alu")
8833 (set_attr "length_immediate" "1")
8834 (set_attr "mode" "QI")])
8835
8836 (define_insn "*iorqi_ext_1"
8837 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8838 (const_int 8)
8839 (const_int 8))
8840 (ior:SI
8841 (zero_extract:SI
8842 (match_operand 1 "ext_register_operand" "0")
8843 (const_int 8)
8844 (const_int 8))
8845 (zero_extend:SI
8846 (match_operand:QI 2 "general_operand" "Qm"))))
8847 (clobber (reg:CC FLAGS_REG))]
8848 "!TARGET_64BIT
8849 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8850 "or{b}\t{%2, %h0|%h0, %2}"
8851 [(set_attr "type" "alu")
8852 (set_attr "length_immediate" "0")
8853 (set_attr "mode" "QI")])
8854
8855 (define_insn "*iorqi_ext_1_rex64"
8856 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8857 (const_int 8)
8858 (const_int 8))
8859 (ior:SI
8860 (zero_extract:SI
8861 (match_operand 1 "ext_register_operand" "0")
8862 (const_int 8)
8863 (const_int 8))
8864 (zero_extend:SI
8865 (match_operand 2 "ext_register_operand" "Q"))))
8866 (clobber (reg:CC FLAGS_REG))]
8867 "TARGET_64BIT
8868 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8869 "or{b}\t{%2, %h0|%h0, %2}"
8870 [(set_attr "type" "alu")
8871 (set_attr "length_immediate" "0")
8872 (set_attr "mode" "QI")])
8873
8874 (define_insn "*iorqi_ext_2"
8875 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8876 (const_int 8)
8877 (const_int 8))
8878 (ior:SI
8879 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8880 (const_int 8)
8881 (const_int 8))
8882 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8883 (const_int 8)
8884 (const_int 8))))
8885 (clobber (reg:CC FLAGS_REG))]
8886 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8887 "ior{b}\t{%h2, %h0|%h0, %h2}"
8888 [(set_attr "type" "alu")
8889 (set_attr "length_immediate" "0")
8890 (set_attr "mode" "QI")])
8891
8892 (define_split
8893 [(set (match_operand 0 "register_operand" "")
8894 (ior (match_operand 1 "register_operand" "")
8895 (match_operand 2 "const_int_operand" "")))
8896 (clobber (reg:CC FLAGS_REG))]
8897 "reload_completed
8898 && QI_REG_P (operands[0])
8899 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8900 && !(INTVAL (operands[2]) & ~(255 << 8))
8901 && GET_MODE (operands[0]) != QImode"
8902 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8903 (ior:SI (zero_extract:SI (match_dup 1)
8904 (const_int 8) (const_int 8))
8905 (match_dup 2)))
8906 (clobber (reg:CC FLAGS_REG))])]
8907 "operands[0] = gen_lowpart (SImode, operands[0]);
8908 operands[1] = gen_lowpart (SImode, operands[1]);
8909 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8910
8911 ;; Since OR can be encoded with sign extended immediate, this is only
8912 ;; profitable when 7th bit is set.
8913 (define_split
8914 [(set (match_operand 0 "register_operand" "")
8915 (ior (match_operand 1 "general_operand" "")
8916 (match_operand 2 "const_int_operand" "")))
8917 (clobber (reg:CC FLAGS_REG))]
8918 "reload_completed
8919 && ANY_QI_REG_P (operands[0])
8920 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8921 && !(INTVAL (operands[2]) & ~255)
8922 && (INTVAL (operands[2]) & 128)
8923 && GET_MODE (operands[0]) != QImode"
8924 [(parallel [(set (strict_low_part (match_dup 0))
8925 (ior:QI (match_dup 1)
8926 (match_dup 2)))
8927 (clobber (reg:CC FLAGS_REG))])]
8928 "operands[0] = gen_lowpart (QImode, operands[0]);
8929 operands[1] = gen_lowpart (QImode, operands[1]);
8930 operands[2] = gen_lowpart (QImode, operands[2]);")
8931 \f
8932 ;; Logical XOR instructions
8933
8934 ;; %%% This used to optimize known byte-wide and operations to memory.
8935 ;; If this is considered useful, it should be done with splitters.
8936
8937 (define_expand "xordi3"
8938 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8939 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8940 (match_operand:DI 2 "x86_64_general_operand" "")))
8941 (clobber (reg:CC FLAGS_REG))]
8942 "TARGET_64BIT"
8943 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8944
8945 (define_insn "*xordi_1_rex64"
8946 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8947 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8948 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8949 (clobber (reg:CC FLAGS_REG))]
8950 "TARGET_64BIT
8951 && ix86_binary_operator_ok (XOR, DImode, operands)"
8952 "@
8953 xor{q}\t{%2, %0|%0, %2}
8954 xor{q}\t{%2, %0|%0, %2}"
8955 [(set_attr "type" "alu")
8956 (set_attr "mode" "DI,DI")])
8957
8958 (define_insn "*xordi_2_rex64"
8959 [(set (reg FLAGS_REG)
8960 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8961 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8962 (const_int 0)))
8963 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8964 (xor:DI (match_dup 1) (match_dup 2)))]
8965 "TARGET_64BIT
8966 && ix86_match_ccmode (insn, CCNOmode)
8967 && ix86_binary_operator_ok (XOR, DImode, operands)"
8968 "@
8969 xor{q}\t{%2, %0|%0, %2}
8970 xor{q}\t{%2, %0|%0, %2}"
8971 [(set_attr "type" "alu")
8972 (set_attr "mode" "DI,DI")])
8973
8974 (define_insn "*xordi_3_rex64"
8975 [(set (reg FLAGS_REG)
8976 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8977 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8978 (const_int 0)))
8979 (clobber (match_scratch:DI 0 "=r"))]
8980 "TARGET_64BIT
8981 && ix86_match_ccmode (insn, CCNOmode)
8982 && ix86_binary_operator_ok (XOR, DImode, operands)"
8983 "xor{q}\t{%2, %0|%0, %2}"
8984 [(set_attr "type" "alu")
8985 (set_attr "mode" "DI")])
8986
8987 (define_expand "xorsi3"
8988 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8989 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8990 (match_operand:SI 2 "general_operand" "")))
8991 (clobber (reg:CC FLAGS_REG))]
8992 ""
8993 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8994
8995 (define_insn "*xorsi_1"
8996 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8997 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8998 (match_operand:SI 2 "general_operand" "ri,rm")))
8999 (clobber (reg:CC FLAGS_REG))]
9000 "ix86_binary_operator_ok (XOR, SImode, operands)"
9001 "xor{l}\t{%2, %0|%0, %2}"
9002 [(set_attr "type" "alu")
9003 (set_attr "mode" "SI")])
9004
9005 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9006 ;; Add speccase for immediates
9007 (define_insn "*xorsi_1_zext"
9008 [(set (match_operand:DI 0 "register_operand" "=r")
9009 (zero_extend:DI
9010 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9011 (match_operand:SI 2 "general_operand" "rim"))))
9012 (clobber (reg:CC FLAGS_REG))]
9013 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9014 "xor{l}\t{%2, %k0|%k0, %2}"
9015 [(set_attr "type" "alu")
9016 (set_attr "mode" "SI")])
9017
9018 (define_insn "*xorsi_1_zext_imm"
9019 [(set (match_operand:DI 0 "register_operand" "=r")
9020 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9021 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9022 (clobber (reg:CC FLAGS_REG))]
9023 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9024 "xor{l}\t{%2, %k0|%k0, %2}"
9025 [(set_attr "type" "alu")
9026 (set_attr "mode" "SI")])
9027
9028 (define_insn "*xorsi_2"
9029 [(set (reg FLAGS_REG)
9030 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9031 (match_operand:SI 2 "general_operand" "rim,ri"))
9032 (const_int 0)))
9033 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9034 (xor:SI (match_dup 1) (match_dup 2)))]
9035 "ix86_match_ccmode (insn, CCNOmode)
9036 && ix86_binary_operator_ok (XOR, SImode, operands)"
9037 "xor{l}\t{%2, %0|%0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "SI")])
9040
9041 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9042 ;; ??? Special case for immediate operand is missing - it is tricky.
9043 (define_insn "*xorsi_2_zext"
9044 [(set (reg FLAGS_REG)
9045 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9046 (match_operand:SI 2 "general_operand" "rim"))
9047 (const_int 0)))
9048 (set (match_operand:DI 0 "register_operand" "=r")
9049 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9050 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9051 && ix86_binary_operator_ok (XOR, SImode, operands)"
9052 "xor{l}\t{%2, %k0|%k0, %2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "mode" "SI")])
9055
9056 (define_insn "*xorsi_2_zext_imm"
9057 [(set (reg FLAGS_REG)
9058 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9059 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9060 (const_int 0)))
9061 (set (match_operand:DI 0 "register_operand" "=r")
9062 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9063 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9064 && ix86_binary_operator_ok (XOR, SImode, operands)"
9065 "xor{l}\t{%2, %k0|%k0, %2}"
9066 [(set_attr "type" "alu")
9067 (set_attr "mode" "SI")])
9068
9069 (define_insn "*xorsi_3"
9070 [(set (reg FLAGS_REG)
9071 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9072 (match_operand:SI 2 "general_operand" "rim"))
9073 (const_int 0)))
9074 (clobber (match_scratch:SI 0 "=r"))]
9075 "ix86_match_ccmode (insn, CCNOmode)
9076 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9077 "xor{l}\t{%2, %0|%0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "mode" "SI")])
9080
9081 (define_expand "xorhi3"
9082 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9083 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9084 (match_operand:HI 2 "general_operand" "")))
9085 (clobber (reg:CC FLAGS_REG))]
9086 "TARGET_HIMODE_MATH"
9087 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9088
9089 (define_insn "*xorhi_1"
9090 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9091 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9092 (match_operand:HI 2 "general_operand" "rmi,ri")))
9093 (clobber (reg:CC FLAGS_REG))]
9094 "ix86_binary_operator_ok (XOR, HImode, operands)"
9095 "xor{w}\t{%2, %0|%0, %2}"
9096 [(set_attr "type" "alu")
9097 (set_attr "mode" "HI")])
9098
9099 (define_insn "*xorhi_2"
9100 [(set (reg FLAGS_REG)
9101 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9102 (match_operand:HI 2 "general_operand" "rim,ri"))
9103 (const_int 0)))
9104 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9105 (xor:HI (match_dup 1) (match_dup 2)))]
9106 "ix86_match_ccmode (insn, CCNOmode)
9107 && ix86_binary_operator_ok (XOR, HImode, operands)"
9108 "xor{w}\t{%2, %0|%0, %2}"
9109 [(set_attr "type" "alu")
9110 (set_attr "mode" "HI")])
9111
9112 (define_insn "*xorhi_3"
9113 [(set (reg FLAGS_REG)
9114 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9115 (match_operand:HI 2 "general_operand" "rim"))
9116 (const_int 0)))
9117 (clobber (match_scratch:HI 0 "=r"))]
9118 "ix86_match_ccmode (insn, CCNOmode)
9119 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9120 "xor{w}\t{%2, %0|%0, %2}"
9121 [(set_attr "type" "alu")
9122 (set_attr "mode" "HI")])
9123
9124 (define_expand "xorqi3"
9125 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9126 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9127 (match_operand:QI 2 "general_operand" "")))
9128 (clobber (reg:CC FLAGS_REG))]
9129 "TARGET_QIMODE_MATH"
9130 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9131
9132 ;; %%% Potential partial reg stall on alternative 2. What to do?
9133 (define_insn "*xorqi_1"
9134 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9135 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9136 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9137 (clobber (reg:CC FLAGS_REG))]
9138 "ix86_binary_operator_ok (XOR, QImode, operands)"
9139 "@
9140 xor{b}\t{%2, %0|%0, %2}
9141 xor{b}\t{%2, %0|%0, %2}
9142 xor{l}\t{%k2, %k0|%k0, %k2}"
9143 [(set_attr "type" "alu")
9144 (set_attr "mode" "QI,QI,SI")])
9145
9146 (define_insn "*xorqi_1_slp"
9147 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9148 (xor:QI (match_dup 0)
9149 (match_operand:QI 1 "general_operand" "qi,qmi")))
9150 (clobber (reg:CC FLAGS_REG))]
9151 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9152 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9153 "xor{b}\t{%1, %0|%0, %1}"
9154 [(set_attr "type" "alu1")
9155 (set_attr "mode" "QI")])
9156
9157 (define_insn "xorqi_ext_0"
9158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159 (const_int 8)
9160 (const_int 8))
9161 (xor:SI
9162 (zero_extract:SI
9163 (match_operand 1 "ext_register_operand" "0")
9164 (const_int 8)
9165 (const_int 8))
9166 (match_operand 2 "const_int_operand" "n")))
9167 (clobber (reg:CC FLAGS_REG))]
9168 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9169 "xor{b}\t{%2, %h0|%h0, %2}"
9170 [(set_attr "type" "alu")
9171 (set_attr "length_immediate" "1")
9172 (set_attr "mode" "QI")])
9173
9174 (define_insn "*xorqi_ext_1"
9175 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9176 (const_int 8)
9177 (const_int 8))
9178 (xor:SI
9179 (zero_extract:SI
9180 (match_operand 1 "ext_register_operand" "0")
9181 (const_int 8)
9182 (const_int 8))
9183 (zero_extend:SI
9184 (match_operand:QI 2 "general_operand" "Qm"))))
9185 (clobber (reg:CC FLAGS_REG))]
9186 "!TARGET_64BIT
9187 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9188 "xor{b}\t{%2, %h0|%h0, %2}"
9189 [(set_attr "type" "alu")
9190 (set_attr "length_immediate" "0")
9191 (set_attr "mode" "QI")])
9192
9193 (define_insn "*xorqi_ext_1_rex64"
9194 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9195 (const_int 8)
9196 (const_int 8))
9197 (xor:SI
9198 (zero_extract:SI
9199 (match_operand 1 "ext_register_operand" "0")
9200 (const_int 8)
9201 (const_int 8))
9202 (zero_extend:SI
9203 (match_operand 2 "ext_register_operand" "Q"))))
9204 (clobber (reg:CC FLAGS_REG))]
9205 "TARGET_64BIT
9206 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9207 "xor{b}\t{%2, %h0|%h0, %2}"
9208 [(set_attr "type" "alu")
9209 (set_attr "length_immediate" "0")
9210 (set_attr "mode" "QI")])
9211
9212 (define_insn "*xorqi_ext_2"
9213 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9214 (const_int 8)
9215 (const_int 8))
9216 (xor:SI
9217 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9218 (const_int 8)
9219 (const_int 8))
9220 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9221 (const_int 8)
9222 (const_int 8))))
9223 (clobber (reg:CC FLAGS_REG))]
9224 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9225 "xor{b}\t{%h2, %h0|%h0, %h2}"
9226 [(set_attr "type" "alu")
9227 (set_attr "length_immediate" "0")
9228 (set_attr "mode" "QI")])
9229
9230 (define_insn "*xorqi_cc_1"
9231 [(set (reg FLAGS_REG)
9232 (compare
9233 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9234 (match_operand:QI 2 "general_operand" "qim,qi"))
9235 (const_int 0)))
9236 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9237 (xor:QI (match_dup 1) (match_dup 2)))]
9238 "ix86_match_ccmode (insn, CCNOmode)
9239 && ix86_binary_operator_ok (XOR, QImode, operands)"
9240 "xor{b}\t{%2, %0|%0, %2}"
9241 [(set_attr "type" "alu")
9242 (set_attr "mode" "QI")])
9243
9244 (define_insn "*xorqi_2_slp"
9245 [(set (reg FLAGS_REG)
9246 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9247 (match_operand:QI 1 "general_operand" "qim,qi"))
9248 (const_int 0)))
9249 (set (strict_low_part (match_dup 0))
9250 (xor:QI (match_dup 0) (match_dup 1)))]
9251 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9252 && ix86_match_ccmode (insn, CCNOmode)
9253 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9254 "xor{b}\t{%1, %0|%0, %1}"
9255 [(set_attr "type" "alu1")
9256 (set_attr "mode" "QI")])
9257
9258 (define_insn "*xorqi_cc_2"
9259 [(set (reg FLAGS_REG)
9260 (compare
9261 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9262 (match_operand:QI 2 "general_operand" "qim"))
9263 (const_int 0)))
9264 (clobber (match_scratch:QI 0 "=q"))]
9265 "ix86_match_ccmode (insn, CCNOmode)
9266 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9267 "xor{b}\t{%2, %0|%0, %2}"
9268 [(set_attr "type" "alu")
9269 (set_attr "mode" "QI")])
9270
9271 (define_insn "*xorqi_cc_ext_1"
9272 [(set (reg FLAGS_REG)
9273 (compare
9274 (xor:SI
9275 (zero_extract:SI
9276 (match_operand 1 "ext_register_operand" "0")
9277 (const_int 8)
9278 (const_int 8))
9279 (match_operand:QI 2 "general_operand" "qmn"))
9280 (const_int 0)))
9281 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
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 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9288 "xor{b}\t{%2, %h0|%h0, %2}"
9289 [(set_attr "type" "alu")
9290 (set_attr "mode" "QI")])
9291
9292 (define_insn "*xorqi_cc_ext_1_rex64"
9293 [(set (reg FLAGS_REG)
9294 (compare
9295 (xor:SI
9296 (zero_extract:SI
9297 (match_operand 1 "ext_register_operand" "0")
9298 (const_int 8)
9299 (const_int 8))
9300 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9301 (const_int 0)))
9302 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9303 (const_int 8)
9304 (const_int 8))
9305 (xor:SI
9306 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9307 (match_dup 2)))]
9308 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9309 "xor{b}\t{%2, %h0|%h0, %2}"
9310 [(set_attr "type" "alu")
9311 (set_attr "mode" "QI")])
9312
9313 (define_expand "xorqi_cc_ext_1"
9314 [(parallel [
9315 (set (reg:CCNO FLAGS_REG)
9316 (compare:CCNO
9317 (xor:SI
9318 (zero_extract:SI
9319 (match_operand 1 "ext_register_operand" "")
9320 (const_int 8)
9321 (const_int 8))
9322 (match_operand:QI 2 "general_operand" ""))
9323 (const_int 0)))
9324 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9325 (const_int 8)
9326 (const_int 8))
9327 (xor:SI
9328 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9329 (match_dup 2)))])]
9330 ""
9331 "")
9332
9333 (define_split
9334 [(set (match_operand 0 "register_operand" "")
9335 (xor (match_operand 1 "register_operand" "")
9336 (match_operand 2 "const_int_operand" "")))
9337 (clobber (reg:CC FLAGS_REG))]
9338 "reload_completed
9339 && QI_REG_P (operands[0])
9340 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9341 && !(INTVAL (operands[2]) & ~(255 << 8))
9342 && GET_MODE (operands[0]) != QImode"
9343 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9344 (xor:SI (zero_extract:SI (match_dup 1)
9345 (const_int 8) (const_int 8))
9346 (match_dup 2)))
9347 (clobber (reg:CC FLAGS_REG))])]
9348 "operands[0] = gen_lowpart (SImode, operands[0]);
9349 operands[1] = gen_lowpart (SImode, operands[1]);
9350 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9351
9352 ;; Since XOR can be encoded with sign extended immediate, this is only
9353 ;; profitable when 7th bit is set.
9354 (define_split
9355 [(set (match_operand 0 "register_operand" "")
9356 (xor (match_operand 1 "general_operand" "")
9357 (match_operand 2 "const_int_operand" "")))
9358 (clobber (reg:CC FLAGS_REG))]
9359 "reload_completed
9360 && ANY_QI_REG_P (operands[0])
9361 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9362 && !(INTVAL (operands[2]) & ~255)
9363 && (INTVAL (operands[2]) & 128)
9364 && GET_MODE (operands[0]) != QImode"
9365 [(parallel [(set (strict_low_part (match_dup 0))
9366 (xor:QI (match_dup 1)
9367 (match_dup 2)))
9368 (clobber (reg:CC FLAGS_REG))])]
9369 "operands[0] = gen_lowpart (QImode, operands[0]);
9370 operands[1] = gen_lowpart (QImode, operands[1]);
9371 operands[2] = gen_lowpart (QImode, operands[2]);")
9372 \f
9373 ;; Negation instructions
9374
9375 (define_expand "negti2"
9376 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9377 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9378 (clobber (reg:CC FLAGS_REG))])]
9379 "TARGET_64BIT"
9380 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9381
9382 (define_insn "*negti2_1"
9383 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9384 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9385 (clobber (reg:CC FLAGS_REG))]
9386 "TARGET_64BIT
9387 && ix86_unary_operator_ok (NEG, TImode, operands)"
9388 "#")
9389
9390 (define_split
9391 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9392 (neg:TI (match_operand:TI 1 "general_operand" "")))
9393 (clobber (reg:CC FLAGS_REG))]
9394 "TARGET_64BIT && reload_completed"
9395 [(parallel
9396 [(set (reg:CCZ FLAGS_REG)
9397 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9398 (set (match_dup 0) (neg:DI (match_dup 2)))])
9399 (parallel
9400 [(set (match_dup 1)
9401 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9402 (match_dup 3))
9403 (const_int 0)))
9404 (clobber (reg:CC FLAGS_REG))])
9405 (parallel
9406 [(set (match_dup 1)
9407 (neg:DI (match_dup 1)))
9408 (clobber (reg:CC FLAGS_REG))])]
9409 "split_ti (operands+1, 1, operands+2, operands+3);
9410 split_ti (operands+0, 1, operands+0, operands+1);")
9411
9412 (define_expand "negdi2"
9413 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9414 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9415 (clobber (reg:CC FLAGS_REG))])]
9416 ""
9417 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9418
9419 (define_insn "*negdi2_1"
9420 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9421 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9422 (clobber (reg:CC FLAGS_REG))]
9423 "!TARGET_64BIT
9424 && ix86_unary_operator_ok (NEG, DImode, operands)"
9425 "#")
9426
9427 (define_split
9428 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9429 (neg:DI (match_operand:DI 1 "general_operand" "")))
9430 (clobber (reg:CC FLAGS_REG))]
9431 "!TARGET_64BIT && reload_completed"
9432 [(parallel
9433 [(set (reg:CCZ FLAGS_REG)
9434 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9435 (set (match_dup 0) (neg:SI (match_dup 2)))])
9436 (parallel
9437 [(set (match_dup 1)
9438 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9439 (match_dup 3))
9440 (const_int 0)))
9441 (clobber (reg:CC FLAGS_REG))])
9442 (parallel
9443 [(set (match_dup 1)
9444 (neg:SI (match_dup 1)))
9445 (clobber (reg:CC FLAGS_REG))])]
9446 "split_di (operands+1, 1, operands+2, operands+3);
9447 split_di (operands+0, 1, operands+0, operands+1);")
9448
9449 (define_insn "*negdi2_1_rex64"
9450 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9451 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9452 (clobber (reg:CC FLAGS_REG))]
9453 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9454 "neg{q}\t%0"
9455 [(set_attr "type" "negnot")
9456 (set_attr "mode" "DI")])
9457
9458 ;; The problem with neg is that it does not perform (compare x 0),
9459 ;; it really performs (compare 0 x), which leaves us with the zero
9460 ;; flag being the only useful item.
9461
9462 (define_insn "*negdi2_cmpz_rex64"
9463 [(set (reg:CCZ FLAGS_REG)
9464 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9465 (const_int 0)))
9466 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9467 (neg:DI (match_dup 1)))]
9468 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9469 "neg{q}\t%0"
9470 [(set_attr "type" "negnot")
9471 (set_attr "mode" "DI")])
9472
9473
9474 (define_expand "negsi2"
9475 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9476 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9477 (clobber (reg:CC FLAGS_REG))])]
9478 ""
9479 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9480
9481 (define_insn "*negsi2_1"
9482 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9483 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9484 (clobber (reg:CC FLAGS_REG))]
9485 "ix86_unary_operator_ok (NEG, SImode, operands)"
9486 "neg{l}\t%0"
9487 [(set_attr "type" "negnot")
9488 (set_attr "mode" "SI")])
9489
9490 ;; Combine is quite creative about this pattern.
9491 (define_insn "*negsi2_1_zext"
9492 [(set (match_operand:DI 0 "register_operand" "=r")
9493 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9494 (const_int 32)))
9495 (const_int 32)))
9496 (clobber (reg:CC FLAGS_REG))]
9497 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9498 "neg{l}\t%k0"
9499 [(set_attr "type" "negnot")
9500 (set_attr "mode" "SI")])
9501
9502 ;; The problem with neg is that it does not perform (compare x 0),
9503 ;; it really performs (compare 0 x), which leaves us with the zero
9504 ;; flag being the only useful item.
9505
9506 (define_insn "*negsi2_cmpz"
9507 [(set (reg:CCZ FLAGS_REG)
9508 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9509 (const_int 0)))
9510 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9511 (neg:SI (match_dup 1)))]
9512 "ix86_unary_operator_ok (NEG, SImode, operands)"
9513 "neg{l}\t%0"
9514 [(set_attr "type" "negnot")
9515 (set_attr "mode" "SI")])
9516
9517 (define_insn "*negsi2_cmpz_zext"
9518 [(set (reg:CCZ FLAGS_REG)
9519 (compare:CCZ (lshiftrt:DI
9520 (neg:DI (ashift:DI
9521 (match_operand:DI 1 "register_operand" "0")
9522 (const_int 32)))
9523 (const_int 32))
9524 (const_int 0)))
9525 (set (match_operand:DI 0 "register_operand" "=r")
9526 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9527 (const_int 32)))
9528 (const_int 32)))]
9529 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9530 "neg{l}\t%k0"
9531 [(set_attr "type" "negnot")
9532 (set_attr "mode" "SI")])
9533
9534 (define_expand "neghi2"
9535 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9536 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9537 (clobber (reg:CC FLAGS_REG))])]
9538 "TARGET_HIMODE_MATH"
9539 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9540
9541 (define_insn "*neghi2_1"
9542 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9543 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9544 (clobber (reg:CC FLAGS_REG))]
9545 "ix86_unary_operator_ok (NEG, HImode, operands)"
9546 "neg{w}\t%0"
9547 [(set_attr "type" "negnot")
9548 (set_attr "mode" "HI")])
9549
9550 (define_insn "*neghi2_cmpz"
9551 [(set (reg:CCZ FLAGS_REG)
9552 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9553 (const_int 0)))
9554 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9555 (neg:HI (match_dup 1)))]
9556 "ix86_unary_operator_ok (NEG, HImode, operands)"
9557 "neg{w}\t%0"
9558 [(set_attr "type" "negnot")
9559 (set_attr "mode" "HI")])
9560
9561 (define_expand "negqi2"
9562 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9563 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9564 (clobber (reg:CC FLAGS_REG))])]
9565 "TARGET_QIMODE_MATH"
9566 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9567
9568 (define_insn "*negqi2_1"
9569 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9570 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9571 (clobber (reg:CC FLAGS_REG))]
9572 "ix86_unary_operator_ok (NEG, QImode, operands)"
9573 "neg{b}\t%0"
9574 [(set_attr "type" "negnot")
9575 (set_attr "mode" "QI")])
9576
9577 (define_insn "*negqi2_cmpz"
9578 [(set (reg:CCZ FLAGS_REG)
9579 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9580 (const_int 0)))
9581 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9582 (neg:QI (match_dup 1)))]
9583 "ix86_unary_operator_ok (NEG, QImode, operands)"
9584 "neg{b}\t%0"
9585 [(set_attr "type" "negnot")
9586 (set_attr "mode" "QI")])
9587
9588 ;; Changing of sign for FP values is doable using integer unit too.
9589
9590 (define_expand "negsf2"
9591 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9592 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9593 "TARGET_80387 || TARGET_SSE_MATH"
9594 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9595
9596 (define_expand "abssf2"
9597 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9598 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9599 "TARGET_80387 || TARGET_SSE_MATH"
9600 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9601
9602 (define_insn "*absnegsf2_mixed"
9603 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9604 (match_operator:SF 3 "absneg_operator"
9605 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9606 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9607 (clobber (reg:CC FLAGS_REG))]
9608 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9609 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9610 "#")
9611
9612 (define_insn "*absnegsf2_sse"
9613 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9614 (match_operator:SF 3 "absneg_operator"
9615 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9616 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9617 (clobber (reg:CC FLAGS_REG))]
9618 "TARGET_SSE_MATH
9619 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9620 "#")
9621
9622 (define_insn "*absnegsf2_i387"
9623 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9624 (match_operator:SF 3 "absneg_operator"
9625 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9626 (use (match_operand 2 "" ""))
9627 (clobber (reg:CC FLAGS_REG))]
9628 "TARGET_80387 && !TARGET_SSE_MATH
9629 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9630 "#")
9631
9632 (define_expand "copysignsf3"
9633 [(match_operand:SF 0 "register_operand" "")
9634 (match_operand:SF 1 "nonmemory_operand" "")
9635 (match_operand:SF 2 "register_operand" "")]
9636 "TARGET_SSE_MATH"
9637 {
9638 ix86_expand_copysign (operands);
9639 DONE;
9640 })
9641
9642 (define_insn_and_split "copysignsf3_const"
9643 [(set (match_operand:SF 0 "register_operand" "=x")
9644 (unspec:SF
9645 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9646 (match_operand:SF 2 "register_operand" "0")
9647 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9648 UNSPEC_COPYSIGN))]
9649 "TARGET_SSE_MATH"
9650 "#"
9651 "&& reload_completed"
9652 [(const_int 0)]
9653 {
9654 ix86_split_copysign_const (operands);
9655 DONE;
9656 })
9657
9658 (define_insn "copysignsf3_var"
9659 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9660 (unspec:SF
9661 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9662 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9663 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9664 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9665 UNSPEC_COPYSIGN))
9666 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9667 "TARGET_SSE_MATH"
9668 "#")
9669
9670 (define_split
9671 [(set (match_operand:SF 0 "register_operand" "")
9672 (unspec:SF
9673 [(match_operand:SF 2 "register_operand" "")
9674 (match_operand:SF 3 "register_operand" "")
9675 (match_operand:V4SF 4 "" "")
9676 (match_operand:V4SF 5 "" "")]
9677 UNSPEC_COPYSIGN))
9678 (clobber (match_scratch:V4SF 1 ""))]
9679 "TARGET_SSE_MATH && reload_completed"
9680 [(const_int 0)]
9681 {
9682 ix86_split_copysign_var (operands);
9683 DONE;
9684 })
9685
9686 (define_expand "negdf2"
9687 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9688 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9689 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9690 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9691
9692 (define_expand "absdf2"
9693 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9694 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9695 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9696 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9697
9698 (define_insn "*absnegdf2_mixed"
9699 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9700 (match_operator:DF 3 "absneg_operator"
9701 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9702 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9703 (clobber (reg:CC FLAGS_REG))]
9704 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9705 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9706 "#")
9707
9708 (define_insn "*absnegdf2_sse"
9709 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9710 (match_operator:DF 3 "absneg_operator"
9711 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9712 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9713 (clobber (reg:CC FLAGS_REG))]
9714 "TARGET_SSE2 && TARGET_SSE_MATH
9715 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9716 "#")
9717
9718 (define_insn "*absnegdf2_i387"
9719 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9720 (match_operator:DF 3 "absneg_operator"
9721 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9722 (use (match_operand 2 "" ""))
9723 (clobber (reg:CC FLAGS_REG))]
9724 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9725 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9726 "#")
9727
9728 (define_expand "copysigndf3"
9729 [(match_operand:DF 0 "register_operand" "")
9730 (match_operand:DF 1 "nonmemory_operand" "")
9731 (match_operand:DF 2 "register_operand" "")]
9732 "TARGET_SSE2 && TARGET_SSE_MATH"
9733 {
9734 ix86_expand_copysign (operands);
9735 DONE;
9736 })
9737
9738 (define_insn_and_split "copysigndf3_const"
9739 [(set (match_operand:DF 0 "register_operand" "=x")
9740 (unspec:DF
9741 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9742 (match_operand:DF 2 "register_operand" "0")
9743 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9744 UNSPEC_COPYSIGN))]
9745 "TARGET_SSE2 && TARGET_SSE_MATH"
9746 "#"
9747 "&& reload_completed"
9748 [(const_int 0)]
9749 {
9750 ix86_split_copysign_const (operands);
9751 DONE;
9752 })
9753
9754 (define_insn "copysigndf3_var"
9755 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9756 (unspec:DF
9757 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9758 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9759 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9760 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9761 UNSPEC_COPYSIGN))
9762 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9763 "TARGET_SSE2 && TARGET_SSE_MATH"
9764 "#")
9765
9766 (define_split
9767 [(set (match_operand:DF 0 "register_operand" "")
9768 (unspec:DF
9769 [(match_operand:DF 2 "register_operand" "")
9770 (match_operand:DF 3 "register_operand" "")
9771 (match_operand:V2DF 4 "" "")
9772 (match_operand:V2DF 5 "" "")]
9773 UNSPEC_COPYSIGN))
9774 (clobber (match_scratch:V2DF 1 ""))]
9775 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9776 [(const_int 0)]
9777 {
9778 ix86_split_copysign_var (operands);
9779 DONE;
9780 })
9781
9782 (define_expand "negxf2"
9783 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9784 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9785 "TARGET_80387"
9786 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9787
9788 (define_expand "absxf2"
9789 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9790 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9791 "TARGET_80387"
9792 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9793
9794 (define_insn "*absnegxf2_i387"
9795 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9796 (match_operator:XF 3 "absneg_operator"
9797 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9798 (use (match_operand 2 "" ""))
9799 (clobber (reg:CC FLAGS_REG))]
9800 "TARGET_80387
9801 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9802 "#")
9803
9804 ;; Splitters for fp abs and neg.
9805
9806 (define_split
9807 [(set (match_operand 0 "fp_register_operand" "")
9808 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9809 (use (match_operand 2 "" ""))
9810 (clobber (reg:CC FLAGS_REG))]
9811 "reload_completed"
9812 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9813
9814 (define_split
9815 [(set (match_operand 0 "register_operand" "")
9816 (match_operator 3 "absneg_operator"
9817 [(match_operand 1 "register_operand" "")]))
9818 (use (match_operand 2 "nonimmediate_operand" ""))
9819 (clobber (reg:CC FLAGS_REG))]
9820 "reload_completed && SSE_REG_P (operands[0])"
9821 [(set (match_dup 0) (match_dup 3))]
9822 {
9823 enum machine_mode mode = GET_MODE (operands[0]);
9824 enum machine_mode vmode = GET_MODE (operands[2]);
9825 rtx tmp;
9826
9827 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9828 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9829 if (operands_match_p (operands[0], operands[2]))
9830 {
9831 tmp = operands[1];
9832 operands[1] = operands[2];
9833 operands[2] = tmp;
9834 }
9835 if (GET_CODE (operands[3]) == ABS)
9836 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9837 else
9838 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9839 operands[3] = tmp;
9840 })
9841
9842 (define_split
9843 [(set (match_operand:SF 0 "register_operand" "")
9844 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9845 (use (match_operand:V4SF 2 "" ""))
9846 (clobber (reg:CC FLAGS_REG))]
9847 "reload_completed"
9848 [(parallel [(set (match_dup 0) (match_dup 1))
9849 (clobber (reg:CC FLAGS_REG))])]
9850 {
9851 rtx tmp;
9852 operands[0] = gen_lowpart (SImode, operands[0]);
9853 if (GET_CODE (operands[1]) == ABS)
9854 {
9855 tmp = gen_int_mode (0x7fffffff, SImode);
9856 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9857 }
9858 else
9859 {
9860 tmp = gen_int_mode (0x80000000, SImode);
9861 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9862 }
9863 operands[1] = tmp;
9864 })
9865
9866 (define_split
9867 [(set (match_operand:DF 0 "register_operand" "")
9868 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9869 (use (match_operand 2 "" ""))
9870 (clobber (reg:CC FLAGS_REG))]
9871 "reload_completed"
9872 [(parallel [(set (match_dup 0) (match_dup 1))
9873 (clobber (reg:CC FLAGS_REG))])]
9874 {
9875 rtx tmp;
9876 if (TARGET_64BIT)
9877 {
9878 tmp = gen_lowpart (DImode, operands[0]);
9879 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9880 operands[0] = tmp;
9881
9882 if (GET_CODE (operands[1]) == ABS)
9883 tmp = const0_rtx;
9884 else
9885 tmp = gen_rtx_NOT (DImode, tmp);
9886 }
9887 else
9888 {
9889 operands[0] = gen_highpart (SImode, operands[0]);
9890 if (GET_CODE (operands[1]) == ABS)
9891 {
9892 tmp = gen_int_mode (0x7fffffff, SImode);
9893 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9894 }
9895 else
9896 {
9897 tmp = gen_int_mode (0x80000000, SImode);
9898 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9899 }
9900 }
9901 operands[1] = tmp;
9902 })
9903
9904 (define_split
9905 [(set (match_operand:XF 0 "register_operand" "")
9906 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9907 (use (match_operand 2 "" ""))
9908 (clobber (reg:CC FLAGS_REG))]
9909 "reload_completed"
9910 [(parallel [(set (match_dup 0) (match_dup 1))
9911 (clobber (reg:CC FLAGS_REG))])]
9912 {
9913 rtx tmp;
9914 operands[0] = gen_rtx_REG (SImode,
9915 true_regnum (operands[0])
9916 + (TARGET_64BIT ? 1 : 2));
9917 if (GET_CODE (operands[1]) == ABS)
9918 {
9919 tmp = GEN_INT (0x7fff);
9920 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9921 }
9922 else
9923 {
9924 tmp = GEN_INT (0x8000);
9925 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9926 }
9927 operands[1] = tmp;
9928 })
9929
9930 (define_split
9931 [(set (match_operand 0 "memory_operand" "")
9932 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9933 (use (match_operand 2 "" ""))
9934 (clobber (reg:CC FLAGS_REG))]
9935 "reload_completed"
9936 [(parallel [(set (match_dup 0) (match_dup 1))
9937 (clobber (reg:CC FLAGS_REG))])]
9938 {
9939 enum machine_mode mode = GET_MODE (operands[0]);
9940 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9941 rtx tmp;
9942
9943 operands[0] = adjust_address (operands[0], QImode, size - 1);
9944 if (GET_CODE (operands[1]) == ABS)
9945 {
9946 tmp = gen_int_mode (0x7f, QImode);
9947 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9948 }
9949 else
9950 {
9951 tmp = gen_int_mode (0x80, QImode);
9952 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9953 }
9954 operands[1] = tmp;
9955 })
9956
9957 ;; Conditionalize these after reload. If they match before reload, we
9958 ;; lose the clobber and ability to use integer instructions.
9959
9960 (define_insn "*negsf2_1"
9961 [(set (match_operand:SF 0 "register_operand" "=f")
9962 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9963 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9964 "fchs"
9965 [(set_attr "type" "fsgn")
9966 (set_attr "mode" "SF")])
9967
9968 (define_insn "*negdf2_1"
9969 [(set (match_operand:DF 0 "register_operand" "=f")
9970 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9971 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9972 "fchs"
9973 [(set_attr "type" "fsgn")
9974 (set_attr "mode" "DF")])
9975
9976 (define_insn "*negxf2_1"
9977 [(set (match_operand:XF 0 "register_operand" "=f")
9978 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9979 "TARGET_80387"
9980 "fchs"
9981 [(set_attr "type" "fsgn")
9982 (set_attr "mode" "XF")])
9983
9984 (define_insn "*abssf2_1"
9985 [(set (match_operand:SF 0 "register_operand" "=f")
9986 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9987 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9988 "fabs"
9989 [(set_attr "type" "fsgn")
9990 (set_attr "mode" "SF")])
9991
9992 (define_insn "*absdf2_1"
9993 [(set (match_operand:DF 0 "register_operand" "=f")
9994 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9995 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9996 "fabs"
9997 [(set_attr "type" "fsgn")
9998 (set_attr "mode" "DF")])
9999
10000 (define_insn "*absxf2_1"
10001 [(set (match_operand:XF 0 "register_operand" "=f")
10002 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10003 "TARGET_80387"
10004 "fabs"
10005 [(set_attr "type" "fsgn")
10006 (set_attr "mode" "DF")])
10007
10008 (define_insn "*negextendsfdf2"
10009 [(set (match_operand:DF 0 "register_operand" "=f")
10010 (neg:DF (float_extend:DF
10011 (match_operand:SF 1 "register_operand" "0"))))]
10012 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10013 "fchs"
10014 [(set_attr "type" "fsgn")
10015 (set_attr "mode" "DF")])
10016
10017 (define_insn "*negextenddfxf2"
10018 [(set (match_operand:XF 0 "register_operand" "=f")
10019 (neg:XF (float_extend:XF
10020 (match_operand:DF 1 "register_operand" "0"))))]
10021 "TARGET_80387"
10022 "fchs"
10023 [(set_attr "type" "fsgn")
10024 (set_attr "mode" "XF")])
10025
10026 (define_insn "*negextendsfxf2"
10027 [(set (match_operand:XF 0 "register_operand" "=f")
10028 (neg:XF (float_extend:XF
10029 (match_operand:SF 1 "register_operand" "0"))))]
10030 "TARGET_80387"
10031 "fchs"
10032 [(set_attr "type" "fsgn")
10033 (set_attr "mode" "XF")])
10034
10035 (define_insn "*absextendsfdf2"
10036 [(set (match_operand:DF 0 "register_operand" "=f")
10037 (abs:DF (float_extend:DF
10038 (match_operand:SF 1 "register_operand" "0"))))]
10039 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10040 "fabs"
10041 [(set_attr "type" "fsgn")
10042 (set_attr "mode" "DF")])
10043
10044 (define_insn "*absextenddfxf2"
10045 [(set (match_operand:XF 0 "register_operand" "=f")
10046 (abs:XF (float_extend:XF
10047 (match_operand:DF 1 "register_operand" "0"))))]
10048 "TARGET_80387"
10049 "fabs"
10050 [(set_attr "type" "fsgn")
10051 (set_attr "mode" "XF")])
10052
10053 (define_insn "*absextendsfxf2"
10054 [(set (match_operand:XF 0 "register_operand" "=f")
10055 (abs:XF (float_extend:XF
10056 (match_operand:SF 1 "register_operand" "0"))))]
10057 "TARGET_80387"
10058 "fabs"
10059 [(set_attr "type" "fsgn")
10060 (set_attr "mode" "XF")])
10061 \f
10062 ;; One complement instructions
10063
10064 (define_expand "one_cmpldi2"
10065 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10066 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10067 "TARGET_64BIT"
10068 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10069
10070 (define_insn "*one_cmpldi2_1_rex64"
10071 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10072 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10073 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10074 "not{q}\t%0"
10075 [(set_attr "type" "negnot")
10076 (set_attr "mode" "DI")])
10077
10078 (define_insn "*one_cmpldi2_2_rex64"
10079 [(set (reg FLAGS_REG)
10080 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10081 (const_int 0)))
10082 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10083 (not:DI (match_dup 1)))]
10084 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10085 && ix86_unary_operator_ok (NOT, DImode, operands)"
10086 "#"
10087 [(set_attr "type" "alu1")
10088 (set_attr "mode" "DI")])
10089
10090 (define_split
10091 [(set (match_operand 0 "flags_reg_operand" "")
10092 (match_operator 2 "compare_operator"
10093 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10094 (const_int 0)]))
10095 (set (match_operand:DI 1 "nonimmediate_operand" "")
10096 (not:DI (match_dup 3)))]
10097 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10098 [(parallel [(set (match_dup 0)
10099 (match_op_dup 2
10100 [(xor:DI (match_dup 3) (const_int -1))
10101 (const_int 0)]))
10102 (set (match_dup 1)
10103 (xor:DI (match_dup 3) (const_int -1)))])]
10104 "")
10105
10106 (define_expand "one_cmplsi2"
10107 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10108 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10109 ""
10110 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10111
10112 (define_insn "*one_cmplsi2_1"
10113 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10114 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10115 "ix86_unary_operator_ok (NOT, SImode, operands)"
10116 "not{l}\t%0"
10117 [(set_attr "type" "negnot")
10118 (set_attr "mode" "SI")])
10119
10120 ;; ??? Currently never generated - xor is used instead.
10121 (define_insn "*one_cmplsi2_1_zext"
10122 [(set (match_operand:DI 0 "register_operand" "=r")
10123 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10124 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10125 "not{l}\t%k0"
10126 [(set_attr "type" "negnot")
10127 (set_attr "mode" "SI")])
10128
10129 (define_insn "*one_cmplsi2_2"
10130 [(set (reg FLAGS_REG)
10131 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10132 (const_int 0)))
10133 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10134 (not:SI (match_dup 1)))]
10135 "ix86_match_ccmode (insn, CCNOmode)
10136 && ix86_unary_operator_ok (NOT, SImode, operands)"
10137 "#"
10138 [(set_attr "type" "alu1")
10139 (set_attr "mode" "SI")])
10140
10141 (define_split
10142 [(set (match_operand 0 "flags_reg_operand" "")
10143 (match_operator 2 "compare_operator"
10144 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10145 (const_int 0)]))
10146 (set (match_operand:SI 1 "nonimmediate_operand" "")
10147 (not:SI (match_dup 3)))]
10148 "ix86_match_ccmode (insn, CCNOmode)"
10149 [(parallel [(set (match_dup 0)
10150 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10151 (const_int 0)]))
10152 (set (match_dup 1)
10153 (xor:SI (match_dup 3) (const_int -1)))])]
10154 "")
10155
10156 ;; ??? Currently never generated - xor is used instead.
10157 (define_insn "*one_cmplsi2_2_zext"
10158 [(set (reg FLAGS_REG)
10159 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10160 (const_int 0)))
10161 (set (match_operand:DI 0 "register_operand" "=r")
10162 (zero_extend:DI (not:SI (match_dup 1))))]
10163 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10164 && ix86_unary_operator_ok (NOT, SImode, operands)"
10165 "#"
10166 [(set_attr "type" "alu1")
10167 (set_attr "mode" "SI")])
10168
10169 (define_split
10170 [(set (match_operand 0 "flags_reg_operand" "")
10171 (match_operator 2 "compare_operator"
10172 [(not:SI (match_operand:SI 3 "register_operand" ""))
10173 (const_int 0)]))
10174 (set (match_operand:DI 1 "register_operand" "")
10175 (zero_extend:DI (not:SI (match_dup 3))))]
10176 "ix86_match_ccmode (insn, CCNOmode)"
10177 [(parallel [(set (match_dup 0)
10178 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10179 (const_int 0)]))
10180 (set (match_dup 1)
10181 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10182 "")
10183
10184 (define_expand "one_cmplhi2"
10185 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10186 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10187 "TARGET_HIMODE_MATH"
10188 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10189
10190 (define_insn "*one_cmplhi2_1"
10191 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10192 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10193 "ix86_unary_operator_ok (NOT, HImode, operands)"
10194 "not{w}\t%0"
10195 [(set_attr "type" "negnot")
10196 (set_attr "mode" "HI")])
10197
10198 (define_insn "*one_cmplhi2_2"
10199 [(set (reg FLAGS_REG)
10200 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10201 (const_int 0)))
10202 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10203 (not:HI (match_dup 1)))]
10204 "ix86_match_ccmode (insn, CCNOmode)
10205 && ix86_unary_operator_ok (NEG, HImode, operands)"
10206 "#"
10207 [(set_attr "type" "alu1")
10208 (set_attr "mode" "HI")])
10209
10210 (define_split
10211 [(set (match_operand 0 "flags_reg_operand" "")
10212 (match_operator 2 "compare_operator"
10213 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10214 (const_int 0)]))
10215 (set (match_operand:HI 1 "nonimmediate_operand" "")
10216 (not:HI (match_dup 3)))]
10217 "ix86_match_ccmode (insn, CCNOmode)"
10218 [(parallel [(set (match_dup 0)
10219 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10220 (const_int 0)]))
10221 (set (match_dup 1)
10222 (xor:HI (match_dup 3) (const_int -1)))])]
10223 "")
10224
10225 ;; %%% Potential partial reg stall on alternative 1. What to do?
10226 (define_expand "one_cmplqi2"
10227 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10228 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10229 "TARGET_QIMODE_MATH"
10230 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10231
10232 (define_insn "*one_cmplqi2_1"
10233 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10234 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10235 "ix86_unary_operator_ok (NOT, QImode, operands)"
10236 "@
10237 not{b}\t%0
10238 not{l}\t%k0"
10239 [(set_attr "type" "negnot")
10240 (set_attr "mode" "QI,SI")])
10241
10242 (define_insn "*one_cmplqi2_2"
10243 [(set (reg FLAGS_REG)
10244 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10245 (const_int 0)))
10246 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10247 (not:QI (match_dup 1)))]
10248 "ix86_match_ccmode (insn, CCNOmode)
10249 && ix86_unary_operator_ok (NOT, QImode, operands)"
10250 "#"
10251 [(set_attr "type" "alu1")
10252 (set_attr "mode" "QI")])
10253
10254 (define_split
10255 [(set (match_operand 0 "flags_reg_operand" "")
10256 (match_operator 2 "compare_operator"
10257 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10258 (const_int 0)]))
10259 (set (match_operand:QI 1 "nonimmediate_operand" "")
10260 (not:QI (match_dup 3)))]
10261 "ix86_match_ccmode (insn, CCNOmode)"
10262 [(parallel [(set (match_dup 0)
10263 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10264 (const_int 0)]))
10265 (set (match_dup 1)
10266 (xor:QI (match_dup 3) (const_int -1)))])]
10267 "")
10268 \f
10269 ;; Arithmetic shift instructions
10270
10271 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10272 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10273 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10274 ;; from the assembler input.
10275 ;;
10276 ;; This instruction shifts the target reg/mem as usual, but instead of
10277 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10278 ;; is a left shift double, bits are taken from the high order bits of
10279 ;; reg, else if the insn is a shift right double, bits are taken from the
10280 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10281 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10282 ;;
10283 ;; Since sh[lr]d does not change the `reg' operand, that is done
10284 ;; separately, making all shifts emit pairs of shift double and normal
10285 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10286 ;; support a 63 bit shift, each shift where the count is in a reg expands
10287 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10288 ;;
10289 ;; If the shift count is a constant, we need never emit more than one
10290 ;; shift pair, instead using moves and sign extension for counts greater
10291 ;; than 31.
10292
10293 (define_expand "ashlti3"
10294 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10295 (ashift:TI (match_operand:TI 1 "register_operand" "")
10296 (match_operand:QI 2 "nonmemory_operand" "")))
10297 (clobber (reg:CC FLAGS_REG))])]
10298 "TARGET_64BIT"
10299 {
10300 if (! immediate_operand (operands[2], QImode))
10301 {
10302 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10303 DONE;
10304 }
10305 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10306 DONE;
10307 })
10308
10309 (define_insn "ashlti3_1"
10310 [(set (match_operand:TI 0 "register_operand" "=r")
10311 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10312 (match_operand:QI 2 "register_operand" "c")))
10313 (clobber (match_scratch:DI 3 "=&r"))
10314 (clobber (reg:CC FLAGS_REG))]
10315 "TARGET_64BIT"
10316 "#"
10317 [(set_attr "type" "multi")])
10318
10319 (define_insn "*ashlti3_2"
10320 [(set (match_operand:TI 0 "register_operand" "=r")
10321 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10322 (match_operand:QI 2 "immediate_operand" "O")))
10323 (clobber (reg:CC FLAGS_REG))]
10324 "TARGET_64BIT"
10325 "#"
10326 [(set_attr "type" "multi")])
10327
10328 (define_split
10329 [(set (match_operand:TI 0 "register_operand" "")
10330 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10331 (match_operand:QI 2 "register_operand" "")))
10332 (clobber (match_scratch:DI 3 ""))
10333 (clobber (reg:CC FLAGS_REG))]
10334 "TARGET_64BIT && reload_completed"
10335 [(const_int 0)]
10336 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10337
10338 (define_split
10339 [(set (match_operand:TI 0 "register_operand" "")
10340 (ashift:TI (match_operand:TI 1 "register_operand" "")
10341 (match_operand:QI 2 "immediate_operand" "")))
10342 (clobber (reg:CC FLAGS_REG))]
10343 "TARGET_64BIT && reload_completed"
10344 [(const_int 0)]
10345 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10346
10347 (define_insn "x86_64_shld"
10348 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10349 (ior:DI (ashift:DI (match_dup 0)
10350 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10351 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10352 (minus:QI (const_int 64) (match_dup 2)))))
10353 (clobber (reg:CC FLAGS_REG))]
10354 "TARGET_64BIT"
10355 "@
10356 shld{q}\t{%2, %1, %0|%0, %1, %2}
10357 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10358 [(set_attr "type" "ishift")
10359 (set_attr "prefix_0f" "1")
10360 (set_attr "mode" "DI")
10361 (set_attr "athlon_decode" "vector")])
10362
10363 (define_expand "x86_64_shift_adj"
10364 [(set (reg:CCZ FLAGS_REG)
10365 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10366 (const_int 64))
10367 (const_int 0)))
10368 (set (match_operand:DI 0 "register_operand" "")
10369 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10370 (match_operand:DI 1 "register_operand" "")
10371 (match_dup 0)))
10372 (set (match_dup 1)
10373 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10374 (match_operand:DI 3 "register_operand" "r")
10375 (match_dup 1)))]
10376 "TARGET_64BIT"
10377 "")
10378
10379 (define_expand "ashldi3"
10380 [(set (match_operand:DI 0 "shiftdi_operand" "")
10381 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10382 (match_operand:QI 2 "nonmemory_operand" "")))]
10383 ""
10384 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10385
10386 (define_insn "*ashldi3_1_rex64"
10387 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10388 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10389 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10390 (clobber (reg:CC FLAGS_REG))]
10391 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10392 {
10393 switch (get_attr_type (insn))
10394 {
10395 case TYPE_ALU:
10396 gcc_assert (operands[2] == const1_rtx);
10397 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10398 return "add{q}\t{%0, %0|%0, %0}";
10399
10400 case TYPE_LEA:
10401 gcc_assert (CONST_INT_P (operands[2]));
10402 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10403 operands[1] = gen_rtx_MULT (DImode, operands[1],
10404 GEN_INT (1 << INTVAL (operands[2])));
10405 return "lea{q}\t{%a1, %0|%0, %a1}";
10406
10407 default:
10408 if (REG_P (operands[2]))
10409 return "sal{q}\t{%b2, %0|%0, %b2}";
10410 else if (operands[2] == const1_rtx
10411 && (TARGET_SHIFT1 || optimize_size))
10412 return "sal{q}\t%0";
10413 else
10414 return "sal{q}\t{%2, %0|%0, %2}";
10415 }
10416 }
10417 [(set (attr "type")
10418 (cond [(eq_attr "alternative" "1")
10419 (const_string "lea")
10420 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10421 (const_int 0))
10422 (match_operand 0 "register_operand" ""))
10423 (match_operand 2 "const1_operand" ""))
10424 (const_string "alu")
10425 ]
10426 (const_string "ishift")))
10427 (set_attr "mode" "DI")])
10428
10429 ;; Convert lea to the lea pattern to avoid flags dependency.
10430 (define_split
10431 [(set (match_operand:DI 0 "register_operand" "")
10432 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10433 (match_operand:QI 2 "immediate_operand" "")))
10434 (clobber (reg:CC FLAGS_REG))]
10435 "TARGET_64BIT && reload_completed
10436 && true_regnum (operands[0]) != true_regnum (operands[1])"
10437 [(set (match_dup 0)
10438 (mult:DI (match_dup 1)
10439 (match_dup 2)))]
10440 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10441
10442 ;; This pattern can't accept a variable shift count, since shifts by
10443 ;; zero don't affect the flags. We assume that shifts by constant
10444 ;; zero are optimized away.
10445 (define_insn "*ashldi3_cmp_rex64"
10446 [(set (reg FLAGS_REG)
10447 (compare
10448 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10449 (match_operand:QI 2 "immediate_operand" "e"))
10450 (const_int 0)))
10451 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10452 (ashift:DI (match_dup 1) (match_dup 2)))]
10453 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10454 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10455 && (optimize_size
10456 || !TARGET_PARTIAL_FLAG_REG_STALL
10457 || (operands[2] == const1_rtx
10458 && (TARGET_SHIFT1
10459 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10460 {
10461 switch (get_attr_type (insn))
10462 {
10463 case TYPE_ALU:
10464 gcc_assert (operands[2] == const1_rtx);
10465 return "add{q}\t{%0, %0|%0, %0}";
10466
10467 default:
10468 if (REG_P (operands[2]))
10469 return "sal{q}\t{%b2, %0|%0, %b2}";
10470 else if (operands[2] == const1_rtx
10471 && (TARGET_SHIFT1 || optimize_size))
10472 return "sal{q}\t%0";
10473 else
10474 return "sal{q}\t{%2, %0|%0, %2}";
10475 }
10476 }
10477 [(set (attr "type")
10478 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10479 (const_int 0))
10480 (match_operand 0 "register_operand" ""))
10481 (match_operand 2 "const1_operand" ""))
10482 (const_string "alu")
10483 ]
10484 (const_string "ishift")))
10485 (set_attr "mode" "DI")])
10486
10487 (define_insn "*ashldi3_cconly_rex64"
10488 [(set (reg FLAGS_REG)
10489 (compare
10490 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10491 (match_operand:QI 2 "immediate_operand" "e"))
10492 (const_int 0)))
10493 (clobber (match_scratch:DI 0 "=r"))]
10494 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10495 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10496 && (optimize_size
10497 || !TARGET_PARTIAL_FLAG_REG_STALL
10498 || (operands[2] == const1_rtx
10499 && (TARGET_SHIFT1
10500 || TARGET_DOUBLE_WITH_ADD)))"
10501 {
10502 switch (get_attr_type (insn))
10503 {
10504 case TYPE_ALU:
10505 gcc_assert (operands[2] == const1_rtx);
10506 return "add{q}\t{%0, %0|%0, %0}";
10507
10508 default:
10509 if (REG_P (operands[2]))
10510 return "sal{q}\t{%b2, %0|%0, %b2}";
10511 else if (operands[2] == const1_rtx
10512 && (TARGET_SHIFT1 || optimize_size))
10513 return "sal{q}\t%0";
10514 else
10515 return "sal{q}\t{%2, %0|%0, %2}";
10516 }
10517 }
10518 [(set (attr "type")
10519 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10520 (const_int 0))
10521 (match_operand 0 "register_operand" ""))
10522 (match_operand 2 "const1_operand" ""))
10523 (const_string "alu")
10524 ]
10525 (const_string "ishift")))
10526 (set_attr "mode" "DI")])
10527
10528 (define_insn "*ashldi3_1"
10529 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10530 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10531 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10532 (clobber (reg:CC FLAGS_REG))]
10533 "!TARGET_64BIT"
10534 "#"
10535 [(set_attr "type" "multi")])
10536
10537 ;; By default we don't ask for a scratch register, because when DImode
10538 ;; values are manipulated, registers are already at a premium. But if
10539 ;; we have one handy, we won't turn it away.
10540 (define_peephole2
10541 [(match_scratch:SI 3 "r")
10542 (parallel [(set (match_operand:DI 0 "register_operand" "")
10543 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10544 (match_operand:QI 2 "nonmemory_operand" "")))
10545 (clobber (reg:CC FLAGS_REG))])
10546 (match_dup 3)]
10547 "!TARGET_64BIT && TARGET_CMOVE"
10548 [(const_int 0)]
10549 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10550
10551 (define_split
10552 [(set (match_operand:DI 0 "register_operand" "")
10553 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10554 (match_operand:QI 2 "nonmemory_operand" "")))
10555 (clobber (reg:CC FLAGS_REG))]
10556 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10557 ? flow2_completed : reload_completed)"
10558 [(const_int 0)]
10559 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10560
10561 (define_insn "x86_shld_1"
10562 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10563 (ior:SI (ashift:SI (match_dup 0)
10564 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10565 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10566 (minus:QI (const_int 32) (match_dup 2)))))
10567 (clobber (reg:CC FLAGS_REG))]
10568 ""
10569 "@
10570 shld{l}\t{%2, %1, %0|%0, %1, %2}
10571 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10572 [(set_attr "type" "ishift")
10573 (set_attr "prefix_0f" "1")
10574 (set_attr "mode" "SI")
10575 (set_attr "pent_pair" "np")
10576 (set_attr "athlon_decode" "vector")])
10577
10578 (define_expand "x86_shift_adj_1"
10579 [(set (reg:CCZ FLAGS_REG)
10580 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10581 (const_int 32))
10582 (const_int 0)))
10583 (set (match_operand:SI 0 "register_operand" "")
10584 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10585 (match_operand:SI 1 "register_operand" "")
10586 (match_dup 0)))
10587 (set (match_dup 1)
10588 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10589 (match_operand:SI 3 "register_operand" "r")
10590 (match_dup 1)))]
10591 "TARGET_CMOVE"
10592 "")
10593
10594 (define_expand "x86_shift_adj_2"
10595 [(use (match_operand:SI 0 "register_operand" ""))
10596 (use (match_operand:SI 1 "register_operand" ""))
10597 (use (match_operand:QI 2 "register_operand" ""))]
10598 ""
10599 {
10600 rtx label = gen_label_rtx ();
10601 rtx tmp;
10602
10603 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10604
10605 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10606 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10607 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10608 gen_rtx_LABEL_REF (VOIDmode, label),
10609 pc_rtx);
10610 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10611 JUMP_LABEL (tmp) = label;
10612
10613 emit_move_insn (operands[0], operands[1]);
10614 ix86_expand_clear (operands[1]);
10615
10616 emit_label (label);
10617 LABEL_NUSES (label) = 1;
10618
10619 DONE;
10620 })
10621
10622 (define_expand "ashlsi3"
10623 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10624 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10625 (match_operand:QI 2 "nonmemory_operand" "")))
10626 (clobber (reg:CC FLAGS_REG))]
10627 ""
10628 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10629
10630 (define_insn "*ashlsi3_1"
10631 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10632 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10633 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10634 (clobber (reg:CC FLAGS_REG))]
10635 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10636 {
10637 switch (get_attr_type (insn))
10638 {
10639 case TYPE_ALU:
10640 gcc_assert (operands[2] == const1_rtx);
10641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10642 return "add{l}\t{%0, %0|%0, %0}";
10643
10644 case TYPE_LEA:
10645 return "#";
10646
10647 default:
10648 if (REG_P (operands[2]))
10649 return "sal{l}\t{%b2, %0|%0, %b2}";
10650 else if (operands[2] == const1_rtx
10651 && (TARGET_SHIFT1 || optimize_size))
10652 return "sal{l}\t%0";
10653 else
10654 return "sal{l}\t{%2, %0|%0, %2}";
10655 }
10656 }
10657 [(set (attr "type")
10658 (cond [(eq_attr "alternative" "1")
10659 (const_string "lea")
10660 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10661 (const_int 0))
10662 (match_operand 0 "register_operand" ""))
10663 (match_operand 2 "const1_operand" ""))
10664 (const_string "alu")
10665 ]
10666 (const_string "ishift")))
10667 (set_attr "mode" "SI")])
10668
10669 ;; Convert lea to the lea pattern to avoid flags dependency.
10670 (define_split
10671 [(set (match_operand 0 "register_operand" "")
10672 (ashift (match_operand 1 "index_register_operand" "")
10673 (match_operand:QI 2 "const_int_operand" "")))
10674 (clobber (reg:CC FLAGS_REG))]
10675 "reload_completed
10676 && true_regnum (operands[0]) != true_regnum (operands[1])
10677 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10678 [(const_int 0)]
10679 {
10680 rtx pat;
10681 enum machine_mode mode = GET_MODE (operands[0]);
10682
10683 if (GET_MODE_SIZE (mode) < 4)
10684 operands[0] = gen_lowpart (SImode, operands[0]);
10685 if (mode != Pmode)
10686 operands[1] = gen_lowpart (Pmode, operands[1]);
10687 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10688
10689 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10690 if (Pmode != SImode)
10691 pat = gen_rtx_SUBREG (SImode, pat, 0);
10692 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10693 DONE;
10694 })
10695
10696 ;; Rare case of shifting RSP is handled by generating move and shift
10697 (define_split
10698 [(set (match_operand 0 "register_operand" "")
10699 (ashift (match_operand 1 "register_operand" "")
10700 (match_operand:QI 2 "const_int_operand" "")))
10701 (clobber (reg:CC FLAGS_REG))]
10702 "reload_completed
10703 && true_regnum (operands[0]) != true_regnum (operands[1])"
10704 [(const_int 0)]
10705 {
10706 rtx pat, clob;
10707 emit_move_insn (operands[0], operands[1]);
10708 pat = gen_rtx_SET (VOIDmode, operands[0],
10709 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10710 operands[0], operands[2]));
10711 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10712 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10713 DONE;
10714 })
10715
10716 (define_insn "*ashlsi3_1_zext"
10717 [(set (match_operand:DI 0 "register_operand" "=r,r")
10718 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10719 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10720 (clobber (reg:CC FLAGS_REG))]
10721 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10722 {
10723 switch (get_attr_type (insn))
10724 {
10725 case TYPE_ALU:
10726 gcc_assert (operands[2] == const1_rtx);
10727 return "add{l}\t{%k0, %k0|%k0, %k0}";
10728
10729 case TYPE_LEA:
10730 return "#";
10731
10732 default:
10733 if (REG_P (operands[2]))
10734 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10735 else if (operands[2] == const1_rtx
10736 && (TARGET_SHIFT1 || optimize_size))
10737 return "sal{l}\t%k0";
10738 else
10739 return "sal{l}\t{%2, %k0|%k0, %2}";
10740 }
10741 }
10742 [(set (attr "type")
10743 (cond [(eq_attr "alternative" "1")
10744 (const_string "lea")
10745 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10746 (const_int 0))
10747 (match_operand 2 "const1_operand" ""))
10748 (const_string "alu")
10749 ]
10750 (const_string "ishift")))
10751 (set_attr "mode" "SI")])
10752
10753 ;; Convert lea to the lea pattern to avoid flags dependency.
10754 (define_split
10755 [(set (match_operand:DI 0 "register_operand" "")
10756 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10757 (match_operand:QI 2 "const_int_operand" ""))))
10758 (clobber (reg:CC FLAGS_REG))]
10759 "TARGET_64BIT && reload_completed
10760 && true_regnum (operands[0]) != true_regnum (operands[1])"
10761 [(set (match_dup 0) (zero_extend:DI
10762 (subreg:SI (mult:SI (match_dup 1)
10763 (match_dup 2)) 0)))]
10764 {
10765 operands[1] = gen_lowpart (Pmode, operands[1]);
10766 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10767 })
10768
10769 ;; This pattern can't accept a variable shift count, since shifts by
10770 ;; zero don't affect the flags. We assume that shifts by constant
10771 ;; zero are optimized away.
10772 (define_insn "*ashlsi3_cmp"
10773 [(set (reg FLAGS_REG)
10774 (compare
10775 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10776 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10777 (const_int 0)))
10778 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10779 (ashift:SI (match_dup 1) (match_dup 2)))]
10780 "ix86_match_ccmode (insn, CCGOCmode)
10781 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10782 && (optimize_size
10783 || !TARGET_PARTIAL_FLAG_REG_STALL
10784 || (operands[2] == const1_rtx
10785 && (TARGET_SHIFT1
10786 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10787 {
10788 switch (get_attr_type (insn))
10789 {
10790 case TYPE_ALU:
10791 gcc_assert (operands[2] == const1_rtx);
10792 return "add{l}\t{%0, %0|%0, %0}";
10793
10794 default:
10795 if (REG_P (operands[2]))
10796 return "sal{l}\t{%b2, %0|%0, %b2}";
10797 else if (operands[2] == const1_rtx
10798 && (TARGET_SHIFT1 || optimize_size))
10799 return "sal{l}\t%0";
10800 else
10801 return "sal{l}\t{%2, %0|%0, %2}";
10802 }
10803 }
10804 [(set (attr "type")
10805 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10806 (const_int 0))
10807 (match_operand 0 "register_operand" ""))
10808 (match_operand 2 "const1_operand" ""))
10809 (const_string "alu")
10810 ]
10811 (const_string "ishift")))
10812 (set_attr "mode" "SI")])
10813
10814 (define_insn "*ashlsi3_cconly"
10815 [(set (reg FLAGS_REG)
10816 (compare
10817 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10818 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10819 (const_int 0)))
10820 (clobber (match_scratch:SI 0 "=r"))]
10821 "ix86_match_ccmode (insn, CCGOCmode)
10822 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10823 && (optimize_size
10824 || !TARGET_PARTIAL_FLAG_REG_STALL
10825 || (operands[2] == const1_rtx
10826 && (TARGET_SHIFT1
10827 || TARGET_DOUBLE_WITH_ADD)))"
10828 {
10829 switch (get_attr_type (insn))
10830 {
10831 case TYPE_ALU:
10832 gcc_assert (operands[2] == const1_rtx);
10833 return "add{l}\t{%0, %0|%0, %0}";
10834
10835 default:
10836 if (REG_P (operands[2]))
10837 return "sal{l}\t{%b2, %0|%0, %b2}";
10838 else if (operands[2] == const1_rtx
10839 && (TARGET_SHIFT1 || optimize_size))
10840 return "sal{l}\t%0";
10841 else
10842 return "sal{l}\t{%2, %0|%0, %2}";
10843 }
10844 }
10845 [(set (attr "type")
10846 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10847 (const_int 0))
10848 (match_operand 0 "register_operand" ""))
10849 (match_operand 2 "const1_operand" ""))
10850 (const_string "alu")
10851 ]
10852 (const_string "ishift")))
10853 (set_attr "mode" "SI")])
10854
10855 (define_insn "*ashlsi3_cmp_zext"
10856 [(set (reg FLAGS_REG)
10857 (compare
10858 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10859 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10860 (const_int 0)))
10861 (set (match_operand:DI 0 "register_operand" "=r")
10862 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10863 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10864 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10865 && (optimize_size
10866 || !TARGET_PARTIAL_FLAG_REG_STALL
10867 || (operands[2] == const1_rtx
10868 && (TARGET_SHIFT1
10869 || TARGET_DOUBLE_WITH_ADD)))"
10870 {
10871 switch (get_attr_type (insn))
10872 {
10873 case TYPE_ALU:
10874 gcc_assert (operands[2] == const1_rtx);
10875 return "add{l}\t{%k0, %k0|%k0, %k0}";
10876
10877 default:
10878 if (REG_P (operands[2]))
10879 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10880 else if (operands[2] == const1_rtx
10881 && (TARGET_SHIFT1 || optimize_size))
10882 return "sal{l}\t%k0";
10883 else
10884 return "sal{l}\t{%2, %k0|%k0, %2}";
10885 }
10886 }
10887 [(set (attr "type")
10888 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10889 (const_int 0))
10890 (match_operand 2 "const1_operand" ""))
10891 (const_string "alu")
10892 ]
10893 (const_string "ishift")))
10894 (set_attr "mode" "SI")])
10895
10896 (define_expand "ashlhi3"
10897 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10898 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10899 (match_operand:QI 2 "nonmemory_operand" "")))
10900 (clobber (reg:CC FLAGS_REG))]
10901 "TARGET_HIMODE_MATH"
10902 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10903
10904 (define_insn "*ashlhi3_1_lea"
10905 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10906 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10907 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10908 (clobber (reg:CC FLAGS_REG))]
10909 "!TARGET_PARTIAL_REG_STALL
10910 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10911 {
10912 switch (get_attr_type (insn))
10913 {
10914 case TYPE_LEA:
10915 return "#";
10916 case TYPE_ALU:
10917 gcc_assert (operands[2] == const1_rtx);
10918 return "add{w}\t{%0, %0|%0, %0}";
10919
10920 default:
10921 if (REG_P (operands[2]))
10922 return "sal{w}\t{%b2, %0|%0, %b2}";
10923 else if (operands[2] == const1_rtx
10924 && (TARGET_SHIFT1 || optimize_size))
10925 return "sal{w}\t%0";
10926 else
10927 return "sal{w}\t{%2, %0|%0, %2}";
10928 }
10929 }
10930 [(set (attr "type")
10931 (cond [(eq_attr "alternative" "1")
10932 (const_string "lea")
10933 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10934 (const_int 0))
10935 (match_operand 0 "register_operand" ""))
10936 (match_operand 2 "const1_operand" ""))
10937 (const_string "alu")
10938 ]
10939 (const_string "ishift")))
10940 (set_attr "mode" "HI,SI")])
10941
10942 (define_insn "*ashlhi3_1"
10943 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10944 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10945 (match_operand:QI 2 "nonmemory_operand" "cI")))
10946 (clobber (reg:CC FLAGS_REG))]
10947 "TARGET_PARTIAL_REG_STALL
10948 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10949 {
10950 switch (get_attr_type (insn))
10951 {
10952 case TYPE_ALU:
10953 gcc_assert (operands[2] == const1_rtx);
10954 return "add{w}\t{%0, %0|%0, %0}";
10955
10956 default:
10957 if (REG_P (operands[2]))
10958 return "sal{w}\t{%b2, %0|%0, %b2}";
10959 else if (operands[2] == const1_rtx
10960 && (TARGET_SHIFT1 || optimize_size))
10961 return "sal{w}\t%0";
10962 else
10963 return "sal{w}\t{%2, %0|%0, %2}";
10964 }
10965 }
10966 [(set (attr "type")
10967 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10968 (const_int 0))
10969 (match_operand 0 "register_operand" ""))
10970 (match_operand 2 "const1_operand" ""))
10971 (const_string "alu")
10972 ]
10973 (const_string "ishift")))
10974 (set_attr "mode" "HI")])
10975
10976 ;; This pattern can't accept a variable shift count, since shifts by
10977 ;; zero don't affect the flags. We assume that shifts by constant
10978 ;; zero are optimized away.
10979 (define_insn "*ashlhi3_cmp"
10980 [(set (reg FLAGS_REG)
10981 (compare
10982 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10983 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10984 (const_int 0)))
10985 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10986 (ashift:HI (match_dup 1) (match_dup 2)))]
10987 "ix86_match_ccmode (insn, CCGOCmode)
10988 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10989 && (optimize_size
10990 || !TARGET_PARTIAL_FLAG_REG_STALL
10991 || (operands[2] == const1_rtx
10992 && (TARGET_SHIFT1
10993 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10994 {
10995 switch (get_attr_type (insn))
10996 {
10997 case TYPE_ALU:
10998 gcc_assert (operands[2] == const1_rtx);
10999 return "add{w}\t{%0, %0|%0, %0}";
11000
11001 default:
11002 if (REG_P (operands[2]))
11003 return "sal{w}\t{%b2, %0|%0, %b2}";
11004 else if (operands[2] == const1_rtx
11005 && (TARGET_SHIFT1 || optimize_size))
11006 return "sal{w}\t%0";
11007 else
11008 return "sal{w}\t{%2, %0|%0, %2}";
11009 }
11010 }
11011 [(set (attr "type")
11012 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11013 (const_int 0))
11014 (match_operand 0 "register_operand" ""))
11015 (match_operand 2 "const1_operand" ""))
11016 (const_string "alu")
11017 ]
11018 (const_string "ishift")))
11019 (set_attr "mode" "HI")])
11020
11021 (define_insn "*ashlhi3_cconly"
11022 [(set (reg FLAGS_REG)
11023 (compare
11024 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11025 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11026 (const_int 0)))
11027 (clobber (match_scratch:HI 0 "=r"))]
11028 "ix86_match_ccmode (insn, CCGOCmode)
11029 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11030 && (optimize_size
11031 || !TARGET_PARTIAL_FLAG_REG_STALL
11032 || (operands[2] == const1_rtx
11033 && (TARGET_SHIFT1
11034 || TARGET_DOUBLE_WITH_ADD)))"
11035 {
11036 switch (get_attr_type (insn))
11037 {
11038 case TYPE_ALU:
11039 gcc_assert (operands[2] == const1_rtx);
11040 return "add{w}\t{%0, %0|%0, %0}";
11041
11042 default:
11043 if (REG_P (operands[2]))
11044 return "sal{w}\t{%b2, %0|%0, %b2}";
11045 else if (operands[2] == const1_rtx
11046 && (TARGET_SHIFT1 || optimize_size))
11047 return "sal{w}\t%0";
11048 else
11049 return "sal{w}\t{%2, %0|%0, %2}";
11050 }
11051 }
11052 [(set (attr "type")
11053 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11054 (const_int 0))
11055 (match_operand 0 "register_operand" ""))
11056 (match_operand 2 "const1_operand" ""))
11057 (const_string "alu")
11058 ]
11059 (const_string "ishift")))
11060 (set_attr "mode" "HI")])
11061
11062 (define_expand "ashlqi3"
11063 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11064 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11065 (match_operand:QI 2 "nonmemory_operand" "")))
11066 (clobber (reg:CC FLAGS_REG))]
11067 "TARGET_QIMODE_MATH"
11068 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11069
11070 ;; %%% Potential partial reg stall on alternative 2. What to do?
11071
11072 (define_insn "*ashlqi3_1_lea"
11073 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11074 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11075 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11076 (clobber (reg:CC FLAGS_REG))]
11077 "!TARGET_PARTIAL_REG_STALL
11078 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11079 {
11080 switch (get_attr_type (insn))
11081 {
11082 case TYPE_LEA:
11083 return "#";
11084 case TYPE_ALU:
11085 gcc_assert (operands[2] == const1_rtx);
11086 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11087 return "add{l}\t{%k0, %k0|%k0, %k0}";
11088 else
11089 return "add{b}\t{%0, %0|%0, %0}";
11090
11091 default:
11092 if (REG_P (operands[2]))
11093 {
11094 if (get_attr_mode (insn) == MODE_SI)
11095 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11096 else
11097 return "sal{b}\t{%b2, %0|%0, %b2}";
11098 }
11099 else if (operands[2] == const1_rtx
11100 && (TARGET_SHIFT1 || optimize_size))
11101 {
11102 if (get_attr_mode (insn) == MODE_SI)
11103 return "sal{l}\t%0";
11104 else
11105 return "sal{b}\t%0";
11106 }
11107 else
11108 {
11109 if (get_attr_mode (insn) == MODE_SI)
11110 return "sal{l}\t{%2, %k0|%k0, %2}";
11111 else
11112 return "sal{b}\t{%2, %0|%0, %2}";
11113 }
11114 }
11115 }
11116 [(set (attr "type")
11117 (cond [(eq_attr "alternative" "2")
11118 (const_string "lea")
11119 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11120 (const_int 0))
11121 (match_operand 0 "register_operand" ""))
11122 (match_operand 2 "const1_operand" ""))
11123 (const_string "alu")
11124 ]
11125 (const_string "ishift")))
11126 (set_attr "mode" "QI,SI,SI")])
11127
11128 (define_insn "*ashlqi3_1"
11129 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11130 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11131 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11132 (clobber (reg:CC FLAGS_REG))]
11133 "TARGET_PARTIAL_REG_STALL
11134 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11135 {
11136 switch (get_attr_type (insn))
11137 {
11138 case TYPE_ALU:
11139 gcc_assert (operands[2] == const1_rtx);
11140 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11141 return "add{l}\t{%k0, %k0|%k0, %k0}";
11142 else
11143 return "add{b}\t{%0, %0|%0, %0}";
11144
11145 default:
11146 if (REG_P (operands[2]))
11147 {
11148 if (get_attr_mode (insn) == MODE_SI)
11149 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11150 else
11151 return "sal{b}\t{%b2, %0|%0, %b2}";
11152 }
11153 else if (operands[2] == const1_rtx
11154 && (TARGET_SHIFT1 || optimize_size))
11155 {
11156 if (get_attr_mode (insn) == MODE_SI)
11157 return "sal{l}\t%0";
11158 else
11159 return "sal{b}\t%0";
11160 }
11161 else
11162 {
11163 if (get_attr_mode (insn) == MODE_SI)
11164 return "sal{l}\t{%2, %k0|%k0, %2}";
11165 else
11166 return "sal{b}\t{%2, %0|%0, %2}";
11167 }
11168 }
11169 }
11170 [(set (attr "type")
11171 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11172 (const_int 0))
11173 (match_operand 0 "register_operand" ""))
11174 (match_operand 2 "const1_operand" ""))
11175 (const_string "alu")
11176 ]
11177 (const_string "ishift")))
11178 (set_attr "mode" "QI,SI")])
11179
11180 ;; This pattern can't accept a variable shift count, since shifts by
11181 ;; zero don't affect the flags. We assume that shifts by constant
11182 ;; zero are optimized away.
11183 (define_insn "*ashlqi3_cmp"
11184 [(set (reg FLAGS_REG)
11185 (compare
11186 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11187 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11188 (const_int 0)))
11189 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11190 (ashift:QI (match_dup 1) (match_dup 2)))]
11191 "ix86_match_ccmode (insn, CCGOCmode)
11192 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11193 && (optimize_size
11194 || !TARGET_PARTIAL_FLAG_REG_STALL
11195 || (operands[2] == const1_rtx
11196 && (TARGET_SHIFT1
11197 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11198 {
11199 switch (get_attr_type (insn))
11200 {
11201 case TYPE_ALU:
11202 gcc_assert (operands[2] == const1_rtx);
11203 return "add{b}\t{%0, %0|%0, %0}";
11204
11205 default:
11206 if (REG_P (operands[2]))
11207 return "sal{b}\t{%b2, %0|%0, %b2}";
11208 else if (operands[2] == const1_rtx
11209 && (TARGET_SHIFT1 || optimize_size))
11210 return "sal{b}\t%0";
11211 else
11212 return "sal{b}\t{%2, %0|%0, %2}";
11213 }
11214 }
11215 [(set (attr "type")
11216 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11217 (const_int 0))
11218 (match_operand 0 "register_operand" ""))
11219 (match_operand 2 "const1_operand" ""))
11220 (const_string "alu")
11221 ]
11222 (const_string "ishift")))
11223 (set_attr "mode" "QI")])
11224
11225 (define_insn "*ashlqi3_cconly"
11226 [(set (reg FLAGS_REG)
11227 (compare
11228 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11229 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11230 (const_int 0)))
11231 (clobber (match_scratch:QI 0 "=q"))]
11232 "ix86_match_ccmode (insn, CCGOCmode)
11233 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11234 && (optimize_size
11235 || !TARGET_PARTIAL_FLAG_REG_STALL
11236 || (operands[2] == const1_rtx
11237 && (TARGET_SHIFT1
11238 || TARGET_DOUBLE_WITH_ADD)))"
11239 {
11240 switch (get_attr_type (insn))
11241 {
11242 case TYPE_ALU:
11243 gcc_assert (operands[2] == const1_rtx);
11244 return "add{b}\t{%0, %0|%0, %0}";
11245
11246 default:
11247 if (REG_P (operands[2]))
11248 return "sal{b}\t{%b2, %0|%0, %b2}";
11249 else if (operands[2] == const1_rtx
11250 && (TARGET_SHIFT1 || optimize_size))
11251 return "sal{b}\t%0";
11252 else
11253 return "sal{b}\t{%2, %0|%0, %2}";
11254 }
11255 }
11256 [(set (attr "type")
11257 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11258 (const_int 0))
11259 (match_operand 0 "register_operand" ""))
11260 (match_operand 2 "const1_operand" ""))
11261 (const_string "alu")
11262 ]
11263 (const_string "ishift")))
11264 (set_attr "mode" "QI")])
11265
11266 ;; See comment above `ashldi3' about how this works.
11267
11268 (define_expand "ashrti3"
11269 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11270 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11271 (match_operand:QI 2 "nonmemory_operand" "")))
11272 (clobber (reg:CC FLAGS_REG))])]
11273 "TARGET_64BIT"
11274 {
11275 if (! immediate_operand (operands[2], QImode))
11276 {
11277 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11278 DONE;
11279 }
11280 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11281 DONE;
11282 })
11283
11284 (define_insn "ashrti3_1"
11285 [(set (match_operand:TI 0 "register_operand" "=r")
11286 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11287 (match_operand:QI 2 "register_operand" "c")))
11288 (clobber (match_scratch:DI 3 "=&r"))
11289 (clobber (reg:CC FLAGS_REG))]
11290 "TARGET_64BIT"
11291 "#"
11292 [(set_attr "type" "multi")])
11293
11294 (define_insn "*ashrti3_2"
11295 [(set (match_operand:TI 0 "register_operand" "=r")
11296 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11297 (match_operand:QI 2 "immediate_operand" "O")))
11298 (clobber (reg:CC FLAGS_REG))]
11299 "TARGET_64BIT"
11300 "#"
11301 [(set_attr "type" "multi")])
11302
11303 (define_split
11304 [(set (match_operand:TI 0 "register_operand" "")
11305 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11306 (match_operand:QI 2 "register_operand" "")))
11307 (clobber (match_scratch:DI 3 ""))
11308 (clobber (reg:CC FLAGS_REG))]
11309 "TARGET_64BIT && reload_completed"
11310 [(const_int 0)]
11311 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11312
11313 (define_split
11314 [(set (match_operand:TI 0 "register_operand" "")
11315 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11316 (match_operand:QI 2 "immediate_operand" "")))
11317 (clobber (reg:CC FLAGS_REG))]
11318 "TARGET_64BIT && reload_completed"
11319 [(const_int 0)]
11320 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11321
11322 (define_insn "x86_64_shrd"
11323 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11324 (ior:DI (ashiftrt:DI (match_dup 0)
11325 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11326 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11327 (minus:QI (const_int 64) (match_dup 2)))))
11328 (clobber (reg:CC FLAGS_REG))]
11329 "TARGET_64BIT"
11330 "@
11331 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11332 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11333 [(set_attr "type" "ishift")
11334 (set_attr "prefix_0f" "1")
11335 (set_attr "mode" "DI")
11336 (set_attr "athlon_decode" "vector")])
11337
11338 (define_expand "ashrdi3"
11339 [(set (match_operand:DI 0 "shiftdi_operand" "")
11340 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11341 (match_operand:QI 2 "nonmemory_operand" "")))]
11342 ""
11343 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11344
11345 (define_insn "*ashrdi3_63_rex64"
11346 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11347 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11348 (match_operand:DI 2 "const_int_operand" "i,i")))
11349 (clobber (reg:CC FLAGS_REG))]
11350 "TARGET_64BIT && INTVAL (operands[2]) == 63
11351 && (TARGET_USE_CLTD || optimize_size)
11352 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11353 "@
11354 {cqto|cqo}
11355 sar{q}\t{%2, %0|%0, %2}"
11356 [(set_attr "type" "imovx,ishift")
11357 (set_attr "prefix_0f" "0,*")
11358 (set_attr "length_immediate" "0,*")
11359 (set_attr "modrm" "0,1")
11360 (set_attr "mode" "DI")])
11361
11362 (define_insn "*ashrdi3_1_one_bit_rex64"
11363 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11364 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11365 (match_operand:QI 2 "const1_operand" "")))
11366 (clobber (reg:CC FLAGS_REG))]
11367 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11368 && (TARGET_SHIFT1 || optimize_size)"
11369 "sar{q}\t%0"
11370 [(set_attr "type" "ishift")
11371 (set (attr "length")
11372 (if_then_else (match_operand:DI 0 "register_operand" "")
11373 (const_string "2")
11374 (const_string "*")))])
11375
11376 (define_insn "*ashrdi3_1_rex64"
11377 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11378 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11379 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11380 (clobber (reg:CC FLAGS_REG))]
11381 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11382 "@
11383 sar{q}\t{%2, %0|%0, %2}
11384 sar{q}\t{%b2, %0|%0, %b2}"
11385 [(set_attr "type" "ishift")
11386 (set_attr "mode" "DI")])
11387
11388 ;; This pattern can't accept a variable shift count, since shifts by
11389 ;; zero don't affect the flags. We assume that shifts by constant
11390 ;; zero are optimized away.
11391 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11392 [(set (reg FLAGS_REG)
11393 (compare
11394 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11395 (match_operand:QI 2 "const1_operand" ""))
11396 (const_int 0)))
11397 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11398 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11399 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11400 && (TARGET_SHIFT1 || optimize_size)
11401 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11402 "sar{q}\t%0"
11403 [(set_attr "type" "ishift")
11404 (set (attr "length")
11405 (if_then_else (match_operand:DI 0 "register_operand" "")
11406 (const_string "2")
11407 (const_string "*")))])
11408
11409 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11410 [(set (reg FLAGS_REG)
11411 (compare
11412 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11413 (match_operand:QI 2 "const1_operand" ""))
11414 (const_int 0)))
11415 (clobber (match_scratch:DI 0 "=r"))]
11416 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11417 && (TARGET_SHIFT1 || optimize_size)
11418 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11419 "sar{q}\t%0"
11420 [(set_attr "type" "ishift")
11421 (set_attr "length" "2")])
11422
11423 ;; This pattern can't accept a variable shift count, since shifts by
11424 ;; zero don't affect the flags. We assume that shifts by constant
11425 ;; zero are optimized away.
11426 (define_insn "*ashrdi3_cmp_rex64"
11427 [(set (reg FLAGS_REG)
11428 (compare
11429 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11430 (match_operand:QI 2 "const_int_operand" "n"))
11431 (const_int 0)))
11432 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11433 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11434 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11435 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11436 && (optimize_size
11437 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11438 "sar{q}\t{%2, %0|%0, %2}"
11439 [(set_attr "type" "ishift")
11440 (set_attr "mode" "DI")])
11441
11442 (define_insn "*ashrdi3_cconly_rex64"
11443 [(set (reg FLAGS_REG)
11444 (compare
11445 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11446 (match_operand:QI 2 "const_int_operand" "n"))
11447 (const_int 0)))
11448 (clobber (match_scratch:DI 0 "=r"))]
11449 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11450 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11451 && (optimize_size
11452 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11453 "sar{q}\t{%2, %0|%0, %2}"
11454 [(set_attr "type" "ishift")
11455 (set_attr "mode" "DI")])
11456
11457 (define_insn "*ashrdi3_1"
11458 [(set (match_operand:DI 0 "register_operand" "=r")
11459 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11460 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11461 (clobber (reg:CC FLAGS_REG))]
11462 "!TARGET_64BIT"
11463 "#"
11464 [(set_attr "type" "multi")])
11465
11466 ;; By default we don't ask for a scratch register, because when DImode
11467 ;; values are manipulated, registers are already at a premium. But if
11468 ;; we have one handy, we won't turn it away.
11469 (define_peephole2
11470 [(match_scratch:SI 3 "r")
11471 (parallel [(set (match_operand:DI 0 "register_operand" "")
11472 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11473 (match_operand:QI 2 "nonmemory_operand" "")))
11474 (clobber (reg:CC FLAGS_REG))])
11475 (match_dup 3)]
11476 "!TARGET_64BIT && TARGET_CMOVE"
11477 [(const_int 0)]
11478 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11479
11480 (define_split
11481 [(set (match_operand:DI 0 "register_operand" "")
11482 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11483 (match_operand:QI 2 "nonmemory_operand" "")))
11484 (clobber (reg:CC FLAGS_REG))]
11485 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11486 ? flow2_completed : reload_completed)"
11487 [(const_int 0)]
11488 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11489
11490 (define_insn "x86_shrd_1"
11491 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11492 (ior:SI (ashiftrt:SI (match_dup 0)
11493 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11494 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11495 (minus:QI (const_int 32) (match_dup 2)))))
11496 (clobber (reg:CC FLAGS_REG))]
11497 ""
11498 "@
11499 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11500 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11501 [(set_attr "type" "ishift")
11502 (set_attr "prefix_0f" "1")
11503 (set_attr "pent_pair" "np")
11504 (set_attr "mode" "SI")])
11505
11506 (define_expand "x86_shift_adj_3"
11507 [(use (match_operand:SI 0 "register_operand" ""))
11508 (use (match_operand:SI 1 "register_operand" ""))
11509 (use (match_operand:QI 2 "register_operand" ""))]
11510 ""
11511 {
11512 rtx label = gen_label_rtx ();
11513 rtx tmp;
11514
11515 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11516
11517 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11518 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11519 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11520 gen_rtx_LABEL_REF (VOIDmode, label),
11521 pc_rtx);
11522 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11523 JUMP_LABEL (tmp) = label;
11524
11525 emit_move_insn (operands[0], operands[1]);
11526 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11527
11528 emit_label (label);
11529 LABEL_NUSES (label) = 1;
11530
11531 DONE;
11532 })
11533
11534 (define_insn "ashrsi3_31"
11535 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11536 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11537 (match_operand:SI 2 "const_int_operand" "i,i")))
11538 (clobber (reg:CC FLAGS_REG))]
11539 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11540 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11541 "@
11542 {cltd|cdq}
11543 sar{l}\t{%2, %0|%0, %2}"
11544 [(set_attr "type" "imovx,ishift")
11545 (set_attr "prefix_0f" "0,*")
11546 (set_attr "length_immediate" "0,*")
11547 (set_attr "modrm" "0,1")
11548 (set_attr "mode" "SI")])
11549
11550 (define_insn "*ashrsi3_31_zext"
11551 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11552 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11553 (match_operand:SI 2 "const_int_operand" "i,i"))))
11554 (clobber (reg:CC FLAGS_REG))]
11555 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11556 && INTVAL (operands[2]) == 31
11557 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11558 "@
11559 {cltd|cdq}
11560 sar{l}\t{%2, %k0|%k0, %2}"
11561 [(set_attr "type" "imovx,ishift")
11562 (set_attr "prefix_0f" "0,*")
11563 (set_attr "length_immediate" "0,*")
11564 (set_attr "modrm" "0,1")
11565 (set_attr "mode" "SI")])
11566
11567 (define_expand "ashrsi3"
11568 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11569 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11570 (match_operand:QI 2 "nonmemory_operand" "")))
11571 (clobber (reg:CC FLAGS_REG))]
11572 ""
11573 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11574
11575 (define_insn "*ashrsi3_1_one_bit"
11576 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11577 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11578 (match_operand:QI 2 "const1_operand" "")))
11579 (clobber (reg:CC FLAGS_REG))]
11580 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11581 && (TARGET_SHIFT1 || optimize_size)"
11582 "sar{l}\t%0"
11583 [(set_attr "type" "ishift")
11584 (set (attr "length")
11585 (if_then_else (match_operand:SI 0 "register_operand" "")
11586 (const_string "2")
11587 (const_string "*")))])
11588
11589 (define_insn "*ashrsi3_1_one_bit_zext"
11590 [(set (match_operand:DI 0 "register_operand" "=r")
11591 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11592 (match_operand:QI 2 "const1_operand" ""))))
11593 (clobber (reg:CC FLAGS_REG))]
11594 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11595 && (TARGET_SHIFT1 || optimize_size)"
11596 "sar{l}\t%k0"
11597 [(set_attr "type" "ishift")
11598 (set_attr "length" "2")])
11599
11600 (define_insn "*ashrsi3_1"
11601 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11602 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11603 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11604 (clobber (reg:CC FLAGS_REG))]
11605 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11606 "@
11607 sar{l}\t{%2, %0|%0, %2}
11608 sar{l}\t{%b2, %0|%0, %b2}"
11609 [(set_attr "type" "ishift")
11610 (set_attr "mode" "SI")])
11611
11612 (define_insn "*ashrsi3_1_zext"
11613 [(set (match_operand:DI 0 "register_operand" "=r,r")
11614 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11615 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11616 (clobber (reg:CC FLAGS_REG))]
11617 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11618 "@
11619 sar{l}\t{%2, %k0|%k0, %2}
11620 sar{l}\t{%b2, %k0|%k0, %b2}"
11621 [(set_attr "type" "ishift")
11622 (set_attr "mode" "SI")])
11623
11624 ;; This pattern can't accept a variable shift count, since shifts by
11625 ;; zero don't affect the flags. We assume that shifts by constant
11626 ;; zero are optimized away.
11627 (define_insn "*ashrsi3_one_bit_cmp"
11628 [(set (reg FLAGS_REG)
11629 (compare
11630 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11631 (match_operand:QI 2 "const1_operand" ""))
11632 (const_int 0)))
11633 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11634 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11635 "ix86_match_ccmode (insn, CCGOCmode)
11636 && (TARGET_SHIFT1 || optimize_size)
11637 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11638 "sar{l}\t%0"
11639 [(set_attr "type" "ishift")
11640 (set (attr "length")
11641 (if_then_else (match_operand:SI 0 "register_operand" "")
11642 (const_string "2")
11643 (const_string "*")))])
11644
11645 (define_insn "*ashrsi3_one_bit_cconly"
11646 [(set (reg FLAGS_REG)
11647 (compare
11648 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11649 (match_operand:QI 2 "const1_operand" ""))
11650 (const_int 0)))
11651 (clobber (match_scratch:SI 0 "=r"))]
11652 "ix86_match_ccmode (insn, CCGOCmode)
11653 && (TARGET_SHIFT1 || optimize_size)
11654 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11655 "sar{l}\t%0"
11656 [(set_attr "type" "ishift")
11657 (set_attr "length" "2")])
11658
11659 (define_insn "*ashrsi3_one_bit_cmp_zext"
11660 [(set (reg FLAGS_REG)
11661 (compare
11662 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11663 (match_operand:QI 2 "const1_operand" ""))
11664 (const_int 0)))
11665 (set (match_operand:DI 0 "register_operand" "=r")
11666 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11667 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11668 && (TARGET_SHIFT1 || optimize_size)
11669 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11670 "sar{l}\t%k0"
11671 [(set_attr "type" "ishift")
11672 (set_attr "length" "2")])
11673
11674 ;; This pattern can't accept a variable shift count, since shifts by
11675 ;; zero don't affect the flags. We assume that shifts by constant
11676 ;; zero are optimized away.
11677 (define_insn "*ashrsi3_cmp"
11678 [(set (reg FLAGS_REG)
11679 (compare
11680 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11681 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11682 (const_int 0)))
11683 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11684 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11685 "ix86_match_ccmode (insn, CCGOCmode)
11686 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11687 && (optimize_size
11688 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11689 "sar{l}\t{%2, %0|%0, %2}"
11690 [(set_attr "type" "ishift")
11691 (set_attr "mode" "SI")])
11692
11693 (define_insn "*ashrsi3_cconly"
11694 [(set (reg FLAGS_REG)
11695 (compare
11696 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11697 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11698 (const_int 0)))
11699 (clobber (match_scratch:SI 0 "=r"))]
11700 "ix86_match_ccmode (insn, CCGOCmode)
11701 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11702 && (optimize_size
11703 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11704 "sar{l}\t{%2, %0|%0, %2}"
11705 [(set_attr "type" "ishift")
11706 (set_attr "mode" "SI")])
11707
11708 (define_insn "*ashrsi3_cmp_zext"
11709 [(set (reg FLAGS_REG)
11710 (compare
11711 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11712 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11713 (const_int 0)))
11714 (set (match_operand:DI 0 "register_operand" "=r")
11715 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11716 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11717 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11718 && (optimize_size
11719 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11720 "sar{l}\t{%2, %k0|%k0, %2}"
11721 [(set_attr "type" "ishift")
11722 (set_attr "mode" "SI")])
11723
11724 (define_expand "ashrhi3"
11725 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11726 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11727 (match_operand:QI 2 "nonmemory_operand" "")))
11728 (clobber (reg:CC FLAGS_REG))]
11729 "TARGET_HIMODE_MATH"
11730 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11731
11732 (define_insn "*ashrhi3_1_one_bit"
11733 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11734 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11735 (match_operand:QI 2 "const1_operand" "")))
11736 (clobber (reg:CC FLAGS_REG))]
11737 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11738 && (TARGET_SHIFT1 || optimize_size)"
11739 "sar{w}\t%0"
11740 [(set_attr "type" "ishift")
11741 (set (attr "length")
11742 (if_then_else (match_operand 0 "register_operand" "")
11743 (const_string "2")
11744 (const_string "*")))])
11745
11746 (define_insn "*ashrhi3_1"
11747 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11748 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11749 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11750 (clobber (reg:CC FLAGS_REG))]
11751 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11752 "@
11753 sar{w}\t{%2, %0|%0, %2}
11754 sar{w}\t{%b2, %0|%0, %b2}"
11755 [(set_attr "type" "ishift")
11756 (set_attr "mode" "HI")])
11757
11758 ;; This pattern can't accept a variable shift count, since shifts by
11759 ;; zero don't affect the flags. We assume that shifts by constant
11760 ;; zero are optimized away.
11761 (define_insn "*ashrhi3_one_bit_cmp"
11762 [(set (reg FLAGS_REG)
11763 (compare
11764 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11765 (match_operand:QI 2 "const1_operand" ""))
11766 (const_int 0)))
11767 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11768 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11769 "ix86_match_ccmode (insn, CCGOCmode)
11770 && (TARGET_SHIFT1 || optimize_size)
11771 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11772 "sar{w}\t%0"
11773 [(set_attr "type" "ishift")
11774 (set (attr "length")
11775 (if_then_else (match_operand 0 "register_operand" "")
11776 (const_string "2")
11777 (const_string "*")))])
11778
11779 (define_insn "*ashrhi3_one_bit_cconly"
11780 [(set (reg FLAGS_REG)
11781 (compare
11782 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11783 (match_operand:QI 2 "const1_operand" ""))
11784 (const_int 0)))
11785 (clobber (match_scratch:HI 0 "=r"))]
11786 "ix86_match_ccmode (insn, CCGOCmode)
11787 && (TARGET_SHIFT1 || optimize_size)
11788 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11789 "sar{w}\t%0"
11790 [(set_attr "type" "ishift")
11791 (set_attr "length" "2")])
11792
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags. We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashrhi3_cmp"
11797 [(set (reg FLAGS_REG)
11798 (compare
11799 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11800 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11801 (const_int 0)))
11802 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11803 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11804 "ix86_match_ccmode (insn, CCGOCmode)
11805 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11806 && (optimize_size
11807 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11808 "sar{w}\t{%2, %0|%0, %2}"
11809 [(set_attr "type" "ishift")
11810 (set_attr "mode" "HI")])
11811
11812 (define_insn "*ashrhi3_cconly"
11813 [(set (reg FLAGS_REG)
11814 (compare
11815 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11816 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11817 (const_int 0)))
11818 (clobber (match_scratch:HI 0 "=r"))]
11819 "ix86_match_ccmode (insn, CCGOCmode)
11820 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11821 && (optimize_size
11822 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11823 "sar{w}\t{%2, %0|%0, %2}"
11824 [(set_attr "type" "ishift")
11825 (set_attr "mode" "HI")])
11826
11827 (define_expand "ashrqi3"
11828 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11829 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11830 (match_operand:QI 2 "nonmemory_operand" "")))
11831 (clobber (reg:CC FLAGS_REG))]
11832 "TARGET_QIMODE_MATH"
11833 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11834
11835 (define_insn "*ashrqi3_1_one_bit"
11836 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11837 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11838 (match_operand:QI 2 "const1_operand" "")))
11839 (clobber (reg:CC FLAGS_REG))]
11840 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11841 && (TARGET_SHIFT1 || optimize_size)"
11842 "sar{b}\t%0"
11843 [(set_attr "type" "ishift")
11844 (set (attr "length")
11845 (if_then_else (match_operand 0 "register_operand" "")
11846 (const_string "2")
11847 (const_string "*")))])
11848
11849 (define_insn "*ashrqi3_1_one_bit_slp"
11850 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11851 (ashiftrt:QI (match_dup 0)
11852 (match_operand:QI 1 "const1_operand" "")))
11853 (clobber (reg:CC FLAGS_REG))]
11854 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11855 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11856 && (TARGET_SHIFT1 || optimize_size)"
11857 "sar{b}\t%0"
11858 [(set_attr "type" "ishift1")
11859 (set (attr "length")
11860 (if_then_else (match_operand 0 "register_operand" "")
11861 (const_string "2")
11862 (const_string "*")))])
11863
11864 (define_insn "*ashrqi3_1"
11865 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11866 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11867 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11868 (clobber (reg:CC FLAGS_REG))]
11869 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11870 "@
11871 sar{b}\t{%2, %0|%0, %2}
11872 sar{b}\t{%b2, %0|%0, %b2}"
11873 [(set_attr "type" "ishift")
11874 (set_attr "mode" "QI")])
11875
11876 (define_insn "*ashrqi3_1_slp"
11877 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11878 (ashiftrt:QI (match_dup 0)
11879 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11880 (clobber (reg:CC FLAGS_REG))]
11881 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11882 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11883 "@
11884 sar{b}\t{%1, %0|%0, %1}
11885 sar{b}\t{%b1, %0|%0, %b1}"
11886 [(set_attr "type" "ishift1")
11887 (set_attr "mode" "QI")])
11888
11889 ;; This pattern can't accept a variable shift count, since shifts by
11890 ;; zero don't affect the flags. We assume that shifts by constant
11891 ;; zero are optimized away.
11892 (define_insn "*ashrqi3_one_bit_cmp"
11893 [(set (reg FLAGS_REG)
11894 (compare
11895 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11896 (match_operand:QI 2 "const1_operand" "I"))
11897 (const_int 0)))
11898 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11899 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11900 "ix86_match_ccmode (insn, CCGOCmode)
11901 && (TARGET_SHIFT1 || optimize_size)
11902 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11903 "sar{b}\t%0"
11904 [(set_attr "type" "ishift")
11905 (set (attr "length")
11906 (if_then_else (match_operand 0 "register_operand" "")
11907 (const_string "2")
11908 (const_string "*")))])
11909
11910 (define_insn "*ashrqi3_one_bit_cconly"
11911 [(set (reg FLAGS_REG)
11912 (compare
11913 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11914 (match_operand:QI 2 "const1_operand" "I"))
11915 (const_int 0)))
11916 (clobber (match_scratch:QI 0 "=q"))]
11917 "ix86_match_ccmode (insn, CCGOCmode)
11918 && (TARGET_SHIFT1 || optimize_size)
11919 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11920 "sar{b}\t%0"
11921 [(set_attr "type" "ishift")
11922 (set_attr "length" "2")])
11923
11924 ;; This pattern can't accept a variable shift count, since shifts by
11925 ;; zero don't affect the flags. We assume that shifts by constant
11926 ;; zero are optimized away.
11927 (define_insn "*ashrqi3_cmp"
11928 [(set (reg FLAGS_REG)
11929 (compare
11930 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11931 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11932 (const_int 0)))
11933 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11934 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11935 "ix86_match_ccmode (insn, CCGOCmode)
11936 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11937 && (optimize_size
11938 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11939 "sar{b}\t{%2, %0|%0, %2}"
11940 [(set_attr "type" "ishift")
11941 (set_attr "mode" "QI")])
11942
11943 (define_insn "*ashrqi3_cconly"
11944 [(set (reg FLAGS_REG)
11945 (compare
11946 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11947 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11948 (const_int 0)))
11949 (clobber (match_scratch:QI 0 "=q"))]
11950 "ix86_match_ccmode (insn, CCGOCmode)
11951 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11952 && (optimize_size
11953 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11954 "sar{b}\t{%2, %0|%0, %2}"
11955 [(set_attr "type" "ishift")
11956 (set_attr "mode" "QI")])
11957
11958 \f
11959 ;; Logical shift instructions
11960
11961 ;; See comment above `ashldi3' about how this works.
11962
11963 (define_expand "lshrti3"
11964 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11965 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11966 (match_operand:QI 2 "nonmemory_operand" "")))
11967 (clobber (reg:CC FLAGS_REG))])]
11968 "TARGET_64BIT"
11969 {
11970 if (! immediate_operand (operands[2], QImode))
11971 {
11972 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11973 DONE;
11974 }
11975 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11976 DONE;
11977 })
11978
11979 (define_insn "lshrti3_1"
11980 [(set (match_operand:TI 0 "register_operand" "=r")
11981 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11982 (match_operand:QI 2 "register_operand" "c")))
11983 (clobber (match_scratch:DI 3 "=&r"))
11984 (clobber (reg:CC FLAGS_REG))]
11985 "TARGET_64BIT"
11986 "#"
11987 [(set_attr "type" "multi")])
11988
11989 (define_insn "*lshrti3_2"
11990 [(set (match_operand:TI 0 "register_operand" "=r")
11991 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11992 (match_operand:QI 2 "immediate_operand" "O")))
11993 (clobber (reg:CC FLAGS_REG))]
11994 "TARGET_64BIT"
11995 "#"
11996 [(set_attr "type" "multi")])
11997
11998 (define_split
11999 [(set (match_operand:TI 0 "register_operand" "")
12000 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12001 (match_operand:QI 2 "register_operand" "")))
12002 (clobber (match_scratch:DI 3 ""))
12003 (clobber (reg:CC FLAGS_REG))]
12004 "TARGET_64BIT && reload_completed"
12005 [(const_int 0)]
12006 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12007
12008 (define_split
12009 [(set (match_operand:TI 0 "register_operand" "")
12010 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12011 (match_operand:QI 2 "immediate_operand" "")))
12012 (clobber (reg:CC FLAGS_REG))]
12013 "TARGET_64BIT && reload_completed"
12014 [(const_int 0)]
12015 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12016
12017 (define_expand "lshrdi3"
12018 [(set (match_operand:DI 0 "shiftdi_operand" "")
12019 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12020 (match_operand:QI 2 "nonmemory_operand" "")))]
12021 ""
12022 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12023
12024 (define_insn "*lshrdi3_1_one_bit_rex64"
12025 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12026 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12027 (match_operand:QI 2 "const1_operand" "")))
12028 (clobber (reg:CC FLAGS_REG))]
12029 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12030 && (TARGET_SHIFT1 || optimize_size)"
12031 "shr{q}\t%0"
12032 [(set_attr "type" "ishift")
12033 (set (attr "length")
12034 (if_then_else (match_operand:DI 0 "register_operand" "")
12035 (const_string "2")
12036 (const_string "*")))])
12037
12038 (define_insn "*lshrdi3_1_rex64"
12039 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12040 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12041 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12042 (clobber (reg:CC FLAGS_REG))]
12043 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12044 "@
12045 shr{q}\t{%2, %0|%0, %2}
12046 shr{q}\t{%b2, %0|%0, %b2}"
12047 [(set_attr "type" "ishift")
12048 (set_attr "mode" "DI")])
12049
12050 ;; This pattern can't accept a variable shift count, since shifts by
12051 ;; zero don't affect the flags. We assume that shifts by constant
12052 ;; zero are optimized away.
12053 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12054 [(set (reg FLAGS_REG)
12055 (compare
12056 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12057 (match_operand:QI 2 "const1_operand" ""))
12058 (const_int 0)))
12059 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12060 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12061 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12062 && (TARGET_SHIFT1 || optimize_size)
12063 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12064 "shr{q}\t%0"
12065 [(set_attr "type" "ishift")
12066 (set (attr "length")
12067 (if_then_else (match_operand:DI 0 "register_operand" "")
12068 (const_string "2")
12069 (const_string "*")))])
12070
12071 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12072 [(set (reg FLAGS_REG)
12073 (compare
12074 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12075 (match_operand:QI 2 "const1_operand" ""))
12076 (const_int 0)))
12077 (clobber (match_scratch:DI 0 "=r"))]
12078 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12079 && (TARGET_SHIFT1 || optimize_size)
12080 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12081 "shr{q}\t%0"
12082 [(set_attr "type" "ishift")
12083 (set_attr "length" "2")])
12084
12085 ;; This pattern can't accept a variable shift count, since shifts by
12086 ;; zero don't affect the flags. We assume that shifts by constant
12087 ;; zero are optimized away.
12088 (define_insn "*lshrdi3_cmp_rex64"
12089 [(set (reg FLAGS_REG)
12090 (compare
12091 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12092 (match_operand:QI 2 "const_int_operand" "e"))
12093 (const_int 0)))
12094 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12095 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12096 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12097 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12098 && (optimize_size
12099 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12100 "shr{q}\t{%2, %0|%0, %2}"
12101 [(set_attr "type" "ishift")
12102 (set_attr "mode" "DI")])
12103
12104 (define_insn "*lshrdi3_cconly_rex64"
12105 [(set (reg FLAGS_REG)
12106 (compare
12107 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12108 (match_operand:QI 2 "const_int_operand" "e"))
12109 (const_int 0)))
12110 (clobber (match_scratch:DI 0 "=r"))]
12111 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12112 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12113 && (optimize_size
12114 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12115 "shr{q}\t{%2, %0|%0, %2}"
12116 [(set_attr "type" "ishift")
12117 (set_attr "mode" "DI")])
12118
12119 (define_insn "*lshrdi3_1"
12120 [(set (match_operand:DI 0 "register_operand" "=r")
12121 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12122 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12123 (clobber (reg:CC FLAGS_REG))]
12124 "!TARGET_64BIT"
12125 "#"
12126 [(set_attr "type" "multi")])
12127
12128 ;; By default we don't ask for a scratch register, because when DImode
12129 ;; values are manipulated, registers are already at a premium. But if
12130 ;; we have one handy, we won't turn it away.
12131 (define_peephole2
12132 [(match_scratch:SI 3 "r")
12133 (parallel [(set (match_operand:DI 0 "register_operand" "")
12134 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12135 (match_operand:QI 2 "nonmemory_operand" "")))
12136 (clobber (reg:CC FLAGS_REG))])
12137 (match_dup 3)]
12138 "!TARGET_64BIT && TARGET_CMOVE"
12139 [(const_int 0)]
12140 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12141
12142 (define_split
12143 [(set (match_operand:DI 0 "register_operand" "")
12144 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12145 (match_operand:QI 2 "nonmemory_operand" "")))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12148 ? flow2_completed : reload_completed)"
12149 [(const_int 0)]
12150 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12151
12152 (define_expand "lshrsi3"
12153 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12154 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12155 (match_operand:QI 2 "nonmemory_operand" "")))
12156 (clobber (reg:CC FLAGS_REG))]
12157 ""
12158 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12159
12160 (define_insn "*lshrsi3_1_one_bit"
12161 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12162 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12163 (match_operand:QI 2 "const1_operand" "")))
12164 (clobber (reg:CC FLAGS_REG))]
12165 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12166 && (TARGET_SHIFT1 || optimize_size)"
12167 "shr{l}\t%0"
12168 [(set_attr "type" "ishift")
12169 (set (attr "length")
12170 (if_then_else (match_operand:SI 0 "register_operand" "")
12171 (const_string "2")
12172 (const_string "*")))])
12173
12174 (define_insn "*lshrsi3_1_one_bit_zext"
12175 [(set (match_operand:DI 0 "register_operand" "=r")
12176 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12177 (match_operand:QI 2 "const1_operand" "")))
12178 (clobber (reg:CC FLAGS_REG))]
12179 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12180 && (TARGET_SHIFT1 || optimize_size)"
12181 "shr{l}\t%k0"
12182 [(set_attr "type" "ishift")
12183 (set_attr "length" "2")])
12184
12185 (define_insn "*lshrsi3_1"
12186 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12187 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12188 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12189 (clobber (reg:CC FLAGS_REG))]
12190 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12191 "@
12192 shr{l}\t{%2, %0|%0, %2}
12193 shr{l}\t{%b2, %0|%0, %b2}"
12194 [(set_attr "type" "ishift")
12195 (set_attr "mode" "SI")])
12196
12197 (define_insn "*lshrsi3_1_zext"
12198 [(set (match_operand:DI 0 "register_operand" "=r,r")
12199 (zero_extend:DI
12200 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12201 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12202 (clobber (reg:CC FLAGS_REG))]
12203 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12204 "@
12205 shr{l}\t{%2, %k0|%k0, %2}
12206 shr{l}\t{%b2, %k0|%k0, %b2}"
12207 [(set_attr "type" "ishift")
12208 (set_attr "mode" "SI")])
12209
12210 ;; This pattern can't accept a variable shift count, since shifts by
12211 ;; zero don't affect the flags. We assume that shifts by constant
12212 ;; zero are optimized away.
12213 (define_insn "*lshrsi3_one_bit_cmp"
12214 [(set (reg FLAGS_REG)
12215 (compare
12216 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12217 (match_operand:QI 2 "const1_operand" ""))
12218 (const_int 0)))
12219 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12220 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12221 "ix86_match_ccmode (insn, CCGOCmode)
12222 && (TARGET_SHIFT1 || optimize_size)
12223 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12224 "shr{l}\t%0"
12225 [(set_attr "type" "ishift")
12226 (set (attr "length")
12227 (if_then_else (match_operand:SI 0 "register_operand" "")
12228 (const_string "2")
12229 (const_string "*")))])
12230
12231 (define_insn "*lshrsi3_one_bit_cconly"
12232 [(set (reg FLAGS_REG)
12233 (compare
12234 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12235 (match_operand:QI 2 "const1_operand" ""))
12236 (const_int 0)))
12237 (clobber (match_scratch:SI 0 "=r"))]
12238 "ix86_match_ccmode (insn, CCGOCmode)
12239 && (TARGET_SHIFT1 || optimize_size)
12240 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12241 "shr{l}\t%0"
12242 [(set_attr "type" "ishift")
12243 (set_attr "length" "2")])
12244
12245 (define_insn "*lshrsi3_cmp_one_bit_zext"
12246 [(set (reg FLAGS_REG)
12247 (compare
12248 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12249 (match_operand:QI 2 "const1_operand" ""))
12250 (const_int 0)))
12251 (set (match_operand:DI 0 "register_operand" "=r")
12252 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12253 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12254 && (TARGET_SHIFT1 || optimize_size)
12255 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12256 "shr{l}\t%k0"
12257 [(set_attr "type" "ishift")
12258 (set_attr "length" "2")])
12259
12260 ;; This pattern can't accept a variable shift count, since shifts by
12261 ;; zero don't affect the flags. We assume that shifts by constant
12262 ;; zero are optimized away.
12263 (define_insn "*lshrsi3_cmp"
12264 [(set (reg FLAGS_REG)
12265 (compare
12266 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12267 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12268 (const_int 0)))
12269 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12270 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12271 "ix86_match_ccmode (insn, CCGOCmode)
12272 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12273 && (optimize_size
12274 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12275 "shr{l}\t{%2, %0|%0, %2}"
12276 [(set_attr "type" "ishift")
12277 (set_attr "mode" "SI")])
12278
12279 (define_insn "*lshrsi3_cconly"
12280 [(set (reg FLAGS_REG)
12281 (compare
12282 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12283 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12284 (const_int 0)))
12285 (clobber (match_scratch:SI 0 "=r"))]
12286 "ix86_match_ccmode (insn, CCGOCmode)
12287 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12288 && (optimize_size
12289 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12290 "shr{l}\t{%2, %0|%0, %2}"
12291 [(set_attr "type" "ishift")
12292 (set_attr "mode" "SI")])
12293
12294 (define_insn "*lshrsi3_cmp_zext"
12295 [(set (reg FLAGS_REG)
12296 (compare
12297 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12298 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12299 (const_int 0)))
12300 (set (match_operand:DI 0 "register_operand" "=r")
12301 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12302 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12303 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12304 && (optimize_size
12305 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12306 "shr{l}\t{%2, %k0|%k0, %2}"
12307 [(set_attr "type" "ishift")
12308 (set_attr "mode" "SI")])
12309
12310 (define_expand "lshrhi3"
12311 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12312 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12313 (match_operand:QI 2 "nonmemory_operand" "")))
12314 (clobber (reg:CC FLAGS_REG))]
12315 "TARGET_HIMODE_MATH"
12316 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12317
12318 (define_insn "*lshrhi3_1_one_bit"
12319 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12320 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12321 (match_operand:QI 2 "const1_operand" "")))
12322 (clobber (reg:CC FLAGS_REG))]
12323 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12324 && (TARGET_SHIFT1 || optimize_size)"
12325 "shr{w}\t%0"
12326 [(set_attr "type" "ishift")
12327 (set (attr "length")
12328 (if_then_else (match_operand 0 "register_operand" "")
12329 (const_string "2")
12330 (const_string "*")))])
12331
12332 (define_insn "*lshrhi3_1"
12333 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12334 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12335 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12336 (clobber (reg:CC FLAGS_REG))]
12337 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12338 "@
12339 shr{w}\t{%2, %0|%0, %2}
12340 shr{w}\t{%b2, %0|%0, %b2}"
12341 [(set_attr "type" "ishift")
12342 (set_attr "mode" "HI")])
12343
12344 ;; This pattern can't accept a variable shift count, since shifts by
12345 ;; zero don't affect the flags. We assume that shifts by constant
12346 ;; zero are optimized away.
12347 (define_insn "*lshrhi3_one_bit_cmp"
12348 [(set (reg FLAGS_REG)
12349 (compare
12350 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12351 (match_operand:QI 2 "const1_operand" ""))
12352 (const_int 0)))
12353 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12354 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12355 "ix86_match_ccmode (insn, CCGOCmode)
12356 && (TARGET_SHIFT1 || optimize_size)
12357 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12358 "shr{w}\t%0"
12359 [(set_attr "type" "ishift")
12360 (set (attr "length")
12361 (if_then_else (match_operand:SI 0 "register_operand" "")
12362 (const_string "2")
12363 (const_string "*")))])
12364
12365 (define_insn "*lshrhi3_one_bit_cconly"
12366 [(set (reg FLAGS_REG)
12367 (compare
12368 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12369 (match_operand:QI 2 "const1_operand" ""))
12370 (const_int 0)))
12371 (clobber (match_scratch:HI 0 "=r"))]
12372 "ix86_match_ccmode (insn, CCGOCmode)
12373 && (TARGET_SHIFT1 || optimize_size)
12374 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12375 "shr{w}\t%0"
12376 [(set_attr "type" "ishift")
12377 (set_attr "length" "2")])
12378
12379 ;; This pattern can't accept a variable shift count, since shifts by
12380 ;; zero don't affect the flags. We assume that shifts by constant
12381 ;; zero are optimized away.
12382 (define_insn "*lshrhi3_cmp"
12383 [(set (reg FLAGS_REG)
12384 (compare
12385 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12386 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12387 (const_int 0)))
12388 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12389 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12390 "ix86_match_ccmode (insn, CCGOCmode)
12391 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12392 && (optimize_size
12393 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12394 "shr{w}\t{%2, %0|%0, %2}"
12395 [(set_attr "type" "ishift")
12396 (set_attr "mode" "HI")])
12397
12398 (define_insn "*lshrhi3_cconly"
12399 [(set (reg FLAGS_REG)
12400 (compare
12401 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12402 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12403 (const_int 0)))
12404 (clobber (match_scratch:HI 0 "=r"))]
12405 "ix86_match_ccmode (insn, CCGOCmode)
12406 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12407 && (optimize_size
12408 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12409 "shr{w}\t{%2, %0|%0, %2}"
12410 [(set_attr "type" "ishift")
12411 (set_attr "mode" "HI")])
12412
12413 (define_expand "lshrqi3"
12414 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12415 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12416 (match_operand:QI 2 "nonmemory_operand" "")))
12417 (clobber (reg:CC FLAGS_REG))]
12418 "TARGET_QIMODE_MATH"
12419 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12420
12421 (define_insn "*lshrqi3_1_one_bit"
12422 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12423 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12424 (match_operand:QI 2 "const1_operand" "")))
12425 (clobber (reg:CC FLAGS_REG))]
12426 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12427 && (TARGET_SHIFT1 || optimize_size)"
12428 "shr{b}\t%0"
12429 [(set_attr "type" "ishift")
12430 (set (attr "length")
12431 (if_then_else (match_operand 0 "register_operand" "")
12432 (const_string "2")
12433 (const_string "*")))])
12434
12435 (define_insn "*lshrqi3_1_one_bit_slp"
12436 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12437 (lshiftrt:QI (match_dup 0)
12438 (match_operand:QI 1 "const1_operand" "")))
12439 (clobber (reg:CC FLAGS_REG))]
12440 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12441 && (TARGET_SHIFT1 || optimize_size)"
12442 "shr{b}\t%0"
12443 [(set_attr "type" "ishift1")
12444 (set (attr "length")
12445 (if_then_else (match_operand 0 "register_operand" "")
12446 (const_string "2")
12447 (const_string "*")))])
12448
12449 (define_insn "*lshrqi3_1"
12450 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12451 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12452 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12453 (clobber (reg:CC FLAGS_REG))]
12454 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12455 "@
12456 shr{b}\t{%2, %0|%0, %2}
12457 shr{b}\t{%b2, %0|%0, %b2}"
12458 [(set_attr "type" "ishift")
12459 (set_attr "mode" "QI")])
12460
12461 (define_insn "*lshrqi3_1_slp"
12462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12463 (lshiftrt:QI (match_dup 0)
12464 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12465 (clobber (reg:CC FLAGS_REG))]
12466 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12468 "@
12469 shr{b}\t{%1, %0|%0, %1}
12470 shr{b}\t{%b1, %0|%0, %b1}"
12471 [(set_attr "type" "ishift1")
12472 (set_attr "mode" "QI")])
12473
12474 ;; This pattern can't accept a variable shift count, since shifts by
12475 ;; zero don't affect the flags. We assume that shifts by constant
12476 ;; zero are optimized away.
12477 (define_insn "*lshrqi2_one_bit_cmp"
12478 [(set (reg FLAGS_REG)
12479 (compare
12480 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12481 (match_operand:QI 2 "const1_operand" ""))
12482 (const_int 0)))
12483 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12484 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12485 "ix86_match_ccmode (insn, CCGOCmode)
12486 && (TARGET_SHIFT1 || optimize_size)
12487 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12488 "shr{b}\t%0"
12489 [(set_attr "type" "ishift")
12490 (set (attr "length")
12491 (if_then_else (match_operand:SI 0 "register_operand" "")
12492 (const_string "2")
12493 (const_string "*")))])
12494
12495 (define_insn "*lshrqi2_one_bit_cconly"
12496 [(set (reg FLAGS_REG)
12497 (compare
12498 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12499 (match_operand:QI 2 "const1_operand" ""))
12500 (const_int 0)))
12501 (clobber (match_scratch:QI 0 "=q"))]
12502 "ix86_match_ccmode (insn, CCGOCmode)
12503 && (TARGET_SHIFT1 || optimize_size)
12504 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12505 "shr{b}\t%0"
12506 [(set_attr "type" "ishift")
12507 (set_attr "length" "2")])
12508
12509 ;; This pattern can't accept a variable shift count, since shifts by
12510 ;; zero don't affect the flags. We assume that shifts by constant
12511 ;; zero are optimized away.
12512 (define_insn "*lshrqi2_cmp"
12513 [(set (reg FLAGS_REG)
12514 (compare
12515 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12516 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12517 (const_int 0)))
12518 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12519 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12520 "ix86_match_ccmode (insn, CCGOCmode)
12521 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12522 && (optimize_size
12523 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12524 "shr{b}\t{%2, %0|%0, %2}"
12525 [(set_attr "type" "ishift")
12526 (set_attr "mode" "QI")])
12527
12528 (define_insn "*lshrqi2_cconly"
12529 [(set (reg FLAGS_REG)
12530 (compare
12531 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12532 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12533 (const_int 0)))
12534 (clobber (match_scratch:QI 0 "=q"))]
12535 "ix86_match_ccmode (insn, CCGOCmode)
12536 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12537 && (optimize_size
12538 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12539 "shr{b}\t{%2, %0|%0, %2}"
12540 [(set_attr "type" "ishift")
12541 (set_attr "mode" "QI")])
12542 \f
12543 ;; Rotate instructions
12544
12545 (define_expand "rotldi3"
12546 [(set (match_operand:DI 0 "shiftdi_operand" "")
12547 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12548 (match_operand:QI 2 "nonmemory_operand" "")))
12549 (clobber (reg:CC FLAGS_REG))]
12550 ""
12551 {
12552 if (TARGET_64BIT)
12553 {
12554 ix86_expand_binary_operator (ROTATE, DImode, operands);
12555 DONE;
12556 }
12557 if (!const_1_to_31_operand (operands[2], VOIDmode))
12558 FAIL;
12559 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12560 DONE;
12561 })
12562
12563 ;; Implement rotation using two double-precision shift instructions
12564 ;; and a scratch register.
12565 (define_insn_and_split "ix86_rotldi3"
12566 [(set (match_operand:DI 0 "register_operand" "=r")
12567 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12568 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12569 (clobber (reg:CC FLAGS_REG))
12570 (clobber (match_scratch:SI 3 "=&r"))]
12571 "!TARGET_64BIT"
12572 ""
12573 "&& reload_completed"
12574 [(set (match_dup 3) (match_dup 4))
12575 (parallel
12576 [(set (match_dup 4)
12577 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12578 (lshiftrt:SI (match_dup 5)
12579 (minus:QI (const_int 32) (match_dup 2)))))
12580 (clobber (reg:CC FLAGS_REG))])
12581 (parallel
12582 [(set (match_dup 5)
12583 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12584 (lshiftrt:SI (match_dup 3)
12585 (minus:QI (const_int 32) (match_dup 2)))))
12586 (clobber (reg:CC FLAGS_REG))])]
12587 "split_di (operands, 1, operands + 4, operands + 5);")
12588
12589 (define_insn "*rotlsi3_1_one_bit_rex64"
12590 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12591 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12592 (match_operand:QI 2 "const1_operand" "")))
12593 (clobber (reg:CC FLAGS_REG))]
12594 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12595 && (TARGET_SHIFT1 || optimize_size)"
12596 "rol{q}\t%0"
12597 [(set_attr "type" "rotate")
12598 (set (attr "length")
12599 (if_then_else (match_operand:DI 0 "register_operand" "")
12600 (const_string "2")
12601 (const_string "*")))])
12602
12603 (define_insn "*rotldi3_1_rex64"
12604 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12605 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12606 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12607 (clobber (reg:CC FLAGS_REG))]
12608 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12609 "@
12610 rol{q}\t{%2, %0|%0, %2}
12611 rol{q}\t{%b2, %0|%0, %b2}"
12612 [(set_attr "type" "rotate")
12613 (set_attr "mode" "DI")])
12614
12615 (define_expand "rotlsi3"
12616 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12617 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12618 (match_operand:QI 2 "nonmemory_operand" "")))
12619 (clobber (reg:CC FLAGS_REG))]
12620 ""
12621 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12622
12623 (define_insn "*rotlsi3_1_one_bit"
12624 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12625 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12626 (match_operand:QI 2 "const1_operand" "")))
12627 (clobber (reg:CC FLAGS_REG))]
12628 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12629 && (TARGET_SHIFT1 || optimize_size)"
12630 "rol{l}\t%0"
12631 [(set_attr "type" "rotate")
12632 (set (attr "length")
12633 (if_then_else (match_operand:SI 0 "register_operand" "")
12634 (const_string "2")
12635 (const_string "*")))])
12636
12637 (define_insn "*rotlsi3_1_one_bit_zext"
12638 [(set (match_operand:DI 0 "register_operand" "=r")
12639 (zero_extend:DI
12640 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12641 (match_operand:QI 2 "const1_operand" ""))))
12642 (clobber (reg:CC FLAGS_REG))]
12643 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12644 && (TARGET_SHIFT1 || optimize_size)"
12645 "rol{l}\t%k0"
12646 [(set_attr "type" "rotate")
12647 (set_attr "length" "2")])
12648
12649 (define_insn "*rotlsi3_1"
12650 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12651 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12652 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12653 (clobber (reg:CC FLAGS_REG))]
12654 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12655 "@
12656 rol{l}\t{%2, %0|%0, %2}
12657 rol{l}\t{%b2, %0|%0, %b2}"
12658 [(set_attr "type" "rotate")
12659 (set_attr "mode" "SI")])
12660
12661 (define_insn "*rotlsi3_1_zext"
12662 [(set (match_operand:DI 0 "register_operand" "=r,r")
12663 (zero_extend:DI
12664 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12665 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12666 (clobber (reg:CC FLAGS_REG))]
12667 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12668 "@
12669 rol{l}\t{%2, %k0|%k0, %2}
12670 rol{l}\t{%b2, %k0|%k0, %b2}"
12671 [(set_attr "type" "rotate")
12672 (set_attr "mode" "SI")])
12673
12674 (define_expand "rotlhi3"
12675 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12676 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12677 (match_operand:QI 2 "nonmemory_operand" "")))
12678 (clobber (reg:CC FLAGS_REG))]
12679 "TARGET_HIMODE_MATH"
12680 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12681
12682 (define_insn "*rotlhi3_1_one_bit"
12683 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12684 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12685 (match_operand:QI 2 "const1_operand" "")))
12686 (clobber (reg:CC FLAGS_REG))]
12687 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12688 && (TARGET_SHIFT1 || optimize_size)"
12689 "rol{w}\t%0"
12690 [(set_attr "type" "rotate")
12691 (set (attr "length")
12692 (if_then_else (match_operand 0 "register_operand" "")
12693 (const_string "2")
12694 (const_string "*")))])
12695
12696 (define_insn "*rotlhi3_1"
12697 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12698 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12699 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12700 (clobber (reg:CC FLAGS_REG))]
12701 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12702 "@
12703 rol{w}\t{%2, %0|%0, %2}
12704 rol{w}\t{%b2, %0|%0, %b2}"
12705 [(set_attr "type" "rotate")
12706 (set_attr "mode" "HI")])
12707
12708 (define_expand "rotlqi3"
12709 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12710 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12711 (match_operand:QI 2 "nonmemory_operand" "")))
12712 (clobber (reg:CC FLAGS_REG))]
12713 "TARGET_QIMODE_MATH"
12714 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12715
12716 (define_insn "*rotlqi3_1_one_bit_slp"
12717 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12718 (rotate:QI (match_dup 0)
12719 (match_operand:QI 1 "const1_operand" "")))
12720 (clobber (reg:CC FLAGS_REG))]
12721 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12722 && (TARGET_SHIFT1 || optimize_size)"
12723 "rol{b}\t%0"
12724 [(set_attr "type" "rotate1")
12725 (set (attr "length")
12726 (if_then_else (match_operand 0 "register_operand" "")
12727 (const_string "2")
12728 (const_string "*")))])
12729
12730 (define_insn "*rotlqi3_1_one_bit"
12731 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12732 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12733 (match_operand:QI 2 "const1_operand" "")))
12734 (clobber (reg:CC FLAGS_REG))]
12735 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12736 && (TARGET_SHIFT1 || optimize_size)"
12737 "rol{b}\t%0"
12738 [(set_attr "type" "rotate")
12739 (set (attr "length")
12740 (if_then_else (match_operand 0 "register_operand" "")
12741 (const_string "2")
12742 (const_string "*")))])
12743
12744 (define_insn "*rotlqi3_1_slp"
12745 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12746 (rotate:QI (match_dup 0)
12747 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12748 (clobber (reg:CC FLAGS_REG))]
12749 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12750 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12751 "@
12752 rol{b}\t{%1, %0|%0, %1}
12753 rol{b}\t{%b1, %0|%0, %b1}"
12754 [(set_attr "type" "rotate1")
12755 (set_attr "mode" "QI")])
12756
12757 (define_insn "*rotlqi3_1"
12758 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12759 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12760 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12761 (clobber (reg:CC FLAGS_REG))]
12762 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12763 "@
12764 rol{b}\t{%2, %0|%0, %2}
12765 rol{b}\t{%b2, %0|%0, %b2}"
12766 [(set_attr "type" "rotate")
12767 (set_attr "mode" "QI")])
12768
12769 (define_expand "rotrdi3"
12770 [(set (match_operand:DI 0 "shiftdi_operand" "")
12771 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12772 (match_operand:QI 2 "nonmemory_operand" "")))
12773 (clobber (reg:CC FLAGS_REG))]
12774 ""
12775 {
12776 if (TARGET_64BIT)
12777 {
12778 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12779 DONE;
12780 }
12781 if (!const_1_to_31_operand (operands[2], VOIDmode))
12782 FAIL;
12783 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12784 DONE;
12785 })
12786
12787 ;; Implement rotation using two double-precision shift instructions
12788 ;; and a scratch register.
12789 (define_insn_and_split "ix86_rotrdi3"
12790 [(set (match_operand:DI 0 "register_operand" "=r")
12791 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12792 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12793 (clobber (reg:CC FLAGS_REG))
12794 (clobber (match_scratch:SI 3 "=&r"))]
12795 "!TARGET_64BIT"
12796 ""
12797 "&& reload_completed"
12798 [(set (match_dup 3) (match_dup 4))
12799 (parallel
12800 [(set (match_dup 4)
12801 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12802 (ashift:SI (match_dup 5)
12803 (minus:QI (const_int 32) (match_dup 2)))))
12804 (clobber (reg:CC FLAGS_REG))])
12805 (parallel
12806 [(set (match_dup 5)
12807 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12808 (ashift:SI (match_dup 3)
12809 (minus:QI (const_int 32) (match_dup 2)))))
12810 (clobber (reg:CC FLAGS_REG))])]
12811 "split_di (operands, 1, operands + 4, operands + 5);")
12812
12813 (define_insn "*rotrdi3_1_one_bit_rex64"
12814 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12815 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12816 (match_operand:QI 2 "const1_operand" "")))
12817 (clobber (reg:CC FLAGS_REG))]
12818 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12819 && (TARGET_SHIFT1 || optimize_size)"
12820 "ror{q}\t%0"
12821 [(set_attr "type" "rotate")
12822 (set (attr "length")
12823 (if_then_else (match_operand:DI 0 "register_operand" "")
12824 (const_string "2")
12825 (const_string "*")))])
12826
12827 (define_insn "*rotrdi3_1_rex64"
12828 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12829 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12830 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12831 (clobber (reg:CC FLAGS_REG))]
12832 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12833 "@
12834 ror{q}\t{%2, %0|%0, %2}
12835 ror{q}\t{%b2, %0|%0, %b2}"
12836 [(set_attr "type" "rotate")
12837 (set_attr "mode" "DI")])
12838
12839 (define_expand "rotrsi3"
12840 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12841 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12842 (match_operand:QI 2 "nonmemory_operand" "")))
12843 (clobber (reg:CC FLAGS_REG))]
12844 ""
12845 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12846
12847 (define_insn "*rotrsi3_1_one_bit"
12848 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12849 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12850 (match_operand:QI 2 "const1_operand" "")))
12851 (clobber (reg:CC FLAGS_REG))]
12852 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12853 && (TARGET_SHIFT1 || optimize_size)"
12854 "ror{l}\t%0"
12855 [(set_attr "type" "rotate")
12856 (set (attr "length")
12857 (if_then_else (match_operand:SI 0 "register_operand" "")
12858 (const_string "2")
12859 (const_string "*")))])
12860
12861 (define_insn "*rotrsi3_1_one_bit_zext"
12862 [(set (match_operand:DI 0 "register_operand" "=r")
12863 (zero_extend:DI
12864 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12865 (match_operand:QI 2 "const1_operand" ""))))
12866 (clobber (reg:CC FLAGS_REG))]
12867 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12868 && (TARGET_SHIFT1 || optimize_size)"
12869 "ror{l}\t%k0"
12870 [(set_attr "type" "rotate")
12871 (set (attr "length")
12872 (if_then_else (match_operand:SI 0 "register_operand" "")
12873 (const_string "2")
12874 (const_string "*")))])
12875
12876 (define_insn "*rotrsi3_1"
12877 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12878 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12879 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12880 (clobber (reg:CC FLAGS_REG))]
12881 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12882 "@
12883 ror{l}\t{%2, %0|%0, %2}
12884 ror{l}\t{%b2, %0|%0, %b2}"
12885 [(set_attr "type" "rotate")
12886 (set_attr "mode" "SI")])
12887
12888 (define_insn "*rotrsi3_1_zext"
12889 [(set (match_operand:DI 0 "register_operand" "=r,r")
12890 (zero_extend:DI
12891 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12892 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12893 (clobber (reg:CC FLAGS_REG))]
12894 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12895 "@
12896 ror{l}\t{%2, %k0|%k0, %2}
12897 ror{l}\t{%b2, %k0|%k0, %b2}"
12898 [(set_attr "type" "rotate")
12899 (set_attr "mode" "SI")])
12900
12901 (define_expand "rotrhi3"
12902 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12903 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12904 (match_operand:QI 2 "nonmemory_operand" "")))
12905 (clobber (reg:CC FLAGS_REG))]
12906 "TARGET_HIMODE_MATH"
12907 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12908
12909 (define_insn "*rotrhi3_one_bit"
12910 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12911 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12912 (match_operand:QI 2 "const1_operand" "")))
12913 (clobber (reg:CC FLAGS_REG))]
12914 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12915 && (TARGET_SHIFT1 || optimize_size)"
12916 "ror{w}\t%0"
12917 [(set_attr "type" "rotate")
12918 (set (attr "length")
12919 (if_then_else (match_operand 0 "register_operand" "")
12920 (const_string "2")
12921 (const_string "*")))])
12922
12923 (define_insn "*rotrhi3"
12924 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12925 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12926 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12927 (clobber (reg:CC FLAGS_REG))]
12928 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12929 "@
12930 ror{w}\t{%2, %0|%0, %2}
12931 ror{w}\t{%b2, %0|%0, %b2}"
12932 [(set_attr "type" "rotate")
12933 (set_attr "mode" "HI")])
12934
12935 (define_expand "rotrqi3"
12936 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12937 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12938 (match_operand:QI 2 "nonmemory_operand" "")))
12939 (clobber (reg:CC FLAGS_REG))]
12940 "TARGET_QIMODE_MATH"
12941 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12942
12943 (define_insn "*rotrqi3_1_one_bit"
12944 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12945 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12946 (match_operand:QI 2 "const1_operand" "")))
12947 (clobber (reg:CC FLAGS_REG))]
12948 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12949 && (TARGET_SHIFT1 || optimize_size)"
12950 "ror{b}\t%0"
12951 [(set_attr "type" "rotate")
12952 (set (attr "length")
12953 (if_then_else (match_operand 0 "register_operand" "")
12954 (const_string "2")
12955 (const_string "*")))])
12956
12957 (define_insn "*rotrqi3_1_one_bit_slp"
12958 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12959 (rotatert:QI (match_dup 0)
12960 (match_operand:QI 1 "const1_operand" "")))
12961 (clobber (reg:CC FLAGS_REG))]
12962 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12963 && (TARGET_SHIFT1 || optimize_size)"
12964 "ror{b}\t%0"
12965 [(set_attr "type" "rotate1")
12966 (set (attr "length")
12967 (if_then_else (match_operand 0 "register_operand" "")
12968 (const_string "2")
12969 (const_string "*")))])
12970
12971 (define_insn "*rotrqi3_1"
12972 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12973 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12974 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12975 (clobber (reg:CC FLAGS_REG))]
12976 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12977 "@
12978 ror{b}\t{%2, %0|%0, %2}
12979 ror{b}\t{%b2, %0|%0, %b2}"
12980 [(set_attr "type" "rotate")
12981 (set_attr "mode" "QI")])
12982
12983 (define_insn "*rotrqi3_1_slp"
12984 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12985 (rotatert:QI (match_dup 0)
12986 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12987 (clobber (reg:CC FLAGS_REG))]
12988 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12989 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12990 "@
12991 ror{b}\t{%1, %0|%0, %1}
12992 ror{b}\t{%b1, %0|%0, %b1}"
12993 [(set_attr "type" "rotate1")
12994 (set_attr "mode" "QI")])
12995 \f
12996 ;; Bit set / bit test instructions
12997
12998 (define_expand "extv"
12999 [(set (match_operand:SI 0 "register_operand" "")
13000 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13001 (match_operand:SI 2 "const8_operand" "")
13002 (match_operand:SI 3 "const8_operand" "")))]
13003 ""
13004 {
13005 /* Handle extractions from %ah et al. */
13006 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13007 FAIL;
13008
13009 /* From mips.md: extract_bit_field doesn't verify that our source
13010 matches the predicate, so check it again here. */
13011 if (! ext_register_operand (operands[1], VOIDmode))
13012 FAIL;
13013 })
13014
13015 (define_expand "extzv"
13016 [(set (match_operand:SI 0 "register_operand" "")
13017 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13018 (match_operand:SI 2 "const8_operand" "")
13019 (match_operand:SI 3 "const8_operand" "")))]
13020 ""
13021 {
13022 /* Handle extractions from %ah et al. */
13023 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13024 FAIL;
13025
13026 /* From mips.md: extract_bit_field doesn't verify that our source
13027 matches the predicate, so check it again here. */
13028 if (! ext_register_operand (operands[1], VOIDmode))
13029 FAIL;
13030 })
13031
13032 (define_expand "insv"
13033 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13034 (match_operand 1 "const8_operand" "")
13035 (match_operand 2 "const8_operand" ""))
13036 (match_operand 3 "register_operand" ""))]
13037 ""
13038 {
13039 /* Handle insertions to %ah et al. */
13040 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13041 FAIL;
13042
13043 /* From mips.md: insert_bit_field doesn't verify that our source
13044 matches the predicate, so check it again here. */
13045 if (! ext_register_operand (operands[0], VOIDmode))
13046 FAIL;
13047
13048 if (TARGET_64BIT)
13049 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13050 else
13051 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13052
13053 DONE;
13054 })
13055
13056 ;; %%% bts, btr, btc, bt.
13057 ;; In general these instructions are *slow* when applied to memory,
13058 ;; since they enforce atomic operation. When applied to registers,
13059 ;; it depends on the cpu implementation. They're never faster than
13060 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13061 ;; no point. But in 64-bit, we can't hold the relevant immediates
13062 ;; within the instruction itself, so operating on bits in the high
13063 ;; 32-bits of a register becomes easier.
13064 ;;
13065 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13066 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13067 ;; negdf respectively, so they can never be disabled entirely.
13068
13069 (define_insn "*btsq"
13070 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13071 (const_int 1)
13072 (match_operand:DI 1 "const_0_to_63_operand" ""))
13073 (const_int 1))
13074 (clobber (reg:CC FLAGS_REG))]
13075 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13076 "bts{q} %1,%0"
13077 [(set_attr "type" "alu1")])
13078
13079 (define_insn "*btrq"
13080 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13081 (const_int 1)
13082 (match_operand:DI 1 "const_0_to_63_operand" ""))
13083 (const_int 0))
13084 (clobber (reg:CC FLAGS_REG))]
13085 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13086 "btr{q} %1,%0"
13087 [(set_attr "type" "alu1")])
13088
13089 (define_insn "*btcq"
13090 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13091 (const_int 1)
13092 (match_operand:DI 1 "const_0_to_63_operand" ""))
13093 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13094 (clobber (reg:CC FLAGS_REG))]
13095 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13096 "btc{q} %1,%0"
13097 [(set_attr "type" "alu1")])
13098
13099 ;; Allow Nocona to avoid these instructions if a register is available.
13100
13101 (define_peephole2
13102 [(match_scratch:DI 2 "r")
13103 (parallel [(set (zero_extract:DI
13104 (match_operand:DI 0 "register_operand" "")
13105 (const_int 1)
13106 (match_operand:DI 1 "const_0_to_63_operand" ""))
13107 (const_int 1))
13108 (clobber (reg:CC FLAGS_REG))])]
13109 "TARGET_64BIT && !TARGET_USE_BT"
13110 [(const_int 0)]
13111 {
13112 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13113 rtx op1;
13114
13115 if (HOST_BITS_PER_WIDE_INT >= 64)
13116 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13117 else if (i < HOST_BITS_PER_WIDE_INT)
13118 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13119 else
13120 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13121
13122 op1 = immed_double_const (lo, hi, DImode);
13123 if (i >= 31)
13124 {
13125 emit_move_insn (operands[2], op1);
13126 op1 = operands[2];
13127 }
13128
13129 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13130 DONE;
13131 })
13132
13133 (define_peephole2
13134 [(match_scratch:DI 2 "r")
13135 (parallel [(set (zero_extract:DI
13136 (match_operand:DI 0 "register_operand" "")
13137 (const_int 1)
13138 (match_operand:DI 1 "const_0_to_63_operand" ""))
13139 (const_int 0))
13140 (clobber (reg:CC FLAGS_REG))])]
13141 "TARGET_64BIT && !TARGET_USE_BT"
13142 [(const_int 0)]
13143 {
13144 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13145 rtx op1;
13146
13147 if (HOST_BITS_PER_WIDE_INT >= 64)
13148 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13149 else if (i < HOST_BITS_PER_WIDE_INT)
13150 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13151 else
13152 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13153
13154 op1 = immed_double_const (~lo, ~hi, DImode);
13155 if (i >= 32)
13156 {
13157 emit_move_insn (operands[2], op1);
13158 op1 = operands[2];
13159 }
13160
13161 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13162 DONE;
13163 })
13164
13165 (define_peephole2
13166 [(match_scratch:DI 2 "r")
13167 (parallel [(set (zero_extract:DI
13168 (match_operand:DI 0 "register_operand" "")
13169 (const_int 1)
13170 (match_operand:DI 1 "const_0_to_63_operand" ""))
13171 (not:DI (zero_extract:DI
13172 (match_dup 0) (const_int 1) (match_dup 1))))
13173 (clobber (reg:CC FLAGS_REG))])]
13174 "TARGET_64BIT && !TARGET_USE_BT"
13175 [(const_int 0)]
13176 {
13177 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13178 rtx op1;
13179
13180 if (HOST_BITS_PER_WIDE_INT >= 64)
13181 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13182 else if (i < HOST_BITS_PER_WIDE_INT)
13183 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13184 else
13185 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13186
13187 op1 = immed_double_const (lo, hi, DImode);
13188 if (i >= 31)
13189 {
13190 emit_move_insn (operands[2], op1);
13191 op1 = operands[2];
13192 }
13193
13194 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13195 DONE;
13196 })
13197 \f
13198 ;; Store-flag instructions.
13199
13200 ;; For all sCOND expanders, also expand the compare or test insn that
13201 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13202
13203 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13204 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13205 ;; way, which can later delete the movzx if only QImode is needed.
13206
13207 (define_expand "seq"
13208 [(set (match_operand:QI 0 "register_operand" "")
13209 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13210 ""
13211 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13212
13213 (define_expand "sne"
13214 [(set (match_operand:QI 0 "register_operand" "")
13215 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13216 ""
13217 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13218
13219 (define_expand "sgt"
13220 [(set (match_operand:QI 0 "register_operand" "")
13221 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13222 ""
13223 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13224
13225 (define_expand "sgtu"
13226 [(set (match_operand:QI 0 "register_operand" "")
13227 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13228 ""
13229 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13230
13231 (define_expand "slt"
13232 [(set (match_operand:QI 0 "register_operand" "")
13233 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13234 ""
13235 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13236
13237 (define_expand "sltu"
13238 [(set (match_operand:QI 0 "register_operand" "")
13239 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13240 ""
13241 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13242
13243 (define_expand "sge"
13244 [(set (match_operand:QI 0 "register_operand" "")
13245 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13246 ""
13247 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13248
13249 (define_expand "sgeu"
13250 [(set (match_operand:QI 0 "register_operand" "")
13251 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252 ""
13253 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13254
13255 (define_expand "sle"
13256 [(set (match_operand:QI 0 "register_operand" "")
13257 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258 ""
13259 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13260
13261 (define_expand "sleu"
13262 [(set (match_operand:QI 0 "register_operand" "")
13263 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264 ""
13265 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13266
13267 (define_expand "sunordered"
13268 [(set (match_operand:QI 0 "register_operand" "")
13269 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13270 "TARGET_80387 || TARGET_SSE"
13271 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13272
13273 (define_expand "sordered"
13274 [(set (match_operand:QI 0 "register_operand" "")
13275 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13276 "TARGET_80387"
13277 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13278
13279 (define_expand "suneq"
13280 [(set (match_operand:QI 0 "register_operand" "")
13281 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13282 "TARGET_80387 || TARGET_SSE"
13283 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13284
13285 (define_expand "sunge"
13286 [(set (match_operand:QI 0 "register_operand" "")
13287 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13288 "TARGET_80387 || TARGET_SSE"
13289 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13290
13291 (define_expand "sungt"
13292 [(set (match_operand:QI 0 "register_operand" "")
13293 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294 "TARGET_80387 || TARGET_SSE"
13295 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13296
13297 (define_expand "sunle"
13298 [(set (match_operand:QI 0 "register_operand" "")
13299 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13300 "TARGET_80387 || TARGET_SSE"
13301 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13302
13303 (define_expand "sunlt"
13304 [(set (match_operand:QI 0 "register_operand" "")
13305 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13306 "TARGET_80387 || TARGET_SSE"
13307 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13308
13309 (define_expand "sltgt"
13310 [(set (match_operand:QI 0 "register_operand" "")
13311 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13312 "TARGET_80387 || TARGET_SSE"
13313 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13314
13315 (define_insn "*setcc_1"
13316 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13317 (match_operator:QI 1 "ix86_comparison_operator"
13318 [(reg FLAGS_REG) (const_int 0)]))]
13319 ""
13320 "set%C1\t%0"
13321 [(set_attr "type" "setcc")
13322 (set_attr "mode" "QI")])
13323
13324 (define_insn "*setcc_2"
13325 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13326 (match_operator:QI 1 "ix86_comparison_operator"
13327 [(reg FLAGS_REG) (const_int 0)]))]
13328 ""
13329 "set%C1\t%0"
13330 [(set_attr "type" "setcc")
13331 (set_attr "mode" "QI")])
13332
13333 ;; In general it is not safe to assume too much about CCmode registers,
13334 ;; so simplify-rtx stops when it sees a second one. Under certain
13335 ;; conditions this is safe on x86, so help combine not create
13336 ;;
13337 ;; seta %al
13338 ;; testb %al, %al
13339 ;; sete %al
13340
13341 (define_split
13342 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13343 (ne:QI (match_operator 1 "ix86_comparison_operator"
13344 [(reg FLAGS_REG) (const_int 0)])
13345 (const_int 0)))]
13346 ""
13347 [(set (match_dup 0) (match_dup 1))]
13348 {
13349 PUT_MODE (operands[1], QImode);
13350 })
13351
13352 (define_split
13353 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13354 (ne:QI (match_operator 1 "ix86_comparison_operator"
13355 [(reg FLAGS_REG) (const_int 0)])
13356 (const_int 0)))]
13357 ""
13358 [(set (match_dup 0) (match_dup 1))]
13359 {
13360 PUT_MODE (operands[1], QImode);
13361 })
13362
13363 (define_split
13364 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13365 (eq:QI (match_operator 1 "ix86_comparison_operator"
13366 [(reg FLAGS_REG) (const_int 0)])
13367 (const_int 0)))]
13368 ""
13369 [(set (match_dup 0) (match_dup 1))]
13370 {
13371 rtx new_op1 = copy_rtx (operands[1]);
13372 operands[1] = new_op1;
13373 PUT_MODE (new_op1, QImode);
13374 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13375 GET_MODE (XEXP (new_op1, 0))));
13376
13377 /* Make sure that (a) the CCmode we have for the flags is strong
13378 enough for the reversed compare or (b) we have a valid FP compare. */
13379 if (! ix86_comparison_operator (new_op1, VOIDmode))
13380 FAIL;
13381 })
13382
13383 (define_split
13384 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13385 (eq:QI (match_operator 1 "ix86_comparison_operator"
13386 [(reg FLAGS_REG) (const_int 0)])
13387 (const_int 0)))]
13388 ""
13389 [(set (match_dup 0) (match_dup 1))]
13390 {
13391 rtx new_op1 = copy_rtx (operands[1]);
13392 operands[1] = new_op1;
13393 PUT_MODE (new_op1, QImode);
13394 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13395 GET_MODE (XEXP (new_op1, 0))));
13396
13397 /* Make sure that (a) the CCmode we have for the flags is strong
13398 enough for the reversed compare or (b) we have a valid FP compare. */
13399 if (! ix86_comparison_operator (new_op1, VOIDmode))
13400 FAIL;
13401 })
13402
13403 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13404 ;; subsequent logical operations are used to imitate conditional moves.
13405 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13406 ;; it directly.
13407
13408 (define_insn "*sse_setccsf"
13409 [(set (match_operand:SF 0 "register_operand" "=x")
13410 (match_operator:SF 1 "sse_comparison_operator"
13411 [(match_operand:SF 2 "register_operand" "0")
13412 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13413 "TARGET_SSE"
13414 "cmp%D1ss\t{%3, %0|%0, %3}"
13415 [(set_attr "type" "ssecmp")
13416 (set_attr "mode" "SF")])
13417
13418 (define_insn "*sse_setccdf"
13419 [(set (match_operand:DF 0 "register_operand" "=Y")
13420 (match_operator:DF 1 "sse_comparison_operator"
13421 [(match_operand:DF 2 "register_operand" "0")
13422 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13423 "TARGET_SSE2"
13424 "cmp%D1sd\t{%3, %0|%0, %3}"
13425 [(set_attr "type" "ssecmp")
13426 (set_attr "mode" "DF")])
13427 \f
13428 ;; Basic conditional jump instructions.
13429 ;; We ignore the overflow flag for signed branch instructions.
13430
13431 ;; For all bCOND expanders, also expand the compare or test insn that
13432 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13433
13434 (define_expand "beq"
13435 [(set (pc)
13436 (if_then_else (match_dup 1)
13437 (label_ref (match_operand 0 "" ""))
13438 (pc)))]
13439 ""
13440 "ix86_expand_branch (EQ, operands[0]); DONE;")
13441
13442 (define_expand "bne"
13443 [(set (pc)
13444 (if_then_else (match_dup 1)
13445 (label_ref (match_operand 0 "" ""))
13446 (pc)))]
13447 ""
13448 "ix86_expand_branch (NE, operands[0]); DONE;")
13449
13450 (define_expand "bgt"
13451 [(set (pc)
13452 (if_then_else (match_dup 1)
13453 (label_ref (match_operand 0 "" ""))
13454 (pc)))]
13455 ""
13456 "ix86_expand_branch (GT, operands[0]); DONE;")
13457
13458 (define_expand "bgtu"
13459 [(set (pc)
13460 (if_then_else (match_dup 1)
13461 (label_ref (match_operand 0 "" ""))
13462 (pc)))]
13463 ""
13464 "ix86_expand_branch (GTU, operands[0]); DONE;")
13465
13466 (define_expand "blt"
13467 [(set (pc)
13468 (if_then_else (match_dup 1)
13469 (label_ref (match_operand 0 "" ""))
13470 (pc)))]
13471 ""
13472 "ix86_expand_branch (LT, operands[0]); DONE;")
13473
13474 (define_expand "bltu"
13475 [(set (pc)
13476 (if_then_else (match_dup 1)
13477 (label_ref (match_operand 0 "" ""))
13478 (pc)))]
13479 ""
13480 "ix86_expand_branch (LTU, operands[0]); DONE;")
13481
13482 (define_expand "bge"
13483 [(set (pc)
13484 (if_then_else (match_dup 1)
13485 (label_ref (match_operand 0 "" ""))
13486 (pc)))]
13487 ""
13488 "ix86_expand_branch (GE, operands[0]); DONE;")
13489
13490 (define_expand "bgeu"
13491 [(set (pc)
13492 (if_then_else (match_dup 1)
13493 (label_ref (match_operand 0 "" ""))
13494 (pc)))]
13495 ""
13496 "ix86_expand_branch (GEU, operands[0]); DONE;")
13497
13498 (define_expand "ble"
13499 [(set (pc)
13500 (if_then_else (match_dup 1)
13501 (label_ref (match_operand 0 "" ""))
13502 (pc)))]
13503 ""
13504 "ix86_expand_branch (LE, operands[0]); DONE;")
13505
13506 (define_expand "bleu"
13507 [(set (pc)
13508 (if_then_else (match_dup 1)
13509 (label_ref (match_operand 0 "" ""))
13510 (pc)))]
13511 ""
13512 "ix86_expand_branch (LEU, operands[0]); DONE;")
13513
13514 (define_expand "bunordered"
13515 [(set (pc)
13516 (if_then_else (match_dup 1)
13517 (label_ref (match_operand 0 "" ""))
13518 (pc)))]
13519 "TARGET_80387 || TARGET_SSE_MATH"
13520 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13521
13522 (define_expand "bordered"
13523 [(set (pc)
13524 (if_then_else (match_dup 1)
13525 (label_ref (match_operand 0 "" ""))
13526 (pc)))]
13527 "TARGET_80387 || TARGET_SSE_MATH"
13528 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13529
13530 (define_expand "buneq"
13531 [(set (pc)
13532 (if_then_else (match_dup 1)
13533 (label_ref (match_operand 0 "" ""))
13534 (pc)))]
13535 "TARGET_80387 || TARGET_SSE_MATH"
13536 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13537
13538 (define_expand "bunge"
13539 [(set (pc)
13540 (if_then_else (match_dup 1)
13541 (label_ref (match_operand 0 "" ""))
13542 (pc)))]
13543 "TARGET_80387 || TARGET_SSE_MATH"
13544 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13545
13546 (define_expand "bungt"
13547 [(set (pc)
13548 (if_then_else (match_dup 1)
13549 (label_ref (match_operand 0 "" ""))
13550 (pc)))]
13551 "TARGET_80387 || TARGET_SSE_MATH"
13552 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13553
13554 (define_expand "bunle"
13555 [(set (pc)
13556 (if_then_else (match_dup 1)
13557 (label_ref (match_operand 0 "" ""))
13558 (pc)))]
13559 "TARGET_80387 || TARGET_SSE_MATH"
13560 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13561
13562 (define_expand "bunlt"
13563 [(set (pc)
13564 (if_then_else (match_dup 1)
13565 (label_ref (match_operand 0 "" ""))
13566 (pc)))]
13567 "TARGET_80387 || TARGET_SSE_MATH"
13568 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13569
13570 (define_expand "bltgt"
13571 [(set (pc)
13572 (if_then_else (match_dup 1)
13573 (label_ref (match_operand 0 "" ""))
13574 (pc)))]
13575 "TARGET_80387 || TARGET_SSE_MATH"
13576 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13577
13578 (define_insn "*jcc_1"
13579 [(set (pc)
13580 (if_then_else (match_operator 1 "ix86_comparison_operator"
13581 [(reg FLAGS_REG) (const_int 0)])
13582 (label_ref (match_operand 0 "" ""))
13583 (pc)))]
13584 ""
13585 "%+j%C1\t%l0"
13586 [(set_attr "type" "ibr")
13587 (set_attr "modrm" "0")
13588 (set (attr "length")
13589 (if_then_else (and (ge (minus (match_dup 0) (pc))
13590 (const_int -126))
13591 (lt (minus (match_dup 0) (pc))
13592 (const_int 128)))
13593 (const_int 2)
13594 (const_int 6)))])
13595
13596 (define_insn "*jcc_2"
13597 [(set (pc)
13598 (if_then_else (match_operator 1 "ix86_comparison_operator"
13599 [(reg FLAGS_REG) (const_int 0)])
13600 (pc)
13601 (label_ref (match_operand 0 "" ""))))]
13602 ""
13603 "%+j%c1\t%l0"
13604 [(set_attr "type" "ibr")
13605 (set_attr "modrm" "0")
13606 (set (attr "length")
13607 (if_then_else (and (ge (minus (match_dup 0) (pc))
13608 (const_int -126))
13609 (lt (minus (match_dup 0) (pc))
13610 (const_int 128)))
13611 (const_int 2)
13612 (const_int 6)))])
13613
13614 ;; In general it is not safe to assume too much about CCmode registers,
13615 ;; so simplify-rtx stops when it sees a second one. Under certain
13616 ;; conditions this is safe on x86, so help combine not create
13617 ;;
13618 ;; seta %al
13619 ;; testb %al, %al
13620 ;; je Lfoo
13621
13622 (define_split
13623 [(set (pc)
13624 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13625 [(reg FLAGS_REG) (const_int 0)])
13626 (const_int 0))
13627 (label_ref (match_operand 1 "" ""))
13628 (pc)))]
13629 ""
13630 [(set (pc)
13631 (if_then_else (match_dup 0)
13632 (label_ref (match_dup 1))
13633 (pc)))]
13634 {
13635 PUT_MODE (operands[0], VOIDmode);
13636 })
13637
13638 (define_split
13639 [(set (pc)
13640 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13641 [(reg FLAGS_REG) (const_int 0)])
13642 (const_int 0))
13643 (label_ref (match_operand 1 "" ""))
13644 (pc)))]
13645 ""
13646 [(set (pc)
13647 (if_then_else (match_dup 0)
13648 (label_ref (match_dup 1))
13649 (pc)))]
13650 {
13651 rtx new_op0 = copy_rtx (operands[0]);
13652 operands[0] = new_op0;
13653 PUT_MODE (new_op0, VOIDmode);
13654 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13655 GET_MODE (XEXP (new_op0, 0))));
13656
13657 /* Make sure that (a) the CCmode we have for the flags is strong
13658 enough for the reversed compare or (b) we have a valid FP compare. */
13659 if (! ix86_comparison_operator (new_op0, VOIDmode))
13660 FAIL;
13661 })
13662
13663 ;; Define combination compare-and-branch fp compare instructions to use
13664 ;; during early optimization. Splitting the operation apart early makes
13665 ;; for bad code when we want to reverse the operation.
13666
13667 (define_insn "*fp_jcc_1_mixed"
13668 [(set (pc)
13669 (if_then_else (match_operator 0 "comparison_operator"
13670 [(match_operand 1 "register_operand" "f,x")
13671 (match_operand 2 "nonimmediate_operand" "f,xm")])
13672 (label_ref (match_operand 3 "" ""))
13673 (pc)))
13674 (clobber (reg:CCFP FPSR_REG))
13675 (clobber (reg:CCFP FLAGS_REG))]
13676 "TARGET_MIX_SSE_I387
13677 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13678 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13679 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13680 "#")
13681
13682 (define_insn "*fp_jcc_1_sse"
13683 [(set (pc)
13684 (if_then_else (match_operator 0 "comparison_operator"
13685 [(match_operand 1 "register_operand" "x")
13686 (match_operand 2 "nonimmediate_operand" "xm")])
13687 (label_ref (match_operand 3 "" ""))
13688 (pc)))
13689 (clobber (reg:CCFP FPSR_REG))
13690 (clobber (reg:CCFP FLAGS_REG))]
13691 "TARGET_SSE_MATH
13692 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13693 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13694 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13695 "#")
13696
13697 (define_insn "*fp_jcc_1_387"
13698 [(set (pc)
13699 (if_then_else (match_operator 0 "comparison_operator"
13700 [(match_operand 1 "register_operand" "f")
13701 (match_operand 2 "register_operand" "f")])
13702 (label_ref (match_operand 3 "" ""))
13703 (pc)))
13704 (clobber (reg:CCFP FPSR_REG))
13705 (clobber (reg:CCFP FLAGS_REG))]
13706 "TARGET_CMOVE && TARGET_80387
13707 && FLOAT_MODE_P (GET_MODE (operands[1]))
13708 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13709 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13710 "#")
13711
13712 (define_insn "*fp_jcc_2_mixed"
13713 [(set (pc)
13714 (if_then_else (match_operator 0 "comparison_operator"
13715 [(match_operand 1 "register_operand" "f,x")
13716 (match_operand 2 "nonimmediate_operand" "f,xm")])
13717 (pc)
13718 (label_ref (match_operand 3 "" ""))))
13719 (clobber (reg:CCFP FPSR_REG))
13720 (clobber (reg:CCFP FLAGS_REG))]
13721 "TARGET_MIX_SSE_I387
13722 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13723 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13724 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13725 "#")
13726
13727 (define_insn "*fp_jcc_2_sse"
13728 [(set (pc)
13729 (if_then_else (match_operator 0 "comparison_operator"
13730 [(match_operand 1 "register_operand" "x")
13731 (match_operand 2 "nonimmediate_operand" "xm")])
13732 (pc)
13733 (label_ref (match_operand 3 "" ""))))
13734 (clobber (reg:CCFP FPSR_REG))
13735 (clobber (reg:CCFP FLAGS_REG))]
13736 "TARGET_SSE_MATH
13737 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13738 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13739 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13740 "#")
13741
13742 (define_insn "*fp_jcc_2_387"
13743 [(set (pc)
13744 (if_then_else (match_operator 0 "comparison_operator"
13745 [(match_operand 1 "register_operand" "f")
13746 (match_operand 2 "register_operand" "f")])
13747 (pc)
13748 (label_ref (match_operand 3 "" ""))))
13749 (clobber (reg:CCFP FPSR_REG))
13750 (clobber (reg:CCFP FLAGS_REG))]
13751 "TARGET_CMOVE && TARGET_80387
13752 && FLOAT_MODE_P (GET_MODE (operands[1]))
13753 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13754 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13755 "#")
13756
13757 (define_insn "*fp_jcc_3_387"
13758 [(set (pc)
13759 (if_then_else (match_operator 0 "comparison_operator"
13760 [(match_operand 1 "register_operand" "f")
13761 (match_operand 2 "nonimmediate_operand" "fm")])
13762 (label_ref (match_operand 3 "" ""))
13763 (pc)))
13764 (clobber (reg:CCFP FPSR_REG))
13765 (clobber (reg:CCFP FLAGS_REG))
13766 (clobber (match_scratch:HI 4 "=a"))]
13767 "TARGET_80387
13768 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13769 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13770 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13771 && SELECT_CC_MODE (GET_CODE (operands[0]),
13772 operands[1], operands[2]) == CCFPmode
13773 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13774 "#")
13775
13776 (define_insn "*fp_jcc_4_387"
13777 [(set (pc)
13778 (if_then_else (match_operator 0 "comparison_operator"
13779 [(match_operand 1 "register_operand" "f")
13780 (match_operand 2 "nonimmediate_operand" "fm")])
13781 (pc)
13782 (label_ref (match_operand 3 "" ""))))
13783 (clobber (reg:CCFP FPSR_REG))
13784 (clobber (reg:CCFP FLAGS_REG))
13785 (clobber (match_scratch:HI 4 "=a"))]
13786 "TARGET_80387
13787 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13788 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13789 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13790 && SELECT_CC_MODE (GET_CODE (operands[0]),
13791 operands[1], operands[2]) == CCFPmode
13792 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13793 "#")
13794
13795 (define_insn "*fp_jcc_5_387"
13796 [(set (pc)
13797 (if_then_else (match_operator 0 "comparison_operator"
13798 [(match_operand 1 "register_operand" "f")
13799 (match_operand 2 "register_operand" "f")])
13800 (label_ref (match_operand 3 "" ""))
13801 (pc)))
13802 (clobber (reg:CCFP FPSR_REG))
13803 (clobber (reg:CCFP FLAGS_REG))
13804 (clobber (match_scratch:HI 4 "=a"))]
13805 "TARGET_80387
13806 && FLOAT_MODE_P (GET_MODE (operands[1]))
13807 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13808 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13809 "#")
13810
13811 (define_insn "*fp_jcc_6_387"
13812 [(set (pc)
13813 (if_then_else (match_operator 0 "comparison_operator"
13814 [(match_operand 1 "register_operand" "f")
13815 (match_operand 2 "register_operand" "f")])
13816 (pc)
13817 (label_ref (match_operand 3 "" ""))))
13818 (clobber (reg:CCFP FPSR_REG))
13819 (clobber (reg:CCFP FLAGS_REG))
13820 (clobber (match_scratch:HI 4 "=a"))]
13821 "TARGET_80387
13822 && FLOAT_MODE_P (GET_MODE (operands[1]))
13823 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13824 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13825 "#")
13826
13827 (define_insn "*fp_jcc_7_387"
13828 [(set (pc)
13829 (if_then_else (match_operator 0 "comparison_operator"
13830 [(match_operand 1 "register_operand" "f")
13831 (match_operand 2 "const0_operand" "X")])
13832 (label_ref (match_operand 3 "" ""))
13833 (pc)))
13834 (clobber (reg:CCFP FPSR_REG))
13835 (clobber (reg:CCFP FLAGS_REG))
13836 (clobber (match_scratch:HI 4 "=a"))]
13837 "TARGET_80387
13838 && FLOAT_MODE_P (GET_MODE (operands[1]))
13839 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13840 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13841 && SELECT_CC_MODE (GET_CODE (operands[0]),
13842 operands[1], operands[2]) == CCFPmode
13843 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13844 "#")
13845
13846 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13847 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13848 ;; with a precedence over other operators and is always put in the first
13849 ;; place. Swap condition and operands to match ficom instruction.
13850
13851 (define_insn "*fp_jcc_8<mode>_387"
13852 [(set (pc)
13853 (if_then_else (match_operator 0 "comparison_operator"
13854 [(match_operator 1 "float_operator"
13855 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13856 (match_operand 3 "register_operand" "f,f")])
13857 (label_ref (match_operand 4 "" ""))
13858 (pc)))
13859 (clobber (reg:CCFP FPSR_REG))
13860 (clobber (reg:CCFP FLAGS_REG))
13861 (clobber (match_scratch:HI 5 "=a,a"))]
13862 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13863 && FLOAT_MODE_P (GET_MODE (operands[3]))
13864 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13865 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13866 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13867 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13868 "#")
13869
13870 (define_split
13871 [(set (pc)
13872 (if_then_else (match_operator 0 "comparison_operator"
13873 [(match_operand 1 "register_operand" "")
13874 (match_operand 2 "nonimmediate_operand" "")])
13875 (match_operand 3 "" "")
13876 (match_operand 4 "" "")))
13877 (clobber (reg:CCFP FPSR_REG))
13878 (clobber (reg:CCFP FLAGS_REG))]
13879 "reload_completed"
13880 [(const_int 0)]
13881 {
13882 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13883 operands[3], operands[4], NULL_RTX, NULL_RTX);
13884 DONE;
13885 })
13886
13887 (define_split
13888 [(set (pc)
13889 (if_then_else (match_operator 0 "comparison_operator"
13890 [(match_operand 1 "register_operand" "")
13891 (match_operand 2 "general_operand" "")])
13892 (match_operand 3 "" "")
13893 (match_operand 4 "" "")))
13894 (clobber (reg:CCFP FPSR_REG))
13895 (clobber (reg:CCFP FLAGS_REG))
13896 (clobber (match_scratch:HI 5 "=a"))]
13897 "reload_completed"
13898 [(const_int 0)]
13899 {
13900 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13901 operands[3], operands[4], operands[5], NULL_RTX);
13902 DONE;
13903 })
13904
13905 (define_split
13906 [(set (pc)
13907 (if_then_else (match_operator 0 "comparison_operator"
13908 [(match_operator 1 "float_operator"
13909 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13910 (match_operand 3 "register_operand" "")])
13911 (match_operand 4 "" "")
13912 (match_operand 5 "" "")))
13913 (clobber (reg:CCFP FPSR_REG))
13914 (clobber (reg:CCFP FLAGS_REG))
13915 (clobber (match_scratch:HI 6 "=a"))]
13916 "reload_completed"
13917 [(const_int 0)]
13918 {
13919 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13920 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13921 operands[3], operands[7],
13922 operands[4], operands[5], operands[6], NULL_RTX);
13923 DONE;
13924 })
13925
13926 ;; %%% Kill this when reload knows how to do it.
13927 (define_split
13928 [(set (pc)
13929 (if_then_else (match_operator 0 "comparison_operator"
13930 [(match_operator 1 "float_operator"
13931 [(match_operand:X87MODEI12 2 "register_operand" "")])
13932 (match_operand 3 "register_operand" "")])
13933 (match_operand 4 "" "")
13934 (match_operand 5 "" "")))
13935 (clobber (reg:CCFP FPSR_REG))
13936 (clobber (reg:CCFP FLAGS_REG))
13937 (clobber (match_scratch:HI 6 "=a"))]
13938 "reload_completed"
13939 [(const_int 0)]
13940 {
13941 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13942 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13943 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13944 operands[3], operands[7],
13945 operands[4], operands[5], operands[6], operands[2]);
13946 DONE;
13947 })
13948 \f
13949 ;; Unconditional and other jump instructions
13950
13951 (define_insn "jump"
13952 [(set (pc)
13953 (label_ref (match_operand 0 "" "")))]
13954 ""
13955 "jmp\t%l0"
13956 [(set_attr "type" "ibr")
13957 (set (attr "length")
13958 (if_then_else (and (ge (minus (match_dup 0) (pc))
13959 (const_int -126))
13960 (lt (minus (match_dup 0) (pc))
13961 (const_int 128)))
13962 (const_int 2)
13963 (const_int 5)))
13964 (set_attr "modrm" "0")])
13965
13966 (define_expand "indirect_jump"
13967 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13968 ""
13969 "")
13970
13971 (define_insn "*indirect_jump"
13972 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13973 "!TARGET_64BIT"
13974 "jmp\t%A0"
13975 [(set_attr "type" "ibr")
13976 (set_attr "length_immediate" "0")])
13977
13978 (define_insn "*indirect_jump_rtx64"
13979 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13980 "TARGET_64BIT"
13981 "jmp\t%A0"
13982 [(set_attr "type" "ibr")
13983 (set_attr "length_immediate" "0")])
13984
13985 (define_expand "tablejump"
13986 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13987 (use (label_ref (match_operand 1 "" "")))])]
13988 ""
13989 {
13990 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13991 relative. Convert the relative address to an absolute address. */
13992 if (flag_pic)
13993 {
13994 rtx op0, op1;
13995 enum rtx_code code;
13996
13997 if (TARGET_64BIT)
13998 {
13999 code = PLUS;
14000 op0 = operands[0];
14001 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14002 }
14003 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14004 {
14005 code = PLUS;
14006 op0 = operands[0];
14007 op1 = pic_offset_table_rtx;
14008 }
14009 else
14010 {
14011 code = MINUS;
14012 op0 = pic_offset_table_rtx;
14013 op1 = operands[0];
14014 }
14015
14016 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14017 OPTAB_DIRECT);
14018 }
14019 })
14020
14021 (define_insn "*tablejump_1"
14022 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14023 (use (label_ref (match_operand 1 "" "")))]
14024 "!TARGET_64BIT"
14025 "jmp\t%A0"
14026 [(set_attr "type" "ibr")
14027 (set_attr "length_immediate" "0")])
14028
14029 (define_insn "*tablejump_1_rtx64"
14030 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14031 (use (label_ref (match_operand 1 "" "")))]
14032 "TARGET_64BIT"
14033 "jmp\t%A0"
14034 [(set_attr "type" "ibr")
14035 (set_attr "length_immediate" "0")])
14036 \f
14037 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14038
14039 (define_peephole2
14040 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14041 (set (match_operand:QI 1 "register_operand" "")
14042 (match_operator:QI 2 "ix86_comparison_operator"
14043 [(reg FLAGS_REG) (const_int 0)]))
14044 (set (match_operand 3 "q_regs_operand" "")
14045 (zero_extend (match_dup 1)))]
14046 "(peep2_reg_dead_p (3, operands[1])
14047 || operands_match_p (operands[1], operands[3]))
14048 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14049 [(set (match_dup 4) (match_dup 0))
14050 (set (strict_low_part (match_dup 5))
14051 (match_dup 2))]
14052 {
14053 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14054 operands[5] = gen_lowpart (QImode, operands[3]);
14055 ix86_expand_clear (operands[3]);
14056 })
14057
14058 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14059
14060 (define_peephole2
14061 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14062 (set (match_operand:QI 1 "register_operand" "")
14063 (match_operator:QI 2 "ix86_comparison_operator"
14064 [(reg FLAGS_REG) (const_int 0)]))
14065 (parallel [(set (match_operand 3 "q_regs_operand" "")
14066 (zero_extend (match_dup 1)))
14067 (clobber (reg:CC FLAGS_REG))])]
14068 "(peep2_reg_dead_p (3, operands[1])
14069 || operands_match_p (operands[1], operands[3]))
14070 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14071 [(set (match_dup 4) (match_dup 0))
14072 (set (strict_low_part (match_dup 5))
14073 (match_dup 2))]
14074 {
14075 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14076 operands[5] = gen_lowpart (QImode, operands[3]);
14077 ix86_expand_clear (operands[3]);
14078 })
14079 \f
14080 ;; Call instructions.
14081
14082 ;; The predicates normally associated with named expanders are not properly
14083 ;; checked for calls. This is a bug in the generic code, but it isn't that
14084 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14085
14086 ;; Call subroutine returning no value.
14087
14088 (define_expand "call_pop"
14089 [(parallel [(call (match_operand:QI 0 "" "")
14090 (match_operand:SI 1 "" ""))
14091 (set (reg:SI SP_REG)
14092 (plus:SI (reg:SI SP_REG)
14093 (match_operand:SI 3 "" "")))])]
14094 "!TARGET_64BIT"
14095 {
14096 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14097 DONE;
14098 })
14099
14100 (define_insn "*call_pop_0"
14101 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14102 (match_operand:SI 1 "" ""))
14103 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14104 (match_operand:SI 2 "immediate_operand" "")))]
14105 "!TARGET_64BIT"
14106 {
14107 if (SIBLING_CALL_P (insn))
14108 return "jmp\t%P0";
14109 else
14110 return "call\t%P0";
14111 }
14112 [(set_attr "type" "call")])
14113
14114 (define_insn "*call_pop_1"
14115 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14116 (match_operand:SI 1 "" ""))
14117 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14118 (match_operand:SI 2 "immediate_operand" "i")))]
14119 "!TARGET_64BIT"
14120 {
14121 if (constant_call_address_operand (operands[0], Pmode))
14122 {
14123 if (SIBLING_CALL_P (insn))
14124 return "jmp\t%P0";
14125 else
14126 return "call\t%P0";
14127 }
14128 if (SIBLING_CALL_P (insn))
14129 return "jmp\t%A0";
14130 else
14131 return "call\t%A0";
14132 }
14133 [(set_attr "type" "call")])
14134
14135 (define_expand "call"
14136 [(call (match_operand:QI 0 "" "")
14137 (match_operand 1 "" ""))
14138 (use (match_operand 2 "" ""))]
14139 ""
14140 {
14141 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14142 DONE;
14143 })
14144
14145 (define_expand "sibcall"
14146 [(call (match_operand:QI 0 "" "")
14147 (match_operand 1 "" ""))
14148 (use (match_operand 2 "" ""))]
14149 ""
14150 {
14151 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14152 DONE;
14153 })
14154
14155 (define_insn "*call_0"
14156 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14157 (match_operand 1 "" ""))]
14158 ""
14159 {
14160 if (SIBLING_CALL_P (insn))
14161 return "jmp\t%P0";
14162 else
14163 return "call\t%P0";
14164 }
14165 [(set_attr "type" "call")])
14166
14167 (define_insn "*call_1"
14168 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14169 (match_operand 1 "" ""))]
14170 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14171 {
14172 if (constant_call_address_operand (operands[0], Pmode))
14173 return "call\t%P0";
14174 return "call\t%A0";
14175 }
14176 [(set_attr "type" "call")])
14177
14178 (define_insn "*sibcall_1"
14179 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14180 (match_operand 1 "" ""))]
14181 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14182 {
14183 if (constant_call_address_operand (operands[0], Pmode))
14184 return "jmp\t%P0";
14185 return "jmp\t%A0";
14186 }
14187 [(set_attr "type" "call")])
14188
14189 (define_insn "*call_1_rex64"
14190 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14191 (match_operand 1 "" ""))]
14192 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14193 {
14194 if (constant_call_address_operand (operands[0], Pmode))
14195 return "call\t%P0";
14196 return "call\t%A0";
14197 }
14198 [(set_attr "type" "call")])
14199
14200 (define_insn "*sibcall_1_rex64"
14201 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14202 (match_operand 1 "" ""))]
14203 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14204 "jmp\t%P0"
14205 [(set_attr "type" "call")])
14206
14207 (define_insn "*sibcall_1_rex64_v"
14208 [(call (mem:QI (reg:DI R11_REG))
14209 (match_operand 0 "" ""))]
14210 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14211 "jmp\t*%%r11"
14212 [(set_attr "type" "call")])
14213
14214
14215 ;; Call subroutine, returning value in operand 0
14216
14217 (define_expand "call_value_pop"
14218 [(parallel [(set (match_operand 0 "" "")
14219 (call (match_operand:QI 1 "" "")
14220 (match_operand:SI 2 "" "")))
14221 (set (reg:SI SP_REG)
14222 (plus:SI (reg:SI SP_REG)
14223 (match_operand:SI 4 "" "")))])]
14224 "!TARGET_64BIT"
14225 {
14226 ix86_expand_call (operands[0], operands[1], operands[2],
14227 operands[3], operands[4], 0);
14228 DONE;
14229 })
14230
14231 (define_expand "call_value"
14232 [(set (match_operand 0 "" "")
14233 (call (match_operand:QI 1 "" "")
14234 (match_operand:SI 2 "" "")))
14235 (use (match_operand:SI 3 "" ""))]
14236 ;; Operand 2 not used on the i386.
14237 ""
14238 {
14239 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14240 DONE;
14241 })
14242
14243 (define_expand "sibcall_value"
14244 [(set (match_operand 0 "" "")
14245 (call (match_operand:QI 1 "" "")
14246 (match_operand:SI 2 "" "")))
14247 (use (match_operand:SI 3 "" ""))]
14248 ;; Operand 2 not used on the i386.
14249 ""
14250 {
14251 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14252 DONE;
14253 })
14254
14255 ;; Call subroutine returning any type.
14256
14257 (define_expand "untyped_call"
14258 [(parallel [(call (match_operand 0 "" "")
14259 (const_int 0))
14260 (match_operand 1 "" "")
14261 (match_operand 2 "" "")])]
14262 ""
14263 {
14264 int i;
14265
14266 /* In order to give reg-stack an easier job in validating two
14267 coprocessor registers as containing a possible return value,
14268 simply pretend the untyped call returns a complex long double
14269 value. */
14270
14271 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14272 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14273 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14274 NULL, 0);
14275
14276 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14277 {
14278 rtx set = XVECEXP (operands[2], 0, i);
14279 emit_move_insn (SET_DEST (set), SET_SRC (set));
14280 }
14281
14282 /* The optimizer does not know that the call sets the function value
14283 registers we stored in the result block. We avoid problems by
14284 claiming that all hard registers are used and clobbered at this
14285 point. */
14286 emit_insn (gen_blockage (const0_rtx));
14287
14288 DONE;
14289 })
14290 \f
14291 ;; Prologue and epilogue instructions
14292
14293 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14294 ;; all of memory. This blocks insns from being moved across this point.
14295
14296 (define_insn "blockage"
14297 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14298 ""
14299 ""
14300 [(set_attr "length" "0")])
14301
14302 ;; Insn emitted into the body of a function to return from a function.
14303 ;; This is only done if the function's epilogue is known to be simple.
14304 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14305
14306 (define_expand "return"
14307 [(return)]
14308 "ix86_can_use_return_insn_p ()"
14309 {
14310 if (current_function_pops_args)
14311 {
14312 rtx popc = GEN_INT (current_function_pops_args);
14313 emit_jump_insn (gen_return_pop_internal (popc));
14314 DONE;
14315 }
14316 })
14317
14318 (define_insn "return_internal"
14319 [(return)]
14320 "reload_completed"
14321 "ret"
14322 [(set_attr "length" "1")
14323 (set_attr "length_immediate" "0")
14324 (set_attr "modrm" "0")])
14325
14326 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14327 ;; instruction Athlon and K8 have.
14328
14329 (define_insn "return_internal_long"
14330 [(return)
14331 (unspec [(const_int 0)] UNSPEC_REP)]
14332 "reload_completed"
14333 "rep {;} ret"
14334 [(set_attr "length" "1")
14335 (set_attr "length_immediate" "0")
14336 (set_attr "prefix_rep" "1")
14337 (set_attr "modrm" "0")])
14338
14339 (define_insn "return_pop_internal"
14340 [(return)
14341 (use (match_operand:SI 0 "const_int_operand" ""))]
14342 "reload_completed"
14343 "ret\t%0"
14344 [(set_attr "length" "3")
14345 (set_attr "length_immediate" "2")
14346 (set_attr "modrm" "0")])
14347
14348 (define_insn "return_indirect_internal"
14349 [(return)
14350 (use (match_operand:SI 0 "register_operand" "r"))]
14351 "reload_completed"
14352 "jmp\t%A0"
14353 [(set_attr "type" "ibr")
14354 (set_attr "length_immediate" "0")])
14355
14356 (define_insn "nop"
14357 [(const_int 0)]
14358 ""
14359 "nop"
14360 [(set_attr "length" "1")
14361 (set_attr "length_immediate" "0")
14362 (set_attr "modrm" "0")])
14363
14364 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14365 ;; branch prediction penalty for the third jump in a 16-byte
14366 ;; block on K8.
14367
14368 (define_insn "align"
14369 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14370 ""
14371 {
14372 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14373 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14374 #else
14375 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14376 The align insn is used to avoid 3 jump instructions in the row to improve
14377 branch prediction and the benefits hardly outweigh the cost of extra 8
14378 nops on the average inserted by full alignment pseudo operation. */
14379 #endif
14380 return "";
14381 }
14382 [(set_attr "length" "16")])
14383
14384 (define_expand "prologue"
14385 [(const_int 1)]
14386 ""
14387 "ix86_expand_prologue (); DONE;")
14388
14389 (define_insn "set_got"
14390 [(set (match_operand:SI 0 "register_operand" "=r")
14391 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14392 (clobber (reg:CC FLAGS_REG))]
14393 "!TARGET_64BIT"
14394 { return output_set_got (operands[0], NULL_RTX); }
14395 [(set_attr "type" "multi")
14396 (set_attr "length" "12")])
14397
14398 (define_insn "set_got_labelled"
14399 [(set (match_operand:SI 0 "register_operand" "=r")
14400 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14401 UNSPEC_SET_GOT))
14402 (clobber (reg:CC FLAGS_REG))]
14403 "!TARGET_64BIT"
14404 { return output_set_got (operands[0], operands[1]); }
14405 [(set_attr "type" "multi")
14406 (set_attr "length" "12")])
14407
14408 (define_insn "set_got_rex64"
14409 [(set (match_operand:DI 0 "register_operand" "=r")
14410 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14411 "TARGET_64BIT"
14412 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14413 [(set_attr "type" "lea")
14414 (set_attr "length" "6")])
14415
14416 (define_expand "epilogue"
14417 [(const_int 1)]
14418 ""
14419 "ix86_expand_epilogue (1); DONE;")
14420
14421 (define_expand "sibcall_epilogue"
14422 [(const_int 1)]
14423 ""
14424 "ix86_expand_epilogue (0); DONE;")
14425
14426 (define_expand "eh_return"
14427 [(use (match_operand 0 "register_operand" ""))]
14428 ""
14429 {
14430 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14431
14432 /* Tricky bit: we write the address of the handler to which we will
14433 be returning into someone else's stack frame, one word below the
14434 stack address we wish to restore. */
14435 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14436 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14437 tmp = gen_rtx_MEM (Pmode, tmp);
14438 emit_move_insn (tmp, ra);
14439
14440 if (Pmode == SImode)
14441 emit_jump_insn (gen_eh_return_si (sa));
14442 else
14443 emit_jump_insn (gen_eh_return_di (sa));
14444 emit_barrier ();
14445 DONE;
14446 })
14447
14448 (define_insn_and_split "eh_return_si"
14449 [(set (pc)
14450 (unspec [(match_operand:SI 0 "register_operand" "c")]
14451 UNSPEC_EH_RETURN))]
14452 "!TARGET_64BIT"
14453 "#"
14454 "reload_completed"
14455 [(const_int 1)]
14456 "ix86_expand_epilogue (2); DONE;")
14457
14458 (define_insn_and_split "eh_return_di"
14459 [(set (pc)
14460 (unspec [(match_operand:DI 0 "register_operand" "c")]
14461 UNSPEC_EH_RETURN))]
14462 "TARGET_64BIT"
14463 "#"
14464 "reload_completed"
14465 [(const_int 1)]
14466 "ix86_expand_epilogue (2); DONE;")
14467
14468 (define_insn "leave"
14469 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14470 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14471 (clobber (mem:BLK (scratch)))]
14472 "!TARGET_64BIT"
14473 "leave"
14474 [(set_attr "type" "leave")])
14475
14476 (define_insn "leave_rex64"
14477 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14478 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14479 (clobber (mem:BLK (scratch)))]
14480 "TARGET_64BIT"
14481 "leave"
14482 [(set_attr "type" "leave")])
14483 \f
14484 (define_expand "ffssi2"
14485 [(parallel
14486 [(set (match_operand:SI 0 "register_operand" "")
14487 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14488 (clobber (match_scratch:SI 2 ""))
14489 (clobber (reg:CC FLAGS_REG))])]
14490 ""
14491 "")
14492
14493 (define_insn_and_split "*ffs_cmove"
14494 [(set (match_operand:SI 0 "register_operand" "=r")
14495 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14496 (clobber (match_scratch:SI 2 "=&r"))
14497 (clobber (reg:CC FLAGS_REG))]
14498 "TARGET_CMOVE"
14499 "#"
14500 "&& reload_completed"
14501 [(set (match_dup 2) (const_int -1))
14502 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14503 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14504 (set (match_dup 0) (if_then_else:SI
14505 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14506 (match_dup 2)
14507 (match_dup 0)))
14508 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14509 (clobber (reg:CC FLAGS_REG))])]
14510 "")
14511
14512 (define_insn_and_split "*ffs_no_cmove"
14513 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14514 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14515 (clobber (match_scratch:SI 2 "=&q"))
14516 (clobber (reg:CC FLAGS_REG))]
14517 ""
14518 "#"
14519 "reload_completed"
14520 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14521 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14522 (set (strict_low_part (match_dup 3))
14523 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14524 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14525 (clobber (reg:CC FLAGS_REG))])
14526 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14527 (clobber (reg:CC FLAGS_REG))])
14528 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14529 (clobber (reg:CC FLAGS_REG))])]
14530 {
14531 operands[3] = gen_lowpart (QImode, operands[2]);
14532 ix86_expand_clear (operands[2]);
14533 })
14534
14535 (define_insn "*ffssi_1"
14536 [(set (reg:CCZ FLAGS_REG)
14537 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14538 (const_int 0)))
14539 (set (match_operand:SI 0 "register_operand" "=r")
14540 (ctz:SI (match_dup 1)))]
14541 ""
14542 "bsf{l}\t{%1, %0|%0, %1}"
14543 [(set_attr "prefix_0f" "1")])
14544
14545 (define_expand "ffsdi2"
14546 [(parallel
14547 [(set (match_operand:DI 0 "register_operand" "")
14548 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14549 (clobber (match_scratch:DI 2 ""))
14550 (clobber (reg:CC FLAGS_REG))])]
14551 "TARGET_64BIT && TARGET_CMOVE"
14552 "")
14553
14554 (define_insn_and_split "*ffs_rex64"
14555 [(set (match_operand:DI 0 "register_operand" "=r")
14556 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14557 (clobber (match_scratch:DI 2 "=&r"))
14558 (clobber (reg:CC FLAGS_REG))]
14559 "TARGET_64BIT && TARGET_CMOVE"
14560 "#"
14561 "&& reload_completed"
14562 [(set (match_dup 2) (const_int -1))
14563 (parallel [(set (reg:CCZ FLAGS_REG)
14564 (compare:CCZ (match_dup 1) (const_int 0)))
14565 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14566 (set (match_dup 0) (if_then_else:DI
14567 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14568 (match_dup 2)
14569 (match_dup 0)))
14570 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14571 (clobber (reg:CC FLAGS_REG))])]
14572 "")
14573
14574 (define_insn "*ffsdi_1"
14575 [(set (reg:CCZ FLAGS_REG)
14576 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14577 (const_int 0)))
14578 (set (match_operand:DI 0 "register_operand" "=r")
14579 (ctz:DI (match_dup 1)))]
14580 "TARGET_64BIT"
14581 "bsf{q}\t{%1, %0|%0, %1}"
14582 [(set_attr "prefix_0f" "1")])
14583
14584 (define_insn "ctzsi2"
14585 [(set (match_operand:SI 0 "register_operand" "=r")
14586 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14587 (clobber (reg:CC FLAGS_REG))]
14588 ""
14589 "bsf{l}\t{%1, %0|%0, %1}"
14590 [(set_attr "prefix_0f" "1")])
14591
14592 (define_insn "ctzdi2"
14593 [(set (match_operand:DI 0 "register_operand" "=r")
14594 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14595 (clobber (reg:CC FLAGS_REG))]
14596 "TARGET_64BIT"
14597 "bsf{q}\t{%1, %0|%0, %1}"
14598 [(set_attr "prefix_0f" "1")])
14599
14600 (define_expand "clzsi2"
14601 [(parallel
14602 [(set (match_operand:SI 0 "register_operand" "")
14603 (minus:SI (const_int 31)
14604 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14605 (clobber (reg:CC FLAGS_REG))])
14606 (parallel
14607 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14608 (clobber (reg:CC FLAGS_REG))])]
14609 ""
14610 "")
14611
14612 (define_insn "*bsr"
14613 [(set (match_operand:SI 0 "register_operand" "=r")
14614 (minus:SI (const_int 31)
14615 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14616 (clobber (reg:CC FLAGS_REG))]
14617 ""
14618 "bsr{l}\t{%1, %0|%0, %1}"
14619 [(set_attr "prefix_0f" "1")])
14620
14621 (define_insn "bswapsi2"
14622 [(set (match_operand:SI 0 "register_operand" "=r")
14623 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14624 (clobber (reg:CC FLAGS_REG))]
14625 "TARGET_BSWAP"
14626 "bswap\t%k0"
14627 [(set_attr "prefix_0f" "1")
14628 (set_attr "length" "2")])
14629
14630 (define_insn "bswapdi2"
14631 [(set (match_operand:DI 0 "register_operand" "=r")
14632 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14633 (clobber (reg:CC FLAGS_REG))]
14634 "TARGET_64BIT && TARGET_BSWAP"
14635 "bswap\t%0"
14636 [(set_attr "prefix_0f" "1")
14637 (set_attr "length" "3")])
14638
14639 (define_expand "clzdi2"
14640 [(parallel
14641 [(set (match_operand:DI 0 "register_operand" "")
14642 (minus:DI (const_int 63)
14643 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14644 (clobber (reg:CC FLAGS_REG))])
14645 (parallel
14646 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14647 (clobber (reg:CC FLAGS_REG))])]
14648 "TARGET_64BIT"
14649 "")
14650
14651 (define_insn "*bsr_rex64"
14652 [(set (match_operand:DI 0 "register_operand" "=r")
14653 (minus:DI (const_int 63)
14654 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14655 (clobber (reg:CC FLAGS_REG))]
14656 "TARGET_64BIT"
14657 "bsr{q}\t{%1, %0|%0, %1}"
14658 [(set_attr "prefix_0f" "1")])
14659 \f
14660 ;; Thread-local storage patterns for ELF.
14661 ;;
14662 ;; Note that these code sequences must appear exactly as shown
14663 ;; in order to allow linker relaxation.
14664
14665 (define_insn "*tls_global_dynamic_32_gnu"
14666 [(set (match_operand:SI 0 "register_operand" "=a")
14667 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14668 (match_operand:SI 2 "tls_symbolic_operand" "")
14669 (match_operand:SI 3 "call_insn_operand" "")]
14670 UNSPEC_TLS_GD))
14671 (clobber (match_scratch:SI 4 "=d"))
14672 (clobber (match_scratch:SI 5 "=c"))
14673 (clobber (reg:CC FLAGS_REG))]
14674 "!TARGET_64BIT && TARGET_GNU_TLS"
14675 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14676 [(set_attr "type" "multi")
14677 (set_attr "length" "12")])
14678
14679 (define_insn "*tls_global_dynamic_32_sun"
14680 [(set (match_operand:SI 0 "register_operand" "=a")
14681 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14682 (match_operand:SI 2 "tls_symbolic_operand" "")
14683 (match_operand:SI 3 "call_insn_operand" "")]
14684 UNSPEC_TLS_GD))
14685 (clobber (match_scratch:SI 4 "=d"))
14686 (clobber (match_scratch:SI 5 "=c"))
14687 (clobber (reg:CC FLAGS_REG))]
14688 "!TARGET_64BIT && TARGET_SUN_TLS"
14689 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14690 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14691 [(set_attr "type" "multi")
14692 (set_attr "length" "14")])
14693
14694 (define_expand "tls_global_dynamic_32"
14695 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14696 (unspec:SI
14697 [(match_dup 2)
14698 (match_operand:SI 1 "tls_symbolic_operand" "")
14699 (match_dup 3)]
14700 UNSPEC_TLS_GD))
14701 (clobber (match_scratch:SI 4 ""))
14702 (clobber (match_scratch:SI 5 ""))
14703 (clobber (reg:CC FLAGS_REG))])]
14704 ""
14705 {
14706 if (flag_pic)
14707 operands[2] = pic_offset_table_rtx;
14708 else
14709 {
14710 operands[2] = gen_reg_rtx (Pmode);
14711 emit_insn (gen_set_got (operands[2]));
14712 }
14713 if (TARGET_GNU2_TLS)
14714 {
14715 emit_insn (gen_tls_dynamic_gnu2_32
14716 (operands[0], operands[1], operands[2]));
14717 DONE;
14718 }
14719 operands[3] = ix86_tls_get_addr ();
14720 })
14721
14722 (define_insn "*tls_global_dynamic_64"
14723 [(set (match_operand:DI 0 "register_operand" "=a")
14724 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14725 (match_operand:DI 3 "" "")))
14726 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14727 UNSPEC_TLS_GD)]
14728 "TARGET_64BIT"
14729 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14730 [(set_attr "type" "multi")
14731 (set_attr "length" "16")])
14732
14733 (define_expand "tls_global_dynamic_64"
14734 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14735 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14736 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14737 UNSPEC_TLS_GD)])]
14738 ""
14739 {
14740 if (TARGET_GNU2_TLS)
14741 {
14742 emit_insn (gen_tls_dynamic_gnu2_64
14743 (operands[0], operands[1]));
14744 DONE;
14745 }
14746 operands[2] = ix86_tls_get_addr ();
14747 })
14748
14749 (define_insn "*tls_local_dynamic_base_32_gnu"
14750 [(set (match_operand:SI 0 "register_operand" "=a")
14751 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14752 (match_operand:SI 2 "call_insn_operand" "")]
14753 UNSPEC_TLS_LD_BASE))
14754 (clobber (match_scratch:SI 3 "=d"))
14755 (clobber (match_scratch:SI 4 "=c"))
14756 (clobber (reg:CC FLAGS_REG))]
14757 "!TARGET_64BIT && TARGET_GNU_TLS"
14758 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14759 [(set_attr "type" "multi")
14760 (set_attr "length" "11")])
14761
14762 (define_insn "*tls_local_dynamic_base_32_sun"
14763 [(set (match_operand:SI 0 "register_operand" "=a")
14764 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14765 (match_operand:SI 2 "call_insn_operand" "")]
14766 UNSPEC_TLS_LD_BASE))
14767 (clobber (match_scratch:SI 3 "=d"))
14768 (clobber (match_scratch:SI 4 "=c"))
14769 (clobber (reg:CC FLAGS_REG))]
14770 "!TARGET_64BIT && TARGET_SUN_TLS"
14771 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14772 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14773 [(set_attr "type" "multi")
14774 (set_attr "length" "13")])
14775
14776 (define_expand "tls_local_dynamic_base_32"
14777 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14778 (unspec:SI [(match_dup 1) (match_dup 2)]
14779 UNSPEC_TLS_LD_BASE))
14780 (clobber (match_scratch:SI 3 ""))
14781 (clobber (match_scratch:SI 4 ""))
14782 (clobber (reg:CC FLAGS_REG))])]
14783 ""
14784 {
14785 if (flag_pic)
14786 operands[1] = pic_offset_table_rtx;
14787 else
14788 {
14789 operands[1] = gen_reg_rtx (Pmode);
14790 emit_insn (gen_set_got (operands[1]));
14791 }
14792 if (TARGET_GNU2_TLS)
14793 {
14794 emit_insn (gen_tls_dynamic_gnu2_32
14795 (operands[0], ix86_tls_module_base (), operands[1]));
14796 DONE;
14797 }
14798 operands[2] = ix86_tls_get_addr ();
14799 })
14800
14801 (define_insn "*tls_local_dynamic_base_64"
14802 [(set (match_operand:DI 0 "register_operand" "=a")
14803 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14804 (match_operand:DI 2 "" "")))
14805 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14806 "TARGET_64BIT"
14807 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14808 [(set_attr "type" "multi")
14809 (set_attr "length" "12")])
14810
14811 (define_expand "tls_local_dynamic_base_64"
14812 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14813 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14814 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14815 ""
14816 {
14817 if (TARGET_GNU2_TLS)
14818 {
14819 emit_insn (gen_tls_dynamic_gnu2_64
14820 (operands[0], ix86_tls_module_base ()));
14821 DONE;
14822 }
14823 operands[1] = ix86_tls_get_addr ();
14824 })
14825
14826 ;; Local dynamic of a single variable is a lose. Show combine how
14827 ;; to convert that back to global dynamic.
14828
14829 (define_insn_and_split "*tls_local_dynamic_32_once"
14830 [(set (match_operand:SI 0 "register_operand" "=a")
14831 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14832 (match_operand:SI 2 "call_insn_operand" "")]
14833 UNSPEC_TLS_LD_BASE)
14834 (const:SI (unspec:SI
14835 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14836 UNSPEC_DTPOFF))))
14837 (clobber (match_scratch:SI 4 "=d"))
14838 (clobber (match_scratch:SI 5 "=c"))
14839 (clobber (reg:CC FLAGS_REG))]
14840 ""
14841 "#"
14842 ""
14843 [(parallel [(set (match_dup 0)
14844 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14845 UNSPEC_TLS_GD))
14846 (clobber (match_dup 4))
14847 (clobber (match_dup 5))
14848 (clobber (reg:CC FLAGS_REG))])]
14849 "")
14850
14851 ;; Load and add the thread base pointer from %gs:0.
14852
14853 (define_insn "*load_tp_si"
14854 [(set (match_operand:SI 0 "register_operand" "=r")
14855 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14856 "!TARGET_64BIT"
14857 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14858 [(set_attr "type" "imov")
14859 (set_attr "modrm" "0")
14860 (set_attr "length" "7")
14861 (set_attr "memory" "load")
14862 (set_attr "imm_disp" "false")])
14863
14864 (define_insn "*add_tp_si"
14865 [(set (match_operand:SI 0 "register_operand" "=r")
14866 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14867 (match_operand:SI 1 "register_operand" "0")))
14868 (clobber (reg:CC FLAGS_REG))]
14869 "!TARGET_64BIT"
14870 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14871 [(set_attr "type" "alu")
14872 (set_attr "modrm" "0")
14873 (set_attr "length" "7")
14874 (set_attr "memory" "load")
14875 (set_attr "imm_disp" "false")])
14876
14877 (define_insn "*load_tp_di"
14878 [(set (match_operand:DI 0 "register_operand" "=r")
14879 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14880 "TARGET_64BIT"
14881 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14882 [(set_attr "type" "imov")
14883 (set_attr "modrm" "0")
14884 (set_attr "length" "7")
14885 (set_attr "memory" "load")
14886 (set_attr "imm_disp" "false")])
14887
14888 (define_insn "*add_tp_di"
14889 [(set (match_operand:DI 0 "register_operand" "=r")
14890 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14891 (match_operand:DI 1 "register_operand" "0")))
14892 (clobber (reg:CC FLAGS_REG))]
14893 "TARGET_64BIT"
14894 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14895 [(set_attr "type" "alu")
14896 (set_attr "modrm" "0")
14897 (set_attr "length" "7")
14898 (set_attr "memory" "load")
14899 (set_attr "imm_disp" "false")])
14900
14901 ;; GNU2 TLS patterns can be split.
14902
14903 (define_expand "tls_dynamic_gnu2_32"
14904 [(set (match_dup 3)
14905 (plus:SI (match_operand:SI 2 "register_operand" "")
14906 (const:SI
14907 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14908 UNSPEC_TLSDESC))))
14909 (parallel
14910 [(set (match_operand:SI 0 "register_operand" "")
14911 (unspec:SI [(match_dup 1) (match_dup 3)
14912 (match_dup 2) (reg:SI SP_REG)]
14913 UNSPEC_TLSDESC))
14914 (clobber (reg:CC FLAGS_REG))])]
14915 "!TARGET_64BIT && TARGET_GNU2_TLS"
14916 {
14917 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14918 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14919 })
14920
14921 (define_insn "*tls_dynamic_lea_32"
14922 [(set (match_operand:SI 0 "register_operand" "=r")
14923 (plus:SI (match_operand:SI 1 "register_operand" "b")
14924 (const:SI
14925 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14926 UNSPEC_TLSDESC))))]
14927 "!TARGET_64BIT && TARGET_GNU2_TLS"
14928 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14929 [(set_attr "type" "lea")
14930 (set_attr "mode" "SI")
14931 (set_attr "length" "6")
14932 (set_attr "length_address" "4")])
14933
14934 (define_insn "*tls_dynamic_call_32"
14935 [(set (match_operand:SI 0 "register_operand" "=a")
14936 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14937 (match_operand:SI 2 "register_operand" "0")
14938 ;; we have to make sure %ebx still points to the GOT
14939 (match_operand:SI 3 "register_operand" "b")
14940 (reg:SI SP_REG)]
14941 UNSPEC_TLSDESC))
14942 (clobber (reg:CC FLAGS_REG))]
14943 "!TARGET_64BIT && TARGET_GNU2_TLS"
14944 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14945 [(set_attr "type" "call")
14946 (set_attr "length" "2")
14947 (set_attr "length_address" "0")])
14948
14949 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14950 [(set (match_operand:SI 0 "register_operand" "=&a")
14951 (plus:SI
14952 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14953 (match_operand:SI 4 "" "")
14954 (match_operand:SI 2 "register_operand" "b")
14955 (reg:SI SP_REG)]
14956 UNSPEC_TLSDESC)
14957 (const:SI (unspec:SI
14958 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14959 UNSPEC_DTPOFF))))
14960 (clobber (reg:CC FLAGS_REG))]
14961 "!TARGET_64BIT && TARGET_GNU2_TLS"
14962 "#"
14963 ""
14964 [(set (match_dup 0) (match_dup 5))]
14965 {
14966 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14967 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14968 })
14969
14970 (define_expand "tls_dynamic_gnu2_64"
14971 [(set (match_dup 2)
14972 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14973 UNSPEC_TLSDESC))
14974 (parallel
14975 [(set (match_operand:DI 0 "register_operand" "")
14976 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14977 UNSPEC_TLSDESC))
14978 (clobber (reg:CC FLAGS_REG))])]
14979 "TARGET_64BIT && TARGET_GNU2_TLS"
14980 {
14981 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14982 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14983 })
14984
14985 (define_insn "*tls_dynamic_lea_64"
14986 [(set (match_operand:DI 0 "register_operand" "=r")
14987 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14988 UNSPEC_TLSDESC))]
14989 "TARGET_64BIT && TARGET_GNU2_TLS"
14990 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14991 [(set_attr "type" "lea")
14992 (set_attr "mode" "DI")
14993 (set_attr "length" "7")
14994 (set_attr "length_address" "4")])
14995
14996 (define_insn "*tls_dynamic_call_64"
14997 [(set (match_operand:DI 0 "register_operand" "=a")
14998 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14999 (match_operand:DI 2 "register_operand" "0")
15000 (reg:DI SP_REG)]
15001 UNSPEC_TLSDESC))
15002 (clobber (reg:CC FLAGS_REG))]
15003 "TARGET_64BIT && TARGET_GNU2_TLS"
15004 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15005 [(set_attr "type" "call")
15006 (set_attr "length" "2")
15007 (set_attr "length_address" "0")])
15008
15009 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15010 [(set (match_operand:DI 0 "register_operand" "=&a")
15011 (plus:DI
15012 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15013 (match_operand:DI 3 "" "")
15014 (reg:DI SP_REG)]
15015 UNSPEC_TLSDESC)
15016 (const:DI (unspec:DI
15017 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15018 UNSPEC_DTPOFF))))
15019 (clobber (reg:CC FLAGS_REG))]
15020 "TARGET_64BIT && TARGET_GNU2_TLS"
15021 "#"
15022 ""
15023 [(set (match_dup 0) (match_dup 4))]
15024 {
15025 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15026 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15027 })
15028
15029 ;;
15030 \f
15031 ;; These patterns match the binary 387 instructions for addM3, subM3,
15032 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15033 ;; SFmode. The first is the normal insn, the second the same insn but
15034 ;; with one operand a conversion, and the third the same insn but with
15035 ;; the other operand a conversion. The conversion may be SFmode or
15036 ;; SImode if the target mode DFmode, but only SImode if the target mode
15037 ;; is SFmode.
15038
15039 ;; Gcc is slightly more smart about handling normal two address instructions
15040 ;; so use special patterns for add and mull.
15041
15042 (define_insn "*fop_sf_comm_mixed"
15043 [(set (match_operand:SF 0 "register_operand" "=f,x")
15044 (match_operator:SF 3 "binary_fp_operator"
15045 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15046 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15047 "TARGET_MIX_SSE_I387
15048 && COMMUTATIVE_ARITH_P (operands[3])
15049 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15050 "* return output_387_binary_op (insn, operands);"
15051 [(set (attr "type")
15052 (if_then_else (eq_attr "alternative" "1")
15053 (if_then_else (match_operand:SF 3 "mult_operator" "")
15054 (const_string "ssemul")
15055 (const_string "sseadd"))
15056 (if_then_else (match_operand:SF 3 "mult_operator" "")
15057 (const_string "fmul")
15058 (const_string "fop"))))
15059 (set_attr "mode" "SF")])
15060
15061 (define_insn "*fop_sf_comm_sse"
15062 [(set (match_operand:SF 0 "register_operand" "=x")
15063 (match_operator:SF 3 "binary_fp_operator"
15064 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15065 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15066 "TARGET_SSE_MATH
15067 && COMMUTATIVE_ARITH_P (operands[3])
15068 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15069 "* return output_387_binary_op (insn, operands);"
15070 [(set (attr "type")
15071 (if_then_else (match_operand:SF 3 "mult_operator" "")
15072 (const_string "ssemul")
15073 (const_string "sseadd")))
15074 (set_attr "mode" "SF")])
15075
15076 (define_insn "*fop_sf_comm_i387"
15077 [(set (match_operand:SF 0 "register_operand" "=f")
15078 (match_operator:SF 3 "binary_fp_operator"
15079 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15080 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15081 "TARGET_80387
15082 && COMMUTATIVE_ARITH_P (operands[3])
15083 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15084 "* return output_387_binary_op (insn, operands);"
15085 [(set (attr "type")
15086 (if_then_else (match_operand:SF 3 "mult_operator" "")
15087 (const_string "fmul")
15088 (const_string "fop")))
15089 (set_attr "mode" "SF")])
15090
15091 (define_insn "*fop_sf_1_mixed"
15092 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15093 (match_operator:SF 3 "binary_fp_operator"
15094 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15095 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15096 "TARGET_MIX_SSE_I387
15097 && !COMMUTATIVE_ARITH_P (operands[3])
15098 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15099 "* return output_387_binary_op (insn, operands);"
15100 [(set (attr "type")
15101 (cond [(and (eq_attr "alternative" "2")
15102 (match_operand:SF 3 "mult_operator" ""))
15103 (const_string "ssemul")
15104 (and (eq_attr "alternative" "2")
15105 (match_operand:SF 3 "div_operator" ""))
15106 (const_string "ssediv")
15107 (eq_attr "alternative" "2")
15108 (const_string "sseadd")
15109 (match_operand:SF 3 "mult_operator" "")
15110 (const_string "fmul")
15111 (match_operand:SF 3 "div_operator" "")
15112 (const_string "fdiv")
15113 ]
15114 (const_string "fop")))
15115 (set_attr "mode" "SF")])
15116
15117 (define_insn "*fop_sf_1_sse"
15118 [(set (match_operand:SF 0 "register_operand" "=x")
15119 (match_operator:SF 3 "binary_fp_operator"
15120 [(match_operand:SF 1 "register_operand" "0")
15121 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15122 "TARGET_SSE_MATH
15123 && !COMMUTATIVE_ARITH_P (operands[3])"
15124 "* return output_387_binary_op (insn, operands);"
15125 [(set (attr "type")
15126 (cond [(match_operand:SF 3 "mult_operator" "")
15127 (const_string "ssemul")
15128 (match_operand:SF 3 "div_operator" "")
15129 (const_string "ssediv")
15130 ]
15131 (const_string "sseadd")))
15132 (set_attr "mode" "SF")])
15133
15134 ;; This pattern is not fully shadowed by the pattern above.
15135 (define_insn "*fop_sf_1_i387"
15136 [(set (match_operand:SF 0 "register_operand" "=f,f")
15137 (match_operator:SF 3 "binary_fp_operator"
15138 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15139 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15140 "TARGET_80387 && !TARGET_SSE_MATH
15141 && !COMMUTATIVE_ARITH_P (operands[3])
15142 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15143 "* return output_387_binary_op (insn, operands);"
15144 [(set (attr "type")
15145 (cond [(match_operand:SF 3 "mult_operator" "")
15146 (const_string "fmul")
15147 (match_operand:SF 3 "div_operator" "")
15148 (const_string "fdiv")
15149 ]
15150 (const_string "fop")))
15151 (set_attr "mode" "SF")])
15152
15153 ;; ??? Add SSE splitters for these!
15154 (define_insn "*fop_sf_2<mode>_i387"
15155 [(set (match_operand:SF 0 "register_operand" "=f,f")
15156 (match_operator:SF 3 "binary_fp_operator"
15157 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15158 (match_operand:SF 2 "register_operand" "0,0")]))]
15159 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15160 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15161 [(set (attr "type")
15162 (cond [(match_operand:SF 3 "mult_operator" "")
15163 (const_string "fmul")
15164 (match_operand:SF 3 "div_operator" "")
15165 (const_string "fdiv")
15166 ]
15167 (const_string "fop")))
15168 (set_attr "fp_int_src" "true")
15169 (set_attr "mode" "<MODE>")])
15170
15171 (define_insn "*fop_sf_3<mode>_i387"
15172 [(set (match_operand:SF 0 "register_operand" "=f,f")
15173 (match_operator:SF 3 "binary_fp_operator"
15174 [(match_operand:SF 1 "register_operand" "0,0")
15175 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15176 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15177 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15178 [(set (attr "type")
15179 (cond [(match_operand:SF 3 "mult_operator" "")
15180 (const_string "fmul")
15181 (match_operand:SF 3 "div_operator" "")
15182 (const_string "fdiv")
15183 ]
15184 (const_string "fop")))
15185 (set_attr "fp_int_src" "true")
15186 (set_attr "mode" "<MODE>")])
15187
15188 (define_insn "*fop_df_comm_mixed"
15189 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15190 (match_operator:DF 3 "binary_fp_operator"
15191 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15192 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15193 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15194 && COMMUTATIVE_ARITH_P (operands[3])
15195 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15196 "* return output_387_binary_op (insn, operands);"
15197 [(set (attr "type")
15198 (if_then_else (eq_attr "alternative" "1")
15199 (if_then_else (match_operand:DF 3 "mult_operator" "")
15200 (const_string "ssemul")
15201 (const_string "sseadd"))
15202 (if_then_else (match_operand:DF 3 "mult_operator" "")
15203 (const_string "fmul")
15204 (const_string "fop"))))
15205 (set_attr "mode" "DF")])
15206
15207 (define_insn "*fop_df_comm_sse"
15208 [(set (match_operand:DF 0 "register_operand" "=Y")
15209 (match_operator:DF 3 "binary_fp_operator"
15210 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15211 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15212 "TARGET_SSE2 && TARGET_SSE_MATH
15213 && COMMUTATIVE_ARITH_P (operands[3])
15214 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15215 "* return output_387_binary_op (insn, operands);"
15216 [(set (attr "type")
15217 (if_then_else (match_operand:DF 3 "mult_operator" "")
15218 (const_string "ssemul")
15219 (const_string "sseadd")))
15220 (set_attr "mode" "DF")])
15221
15222 (define_insn "*fop_df_comm_i387"
15223 [(set (match_operand:DF 0 "register_operand" "=f")
15224 (match_operator:DF 3 "binary_fp_operator"
15225 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15226 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15227 "TARGET_80387
15228 && COMMUTATIVE_ARITH_P (operands[3])
15229 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15230 "* return output_387_binary_op (insn, operands);"
15231 [(set (attr "type")
15232 (if_then_else (match_operand:DF 3 "mult_operator" "")
15233 (const_string "fmul")
15234 (const_string "fop")))
15235 (set_attr "mode" "DF")])
15236
15237 (define_insn "*fop_df_1_mixed"
15238 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15239 (match_operator:DF 3 "binary_fp_operator"
15240 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15241 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15242 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15243 && !COMMUTATIVE_ARITH_P (operands[3])
15244 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15245 "* return output_387_binary_op (insn, operands);"
15246 [(set (attr "type")
15247 (cond [(and (eq_attr "alternative" "2")
15248 (match_operand:DF 3 "mult_operator" ""))
15249 (const_string "ssemul")
15250 (and (eq_attr "alternative" "2")
15251 (match_operand:DF 3 "div_operator" ""))
15252 (const_string "ssediv")
15253 (eq_attr "alternative" "2")
15254 (const_string "sseadd")
15255 (match_operand:DF 3 "mult_operator" "")
15256 (const_string "fmul")
15257 (match_operand:DF 3 "div_operator" "")
15258 (const_string "fdiv")
15259 ]
15260 (const_string "fop")))
15261 (set_attr "mode" "DF")])
15262
15263 (define_insn "*fop_df_1_sse"
15264 [(set (match_operand:DF 0 "register_operand" "=Y")
15265 (match_operator:DF 3 "binary_fp_operator"
15266 [(match_operand:DF 1 "register_operand" "0")
15267 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15268 "TARGET_SSE2 && TARGET_SSE_MATH
15269 && !COMMUTATIVE_ARITH_P (operands[3])"
15270 "* return output_387_binary_op (insn, operands);"
15271 [(set_attr "mode" "DF")
15272 (set (attr "type")
15273 (cond [(match_operand:DF 3 "mult_operator" "")
15274 (const_string "ssemul")
15275 (match_operand:DF 3 "div_operator" "")
15276 (const_string "ssediv")
15277 ]
15278 (const_string "sseadd")))])
15279
15280 ;; This pattern is not fully shadowed by the pattern above.
15281 (define_insn "*fop_df_1_i387"
15282 [(set (match_operand:DF 0 "register_operand" "=f,f")
15283 (match_operator:DF 3 "binary_fp_operator"
15284 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15285 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15286 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15287 && !COMMUTATIVE_ARITH_P (operands[3])
15288 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15289 "* return output_387_binary_op (insn, operands);"
15290 [(set (attr "type")
15291 (cond [(match_operand:DF 3 "mult_operator" "")
15292 (const_string "fmul")
15293 (match_operand:DF 3 "div_operator" "")
15294 (const_string "fdiv")
15295 ]
15296 (const_string "fop")))
15297 (set_attr "mode" "DF")])
15298
15299 ;; ??? Add SSE splitters for these!
15300 (define_insn "*fop_df_2<mode>_i387"
15301 [(set (match_operand:DF 0 "register_operand" "=f,f")
15302 (match_operator:DF 3 "binary_fp_operator"
15303 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15304 (match_operand:DF 2 "register_operand" "0,0")]))]
15305 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15306 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15307 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15308 [(set (attr "type")
15309 (cond [(match_operand:DF 3 "mult_operator" "")
15310 (const_string "fmul")
15311 (match_operand:DF 3 "div_operator" "")
15312 (const_string "fdiv")
15313 ]
15314 (const_string "fop")))
15315 (set_attr "fp_int_src" "true")
15316 (set_attr "mode" "<MODE>")])
15317
15318 (define_insn "*fop_df_3<mode>_i387"
15319 [(set (match_operand:DF 0 "register_operand" "=f,f")
15320 (match_operator:DF 3 "binary_fp_operator"
15321 [(match_operand:DF 1 "register_operand" "0,0")
15322 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15323 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15324 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15325 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15326 [(set (attr "type")
15327 (cond [(match_operand:DF 3 "mult_operator" "")
15328 (const_string "fmul")
15329 (match_operand:DF 3 "div_operator" "")
15330 (const_string "fdiv")
15331 ]
15332 (const_string "fop")))
15333 (set_attr "fp_int_src" "true")
15334 (set_attr "mode" "<MODE>")])
15335
15336 (define_insn "*fop_df_4_i387"
15337 [(set (match_operand:DF 0 "register_operand" "=f,f")
15338 (match_operator:DF 3 "binary_fp_operator"
15339 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15340 (match_operand:DF 2 "register_operand" "0,f")]))]
15341 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15342 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15343 "* return output_387_binary_op (insn, operands);"
15344 [(set (attr "type")
15345 (cond [(match_operand:DF 3 "mult_operator" "")
15346 (const_string "fmul")
15347 (match_operand:DF 3 "div_operator" "")
15348 (const_string "fdiv")
15349 ]
15350 (const_string "fop")))
15351 (set_attr "mode" "SF")])
15352
15353 (define_insn "*fop_df_5_i387"
15354 [(set (match_operand:DF 0 "register_operand" "=f,f")
15355 (match_operator:DF 3 "binary_fp_operator"
15356 [(match_operand:DF 1 "register_operand" "0,f")
15357 (float_extend:DF
15358 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15359 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15360 "* return output_387_binary_op (insn, operands);"
15361 [(set (attr "type")
15362 (cond [(match_operand:DF 3 "mult_operator" "")
15363 (const_string "fmul")
15364 (match_operand:DF 3 "div_operator" "")
15365 (const_string "fdiv")
15366 ]
15367 (const_string "fop")))
15368 (set_attr "mode" "SF")])
15369
15370 (define_insn "*fop_df_6_i387"
15371 [(set (match_operand:DF 0 "register_operand" "=f,f")
15372 (match_operator:DF 3 "binary_fp_operator"
15373 [(float_extend:DF
15374 (match_operand:SF 1 "register_operand" "0,f"))
15375 (float_extend:DF
15376 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15377 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15378 "* return output_387_binary_op (insn, operands);"
15379 [(set (attr "type")
15380 (cond [(match_operand:DF 3 "mult_operator" "")
15381 (const_string "fmul")
15382 (match_operand:DF 3 "div_operator" "")
15383 (const_string "fdiv")
15384 ]
15385 (const_string "fop")))
15386 (set_attr "mode" "SF")])
15387
15388 (define_insn "*fop_xf_comm_i387"
15389 [(set (match_operand:XF 0 "register_operand" "=f")
15390 (match_operator:XF 3 "binary_fp_operator"
15391 [(match_operand:XF 1 "register_operand" "%0")
15392 (match_operand:XF 2 "register_operand" "f")]))]
15393 "TARGET_80387
15394 && COMMUTATIVE_ARITH_P (operands[3])"
15395 "* return output_387_binary_op (insn, operands);"
15396 [(set (attr "type")
15397 (if_then_else (match_operand:XF 3 "mult_operator" "")
15398 (const_string "fmul")
15399 (const_string "fop")))
15400 (set_attr "mode" "XF")])
15401
15402 (define_insn "*fop_xf_1_i387"
15403 [(set (match_operand:XF 0 "register_operand" "=f,f")
15404 (match_operator:XF 3 "binary_fp_operator"
15405 [(match_operand:XF 1 "register_operand" "0,f")
15406 (match_operand:XF 2 "register_operand" "f,0")]))]
15407 "TARGET_80387
15408 && !COMMUTATIVE_ARITH_P (operands[3])"
15409 "* return output_387_binary_op (insn, operands);"
15410 [(set (attr "type")
15411 (cond [(match_operand:XF 3 "mult_operator" "")
15412 (const_string "fmul")
15413 (match_operand:XF 3 "div_operator" "")
15414 (const_string "fdiv")
15415 ]
15416 (const_string "fop")))
15417 (set_attr "mode" "XF")])
15418
15419 (define_insn "*fop_xf_2<mode>_i387"
15420 [(set (match_operand:XF 0 "register_operand" "=f,f")
15421 (match_operator:XF 3 "binary_fp_operator"
15422 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15423 (match_operand:XF 2 "register_operand" "0,0")]))]
15424 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15425 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15426 [(set (attr "type")
15427 (cond [(match_operand:XF 3 "mult_operator" "")
15428 (const_string "fmul")
15429 (match_operand:XF 3 "div_operator" "")
15430 (const_string "fdiv")
15431 ]
15432 (const_string "fop")))
15433 (set_attr "fp_int_src" "true")
15434 (set_attr "mode" "<MODE>")])
15435
15436 (define_insn "*fop_xf_3<mode>_i387"
15437 [(set (match_operand:XF 0 "register_operand" "=f,f")
15438 (match_operator:XF 3 "binary_fp_operator"
15439 [(match_operand:XF 1 "register_operand" "0,0")
15440 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15441 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15442 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15443 [(set (attr "type")
15444 (cond [(match_operand:XF 3 "mult_operator" "")
15445 (const_string "fmul")
15446 (match_operand:XF 3 "div_operator" "")
15447 (const_string "fdiv")
15448 ]
15449 (const_string "fop")))
15450 (set_attr "fp_int_src" "true")
15451 (set_attr "mode" "<MODE>")])
15452
15453 (define_insn "*fop_xf_4_i387"
15454 [(set (match_operand:XF 0 "register_operand" "=f,f")
15455 (match_operator:XF 3 "binary_fp_operator"
15456 [(float_extend:XF
15457 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15458 (match_operand:XF 2 "register_operand" "0,f")]))]
15459 "TARGET_80387"
15460 "* return output_387_binary_op (insn, operands);"
15461 [(set (attr "type")
15462 (cond [(match_operand:XF 3 "mult_operator" "")
15463 (const_string "fmul")
15464 (match_operand:XF 3 "div_operator" "")
15465 (const_string "fdiv")
15466 ]
15467 (const_string "fop")))
15468 (set_attr "mode" "SF")])
15469
15470 (define_insn "*fop_xf_5_i387"
15471 [(set (match_operand:XF 0 "register_operand" "=f,f")
15472 (match_operator:XF 3 "binary_fp_operator"
15473 [(match_operand:XF 1 "register_operand" "0,f")
15474 (float_extend:XF
15475 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15476 "TARGET_80387"
15477 "* return output_387_binary_op (insn, operands);"
15478 [(set (attr "type")
15479 (cond [(match_operand:XF 3 "mult_operator" "")
15480 (const_string "fmul")
15481 (match_operand:XF 3 "div_operator" "")
15482 (const_string "fdiv")
15483 ]
15484 (const_string "fop")))
15485 (set_attr "mode" "SF")])
15486
15487 (define_insn "*fop_xf_6_i387"
15488 [(set (match_operand:XF 0 "register_operand" "=f,f")
15489 (match_operator:XF 3 "binary_fp_operator"
15490 [(float_extend:XF
15491 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15492 (float_extend:XF
15493 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15494 "TARGET_80387"
15495 "* return output_387_binary_op (insn, operands);"
15496 [(set (attr "type")
15497 (cond [(match_operand:XF 3 "mult_operator" "")
15498 (const_string "fmul")
15499 (match_operand:XF 3 "div_operator" "")
15500 (const_string "fdiv")
15501 ]
15502 (const_string "fop")))
15503 (set_attr "mode" "SF")])
15504
15505 (define_split
15506 [(set (match_operand 0 "register_operand" "")
15507 (match_operator 3 "binary_fp_operator"
15508 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15509 (match_operand 2 "register_operand" "")]))]
15510 "TARGET_80387 && reload_completed
15511 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15512 [(const_int 0)]
15513 {
15514 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15515 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15516 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15517 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15518 GET_MODE (operands[3]),
15519 operands[4],
15520 operands[2])));
15521 ix86_free_from_memory (GET_MODE (operands[1]));
15522 DONE;
15523 })
15524
15525 (define_split
15526 [(set (match_operand 0 "register_operand" "")
15527 (match_operator 3 "binary_fp_operator"
15528 [(match_operand 1 "register_operand" "")
15529 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15530 "TARGET_80387 && reload_completed
15531 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15532 [(const_int 0)]
15533 {
15534 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15535 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15536 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15537 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15538 GET_MODE (operands[3]),
15539 operands[1],
15540 operands[4])));
15541 ix86_free_from_memory (GET_MODE (operands[2]));
15542 DONE;
15543 })
15544 \f
15545 ;; FPU special functions.
15546
15547 ;; This pattern implements a no-op XFmode truncation for
15548 ;; all fancy i386 XFmode math functions.
15549
15550 (define_insn "truncxf<mode>2_i387_noop_unspec"
15551 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15552 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15553 UNSPEC_TRUNC_NOOP))]
15554 "TARGET_USE_FANCY_MATH_387"
15555 "* return output_387_reg_move (insn, operands);"
15556 [(set_attr "type" "fmov")
15557 (set_attr "mode" "<MODE>")])
15558
15559 (define_insn "sqrtxf2"
15560 [(set (match_operand:XF 0 "register_operand" "=f")
15561 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15562 "TARGET_USE_FANCY_MATH_387"
15563 "fsqrt"
15564 [(set_attr "type" "fpspc")
15565 (set_attr "mode" "XF")
15566 (set_attr "athlon_decode" "direct")])
15567
15568 (define_insn "sqrt_extend<mode>xf2_i387"
15569 [(set (match_operand:XF 0 "register_operand" "=f")
15570 (sqrt:XF
15571 (float_extend:XF
15572 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15573 "TARGET_USE_FANCY_MATH_387"
15574 "fsqrt"
15575 [(set_attr "type" "fpspc")
15576 (set_attr "mode" "XF")
15577 (set_attr "athlon_decode" "direct")])
15578
15579 (define_insn "*sqrt<mode>2_sse"
15580 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15581 (sqrt:SSEMODEF
15582 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15583 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15584 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15585 [(set_attr "type" "sse")
15586 (set_attr "mode" "<MODE>")
15587 (set_attr "athlon_decode" "*")])
15588
15589 (define_expand "sqrt<mode>2"
15590 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15591 (sqrt:X87MODEF12
15592 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15593 "TARGET_USE_FANCY_MATH_387
15594 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15595 {
15596 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15597 {
15598 rtx op0 = gen_reg_rtx (XFmode);
15599 rtx op1 = force_reg (<MODE>mode, operands[1]);
15600
15601 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15602 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15603 DONE;
15604 }
15605 })
15606
15607 (define_insn "fpremxf4_i387"
15608 [(set (match_operand:XF 0 "register_operand" "=f")
15609 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15610 (match_operand:XF 3 "register_operand" "1")]
15611 UNSPEC_FPREM_F))
15612 (set (match_operand:XF 1 "register_operand" "=u")
15613 (unspec:XF [(match_dup 2) (match_dup 3)]
15614 UNSPEC_FPREM_U))
15615 (set (reg:CCFP FPSR_REG)
15616 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15617 "TARGET_USE_FANCY_MATH_387"
15618 "fprem"
15619 [(set_attr "type" "fpspc")
15620 (set_attr "mode" "XF")])
15621
15622 (define_expand "fmodxf3"
15623 [(use (match_operand:XF 0 "register_operand" ""))
15624 (use (match_operand:XF 1 "register_operand" ""))
15625 (use (match_operand:XF 2 "register_operand" ""))]
15626 "TARGET_USE_FANCY_MATH_387"
15627 {
15628 rtx label = gen_label_rtx ();
15629
15630 emit_label (label);
15631
15632 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15633 operands[1], operands[2]));
15634 ix86_emit_fp_unordered_jump (label);
15635
15636 emit_move_insn (operands[0], operands[1]);
15637 DONE;
15638 })
15639
15640 (define_expand "fmod<mode>3"
15641 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15642 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15643 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15644 "TARGET_USE_FANCY_MATH_387"
15645 {
15646 rtx label = gen_label_rtx ();
15647
15648 rtx op1 = gen_reg_rtx (XFmode);
15649 rtx op2 = gen_reg_rtx (XFmode);
15650
15651 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15652 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15653
15654 emit_label (label);
15655 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15656 ix86_emit_fp_unordered_jump (label);
15657
15658 /* Truncate the result properly for strict SSE math. */
15659 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15660 && !TARGET_MIX_SSE_I387)
15661 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15662 else
15663 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15664
15665 DONE;
15666 })
15667
15668 (define_insn "fprem1xf4_i387"
15669 [(set (match_operand:XF 0 "register_operand" "=f")
15670 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15671 (match_operand:XF 3 "register_operand" "1")]
15672 UNSPEC_FPREM1_F))
15673 (set (match_operand:XF 1 "register_operand" "=u")
15674 (unspec:XF [(match_dup 2) (match_dup 3)]
15675 UNSPEC_FPREM1_U))
15676 (set (reg:CCFP FPSR_REG)
15677 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15678 "TARGET_USE_FANCY_MATH_387"
15679 "fprem1"
15680 [(set_attr "type" "fpspc")
15681 (set_attr "mode" "XF")])
15682
15683 (define_expand "remainderxf3"
15684 [(use (match_operand:XF 0 "register_operand" ""))
15685 (use (match_operand:XF 1 "register_operand" ""))
15686 (use (match_operand:XF 2 "register_operand" ""))]
15687 "TARGET_USE_FANCY_MATH_387"
15688 {
15689 rtx label = gen_label_rtx ();
15690
15691 emit_label (label);
15692
15693 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15694 operands[1], operands[2]));
15695 ix86_emit_fp_unordered_jump (label);
15696
15697 emit_move_insn (operands[0], operands[1]);
15698 DONE;
15699 })
15700
15701 (define_expand "remainder<mode>3"
15702 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15703 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15704 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15705 "TARGET_USE_FANCY_MATH_387"
15706 {
15707 rtx label = gen_label_rtx ();
15708
15709 rtx op1 = gen_reg_rtx (XFmode);
15710 rtx op2 = gen_reg_rtx (XFmode);
15711
15712 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15713 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15714
15715 emit_label (label);
15716
15717 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15718 ix86_emit_fp_unordered_jump (label);
15719
15720 /* Truncate the result properly for strict SSE math. */
15721 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15722 && !TARGET_MIX_SSE_I387)
15723 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15724 else
15725 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15726
15727 DONE;
15728 })
15729
15730 (define_insn "*sinxf2_i387"
15731 [(set (match_operand:XF 0 "register_operand" "=f")
15732 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15733 "TARGET_USE_FANCY_MATH_387
15734 && flag_unsafe_math_optimizations"
15735 "fsin"
15736 [(set_attr "type" "fpspc")
15737 (set_attr "mode" "XF")])
15738
15739 (define_insn "*sin_extend<mode>xf2_i387"
15740 [(set (match_operand:XF 0 "register_operand" "=f")
15741 (unspec:XF [(float_extend:XF
15742 (match_operand:X87MODEF12 1 "register_operand" "0"))]
15743 UNSPEC_SIN))]
15744 "TARGET_USE_FANCY_MATH_387
15745 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15746 || TARGET_MIX_SSE_I387)
15747 && flag_unsafe_math_optimizations"
15748 "fsin"
15749 [(set_attr "type" "fpspc")
15750 (set_attr "mode" "XF")])
15751
15752 (define_insn "*cosxf2_i387"
15753 [(set (match_operand:XF 0 "register_operand" "=f")
15754 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15755 "TARGET_USE_FANCY_MATH_387
15756 && flag_unsafe_math_optimizations"
15757 "fcos"
15758 [(set_attr "type" "fpspc")
15759 (set_attr "mode" "XF")])
15760
15761 (define_insn "*cos_extend<mode>xf2_i387"
15762 [(set (match_operand:XF 0 "register_operand" "=f")
15763 (unspec:XF [(float_extend:XF
15764 (match_operand:X87MODEF12 1 "register_operand" "0"))]
15765 UNSPEC_COS))]
15766 "TARGET_USE_FANCY_MATH_387
15767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15768 || TARGET_MIX_SSE_I387)
15769 && flag_unsafe_math_optimizations"
15770 "fcos"
15771 [(set_attr "type" "fpspc")
15772 (set_attr "mode" "XF")])
15773
15774 ;; When sincos pattern is defined, sin and cos builtin functions will be
15775 ;; expanded to sincos pattern with one of its outputs left unused.
15776 ;; CSE pass will figure out if two sincos patterns can be combined,
15777 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15778 ;; depending on the unused output.
15779
15780 (define_insn "sincosxf3"
15781 [(set (match_operand:XF 0 "register_operand" "=f")
15782 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15783 UNSPEC_SINCOS_COS))
15784 (set (match_operand:XF 1 "register_operand" "=u")
15785 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15786 "TARGET_USE_FANCY_MATH_387
15787 && flag_unsafe_math_optimizations"
15788 "fsincos"
15789 [(set_attr "type" "fpspc")
15790 (set_attr "mode" "XF")])
15791
15792 (define_split
15793 [(set (match_operand:XF 0 "register_operand" "")
15794 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15795 UNSPEC_SINCOS_COS))
15796 (set (match_operand:XF 1 "register_operand" "")
15797 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15798 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15799 && !reload_completed && !reload_in_progress"
15800 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15801 "")
15802
15803 (define_split
15804 [(set (match_operand:XF 0 "register_operand" "")
15805 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15806 UNSPEC_SINCOS_COS))
15807 (set (match_operand:XF 1 "register_operand" "")
15808 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15809 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15810 && !reload_completed && !reload_in_progress"
15811 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15812 "")
15813
15814 (define_insn "sincos_extend<mode>xf3_i387"
15815 [(set (match_operand:XF 0 "register_operand" "=f")
15816 (unspec:XF [(float_extend:XF
15817 (match_operand:X87MODEF12 2 "register_operand" "0"))]
15818 UNSPEC_SINCOS_COS))
15819 (set (match_operand:XF 1 "register_operand" "=u")
15820 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15821 "TARGET_USE_FANCY_MATH_387
15822 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15823 || TARGET_MIX_SSE_I387)
15824 && flag_unsafe_math_optimizations"
15825 "fsincos"
15826 [(set_attr "type" "fpspc")
15827 (set_attr "mode" "XF")])
15828
15829 (define_split
15830 [(set (match_operand:XF 0 "register_operand" "")
15831 (unspec:XF [(float_extend:XF
15832 (match_operand:X87MODEF12 2 "register_operand" ""))]
15833 UNSPEC_SINCOS_COS))
15834 (set (match_operand:XF 1 "register_operand" "")
15835 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15836 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15837 && !reload_completed && !reload_in_progress"
15838 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15839 "")
15840
15841 (define_split
15842 [(set (match_operand:XF 0 "register_operand" "")
15843 (unspec:XF [(float_extend:XF
15844 (match_operand:X87MODEF12 2 "register_operand" ""))]
15845 UNSPEC_SINCOS_COS))
15846 (set (match_operand:XF 1 "register_operand" "")
15847 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15848 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15849 && !reload_completed && !reload_in_progress"
15850 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15851 "")
15852
15853 (define_expand "sincos<mode>3"
15854 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15855 (use (match_operand:X87MODEF12 1 "register_operand" ""))
15856 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15857 "TARGET_USE_FANCY_MATH_387
15858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15859 || TARGET_MIX_SSE_I387)
15860 && flag_unsafe_math_optimizations"
15861 {
15862 rtx op0 = gen_reg_rtx (XFmode);
15863 rtx op1 = gen_reg_rtx (XFmode);
15864
15865 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15866 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15867 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15868 DONE;
15869 })
15870
15871 (define_insn "fptanxf4_i387"
15872 [(set (match_operand:XF 0 "register_operand" "=f")
15873 (match_operand:XF 3 "const_double_operand" "F"))
15874 (set (match_operand:XF 1 "register_operand" "=u")
15875 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15876 UNSPEC_TAN))]
15877 "TARGET_USE_FANCY_MATH_387
15878 && flag_unsafe_math_optimizations
15879 && standard_80387_constant_p (operands[3]) == 2"
15880 "fptan"
15881 [(set_attr "type" "fpspc")
15882 (set_attr "mode" "XF")])
15883
15884 (define_insn "fptan_extend<mode>xf4_i387"
15885 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15886 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
15887 (set (match_operand:XF 1 "register_operand" "=u")
15888 (unspec:XF [(float_extend:XF
15889 (match_operand:X87MODEF12 2 "register_operand" "0"))]
15890 UNSPEC_TAN))]
15891 "TARGET_USE_FANCY_MATH_387
15892 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15893 || TARGET_MIX_SSE_I387)
15894 && flag_unsafe_math_optimizations
15895 && standard_80387_constant_p (operands[3]) == 2"
15896 "fptan"
15897 [(set_attr "type" "fpspc")
15898 (set_attr "mode" "XF")])
15899
15900 (define_expand "tanxf2"
15901 [(use (match_operand:XF 0 "register_operand" ""))
15902 (use (match_operand:XF 1 "register_operand" ""))]
15903 "TARGET_USE_FANCY_MATH_387
15904 && flag_unsafe_math_optimizations"
15905 {
15906 rtx one = gen_reg_rtx (XFmode);
15907 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15908
15909 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15910 DONE;
15911 })
15912
15913 (define_expand "tan<mode>2"
15914 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15915 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
15916 "TARGET_USE_FANCY_MATH_387
15917 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15918 || TARGET_MIX_SSE_I387)
15919 && flag_unsafe_math_optimizations"
15920 {
15921 rtx op0 = gen_reg_rtx (XFmode);
15922
15923 rtx one = gen_reg_rtx (<MODE>mode);
15924 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15925
15926 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15927 operands[1], op2));
15928 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15929 DONE;
15930 })
15931
15932 (define_insn "*fpatanxf3_i387"
15933 [(set (match_operand:XF 0 "register_operand" "=f")
15934 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15935 (match_operand:XF 2 "register_operand" "u")]
15936 UNSPEC_FPATAN))
15937 (clobber (match_scratch:XF 3 "=2"))]
15938 "TARGET_USE_FANCY_MATH_387
15939 && flag_unsafe_math_optimizations"
15940 "fpatan"
15941 [(set_attr "type" "fpspc")
15942 (set_attr "mode" "XF")])
15943
15944 (define_insn "fpatan_extend<mode>xf3_i387"
15945 [(set (match_operand:XF 0 "register_operand" "=f")
15946 (unspec:XF [(float_extend:XF
15947 (match_operand:X87MODEF12 1 "register_operand" "0"))
15948 (float_extend:XF
15949 (match_operand:X87MODEF12 2 "register_operand" "u"))]
15950 UNSPEC_FPATAN))
15951 (clobber (match_scratch:XF 3 "=2"))]
15952 "TARGET_USE_FANCY_MATH_387
15953 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15954 || TARGET_MIX_SSE_I387)
15955 && flag_unsafe_math_optimizations"
15956 "fpatan"
15957 [(set_attr "type" "fpspc")
15958 (set_attr "mode" "XF")])
15959
15960 (define_expand "atan2xf3"
15961 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15962 (unspec:XF [(match_operand:XF 2 "register_operand" "")
15963 (match_operand:XF 1 "register_operand" "")]
15964 UNSPEC_FPATAN))
15965 (clobber (match_scratch:XF 3 ""))])]
15966 "TARGET_USE_FANCY_MATH_387
15967 && flag_unsafe_math_optimizations"
15968 "")
15969
15970 (define_expand "atan2<mode>3"
15971 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15972 (use (match_operand:X87MODEF12 1 "register_operand" ""))
15973 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15974 "TARGET_USE_FANCY_MATH_387
15975 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15976 || TARGET_MIX_SSE_I387)
15977 && flag_unsafe_math_optimizations"
15978 {
15979 rtx op0 = gen_reg_rtx (XFmode);
15980
15981 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15982 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15983 DONE;
15984 })
15985
15986 (define_expand "atanxf2"
15987 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15988 (unspec:XF [(match_dup 2)
15989 (match_operand:XF 1 "register_operand" "")]
15990 UNSPEC_FPATAN))
15991 (clobber (match_scratch:XF 3 ""))])]
15992 "TARGET_USE_FANCY_MATH_387
15993 && flag_unsafe_math_optimizations"
15994 {
15995 operands[2] = gen_reg_rtx (XFmode);
15996 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15997 })
15998
15999 (define_expand "atan<mode>2"
16000 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16001 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16002 "TARGET_USE_FANCY_MATH_387
16003 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16004 || TARGET_MIX_SSE_I387)
16005 && flag_unsafe_math_optimizations"
16006 {
16007 rtx op0 = gen_reg_rtx (XFmode);
16008
16009 rtx op2 = gen_reg_rtx (<MODE>mode);
16010 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16011
16012 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16013 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16014 DONE;
16015 })
16016
16017 (define_expand "asinxf2"
16018 [(set (match_dup 2)
16019 (mult:XF (match_operand:XF 1 "register_operand" "")
16020 (match_dup 1)))
16021 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16022 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16023 (parallel [(set (match_operand:XF 0 "register_operand" "")
16024 (unspec:XF [(match_dup 5) (match_dup 1)]
16025 UNSPEC_FPATAN))
16026 (clobber (match_scratch:XF 6 ""))])]
16027 "TARGET_USE_FANCY_MATH_387
16028 && flag_unsafe_math_optimizations && !optimize_size"
16029 {
16030 int i;
16031
16032 for (i = 2; i < 6; i++)
16033 operands[i] = gen_reg_rtx (XFmode);
16034
16035 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16036 })
16037
16038 (define_expand "asin<mode>2"
16039 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16040 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16041 "TARGET_USE_FANCY_MATH_387
16042 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16043 || TARGET_MIX_SSE_I387)
16044 && flag_unsafe_math_optimizations && !optimize_size"
16045 {
16046 rtx op0 = gen_reg_rtx (XFmode);
16047 rtx op1 = gen_reg_rtx (XFmode);
16048
16049 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16050 emit_insn (gen_asinxf2 (op0, op1));
16051 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16052 DONE;
16053 })
16054
16055 (define_expand "acosxf2"
16056 [(set (match_dup 2)
16057 (mult:XF (match_operand:XF 1 "register_operand" "")
16058 (match_dup 1)))
16059 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16060 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16061 (parallel [(set (match_operand:XF 0 "register_operand" "")
16062 (unspec:XF [(match_dup 1) (match_dup 5)]
16063 UNSPEC_FPATAN))
16064 (clobber (match_scratch:XF 6 ""))])]
16065 "TARGET_USE_FANCY_MATH_387
16066 && flag_unsafe_math_optimizations && !optimize_size"
16067 {
16068 int i;
16069
16070 for (i = 2; i < 6; i++)
16071 operands[i] = gen_reg_rtx (XFmode);
16072
16073 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16074 })
16075
16076 (define_expand "acos<mode>2"
16077 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16078 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16079 "TARGET_USE_FANCY_MATH_387
16080 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16081 || TARGET_MIX_SSE_I387)
16082 && flag_unsafe_math_optimizations && !optimize_size"
16083 {
16084 rtx op0 = gen_reg_rtx (XFmode);
16085 rtx op1 = gen_reg_rtx (XFmode);
16086
16087 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16088 emit_insn (gen_acosxf2 (op0, op1));
16089 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16090 DONE;
16091 })
16092
16093 (define_insn "fyl2xxf3_i387"
16094 [(set (match_operand:XF 0 "register_operand" "=f")
16095 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16096 (match_operand:XF 2 "register_operand" "u")]
16097 UNSPEC_FYL2X))
16098 (clobber (match_scratch:XF 3 "=2"))]
16099 "TARGET_USE_FANCY_MATH_387
16100 && flag_unsafe_math_optimizations"
16101 "fyl2x"
16102 [(set_attr "type" "fpspc")
16103 (set_attr "mode" "XF")])
16104
16105 (define_insn "fyl2x_extend<mode>xf3_i387"
16106 [(set (match_operand:XF 0 "register_operand" "=f")
16107 (unspec:XF [(float_extend:XF
16108 (match_operand:X87MODEF12 1 "register_operand" "0"))
16109 (match_operand:XF 2 "register_operand" "u")]
16110 UNSPEC_FYL2X))
16111 (clobber (match_scratch:XF 3 "=2"))]
16112 "TARGET_USE_FANCY_MATH_387
16113 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16114 || TARGET_MIX_SSE_I387)
16115 && flag_unsafe_math_optimizations"
16116 "fyl2x"
16117 [(set_attr "type" "fpspc")
16118 (set_attr "mode" "XF")])
16119
16120 (define_expand "logxf2"
16121 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16122 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16123 (match_dup 2)] UNSPEC_FYL2X))
16124 (clobber (match_scratch:XF 3 ""))])]
16125 "TARGET_USE_FANCY_MATH_387
16126 && flag_unsafe_math_optimizations"
16127 {
16128 operands[2] = gen_reg_rtx (XFmode);
16129 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16130 })
16131
16132 (define_expand "log<mode>2"
16133 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16134 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16135 "TARGET_USE_FANCY_MATH_387
16136 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16137 || TARGET_MIX_SSE_I387)
16138 && flag_unsafe_math_optimizations"
16139 {
16140 rtx op0 = gen_reg_rtx (XFmode);
16141
16142 rtx op2 = gen_reg_rtx (XFmode);
16143 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16144
16145 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16147 DONE;
16148 })
16149
16150 (define_expand "log10xf2"
16151 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16152 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16153 (match_dup 2)] UNSPEC_FYL2X))
16154 (clobber (match_scratch:XF 3 ""))])]
16155 "TARGET_USE_FANCY_MATH_387
16156 && flag_unsafe_math_optimizations"
16157 {
16158 operands[2] = gen_reg_rtx (XFmode);
16159 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16160 })
16161
16162 (define_expand "log10<mode>2"
16163 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16164 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16165 "TARGET_USE_FANCY_MATH_387
16166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16167 || TARGET_MIX_SSE_I387)
16168 && flag_unsafe_math_optimizations"
16169 {
16170 rtx op0 = gen_reg_rtx (XFmode);
16171
16172 rtx op2 = gen_reg_rtx (XFmode);
16173 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16174
16175 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16176 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16177 DONE;
16178 })
16179
16180 (define_expand "log2xf2"
16181 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16182 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16183 (match_dup 2)] UNSPEC_FYL2X))
16184 (clobber (match_scratch:XF 3 ""))])]
16185 "TARGET_USE_FANCY_MATH_387
16186 && flag_unsafe_math_optimizations"
16187 {
16188 operands[2] = gen_reg_rtx (XFmode);
16189 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16190 })
16191
16192 (define_expand "log2<mode>2"
16193 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16194 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16195 "TARGET_USE_FANCY_MATH_387
16196 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16197 || TARGET_MIX_SSE_I387)
16198 && flag_unsafe_math_optimizations"
16199 {
16200 rtx op0 = gen_reg_rtx (XFmode);
16201
16202 rtx op2 = gen_reg_rtx (XFmode);
16203 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16204
16205 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16206 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16207 DONE;
16208 })
16209
16210 (define_insn "fyl2xp1xf3_i387"
16211 [(set (match_operand:XF 0 "register_operand" "=f")
16212 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16213 (match_operand:XF 2 "register_operand" "u")]
16214 UNSPEC_FYL2XP1))
16215 (clobber (match_scratch:XF 3 "=2"))]
16216 "TARGET_USE_FANCY_MATH_387
16217 && flag_unsafe_math_optimizations"
16218 "fyl2xp1"
16219 [(set_attr "type" "fpspc")
16220 (set_attr "mode" "XF")])
16221
16222 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16223 [(set (match_operand:XF 0 "register_operand" "=f")
16224 (unspec:XF [(float_extend:XF
16225 (match_operand:X87MODEF12 1 "register_operand" "0"))
16226 (match_operand:XF 2 "register_operand" "u")]
16227 UNSPEC_FYL2XP1))
16228 (clobber (match_scratch:XF 3 "=2"))]
16229 "TARGET_USE_FANCY_MATH_387
16230 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16231 || TARGET_MIX_SSE_I387)
16232 && flag_unsafe_math_optimizations"
16233 "fyl2xp1"
16234 [(set_attr "type" "fpspc")
16235 (set_attr "mode" "XF")])
16236
16237 (define_expand "log1pxf2"
16238 [(use (match_operand:XF 0 "register_operand" ""))
16239 (use (match_operand:XF 1 "register_operand" ""))]
16240 "TARGET_USE_FANCY_MATH_387
16241 && flag_unsafe_math_optimizations && !optimize_size"
16242 {
16243 ix86_emit_i387_log1p (operands[0], operands[1]);
16244 DONE;
16245 })
16246
16247 (define_expand "log1p<mode>2"
16248 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16249 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16250 "TARGET_USE_FANCY_MATH_387
16251 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16252 || TARGET_MIX_SSE_I387)
16253 && flag_unsafe_math_optimizations && !optimize_size"
16254 {
16255 rtx op0 = gen_reg_rtx (XFmode);
16256
16257 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16258
16259 ix86_emit_i387_log1p (op0, operands[1]);
16260 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16261 DONE;
16262 })
16263
16264 (define_insn "fxtractxf3_i387"
16265 [(set (match_operand:XF 0 "register_operand" "=f")
16266 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16267 UNSPEC_XTRACT_FRACT))
16268 (set (match_operand:XF 1 "register_operand" "=u")
16269 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16270 "TARGET_USE_FANCY_MATH_387
16271 && flag_unsafe_math_optimizations"
16272 "fxtract"
16273 [(set_attr "type" "fpspc")
16274 (set_attr "mode" "XF")])
16275
16276 (define_insn "fxtract_extend<mode>xf3_i387"
16277 [(set (match_operand:XF 0 "register_operand" "=f")
16278 (unspec:XF [(float_extend:XF
16279 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16280 UNSPEC_XTRACT_FRACT))
16281 (set (match_operand:XF 1 "register_operand" "=u")
16282 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16283 "TARGET_USE_FANCY_MATH_387
16284 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16285 || TARGET_MIX_SSE_I387)
16286 && flag_unsafe_math_optimizations"
16287 "fxtract"
16288 [(set_attr "type" "fpspc")
16289 (set_attr "mode" "XF")])
16290
16291 (define_expand "logbxf2"
16292 [(parallel [(set (match_dup 2)
16293 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16294 UNSPEC_XTRACT_FRACT))
16295 (set (match_operand:XF 0 "register_operand" "")
16296 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16297 "TARGET_USE_FANCY_MATH_387
16298 && flag_unsafe_math_optimizations"
16299 {
16300 operands[2] = gen_reg_rtx (XFmode);
16301 })
16302
16303 (define_expand "logb<mode>2"
16304 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16305 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16306 "TARGET_USE_FANCY_MATH_387
16307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16308 || TARGET_MIX_SSE_I387)
16309 && flag_unsafe_math_optimizations"
16310 {
16311 rtx op0 = gen_reg_rtx (XFmode);
16312 rtx op1 = gen_reg_rtx (XFmode);
16313
16314 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16315 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16316 DONE;
16317 })
16318
16319 (define_expand "ilogbxf2"
16320 [(use (match_operand:SI 0 "register_operand" ""))
16321 (use (match_operand:XF 1 "register_operand" ""))]
16322 "TARGET_USE_FANCY_MATH_387
16323 && flag_unsafe_math_optimizations && !optimize_size"
16324 {
16325 rtx op0 = gen_reg_rtx (XFmode);
16326 rtx op1 = gen_reg_rtx (XFmode);
16327
16328 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16329 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16330 DONE;
16331 })
16332
16333 (define_expand "ilogb<mode>2"
16334 [(use (match_operand:SI 0 "register_operand" ""))
16335 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16336 "TARGET_USE_FANCY_MATH_387
16337 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16338 || TARGET_MIX_SSE_I387)
16339 && flag_unsafe_math_optimizations && !optimize_size"
16340 {
16341 rtx op0 = gen_reg_rtx (XFmode);
16342 rtx op1 = gen_reg_rtx (XFmode);
16343
16344 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16345 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16346 DONE;
16347 })
16348
16349 (define_insn "*f2xm1xf2_i387"
16350 [(set (match_operand:XF 0 "register_operand" "=f")
16351 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16352 UNSPEC_F2XM1))]
16353 "TARGET_USE_FANCY_MATH_387
16354 && flag_unsafe_math_optimizations"
16355 "f2xm1"
16356 [(set_attr "type" "fpspc")
16357 (set_attr "mode" "XF")])
16358
16359 (define_insn "*fscalexf4_i387"
16360 [(set (match_operand:XF 0 "register_operand" "=f")
16361 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16362 (match_operand:XF 3 "register_operand" "1")]
16363 UNSPEC_FSCALE_FRACT))
16364 (set (match_operand:XF 1 "register_operand" "=u")
16365 (unspec:XF [(match_dup 2) (match_dup 3)]
16366 UNSPEC_FSCALE_EXP))]
16367 "TARGET_USE_FANCY_MATH_387
16368 && flag_unsafe_math_optimizations"
16369 "fscale"
16370 [(set_attr "type" "fpspc")
16371 (set_attr "mode" "XF")])
16372
16373 (define_expand "expNcorexf3"
16374 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16375 (match_operand:XF 2 "register_operand" "")))
16376 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16377 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16378 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16379 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16380 (parallel [(set (match_operand:XF 0 "register_operand" "")
16381 (unspec:XF [(match_dup 8) (match_dup 4)]
16382 UNSPEC_FSCALE_FRACT))
16383 (set (match_dup 9)
16384 (unspec:XF [(match_dup 8) (match_dup 4)]
16385 UNSPEC_FSCALE_EXP))])]
16386 "TARGET_USE_FANCY_MATH_387
16387 && flag_unsafe_math_optimizations && !optimize_size"
16388 {
16389 int i;
16390
16391 for (i = 3; i < 10; i++)
16392 operands[i] = gen_reg_rtx (XFmode);
16393
16394 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16395 })
16396
16397 (define_expand "expxf2"
16398 [(use (match_operand:XF 0 "register_operand" ""))
16399 (use (match_operand:XF 1 "register_operand" ""))]
16400 "TARGET_USE_FANCY_MATH_387
16401 && flag_unsafe_math_optimizations && !optimize_size"
16402 {
16403 rtx op2 = gen_reg_rtx (XFmode);
16404 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16405
16406 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16407 DONE;
16408 })
16409
16410 (define_expand "exp<mode>2"
16411 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16412 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16413 "TARGET_USE_FANCY_MATH_387
16414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16415 || TARGET_MIX_SSE_I387)
16416 && flag_unsafe_math_optimizations && !optimize_size"
16417 {
16418 rtx op0 = gen_reg_rtx (XFmode);
16419 rtx op1 = gen_reg_rtx (XFmode);
16420
16421 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16422 emit_insn (gen_expxf2 (op0, op1));
16423 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16424 DONE;
16425 })
16426
16427 (define_expand "exp10xf2"
16428 [(use (match_operand:XF 0 "register_operand" ""))
16429 (use (match_operand:XF 1 "register_operand" ""))]
16430 "TARGET_USE_FANCY_MATH_387
16431 && flag_unsafe_math_optimizations && !optimize_size"
16432 {
16433 rtx op2 = gen_reg_rtx (XFmode);
16434 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16435
16436 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16437 DONE;
16438 })
16439
16440 (define_expand "exp10<mode>2"
16441 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16442 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16443 "TARGET_USE_FANCY_MATH_387
16444 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16445 || TARGET_MIX_SSE_I387)
16446 && flag_unsafe_math_optimizations && !optimize_size"
16447 {
16448 rtx op0 = gen_reg_rtx (XFmode);
16449 rtx op1 = gen_reg_rtx (XFmode);
16450
16451 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16452 emit_insn (gen_exp10xf2 (op0, op1));
16453 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16454 DONE;
16455 })
16456
16457 (define_expand "exp2xf2"
16458 [(use (match_operand:XF 0 "register_operand" ""))
16459 (use (match_operand:XF 1 "register_operand" ""))]
16460 "TARGET_USE_FANCY_MATH_387
16461 && flag_unsafe_math_optimizations && !optimize_size"
16462 {
16463 rtx op2 = gen_reg_rtx (XFmode);
16464 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16465
16466 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16467 DONE;
16468 })
16469
16470 (define_expand "exp2<mode>2"
16471 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16472 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16473 "TARGET_USE_FANCY_MATH_387
16474 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16475 || TARGET_MIX_SSE_I387)
16476 && flag_unsafe_math_optimizations && !optimize_size"
16477 {
16478 rtx op0 = gen_reg_rtx (XFmode);
16479 rtx op1 = gen_reg_rtx (XFmode);
16480
16481 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16482 emit_insn (gen_exp2xf2 (op0, op1));
16483 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16484 DONE;
16485 })
16486
16487 (define_expand "expm1xf2"
16488 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16489 (match_dup 2)))
16490 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16491 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16492 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16493 (parallel [(set (match_dup 7)
16494 (unspec:XF [(match_dup 6) (match_dup 4)]
16495 UNSPEC_FSCALE_FRACT))
16496 (set (match_dup 8)
16497 (unspec:XF [(match_dup 6) (match_dup 4)]
16498 UNSPEC_FSCALE_EXP))])
16499 (parallel [(set (match_dup 10)
16500 (unspec:XF [(match_dup 9) (match_dup 8)]
16501 UNSPEC_FSCALE_FRACT))
16502 (set (match_dup 11)
16503 (unspec:XF [(match_dup 9) (match_dup 8)]
16504 UNSPEC_FSCALE_EXP))])
16505 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16506 (set (match_operand:XF 0 "register_operand" "")
16507 (plus:XF (match_dup 12) (match_dup 7)))]
16508 "TARGET_USE_FANCY_MATH_387
16509 && flag_unsafe_math_optimizations && !optimize_size"
16510 {
16511 int i;
16512
16513 for (i = 2; i < 13; i++)
16514 operands[i] = gen_reg_rtx (XFmode);
16515
16516 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16517 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16518 })
16519
16520 (define_expand "expm1<mode>2"
16521 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16522 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16523 "TARGET_USE_FANCY_MATH_387
16524 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16525 || TARGET_MIX_SSE_I387)
16526 && flag_unsafe_math_optimizations && !optimize_size"
16527 {
16528 rtx op0 = gen_reg_rtx (XFmode);
16529 rtx op1 = gen_reg_rtx (XFmode);
16530
16531 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16532 emit_insn (gen_expm1xf2 (op0, op1));
16533 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16534 DONE;
16535 })
16536
16537 (define_expand "ldexpxf3"
16538 [(set (match_dup 3)
16539 (float:XF (match_operand:SI 2 "register_operand" "")))
16540 (parallel [(set (match_operand:XF 0 " register_operand" "")
16541 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16542 (match_dup 3)]
16543 UNSPEC_FSCALE_FRACT))
16544 (set (match_dup 4)
16545 (unspec:XF [(match_dup 1) (match_dup 3)]
16546 UNSPEC_FSCALE_EXP))])]
16547 "TARGET_USE_FANCY_MATH_387
16548 && flag_unsafe_math_optimizations && !optimize_size"
16549 {
16550 operands[3] = gen_reg_rtx (XFmode);
16551 operands[4] = gen_reg_rtx (XFmode);
16552 })
16553
16554 (define_expand "ldexp<mode>3"
16555 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16556 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16557 (use (match_operand:SI 2 "register_operand" ""))]
16558 "TARGET_USE_FANCY_MATH_387
16559 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16560 || TARGET_MIX_SSE_I387)
16561 && flag_unsafe_math_optimizations && !optimize_size"
16562 {
16563 rtx op0 = gen_reg_rtx (XFmode);
16564 rtx op1 = gen_reg_rtx (XFmode);
16565
16566 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16567 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16568 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16569 DONE;
16570 })
16571 \f
16572
16573 (define_insn "frndintxf2"
16574 [(set (match_operand:XF 0 "register_operand" "=f")
16575 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16576 UNSPEC_FRNDINT))]
16577 "TARGET_USE_FANCY_MATH_387
16578 && flag_unsafe_math_optimizations"
16579 "frndint"
16580 [(set_attr "type" "fpspc")
16581 (set_attr "mode" "XF")])
16582
16583 (define_expand "rintdf2"
16584 [(use (match_operand:DF 0 "register_operand" ""))
16585 (use (match_operand:DF 1 "register_operand" ""))]
16586 "(TARGET_USE_FANCY_MATH_387
16587 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16588 && flag_unsafe_math_optimizations)
16589 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16590 && !flag_trapping_math
16591 && !optimize_size)"
16592 {
16593 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16594 && !flag_trapping_math
16595 && !optimize_size)
16596 ix86_expand_rint (operand0, operand1);
16597 else
16598 {
16599 rtx op0 = gen_reg_rtx (XFmode);
16600 rtx op1 = gen_reg_rtx (XFmode);
16601
16602 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16603 emit_insn (gen_frndintxf2 (op0, op1));
16604
16605 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16606 }
16607 DONE;
16608 })
16609
16610 (define_expand "rintsf2"
16611 [(use (match_operand:SF 0 "register_operand" ""))
16612 (use (match_operand:SF 1 "register_operand" ""))]
16613 "(TARGET_USE_FANCY_MATH_387
16614 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16615 && flag_unsafe_math_optimizations)
16616 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16617 && !flag_trapping_math
16618 && !optimize_size)"
16619 {
16620 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16621 && !flag_trapping_math
16622 && !optimize_size)
16623 ix86_expand_rint (operand0, operand1);
16624 else
16625 {
16626 rtx op0 = gen_reg_rtx (XFmode);
16627 rtx op1 = gen_reg_rtx (XFmode);
16628
16629 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16630 emit_insn (gen_frndintxf2 (op0, op1));
16631
16632 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16633 }
16634 DONE;
16635 })
16636
16637 (define_expand "rintxf2"
16638 [(use (match_operand:XF 0 "register_operand" ""))
16639 (use (match_operand:XF 1 "register_operand" ""))]
16640 "TARGET_USE_FANCY_MATH_387
16641 && flag_unsafe_math_optimizations && !optimize_size"
16642 {
16643 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16644 DONE;
16645 })
16646
16647 (define_expand "roundsf2"
16648 [(match_operand:SF 0 "register_operand" "")
16649 (match_operand:SF 1 "nonimmediate_operand" "")]
16650 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16651 && !flag_trapping_math && !flag_rounding_math
16652 && !optimize_size"
16653 {
16654 ix86_expand_round (operand0, operand1);
16655 DONE;
16656 })
16657
16658 (define_expand "rounddf2"
16659 [(match_operand:DF 0 "register_operand" "")
16660 (match_operand:DF 1 "nonimmediate_operand" "")]
16661 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16662 && !flag_trapping_math && !flag_rounding_math
16663 && !optimize_size"
16664 {
16665 if (TARGET_64BIT)
16666 ix86_expand_round (operand0, operand1);
16667 else
16668 ix86_expand_rounddf_32 (operand0, operand1);
16669 DONE;
16670 })
16671
16672 (define_insn_and_split "*fistdi2_1"
16673 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16674 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16675 UNSPEC_FIST))]
16676 "TARGET_USE_FANCY_MATH_387
16677 && !(reload_completed || reload_in_progress)"
16678 "#"
16679 "&& 1"
16680 [(const_int 0)]
16681 {
16682 if (memory_operand (operands[0], VOIDmode))
16683 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16684 else
16685 {
16686 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16687 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16688 operands[2]));
16689 }
16690 DONE;
16691 }
16692 [(set_attr "type" "fpspc")
16693 (set_attr "mode" "DI")])
16694
16695 (define_insn "fistdi2"
16696 [(set (match_operand:DI 0 "memory_operand" "=m")
16697 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16698 UNSPEC_FIST))
16699 (clobber (match_scratch:XF 2 "=&1f"))]
16700 "TARGET_USE_FANCY_MATH_387"
16701 "* return output_fix_trunc (insn, operands, 0);"
16702 [(set_attr "type" "fpspc")
16703 (set_attr "mode" "DI")])
16704
16705 (define_insn "fistdi2_with_temp"
16706 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16707 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16708 UNSPEC_FIST))
16709 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16710 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16711 "TARGET_USE_FANCY_MATH_387"
16712 "#"
16713 [(set_attr "type" "fpspc")
16714 (set_attr "mode" "DI")])
16715
16716 (define_split
16717 [(set (match_operand:DI 0 "register_operand" "")
16718 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16719 UNSPEC_FIST))
16720 (clobber (match_operand:DI 2 "memory_operand" ""))
16721 (clobber (match_scratch 3 ""))]
16722 "reload_completed"
16723 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16724 (clobber (match_dup 3))])
16725 (set (match_dup 0) (match_dup 2))]
16726 "")
16727
16728 (define_split
16729 [(set (match_operand:DI 0 "memory_operand" "")
16730 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16731 UNSPEC_FIST))
16732 (clobber (match_operand:DI 2 "memory_operand" ""))
16733 (clobber (match_scratch 3 ""))]
16734 "reload_completed"
16735 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16736 (clobber (match_dup 3))])]
16737 "")
16738
16739 (define_insn_and_split "*fist<mode>2_1"
16740 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16741 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16742 UNSPEC_FIST))]
16743 "TARGET_USE_FANCY_MATH_387
16744 && !(reload_completed || reload_in_progress)"
16745 "#"
16746 "&& 1"
16747 [(const_int 0)]
16748 {
16749 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16750 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16751 operands[2]));
16752 DONE;
16753 }
16754 [(set_attr "type" "fpspc")
16755 (set_attr "mode" "<MODE>")])
16756
16757 (define_insn "fist<mode>2"
16758 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16759 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16760 UNSPEC_FIST))]
16761 "TARGET_USE_FANCY_MATH_387"
16762 "* return output_fix_trunc (insn, operands, 0);"
16763 [(set_attr "type" "fpspc")
16764 (set_attr "mode" "<MODE>")])
16765
16766 (define_insn "fist<mode>2_with_temp"
16767 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16768 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16769 UNSPEC_FIST))
16770 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16771 "TARGET_USE_FANCY_MATH_387"
16772 "#"
16773 [(set_attr "type" "fpspc")
16774 (set_attr "mode" "<MODE>")])
16775
16776 (define_split
16777 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16778 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16779 UNSPEC_FIST))
16780 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16781 "reload_completed"
16782 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16783 UNSPEC_FIST))
16784 (set (match_dup 0) (match_dup 2))]
16785 "")
16786
16787 (define_split
16788 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16789 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16790 UNSPEC_FIST))
16791 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16792 "reload_completed"
16793 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16794 UNSPEC_FIST))]
16795 "")
16796
16797 (define_expand "lrintxf<mode>2"
16798 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16799 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16800 UNSPEC_FIST))]
16801 "TARGET_USE_FANCY_MATH_387"
16802 "")
16803
16804 (define_expand "lrint<mode>di2"
16805 [(set (match_operand:DI 0 "nonimmediate_operand" "")
16806 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
16807 UNSPEC_FIX_NOTRUNC))]
16808 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
16809 "")
16810
16811 (define_expand "lrint<mode>si2"
16812 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16813 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
16814 UNSPEC_FIX_NOTRUNC))]
16815 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16816 "")
16817
16818 (define_expand "lround<mode>di2"
16819 [(match_operand:DI 0 "nonimmediate_operand" "")
16820 (match_operand:SSEMODEF 1 "register_operand" "")]
16821 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
16822 && !flag_trapping_math && !flag_rounding_math
16823 && !optimize_size"
16824 {
16825 ix86_expand_lround (operand0, operand1);
16826 DONE;
16827 })
16828
16829 (define_expand "lround<mode>si2"
16830 [(match_operand:SI 0 "nonimmediate_operand" "")
16831 (match_operand:SSEMODEF 1 "register_operand" "")]
16832 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16833 && !flag_trapping_math && !flag_rounding_math
16834 && !optimize_size"
16835 {
16836 ix86_expand_lround (operand0, operand1);
16837 DONE;
16838 })
16839
16840 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16841 (define_insn_and_split "frndintxf2_floor"
16842 [(set (match_operand:XF 0 "register_operand" "=f")
16843 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16844 UNSPEC_FRNDINT_FLOOR))
16845 (clobber (reg:CC FLAGS_REG))]
16846 "TARGET_USE_FANCY_MATH_387
16847 && flag_unsafe_math_optimizations
16848 && !(reload_completed || reload_in_progress)"
16849 "#"
16850 "&& 1"
16851 [(const_int 0)]
16852 {
16853 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16854
16855 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16856 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16857
16858 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16859 operands[2], operands[3]));
16860 DONE;
16861 }
16862 [(set_attr "type" "frndint")
16863 (set_attr "i387_cw" "floor")
16864 (set_attr "mode" "XF")])
16865
16866 (define_insn "frndintxf2_floor_i387"
16867 [(set (match_operand:XF 0 "register_operand" "=f")
16868 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16869 UNSPEC_FRNDINT_FLOOR))
16870 (use (match_operand:HI 2 "memory_operand" "m"))
16871 (use (match_operand:HI 3 "memory_operand" "m"))]
16872 "TARGET_USE_FANCY_MATH_387
16873 && flag_unsafe_math_optimizations"
16874 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16875 [(set_attr "type" "frndint")
16876 (set_attr "i387_cw" "floor")
16877 (set_attr "mode" "XF")])
16878
16879 (define_expand "floorxf2"
16880 [(use (match_operand:XF 0 "register_operand" ""))
16881 (use (match_operand:XF 1 "register_operand" ""))]
16882 "TARGET_USE_FANCY_MATH_387
16883 && flag_unsafe_math_optimizations && !optimize_size"
16884 {
16885 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16886 DONE;
16887 })
16888
16889 (define_expand "floordf2"
16890 [(use (match_operand:DF 0 "register_operand" ""))
16891 (use (match_operand:DF 1 "register_operand" ""))]
16892 "((TARGET_USE_FANCY_MATH_387
16893 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16894 && flag_unsafe_math_optimizations)
16895 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16896 && !flag_trapping_math))
16897 && !optimize_size"
16898 {
16899 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16900 && !flag_trapping_math)
16901 {
16902 if (TARGET_64BIT)
16903 ix86_expand_floorceil (operand0, operand1, true);
16904 else
16905 ix86_expand_floorceildf_32 (operand0, operand1, true);
16906 }
16907 else
16908 {
16909 rtx op0 = gen_reg_rtx (XFmode);
16910 rtx op1 = gen_reg_rtx (XFmode);
16911
16912 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16913 emit_insn (gen_frndintxf2_floor (op0, op1));
16914
16915 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16916 }
16917 DONE;
16918 })
16919
16920 (define_expand "floorsf2"
16921 [(use (match_operand:SF 0 "register_operand" ""))
16922 (use (match_operand:SF 1 "register_operand" ""))]
16923 "((TARGET_USE_FANCY_MATH_387
16924 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16925 && flag_unsafe_math_optimizations)
16926 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16927 && !flag_trapping_math))
16928 && !optimize_size"
16929 {
16930 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16931 && !flag_trapping_math)
16932 ix86_expand_floorceil (operand0, operand1, true);
16933 else
16934 {
16935 rtx op0 = gen_reg_rtx (XFmode);
16936 rtx op1 = gen_reg_rtx (XFmode);
16937
16938 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16939 emit_insn (gen_frndintxf2_floor (op0, op1));
16940
16941 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16942 }
16943 DONE;
16944 })
16945
16946 (define_insn_and_split "*fist<mode>2_floor_1"
16947 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16948 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16949 UNSPEC_FIST_FLOOR))
16950 (clobber (reg:CC FLAGS_REG))]
16951 "TARGET_USE_FANCY_MATH_387
16952 && flag_unsafe_math_optimizations
16953 && !(reload_completed || reload_in_progress)"
16954 "#"
16955 "&& 1"
16956 [(const_int 0)]
16957 {
16958 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16959
16960 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16961 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16962 if (memory_operand (operands[0], VOIDmode))
16963 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16964 operands[2], operands[3]));
16965 else
16966 {
16967 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16968 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16969 operands[2], operands[3],
16970 operands[4]));
16971 }
16972 DONE;
16973 }
16974 [(set_attr "type" "fistp")
16975 (set_attr "i387_cw" "floor")
16976 (set_attr "mode" "<MODE>")])
16977
16978 (define_insn "fistdi2_floor"
16979 [(set (match_operand:DI 0 "memory_operand" "=m")
16980 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16981 UNSPEC_FIST_FLOOR))
16982 (use (match_operand:HI 2 "memory_operand" "m"))
16983 (use (match_operand:HI 3 "memory_operand" "m"))
16984 (clobber (match_scratch:XF 4 "=&1f"))]
16985 "TARGET_USE_FANCY_MATH_387
16986 && flag_unsafe_math_optimizations"
16987 "* return output_fix_trunc (insn, operands, 0);"
16988 [(set_attr "type" "fistp")
16989 (set_attr "i387_cw" "floor")
16990 (set_attr "mode" "DI")])
16991
16992 (define_insn "fistdi2_floor_with_temp"
16993 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16994 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16995 UNSPEC_FIST_FLOOR))
16996 (use (match_operand:HI 2 "memory_operand" "m,m"))
16997 (use (match_operand:HI 3 "memory_operand" "m,m"))
16998 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16999 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17000 "TARGET_USE_FANCY_MATH_387
17001 && flag_unsafe_math_optimizations"
17002 "#"
17003 [(set_attr "type" "fistp")
17004 (set_attr "i387_cw" "floor")
17005 (set_attr "mode" "DI")])
17006
17007 (define_split
17008 [(set (match_operand:DI 0 "register_operand" "")
17009 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17010 UNSPEC_FIST_FLOOR))
17011 (use (match_operand:HI 2 "memory_operand" ""))
17012 (use (match_operand:HI 3 "memory_operand" ""))
17013 (clobber (match_operand:DI 4 "memory_operand" ""))
17014 (clobber (match_scratch 5 ""))]
17015 "reload_completed"
17016 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17017 (use (match_dup 2))
17018 (use (match_dup 3))
17019 (clobber (match_dup 5))])
17020 (set (match_dup 0) (match_dup 4))]
17021 "")
17022
17023 (define_split
17024 [(set (match_operand:DI 0 "memory_operand" "")
17025 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17026 UNSPEC_FIST_FLOOR))
17027 (use (match_operand:HI 2 "memory_operand" ""))
17028 (use (match_operand:HI 3 "memory_operand" ""))
17029 (clobber (match_operand:DI 4 "memory_operand" ""))
17030 (clobber (match_scratch 5 ""))]
17031 "reload_completed"
17032 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17033 (use (match_dup 2))
17034 (use (match_dup 3))
17035 (clobber (match_dup 5))])]
17036 "")
17037
17038 (define_insn "fist<mode>2_floor"
17039 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17040 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17041 UNSPEC_FIST_FLOOR))
17042 (use (match_operand:HI 2 "memory_operand" "m"))
17043 (use (match_operand:HI 3 "memory_operand" "m"))]
17044 "TARGET_USE_FANCY_MATH_387
17045 && flag_unsafe_math_optimizations"
17046 "* return output_fix_trunc (insn, operands, 0);"
17047 [(set_attr "type" "fistp")
17048 (set_attr "i387_cw" "floor")
17049 (set_attr "mode" "<MODE>")])
17050
17051 (define_insn "fist<mode>2_floor_with_temp"
17052 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17053 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17054 UNSPEC_FIST_FLOOR))
17055 (use (match_operand:HI 2 "memory_operand" "m,m"))
17056 (use (match_operand:HI 3 "memory_operand" "m,m"))
17057 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17058 "TARGET_USE_FANCY_MATH_387
17059 && flag_unsafe_math_optimizations"
17060 "#"
17061 [(set_attr "type" "fistp")
17062 (set_attr "i387_cw" "floor")
17063 (set_attr "mode" "<MODE>")])
17064
17065 (define_split
17066 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17067 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17068 UNSPEC_FIST_FLOOR))
17069 (use (match_operand:HI 2 "memory_operand" ""))
17070 (use (match_operand:HI 3 "memory_operand" ""))
17071 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17072 "reload_completed"
17073 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17074 UNSPEC_FIST_FLOOR))
17075 (use (match_dup 2))
17076 (use (match_dup 3))])
17077 (set (match_dup 0) (match_dup 4))]
17078 "")
17079
17080 (define_split
17081 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17082 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17083 UNSPEC_FIST_FLOOR))
17084 (use (match_operand:HI 2 "memory_operand" ""))
17085 (use (match_operand:HI 3 "memory_operand" ""))
17086 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17087 "reload_completed"
17088 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17089 UNSPEC_FIST_FLOOR))
17090 (use (match_dup 2))
17091 (use (match_dup 3))])]
17092 "")
17093
17094 (define_expand "lfloorxf<mode>2"
17095 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17096 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17097 UNSPEC_FIST_FLOOR))
17098 (clobber (reg:CC FLAGS_REG))])]
17099 "TARGET_USE_FANCY_MATH_387
17100 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17101 && flag_unsafe_math_optimizations"
17102 "")
17103
17104 (define_expand "lfloor<mode>di2"
17105 [(match_operand:DI 0 "nonimmediate_operand" "")
17106 (match_operand:SSEMODEF 1 "register_operand" "")]
17107 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17108 && !flag_trapping_math
17109 && !optimize_size"
17110 {
17111 ix86_expand_lfloorceil (operand0, operand1, true);
17112 DONE;
17113 })
17114
17115 (define_expand "lfloor<mode>si2"
17116 [(match_operand:SI 0 "nonimmediate_operand" "")
17117 (match_operand:SSEMODEF 1 "register_operand" "")]
17118 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17119 && !flag_trapping_math
17120 && (!optimize_size || !TARGET_64BIT)"
17121 {
17122 ix86_expand_lfloorceil (operand0, operand1, true);
17123 DONE;
17124 })
17125
17126 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17127 (define_insn_and_split "frndintxf2_ceil"
17128 [(set (match_operand:XF 0 "register_operand" "=f")
17129 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17130 UNSPEC_FRNDINT_CEIL))
17131 (clobber (reg:CC FLAGS_REG))]
17132 "TARGET_USE_FANCY_MATH_387
17133 && flag_unsafe_math_optimizations
17134 && !(reload_completed || reload_in_progress)"
17135 "#"
17136 "&& 1"
17137 [(const_int 0)]
17138 {
17139 ix86_optimize_mode_switching[I387_CEIL] = 1;
17140
17141 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17142 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17143
17144 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17145 operands[2], operands[3]));
17146 DONE;
17147 }
17148 [(set_attr "type" "frndint")
17149 (set_attr "i387_cw" "ceil")
17150 (set_attr "mode" "XF")])
17151
17152 (define_insn "frndintxf2_ceil_i387"
17153 [(set (match_operand:XF 0 "register_operand" "=f")
17154 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17155 UNSPEC_FRNDINT_CEIL))
17156 (use (match_operand:HI 2 "memory_operand" "m"))
17157 (use (match_operand:HI 3 "memory_operand" "m"))]
17158 "TARGET_USE_FANCY_MATH_387
17159 && flag_unsafe_math_optimizations"
17160 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17161 [(set_attr "type" "frndint")
17162 (set_attr "i387_cw" "ceil")
17163 (set_attr "mode" "XF")])
17164
17165 (define_expand "ceilxf2"
17166 [(use (match_operand:XF 0 "register_operand" ""))
17167 (use (match_operand:XF 1 "register_operand" ""))]
17168 "TARGET_USE_FANCY_MATH_387
17169 && flag_unsafe_math_optimizations && !optimize_size"
17170 {
17171 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17172 DONE;
17173 })
17174
17175 (define_expand "ceildf2"
17176 [(use (match_operand:DF 0 "register_operand" ""))
17177 (use (match_operand:DF 1 "register_operand" ""))]
17178 "((TARGET_USE_FANCY_MATH_387
17179 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17180 && flag_unsafe_math_optimizations)
17181 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17182 && !flag_trapping_math))
17183 && !optimize_size"
17184 {
17185 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17186 && !flag_trapping_math)
17187 {
17188 if (TARGET_64BIT)
17189 ix86_expand_floorceil (operand0, operand1, false);
17190 else
17191 ix86_expand_floorceildf_32 (operand0, operand1, false);
17192 }
17193 else
17194 {
17195 rtx op0 = gen_reg_rtx (XFmode);
17196 rtx op1 = gen_reg_rtx (XFmode);
17197
17198 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17199 emit_insn (gen_frndintxf2_ceil (op0, op1));
17200
17201 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17202 }
17203 DONE;
17204 })
17205
17206 (define_expand "ceilsf2"
17207 [(use (match_operand:SF 0 "register_operand" ""))
17208 (use (match_operand:SF 1 "register_operand" ""))]
17209 "((TARGET_USE_FANCY_MATH_387
17210 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17211 && flag_unsafe_math_optimizations)
17212 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17213 && !flag_trapping_math))
17214 && !optimize_size"
17215 {
17216 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17217 && !flag_trapping_math)
17218 ix86_expand_floorceil (operand0, operand1, false);
17219 else
17220 {
17221 rtx op0 = gen_reg_rtx (XFmode);
17222 rtx op1 = gen_reg_rtx (XFmode);
17223
17224 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17225 emit_insn (gen_frndintxf2_ceil (op0, op1));
17226
17227 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17228 }
17229 DONE;
17230 })
17231
17232 (define_insn_and_split "*fist<mode>2_ceil_1"
17233 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17234 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17235 UNSPEC_FIST_CEIL))
17236 (clobber (reg:CC FLAGS_REG))]
17237 "TARGET_USE_FANCY_MATH_387
17238 && flag_unsafe_math_optimizations
17239 && !(reload_completed || reload_in_progress)"
17240 "#"
17241 "&& 1"
17242 [(const_int 0)]
17243 {
17244 ix86_optimize_mode_switching[I387_CEIL] = 1;
17245
17246 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17247 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17248 if (memory_operand (operands[0], VOIDmode))
17249 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17250 operands[2], operands[3]));
17251 else
17252 {
17253 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17254 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17255 operands[2], operands[3],
17256 operands[4]));
17257 }
17258 DONE;
17259 }
17260 [(set_attr "type" "fistp")
17261 (set_attr "i387_cw" "ceil")
17262 (set_attr "mode" "<MODE>")])
17263
17264 (define_insn "fistdi2_ceil"
17265 [(set (match_operand:DI 0 "memory_operand" "=m")
17266 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17267 UNSPEC_FIST_CEIL))
17268 (use (match_operand:HI 2 "memory_operand" "m"))
17269 (use (match_operand:HI 3 "memory_operand" "m"))
17270 (clobber (match_scratch:XF 4 "=&1f"))]
17271 "TARGET_USE_FANCY_MATH_387
17272 && flag_unsafe_math_optimizations"
17273 "* return output_fix_trunc (insn, operands, 0);"
17274 [(set_attr "type" "fistp")
17275 (set_attr "i387_cw" "ceil")
17276 (set_attr "mode" "DI")])
17277
17278 (define_insn "fistdi2_ceil_with_temp"
17279 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17280 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17281 UNSPEC_FIST_CEIL))
17282 (use (match_operand:HI 2 "memory_operand" "m,m"))
17283 (use (match_operand:HI 3 "memory_operand" "m,m"))
17284 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17285 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17286 "TARGET_USE_FANCY_MATH_387
17287 && flag_unsafe_math_optimizations"
17288 "#"
17289 [(set_attr "type" "fistp")
17290 (set_attr "i387_cw" "ceil")
17291 (set_attr "mode" "DI")])
17292
17293 (define_split
17294 [(set (match_operand:DI 0 "register_operand" "")
17295 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17296 UNSPEC_FIST_CEIL))
17297 (use (match_operand:HI 2 "memory_operand" ""))
17298 (use (match_operand:HI 3 "memory_operand" ""))
17299 (clobber (match_operand:DI 4 "memory_operand" ""))
17300 (clobber (match_scratch 5 ""))]
17301 "reload_completed"
17302 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17303 (use (match_dup 2))
17304 (use (match_dup 3))
17305 (clobber (match_dup 5))])
17306 (set (match_dup 0) (match_dup 4))]
17307 "")
17308
17309 (define_split
17310 [(set (match_operand:DI 0 "memory_operand" "")
17311 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17312 UNSPEC_FIST_CEIL))
17313 (use (match_operand:HI 2 "memory_operand" ""))
17314 (use (match_operand:HI 3 "memory_operand" ""))
17315 (clobber (match_operand:DI 4 "memory_operand" ""))
17316 (clobber (match_scratch 5 ""))]
17317 "reload_completed"
17318 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17319 (use (match_dup 2))
17320 (use (match_dup 3))
17321 (clobber (match_dup 5))])]
17322 "")
17323
17324 (define_insn "fist<mode>2_ceil"
17325 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17326 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17327 UNSPEC_FIST_CEIL))
17328 (use (match_operand:HI 2 "memory_operand" "m"))
17329 (use (match_operand:HI 3 "memory_operand" "m"))]
17330 "TARGET_USE_FANCY_MATH_387
17331 && flag_unsafe_math_optimizations"
17332 "* return output_fix_trunc (insn, operands, 0);"
17333 [(set_attr "type" "fistp")
17334 (set_attr "i387_cw" "ceil")
17335 (set_attr "mode" "<MODE>")])
17336
17337 (define_insn "fist<mode>2_ceil_with_temp"
17338 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17339 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17340 UNSPEC_FIST_CEIL))
17341 (use (match_operand:HI 2 "memory_operand" "m,m"))
17342 (use (match_operand:HI 3 "memory_operand" "m,m"))
17343 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17344 "TARGET_USE_FANCY_MATH_387
17345 && flag_unsafe_math_optimizations"
17346 "#"
17347 [(set_attr "type" "fistp")
17348 (set_attr "i387_cw" "ceil")
17349 (set_attr "mode" "<MODE>")])
17350
17351 (define_split
17352 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17353 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17354 UNSPEC_FIST_CEIL))
17355 (use (match_operand:HI 2 "memory_operand" ""))
17356 (use (match_operand:HI 3 "memory_operand" ""))
17357 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17358 "reload_completed"
17359 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17360 UNSPEC_FIST_CEIL))
17361 (use (match_dup 2))
17362 (use (match_dup 3))])
17363 (set (match_dup 0) (match_dup 4))]
17364 "")
17365
17366 (define_split
17367 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17368 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17369 UNSPEC_FIST_CEIL))
17370 (use (match_operand:HI 2 "memory_operand" ""))
17371 (use (match_operand:HI 3 "memory_operand" ""))
17372 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17373 "reload_completed"
17374 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17375 UNSPEC_FIST_CEIL))
17376 (use (match_dup 2))
17377 (use (match_dup 3))])]
17378 "")
17379
17380 (define_expand "lceilxf<mode>2"
17381 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17382 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17383 UNSPEC_FIST_CEIL))
17384 (clobber (reg:CC FLAGS_REG))])]
17385 "TARGET_USE_FANCY_MATH_387
17386 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17387 && flag_unsafe_math_optimizations"
17388 "")
17389
17390 (define_expand "lceil<mode>di2"
17391 [(match_operand:DI 0 "nonimmediate_operand" "")
17392 (match_operand:SSEMODEF 1 "register_operand" "")]
17393 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17394 && !flag_trapping_math"
17395 {
17396 ix86_expand_lfloorceil (operand0, operand1, false);
17397 DONE;
17398 })
17399
17400 (define_expand "lceil<mode>si2"
17401 [(match_operand:SI 0 "nonimmediate_operand" "")
17402 (match_operand:SSEMODEF 1 "register_operand" "")]
17403 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17404 && !flag_trapping_math"
17405 {
17406 ix86_expand_lfloorceil (operand0, operand1, false);
17407 DONE;
17408 })
17409
17410 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17411 (define_insn_and_split "frndintxf2_trunc"
17412 [(set (match_operand:XF 0 "register_operand" "=f")
17413 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17414 UNSPEC_FRNDINT_TRUNC))
17415 (clobber (reg:CC FLAGS_REG))]
17416 "TARGET_USE_FANCY_MATH_387
17417 && flag_unsafe_math_optimizations
17418 && !(reload_completed || reload_in_progress)"
17419 "#"
17420 "&& 1"
17421 [(const_int 0)]
17422 {
17423 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17424
17425 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17426 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17427
17428 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17429 operands[2], operands[3]));
17430 DONE;
17431 }
17432 [(set_attr "type" "frndint")
17433 (set_attr "i387_cw" "trunc")
17434 (set_attr "mode" "XF")])
17435
17436 (define_insn "frndintxf2_trunc_i387"
17437 [(set (match_operand:XF 0 "register_operand" "=f")
17438 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17439 UNSPEC_FRNDINT_TRUNC))
17440 (use (match_operand:HI 2 "memory_operand" "m"))
17441 (use (match_operand:HI 3 "memory_operand" "m"))]
17442 "TARGET_USE_FANCY_MATH_387
17443 && flag_unsafe_math_optimizations"
17444 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17445 [(set_attr "type" "frndint")
17446 (set_attr "i387_cw" "trunc")
17447 (set_attr "mode" "XF")])
17448
17449 (define_expand "btruncxf2"
17450 [(use (match_operand:XF 0 "register_operand" ""))
17451 (use (match_operand:XF 1 "register_operand" ""))]
17452 "TARGET_USE_FANCY_MATH_387
17453 && flag_unsafe_math_optimizations && !optimize_size"
17454 {
17455 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17456 DONE;
17457 })
17458
17459 (define_expand "btruncdf2"
17460 [(use (match_operand:DF 0 "register_operand" ""))
17461 (use (match_operand:DF 1 "register_operand" ""))]
17462 "((TARGET_USE_FANCY_MATH_387
17463 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17464 && flag_unsafe_math_optimizations)
17465 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17466 && !flag_trapping_math))
17467 && !optimize_size"
17468 {
17469 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17470 && !flag_trapping_math)
17471 {
17472 if (TARGET_64BIT)
17473 ix86_expand_trunc (operand0, operand1);
17474 else
17475 ix86_expand_truncdf_32 (operand0, operand1);
17476 }
17477 else
17478 {
17479 rtx op0 = gen_reg_rtx (XFmode);
17480 rtx op1 = gen_reg_rtx (XFmode);
17481
17482 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17483 emit_insn (gen_frndintxf2_trunc (op0, op1));
17484
17485 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17486 }
17487 DONE;
17488 })
17489
17490 (define_expand "btruncsf2"
17491 [(use (match_operand:SF 0 "register_operand" ""))
17492 (use (match_operand:SF 1 "register_operand" ""))]
17493 "((TARGET_USE_FANCY_MATH_387
17494 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17495 && flag_unsafe_math_optimizations)
17496 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17497 && !flag_trapping_math))
17498 && !optimize_size"
17499 {
17500 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17501 && !flag_trapping_math)
17502 ix86_expand_trunc (operand0, operand1);
17503 else
17504 {
17505 rtx op0 = gen_reg_rtx (XFmode);
17506 rtx op1 = gen_reg_rtx (XFmode);
17507
17508 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17509 emit_insn (gen_frndintxf2_trunc (op0, op1));
17510
17511 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17512 }
17513 DONE;
17514 })
17515
17516 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17517 (define_insn_and_split "frndintxf2_mask_pm"
17518 [(set (match_operand:XF 0 "register_operand" "=f")
17519 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17520 UNSPEC_FRNDINT_MASK_PM))
17521 (clobber (reg:CC FLAGS_REG))]
17522 "TARGET_USE_FANCY_MATH_387
17523 && flag_unsafe_math_optimizations
17524 && !(reload_completed || reload_in_progress)"
17525 "#"
17526 "&& 1"
17527 [(const_int 0)]
17528 {
17529 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17530
17531 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17532 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17533
17534 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17535 operands[2], operands[3]));
17536 DONE;
17537 }
17538 [(set_attr "type" "frndint")
17539 (set_attr "i387_cw" "mask_pm")
17540 (set_attr "mode" "XF")])
17541
17542 (define_insn "frndintxf2_mask_pm_i387"
17543 [(set (match_operand:XF 0 "register_operand" "=f")
17544 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17545 UNSPEC_FRNDINT_MASK_PM))
17546 (use (match_operand:HI 2 "memory_operand" "m"))
17547 (use (match_operand:HI 3 "memory_operand" "m"))]
17548 "TARGET_USE_FANCY_MATH_387
17549 && flag_unsafe_math_optimizations"
17550 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17551 [(set_attr "type" "frndint")
17552 (set_attr "i387_cw" "mask_pm")
17553 (set_attr "mode" "XF")])
17554
17555 (define_expand "nearbyintxf2"
17556 [(use (match_operand:XF 0 "register_operand" ""))
17557 (use (match_operand:XF 1 "register_operand" ""))]
17558 "TARGET_USE_FANCY_MATH_387
17559 && flag_unsafe_math_optimizations"
17560 {
17561 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17562
17563 DONE;
17564 })
17565
17566 (define_expand "nearbyintdf2"
17567 [(use (match_operand:DF 0 "register_operand" ""))
17568 (use (match_operand:DF 1 "register_operand" ""))]
17569 "TARGET_USE_FANCY_MATH_387
17570 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17571 && flag_unsafe_math_optimizations"
17572 {
17573 rtx op0 = gen_reg_rtx (XFmode);
17574 rtx op1 = gen_reg_rtx (XFmode);
17575
17576 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17577 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17578
17579 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17580 DONE;
17581 })
17582
17583 (define_expand "nearbyintsf2"
17584 [(use (match_operand:SF 0 "register_operand" ""))
17585 (use (match_operand:SF 1 "register_operand" ""))]
17586 "TARGET_USE_FANCY_MATH_387
17587 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17588 && flag_unsafe_math_optimizations"
17589 {
17590 rtx op0 = gen_reg_rtx (XFmode);
17591 rtx op1 = gen_reg_rtx (XFmode);
17592
17593 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17594 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17595
17596 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17597 DONE;
17598 })
17599
17600 \f
17601 ;; Block operation instructions
17602
17603 (define_expand "movmemsi"
17604 [(use (match_operand:BLK 0 "memory_operand" ""))
17605 (use (match_operand:BLK 1 "memory_operand" ""))
17606 (use (match_operand:SI 2 "nonmemory_operand" ""))
17607 (use (match_operand:SI 3 "const_int_operand" ""))
17608 (use (match_operand:SI 4 "const_int_operand" ""))
17609 (use (match_operand:SI 5 "const_int_operand" ""))]
17610 ""
17611 {
17612 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17613 operands[4], operands[5]))
17614 DONE;
17615 else
17616 FAIL;
17617 })
17618
17619 (define_expand "movmemdi"
17620 [(use (match_operand:BLK 0 "memory_operand" ""))
17621 (use (match_operand:BLK 1 "memory_operand" ""))
17622 (use (match_operand:DI 2 "nonmemory_operand" ""))
17623 (use (match_operand:DI 3 "const_int_operand" ""))
17624 (use (match_operand:SI 4 "const_int_operand" ""))
17625 (use (match_operand:SI 5 "const_int_operand" ""))]
17626 "TARGET_64BIT"
17627 {
17628 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17629 operands[4], operands[5]))
17630 DONE;
17631 else
17632 FAIL;
17633 })
17634
17635 ;; Most CPUs don't like single string operations
17636 ;; Handle this case here to simplify previous expander.
17637
17638 (define_expand "strmov"
17639 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17640 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17641 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17642 (clobber (reg:CC FLAGS_REG))])
17643 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17644 (clobber (reg:CC FLAGS_REG))])]
17645 ""
17646 {
17647 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17648
17649 /* If .md ever supports :P for Pmode, these can be directly
17650 in the pattern above. */
17651 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17652 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17653
17654 if (TARGET_SINGLE_STRINGOP || optimize_size)
17655 {
17656 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17657 operands[2], operands[3],
17658 operands[5], operands[6]));
17659 DONE;
17660 }
17661
17662 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17663 })
17664
17665 (define_expand "strmov_singleop"
17666 [(parallel [(set (match_operand 1 "memory_operand" "")
17667 (match_operand 3 "memory_operand" ""))
17668 (set (match_operand 0 "register_operand" "")
17669 (match_operand 4 "" ""))
17670 (set (match_operand 2 "register_operand" "")
17671 (match_operand 5 "" ""))])]
17672 "TARGET_SINGLE_STRINGOP || optimize_size"
17673 "")
17674
17675 (define_insn "*strmovdi_rex_1"
17676 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17677 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17678 (set (match_operand:DI 0 "register_operand" "=D")
17679 (plus:DI (match_dup 2)
17680 (const_int 8)))
17681 (set (match_operand:DI 1 "register_operand" "=S")
17682 (plus:DI (match_dup 3)
17683 (const_int 8)))]
17684 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17685 "movsq"
17686 [(set_attr "type" "str")
17687 (set_attr "mode" "DI")
17688 (set_attr "memory" "both")])
17689
17690 (define_insn "*strmovsi_1"
17691 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17692 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17693 (set (match_operand:SI 0 "register_operand" "=D")
17694 (plus:SI (match_dup 2)
17695 (const_int 4)))
17696 (set (match_operand:SI 1 "register_operand" "=S")
17697 (plus:SI (match_dup 3)
17698 (const_int 4)))]
17699 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17700 "{movsl|movsd}"
17701 [(set_attr "type" "str")
17702 (set_attr "mode" "SI")
17703 (set_attr "memory" "both")])
17704
17705 (define_insn "*strmovsi_rex_1"
17706 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17707 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17708 (set (match_operand:DI 0 "register_operand" "=D")
17709 (plus:DI (match_dup 2)
17710 (const_int 4)))
17711 (set (match_operand:DI 1 "register_operand" "=S")
17712 (plus:DI (match_dup 3)
17713 (const_int 4)))]
17714 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17715 "{movsl|movsd}"
17716 [(set_attr "type" "str")
17717 (set_attr "mode" "SI")
17718 (set_attr "memory" "both")])
17719
17720 (define_insn "*strmovhi_1"
17721 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17722 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17723 (set (match_operand:SI 0 "register_operand" "=D")
17724 (plus:SI (match_dup 2)
17725 (const_int 2)))
17726 (set (match_operand:SI 1 "register_operand" "=S")
17727 (plus:SI (match_dup 3)
17728 (const_int 2)))]
17729 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17730 "movsw"
17731 [(set_attr "type" "str")
17732 (set_attr "memory" "both")
17733 (set_attr "mode" "HI")])
17734
17735 (define_insn "*strmovhi_rex_1"
17736 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17737 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17738 (set (match_operand:DI 0 "register_operand" "=D")
17739 (plus:DI (match_dup 2)
17740 (const_int 2)))
17741 (set (match_operand:DI 1 "register_operand" "=S")
17742 (plus:DI (match_dup 3)
17743 (const_int 2)))]
17744 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17745 "movsw"
17746 [(set_attr "type" "str")
17747 (set_attr "memory" "both")
17748 (set_attr "mode" "HI")])
17749
17750 (define_insn "*strmovqi_1"
17751 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17752 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17753 (set (match_operand:SI 0 "register_operand" "=D")
17754 (plus:SI (match_dup 2)
17755 (const_int 1)))
17756 (set (match_operand:SI 1 "register_operand" "=S")
17757 (plus:SI (match_dup 3)
17758 (const_int 1)))]
17759 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17760 "movsb"
17761 [(set_attr "type" "str")
17762 (set_attr "memory" "both")
17763 (set_attr "mode" "QI")])
17764
17765 (define_insn "*strmovqi_rex_1"
17766 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17767 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17768 (set (match_operand:DI 0 "register_operand" "=D")
17769 (plus:DI (match_dup 2)
17770 (const_int 1)))
17771 (set (match_operand:DI 1 "register_operand" "=S")
17772 (plus:DI (match_dup 3)
17773 (const_int 1)))]
17774 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17775 "movsb"
17776 [(set_attr "type" "str")
17777 (set_attr "memory" "both")
17778 (set_attr "mode" "QI")])
17779
17780 (define_expand "rep_mov"
17781 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17782 (set (match_operand 0 "register_operand" "")
17783 (match_operand 5 "" ""))
17784 (set (match_operand 2 "register_operand" "")
17785 (match_operand 6 "" ""))
17786 (set (match_operand 1 "memory_operand" "")
17787 (match_operand 3 "memory_operand" ""))
17788 (use (match_dup 4))])]
17789 ""
17790 "")
17791
17792 (define_insn "*rep_movdi_rex64"
17793 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17794 (set (match_operand:DI 0 "register_operand" "=D")
17795 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17796 (const_int 3))
17797 (match_operand:DI 3 "register_operand" "0")))
17798 (set (match_operand:DI 1 "register_operand" "=S")
17799 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17800 (match_operand:DI 4 "register_operand" "1")))
17801 (set (mem:BLK (match_dup 3))
17802 (mem:BLK (match_dup 4)))
17803 (use (match_dup 5))]
17804 "TARGET_64BIT"
17805 "{rep\;movsq|rep movsq}"
17806 [(set_attr "type" "str")
17807 (set_attr "prefix_rep" "1")
17808 (set_attr "memory" "both")
17809 (set_attr "mode" "DI")])
17810
17811 (define_insn "*rep_movsi"
17812 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17813 (set (match_operand:SI 0 "register_operand" "=D")
17814 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17815 (const_int 2))
17816 (match_operand:SI 3 "register_operand" "0")))
17817 (set (match_operand:SI 1 "register_operand" "=S")
17818 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17819 (match_operand:SI 4 "register_operand" "1")))
17820 (set (mem:BLK (match_dup 3))
17821 (mem:BLK (match_dup 4)))
17822 (use (match_dup 5))]
17823 "!TARGET_64BIT"
17824 "{rep\;movsl|rep movsd}"
17825 [(set_attr "type" "str")
17826 (set_attr "prefix_rep" "1")
17827 (set_attr "memory" "both")
17828 (set_attr "mode" "SI")])
17829
17830 (define_insn "*rep_movsi_rex64"
17831 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17832 (set (match_operand:DI 0 "register_operand" "=D")
17833 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17834 (const_int 2))
17835 (match_operand:DI 3 "register_operand" "0")))
17836 (set (match_operand:DI 1 "register_operand" "=S")
17837 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17838 (match_operand:DI 4 "register_operand" "1")))
17839 (set (mem:BLK (match_dup 3))
17840 (mem:BLK (match_dup 4)))
17841 (use (match_dup 5))]
17842 "TARGET_64BIT"
17843 "{rep\;movsl|rep movsd}"
17844 [(set_attr "type" "str")
17845 (set_attr "prefix_rep" "1")
17846 (set_attr "memory" "both")
17847 (set_attr "mode" "SI")])
17848
17849 (define_insn "*rep_movqi"
17850 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17851 (set (match_operand:SI 0 "register_operand" "=D")
17852 (plus:SI (match_operand:SI 3 "register_operand" "0")
17853 (match_operand:SI 5 "register_operand" "2")))
17854 (set (match_operand:SI 1 "register_operand" "=S")
17855 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17856 (set (mem:BLK (match_dup 3))
17857 (mem:BLK (match_dup 4)))
17858 (use (match_dup 5))]
17859 "!TARGET_64BIT"
17860 "{rep\;movsb|rep movsb}"
17861 [(set_attr "type" "str")
17862 (set_attr "prefix_rep" "1")
17863 (set_attr "memory" "both")
17864 (set_attr "mode" "SI")])
17865
17866 (define_insn "*rep_movqi_rex64"
17867 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17868 (set (match_operand:DI 0 "register_operand" "=D")
17869 (plus:DI (match_operand:DI 3 "register_operand" "0")
17870 (match_operand:DI 5 "register_operand" "2")))
17871 (set (match_operand:DI 1 "register_operand" "=S")
17872 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17873 (set (mem:BLK (match_dup 3))
17874 (mem:BLK (match_dup 4)))
17875 (use (match_dup 5))]
17876 "TARGET_64BIT"
17877 "{rep\;movsb|rep movsb}"
17878 [(set_attr "type" "str")
17879 (set_attr "prefix_rep" "1")
17880 (set_attr "memory" "both")
17881 (set_attr "mode" "SI")])
17882
17883 (define_expand "setmemsi"
17884 [(use (match_operand:BLK 0 "memory_operand" ""))
17885 (use (match_operand:SI 1 "nonmemory_operand" ""))
17886 (use (match_operand 2 "const_int_operand" ""))
17887 (use (match_operand 3 "const_int_operand" ""))
17888 (use (match_operand:SI 4 "const_int_operand" ""))
17889 (use (match_operand:SI 5 "const_int_operand" ""))]
17890 ""
17891 {
17892 if (ix86_expand_setmem (operands[0], operands[1],
17893 operands[2], operands[3],
17894 operands[4], operands[5]))
17895 DONE;
17896 else
17897 FAIL;
17898 })
17899
17900 (define_expand "setmemdi"
17901 [(use (match_operand:BLK 0 "memory_operand" ""))
17902 (use (match_operand:DI 1 "nonmemory_operand" ""))
17903 (use (match_operand 2 "const_int_operand" ""))
17904 (use (match_operand 3 "const_int_operand" ""))
17905 (use (match_operand 4 "const_int_operand" ""))
17906 (use (match_operand 5 "const_int_operand" ""))]
17907 "TARGET_64BIT"
17908 {
17909 if (ix86_expand_setmem (operands[0], operands[1],
17910 operands[2], operands[3],
17911 operands[4], operands[5]))
17912 DONE;
17913 else
17914 FAIL;
17915 })
17916
17917 ;; Most CPUs don't like single string operations
17918 ;; Handle this case here to simplify previous expander.
17919
17920 (define_expand "strset"
17921 [(set (match_operand 1 "memory_operand" "")
17922 (match_operand 2 "register_operand" ""))
17923 (parallel [(set (match_operand 0 "register_operand" "")
17924 (match_dup 3))
17925 (clobber (reg:CC FLAGS_REG))])]
17926 ""
17927 {
17928 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17929 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17930
17931 /* If .md ever supports :P for Pmode, this can be directly
17932 in the pattern above. */
17933 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17934 GEN_INT (GET_MODE_SIZE (GET_MODE
17935 (operands[2]))));
17936 if (TARGET_SINGLE_STRINGOP || optimize_size)
17937 {
17938 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17939 operands[3]));
17940 DONE;
17941 }
17942 })
17943
17944 (define_expand "strset_singleop"
17945 [(parallel [(set (match_operand 1 "memory_operand" "")
17946 (match_operand 2 "register_operand" ""))
17947 (set (match_operand 0 "register_operand" "")
17948 (match_operand 3 "" ""))])]
17949 "TARGET_SINGLE_STRINGOP || optimize_size"
17950 "")
17951
17952 (define_insn "*strsetdi_rex_1"
17953 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17954 (match_operand:DI 2 "register_operand" "a"))
17955 (set (match_operand:DI 0 "register_operand" "=D")
17956 (plus:DI (match_dup 1)
17957 (const_int 8)))]
17958 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17959 "stosq"
17960 [(set_attr "type" "str")
17961 (set_attr "memory" "store")
17962 (set_attr "mode" "DI")])
17963
17964 (define_insn "*strsetsi_1"
17965 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17966 (match_operand:SI 2 "register_operand" "a"))
17967 (set (match_operand:SI 0 "register_operand" "=D")
17968 (plus:SI (match_dup 1)
17969 (const_int 4)))]
17970 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17971 "{stosl|stosd}"
17972 [(set_attr "type" "str")
17973 (set_attr "memory" "store")
17974 (set_attr "mode" "SI")])
17975
17976 (define_insn "*strsetsi_rex_1"
17977 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17978 (match_operand:SI 2 "register_operand" "a"))
17979 (set (match_operand:DI 0 "register_operand" "=D")
17980 (plus:DI (match_dup 1)
17981 (const_int 4)))]
17982 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17983 "{stosl|stosd}"
17984 [(set_attr "type" "str")
17985 (set_attr "memory" "store")
17986 (set_attr "mode" "SI")])
17987
17988 (define_insn "*strsethi_1"
17989 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17990 (match_operand:HI 2 "register_operand" "a"))
17991 (set (match_operand:SI 0 "register_operand" "=D")
17992 (plus:SI (match_dup 1)
17993 (const_int 2)))]
17994 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17995 "stosw"
17996 [(set_attr "type" "str")
17997 (set_attr "memory" "store")
17998 (set_attr "mode" "HI")])
17999
18000 (define_insn "*strsethi_rex_1"
18001 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18002 (match_operand:HI 2 "register_operand" "a"))
18003 (set (match_operand:DI 0 "register_operand" "=D")
18004 (plus:DI (match_dup 1)
18005 (const_int 2)))]
18006 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18007 "stosw"
18008 [(set_attr "type" "str")
18009 (set_attr "memory" "store")
18010 (set_attr "mode" "HI")])
18011
18012 (define_insn "*strsetqi_1"
18013 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18014 (match_operand:QI 2 "register_operand" "a"))
18015 (set (match_operand:SI 0 "register_operand" "=D")
18016 (plus:SI (match_dup 1)
18017 (const_int 1)))]
18018 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18019 "stosb"
18020 [(set_attr "type" "str")
18021 (set_attr "memory" "store")
18022 (set_attr "mode" "QI")])
18023
18024 (define_insn "*strsetqi_rex_1"
18025 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18026 (match_operand:QI 2 "register_operand" "a"))
18027 (set (match_operand:DI 0 "register_operand" "=D")
18028 (plus:DI (match_dup 1)
18029 (const_int 1)))]
18030 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18031 "stosb"
18032 [(set_attr "type" "str")
18033 (set_attr "memory" "store")
18034 (set_attr "mode" "QI")])
18035
18036 (define_expand "rep_stos"
18037 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18038 (set (match_operand 0 "register_operand" "")
18039 (match_operand 4 "" ""))
18040 (set (match_operand 2 "memory_operand" "") (const_int 0))
18041 (use (match_operand 3 "register_operand" ""))
18042 (use (match_dup 1))])]
18043 ""
18044 "")
18045
18046 (define_insn "*rep_stosdi_rex64"
18047 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18048 (set (match_operand:DI 0 "register_operand" "=D")
18049 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18050 (const_int 3))
18051 (match_operand:DI 3 "register_operand" "0")))
18052 (set (mem:BLK (match_dup 3))
18053 (const_int 0))
18054 (use (match_operand:DI 2 "register_operand" "a"))
18055 (use (match_dup 4))]
18056 "TARGET_64BIT"
18057 "{rep\;stosq|rep stosq}"
18058 [(set_attr "type" "str")
18059 (set_attr "prefix_rep" "1")
18060 (set_attr "memory" "store")
18061 (set_attr "mode" "DI")])
18062
18063 (define_insn "*rep_stossi"
18064 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18065 (set (match_operand:SI 0 "register_operand" "=D")
18066 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18067 (const_int 2))
18068 (match_operand:SI 3 "register_operand" "0")))
18069 (set (mem:BLK (match_dup 3))
18070 (const_int 0))
18071 (use (match_operand:SI 2 "register_operand" "a"))
18072 (use (match_dup 4))]
18073 "!TARGET_64BIT"
18074 "{rep\;stosl|rep stosd}"
18075 [(set_attr "type" "str")
18076 (set_attr "prefix_rep" "1")
18077 (set_attr "memory" "store")
18078 (set_attr "mode" "SI")])
18079
18080 (define_insn "*rep_stossi_rex64"
18081 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18082 (set (match_operand:DI 0 "register_operand" "=D")
18083 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18084 (const_int 2))
18085 (match_operand:DI 3 "register_operand" "0")))
18086 (set (mem:BLK (match_dup 3))
18087 (const_int 0))
18088 (use (match_operand:SI 2 "register_operand" "a"))
18089 (use (match_dup 4))]
18090 "TARGET_64BIT"
18091 "{rep\;stosl|rep stosd}"
18092 [(set_attr "type" "str")
18093 (set_attr "prefix_rep" "1")
18094 (set_attr "memory" "store")
18095 (set_attr "mode" "SI")])
18096
18097 (define_insn "*rep_stosqi"
18098 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18099 (set (match_operand:SI 0 "register_operand" "=D")
18100 (plus:SI (match_operand:SI 3 "register_operand" "0")
18101 (match_operand:SI 4 "register_operand" "1")))
18102 (set (mem:BLK (match_dup 3))
18103 (const_int 0))
18104 (use (match_operand:QI 2 "register_operand" "a"))
18105 (use (match_dup 4))]
18106 "!TARGET_64BIT"
18107 "{rep\;stosb|rep stosb}"
18108 [(set_attr "type" "str")
18109 (set_attr "prefix_rep" "1")
18110 (set_attr "memory" "store")
18111 (set_attr "mode" "QI")])
18112
18113 (define_insn "*rep_stosqi_rex64"
18114 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18115 (set (match_operand:DI 0 "register_operand" "=D")
18116 (plus:DI (match_operand:DI 3 "register_operand" "0")
18117 (match_operand:DI 4 "register_operand" "1")))
18118 (set (mem:BLK (match_dup 3))
18119 (const_int 0))
18120 (use (match_operand:QI 2 "register_operand" "a"))
18121 (use (match_dup 4))]
18122 "TARGET_64BIT"
18123 "{rep\;stosb|rep stosb}"
18124 [(set_attr "type" "str")
18125 (set_attr "prefix_rep" "1")
18126 (set_attr "memory" "store")
18127 (set_attr "mode" "QI")])
18128
18129 (define_expand "cmpstrnsi"
18130 [(set (match_operand:SI 0 "register_operand" "")
18131 (compare:SI (match_operand:BLK 1 "general_operand" "")
18132 (match_operand:BLK 2 "general_operand" "")))
18133 (use (match_operand 3 "general_operand" ""))
18134 (use (match_operand 4 "immediate_operand" ""))]
18135 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18136 {
18137 rtx addr1, addr2, out, outlow, count, countreg, align;
18138
18139 /* Can't use this if the user has appropriated esi or edi. */
18140 if (global_regs[4] || global_regs[5])
18141 FAIL;
18142
18143 out = operands[0];
18144 if (!REG_P (out))
18145 out = gen_reg_rtx (SImode);
18146
18147 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18148 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18149 if (addr1 != XEXP (operands[1], 0))
18150 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18151 if (addr2 != XEXP (operands[2], 0))
18152 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18153
18154 count = operands[3];
18155 countreg = ix86_zero_extend_to_Pmode (count);
18156
18157 /* %%% Iff we are testing strict equality, we can use known alignment
18158 to good advantage. This may be possible with combine, particularly
18159 once cc0 is dead. */
18160 align = operands[4];
18161
18162 if (CONST_INT_P (count))
18163 {
18164 if (INTVAL (count) == 0)
18165 {
18166 emit_move_insn (operands[0], const0_rtx);
18167 DONE;
18168 }
18169 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18170 operands[1], operands[2]));
18171 }
18172 else
18173 {
18174 if (TARGET_64BIT)
18175 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18176 else
18177 emit_insn (gen_cmpsi_1 (countreg, countreg));
18178 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18179 operands[1], operands[2]));
18180 }
18181
18182 outlow = gen_lowpart (QImode, out);
18183 emit_insn (gen_cmpintqi (outlow));
18184 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18185
18186 if (operands[0] != out)
18187 emit_move_insn (operands[0], out);
18188
18189 DONE;
18190 })
18191
18192 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18193
18194 (define_expand "cmpintqi"
18195 [(set (match_dup 1)
18196 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18197 (set (match_dup 2)
18198 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18199 (parallel [(set (match_operand:QI 0 "register_operand" "")
18200 (minus:QI (match_dup 1)
18201 (match_dup 2)))
18202 (clobber (reg:CC FLAGS_REG))])]
18203 ""
18204 "operands[1] = gen_reg_rtx (QImode);
18205 operands[2] = gen_reg_rtx (QImode);")
18206
18207 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18208 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18209
18210 (define_expand "cmpstrnqi_nz_1"
18211 [(parallel [(set (reg:CC FLAGS_REG)
18212 (compare:CC (match_operand 4 "memory_operand" "")
18213 (match_operand 5 "memory_operand" "")))
18214 (use (match_operand 2 "register_operand" ""))
18215 (use (match_operand:SI 3 "immediate_operand" ""))
18216 (clobber (match_operand 0 "register_operand" ""))
18217 (clobber (match_operand 1 "register_operand" ""))
18218 (clobber (match_dup 2))])]
18219 ""
18220 "")
18221
18222 (define_insn "*cmpstrnqi_nz_1"
18223 [(set (reg:CC FLAGS_REG)
18224 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18225 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18226 (use (match_operand:SI 6 "register_operand" "2"))
18227 (use (match_operand:SI 3 "immediate_operand" "i"))
18228 (clobber (match_operand:SI 0 "register_operand" "=S"))
18229 (clobber (match_operand:SI 1 "register_operand" "=D"))
18230 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18231 "!TARGET_64BIT"
18232 "repz{\;| }cmpsb"
18233 [(set_attr "type" "str")
18234 (set_attr "mode" "QI")
18235 (set_attr "prefix_rep" "1")])
18236
18237 (define_insn "*cmpstrnqi_nz_rex_1"
18238 [(set (reg:CC FLAGS_REG)
18239 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18240 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18241 (use (match_operand:DI 6 "register_operand" "2"))
18242 (use (match_operand:SI 3 "immediate_operand" "i"))
18243 (clobber (match_operand:DI 0 "register_operand" "=S"))
18244 (clobber (match_operand:DI 1 "register_operand" "=D"))
18245 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18246 "TARGET_64BIT"
18247 "repz{\;| }cmpsb"
18248 [(set_attr "type" "str")
18249 (set_attr "mode" "QI")
18250 (set_attr "prefix_rep" "1")])
18251
18252 ;; The same, but the count is not known to not be zero.
18253
18254 (define_expand "cmpstrnqi_1"
18255 [(parallel [(set (reg:CC FLAGS_REG)
18256 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18257 (const_int 0))
18258 (compare:CC (match_operand 4 "memory_operand" "")
18259 (match_operand 5 "memory_operand" ""))
18260 (const_int 0)))
18261 (use (match_operand:SI 3 "immediate_operand" ""))
18262 (use (reg:CC FLAGS_REG))
18263 (clobber (match_operand 0 "register_operand" ""))
18264 (clobber (match_operand 1 "register_operand" ""))
18265 (clobber (match_dup 2))])]
18266 ""
18267 "")
18268
18269 (define_insn "*cmpstrnqi_1"
18270 [(set (reg:CC FLAGS_REG)
18271 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18272 (const_int 0))
18273 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18274 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18275 (const_int 0)))
18276 (use (match_operand:SI 3 "immediate_operand" "i"))
18277 (use (reg:CC FLAGS_REG))
18278 (clobber (match_operand:SI 0 "register_operand" "=S"))
18279 (clobber (match_operand:SI 1 "register_operand" "=D"))
18280 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18281 "!TARGET_64BIT"
18282 "repz{\;| }cmpsb"
18283 [(set_attr "type" "str")
18284 (set_attr "mode" "QI")
18285 (set_attr "prefix_rep" "1")])
18286
18287 (define_insn "*cmpstrnqi_rex_1"
18288 [(set (reg:CC FLAGS_REG)
18289 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18290 (const_int 0))
18291 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18292 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18293 (const_int 0)))
18294 (use (match_operand:SI 3 "immediate_operand" "i"))
18295 (use (reg:CC FLAGS_REG))
18296 (clobber (match_operand:DI 0 "register_operand" "=S"))
18297 (clobber (match_operand:DI 1 "register_operand" "=D"))
18298 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18299 "TARGET_64BIT"
18300 "repz{\;| }cmpsb"
18301 [(set_attr "type" "str")
18302 (set_attr "mode" "QI")
18303 (set_attr "prefix_rep" "1")])
18304
18305 (define_expand "strlensi"
18306 [(set (match_operand:SI 0 "register_operand" "")
18307 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18308 (match_operand:QI 2 "immediate_operand" "")
18309 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18310 ""
18311 {
18312 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18313 DONE;
18314 else
18315 FAIL;
18316 })
18317
18318 (define_expand "strlendi"
18319 [(set (match_operand:DI 0 "register_operand" "")
18320 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18321 (match_operand:QI 2 "immediate_operand" "")
18322 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18323 ""
18324 {
18325 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18326 DONE;
18327 else
18328 FAIL;
18329 })
18330
18331 (define_expand "strlenqi_1"
18332 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18333 (clobber (match_operand 1 "register_operand" ""))
18334 (clobber (reg:CC FLAGS_REG))])]
18335 ""
18336 "")
18337
18338 (define_insn "*strlenqi_1"
18339 [(set (match_operand:SI 0 "register_operand" "=&c")
18340 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18341 (match_operand:QI 2 "register_operand" "a")
18342 (match_operand:SI 3 "immediate_operand" "i")
18343 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18344 (clobber (match_operand:SI 1 "register_operand" "=D"))
18345 (clobber (reg:CC FLAGS_REG))]
18346 "!TARGET_64BIT"
18347 "repnz{\;| }scasb"
18348 [(set_attr "type" "str")
18349 (set_attr "mode" "QI")
18350 (set_attr "prefix_rep" "1")])
18351
18352 (define_insn "*strlenqi_rex_1"
18353 [(set (match_operand:DI 0 "register_operand" "=&c")
18354 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18355 (match_operand:QI 2 "register_operand" "a")
18356 (match_operand:DI 3 "immediate_operand" "i")
18357 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18358 (clobber (match_operand:DI 1 "register_operand" "=D"))
18359 (clobber (reg:CC FLAGS_REG))]
18360 "TARGET_64BIT"
18361 "repnz{\;| }scasb"
18362 [(set_attr "type" "str")
18363 (set_attr "mode" "QI")
18364 (set_attr "prefix_rep" "1")])
18365
18366 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18367 ;; handled in combine, but it is not currently up to the task.
18368 ;; When used for their truth value, the cmpstrn* expanders generate
18369 ;; code like this:
18370 ;;
18371 ;; repz cmpsb
18372 ;; seta %al
18373 ;; setb %dl
18374 ;; cmpb %al, %dl
18375 ;; jcc label
18376 ;;
18377 ;; The intermediate three instructions are unnecessary.
18378
18379 ;; This one handles cmpstrn*_nz_1...
18380 (define_peephole2
18381 [(parallel[
18382 (set (reg:CC FLAGS_REG)
18383 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18384 (mem:BLK (match_operand 5 "register_operand" ""))))
18385 (use (match_operand 6 "register_operand" ""))
18386 (use (match_operand:SI 3 "immediate_operand" ""))
18387 (clobber (match_operand 0 "register_operand" ""))
18388 (clobber (match_operand 1 "register_operand" ""))
18389 (clobber (match_operand 2 "register_operand" ""))])
18390 (set (match_operand:QI 7 "register_operand" "")
18391 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18392 (set (match_operand:QI 8 "register_operand" "")
18393 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18394 (set (reg FLAGS_REG)
18395 (compare (match_dup 7) (match_dup 8)))
18396 ]
18397 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18398 [(parallel[
18399 (set (reg:CC FLAGS_REG)
18400 (compare:CC (mem:BLK (match_dup 4))
18401 (mem:BLK (match_dup 5))))
18402 (use (match_dup 6))
18403 (use (match_dup 3))
18404 (clobber (match_dup 0))
18405 (clobber (match_dup 1))
18406 (clobber (match_dup 2))])]
18407 "")
18408
18409 ;; ...and this one handles cmpstrn*_1.
18410 (define_peephole2
18411 [(parallel[
18412 (set (reg:CC FLAGS_REG)
18413 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18414 (const_int 0))
18415 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18416 (mem:BLK (match_operand 5 "register_operand" "")))
18417 (const_int 0)))
18418 (use (match_operand:SI 3 "immediate_operand" ""))
18419 (use (reg:CC FLAGS_REG))
18420 (clobber (match_operand 0 "register_operand" ""))
18421 (clobber (match_operand 1 "register_operand" ""))
18422 (clobber (match_operand 2 "register_operand" ""))])
18423 (set (match_operand:QI 7 "register_operand" "")
18424 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18425 (set (match_operand:QI 8 "register_operand" "")
18426 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18427 (set (reg FLAGS_REG)
18428 (compare (match_dup 7) (match_dup 8)))
18429 ]
18430 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18431 [(parallel[
18432 (set (reg:CC FLAGS_REG)
18433 (if_then_else:CC (ne (match_dup 6)
18434 (const_int 0))
18435 (compare:CC (mem:BLK (match_dup 4))
18436 (mem:BLK (match_dup 5)))
18437 (const_int 0)))
18438 (use (match_dup 3))
18439 (use (reg:CC FLAGS_REG))
18440 (clobber (match_dup 0))
18441 (clobber (match_dup 1))
18442 (clobber (match_dup 2))])]
18443 "")
18444
18445
18446 \f
18447 ;; Conditional move instructions.
18448
18449 (define_expand "movdicc"
18450 [(set (match_operand:DI 0 "register_operand" "")
18451 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18452 (match_operand:DI 2 "general_operand" "")
18453 (match_operand:DI 3 "general_operand" "")))]
18454 "TARGET_64BIT"
18455 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18456
18457 (define_insn "x86_movdicc_0_m1_rex64"
18458 [(set (match_operand:DI 0 "register_operand" "=r")
18459 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18460 (const_int -1)
18461 (const_int 0)))
18462 (clobber (reg:CC FLAGS_REG))]
18463 "TARGET_64BIT"
18464 "sbb{q}\t%0, %0"
18465 ; Since we don't have the proper number of operands for an alu insn,
18466 ; fill in all the blanks.
18467 [(set_attr "type" "alu")
18468 (set_attr "pent_pair" "pu")
18469 (set_attr "memory" "none")
18470 (set_attr "imm_disp" "false")
18471 (set_attr "mode" "DI")
18472 (set_attr "length_immediate" "0")])
18473
18474 (define_insn "*movdicc_c_rex64"
18475 [(set (match_operand:DI 0 "register_operand" "=r,r")
18476 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18477 [(reg FLAGS_REG) (const_int 0)])
18478 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18479 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18480 "TARGET_64BIT && TARGET_CMOVE
18481 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18482 "@
18483 cmov%O2%C1\t{%2, %0|%0, %2}
18484 cmov%O2%c1\t{%3, %0|%0, %3}"
18485 [(set_attr "type" "icmov")
18486 (set_attr "mode" "DI")])
18487
18488 (define_expand "movsicc"
18489 [(set (match_operand:SI 0 "register_operand" "")
18490 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18491 (match_operand:SI 2 "general_operand" "")
18492 (match_operand:SI 3 "general_operand" "")))]
18493 ""
18494 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18495
18496 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18497 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18498 ;; So just document what we're doing explicitly.
18499
18500 (define_insn "x86_movsicc_0_m1"
18501 [(set (match_operand:SI 0 "register_operand" "=r")
18502 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18503 (const_int -1)
18504 (const_int 0)))
18505 (clobber (reg:CC FLAGS_REG))]
18506 ""
18507 "sbb{l}\t%0, %0"
18508 ; Since we don't have the proper number of operands for an alu insn,
18509 ; fill in all the blanks.
18510 [(set_attr "type" "alu")
18511 (set_attr "pent_pair" "pu")
18512 (set_attr "memory" "none")
18513 (set_attr "imm_disp" "false")
18514 (set_attr "mode" "SI")
18515 (set_attr "length_immediate" "0")])
18516
18517 (define_insn "*movsicc_noc"
18518 [(set (match_operand:SI 0 "register_operand" "=r,r")
18519 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18520 [(reg FLAGS_REG) (const_int 0)])
18521 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18522 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18523 "TARGET_CMOVE
18524 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18525 "@
18526 cmov%O2%C1\t{%2, %0|%0, %2}
18527 cmov%O2%c1\t{%3, %0|%0, %3}"
18528 [(set_attr "type" "icmov")
18529 (set_attr "mode" "SI")])
18530
18531 (define_expand "movhicc"
18532 [(set (match_operand:HI 0 "register_operand" "")
18533 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18534 (match_operand:HI 2 "general_operand" "")
18535 (match_operand:HI 3 "general_operand" "")))]
18536 "TARGET_HIMODE_MATH"
18537 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18538
18539 (define_insn "*movhicc_noc"
18540 [(set (match_operand:HI 0 "register_operand" "=r,r")
18541 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18542 [(reg FLAGS_REG) (const_int 0)])
18543 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18544 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18545 "TARGET_CMOVE
18546 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18547 "@
18548 cmov%O2%C1\t{%2, %0|%0, %2}
18549 cmov%O2%c1\t{%3, %0|%0, %3}"
18550 [(set_attr "type" "icmov")
18551 (set_attr "mode" "HI")])
18552
18553 (define_expand "movqicc"
18554 [(set (match_operand:QI 0 "register_operand" "")
18555 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18556 (match_operand:QI 2 "general_operand" "")
18557 (match_operand:QI 3 "general_operand" "")))]
18558 "TARGET_QIMODE_MATH"
18559 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18560
18561 (define_insn_and_split "*movqicc_noc"
18562 [(set (match_operand:QI 0 "register_operand" "=r,r")
18563 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18564 [(match_operand 4 "flags_reg_operand" "")
18565 (const_int 0)])
18566 (match_operand:QI 2 "register_operand" "r,0")
18567 (match_operand:QI 3 "register_operand" "0,r")))]
18568 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18569 "#"
18570 "&& reload_completed"
18571 [(set (match_dup 0)
18572 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18573 (match_dup 2)
18574 (match_dup 3)))]
18575 "operands[0] = gen_lowpart (SImode, operands[0]);
18576 operands[2] = gen_lowpart (SImode, operands[2]);
18577 operands[3] = gen_lowpart (SImode, operands[3]);"
18578 [(set_attr "type" "icmov")
18579 (set_attr "mode" "SI")])
18580
18581 (define_expand "movsfcc"
18582 [(set (match_operand:SF 0 "register_operand" "")
18583 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18584 (match_operand:SF 2 "register_operand" "")
18585 (match_operand:SF 3 "register_operand" "")))]
18586 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18587 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18588
18589 (define_insn "*movsfcc_1_387"
18590 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18591 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18592 [(reg FLAGS_REG) (const_int 0)])
18593 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18594 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18595 "TARGET_80387 && TARGET_CMOVE
18596 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18597 "@
18598 fcmov%F1\t{%2, %0|%0, %2}
18599 fcmov%f1\t{%3, %0|%0, %3}
18600 cmov%O2%C1\t{%2, %0|%0, %2}
18601 cmov%O2%c1\t{%3, %0|%0, %3}"
18602 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18603 (set_attr "mode" "SF,SF,SI,SI")])
18604
18605 (define_expand "movdfcc"
18606 [(set (match_operand:DF 0 "register_operand" "")
18607 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18608 (match_operand:DF 2 "register_operand" "")
18609 (match_operand:DF 3 "register_operand" "")))]
18610 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18611 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18612
18613 (define_insn "*movdfcc_1"
18614 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18615 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18616 [(reg FLAGS_REG) (const_int 0)])
18617 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18618 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18619 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18620 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18621 "@
18622 fcmov%F1\t{%2, %0|%0, %2}
18623 fcmov%f1\t{%3, %0|%0, %3}
18624 #
18625 #"
18626 [(set_attr "type" "fcmov,fcmov,multi,multi")
18627 (set_attr "mode" "DF")])
18628
18629 (define_insn "*movdfcc_1_rex64"
18630 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18631 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18632 [(reg FLAGS_REG) (const_int 0)])
18633 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18634 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18635 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18636 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18637 "@
18638 fcmov%F1\t{%2, %0|%0, %2}
18639 fcmov%f1\t{%3, %0|%0, %3}
18640 cmov%O2%C1\t{%2, %0|%0, %2}
18641 cmov%O2%c1\t{%3, %0|%0, %3}"
18642 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18643 (set_attr "mode" "DF")])
18644
18645 (define_split
18646 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18647 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18648 [(match_operand 4 "flags_reg_operand" "")
18649 (const_int 0)])
18650 (match_operand:DF 2 "nonimmediate_operand" "")
18651 (match_operand:DF 3 "nonimmediate_operand" "")))]
18652 "!TARGET_64BIT && reload_completed"
18653 [(set (match_dup 2)
18654 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18655 (match_dup 5)
18656 (match_dup 7)))
18657 (set (match_dup 3)
18658 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18659 (match_dup 6)
18660 (match_dup 8)))]
18661 "split_di (operands+2, 1, operands+5, operands+6);
18662 split_di (operands+3, 1, operands+7, operands+8);
18663 split_di (operands, 1, operands+2, operands+3);")
18664
18665 (define_expand "movxfcc"
18666 [(set (match_operand:XF 0 "register_operand" "")
18667 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18668 (match_operand:XF 2 "register_operand" "")
18669 (match_operand:XF 3 "register_operand" "")))]
18670 "TARGET_80387 && TARGET_CMOVE"
18671 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18672
18673 (define_insn "*movxfcc_1"
18674 [(set (match_operand:XF 0 "register_operand" "=f,f")
18675 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18676 [(reg FLAGS_REG) (const_int 0)])
18677 (match_operand:XF 2 "register_operand" "f,0")
18678 (match_operand:XF 3 "register_operand" "0,f")))]
18679 "TARGET_80387 && TARGET_CMOVE"
18680 "@
18681 fcmov%F1\t{%2, %0|%0, %2}
18682 fcmov%f1\t{%3, %0|%0, %3}"
18683 [(set_attr "type" "fcmov")
18684 (set_attr "mode" "XF")])
18685
18686 ;; These versions of the min/max patterns are intentionally ignorant of
18687 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18688 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18689 ;; are undefined in this condition, we're certain this is correct.
18690
18691 (define_insn "sminsf3"
18692 [(set (match_operand:SF 0 "register_operand" "=x")
18693 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18694 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18695 "TARGET_SSE_MATH"
18696 "minss\t{%2, %0|%0, %2}"
18697 [(set_attr "type" "sseadd")
18698 (set_attr "mode" "SF")])
18699
18700 (define_insn "smaxsf3"
18701 [(set (match_operand:SF 0 "register_operand" "=x")
18702 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18703 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18704 "TARGET_SSE_MATH"
18705 "maxss\t{%2, %0|%0, %2}"
18706 [(set_attr "type" "sseadd")
18707 (set_attr "mode" "SF")])
18708
18709 (define_insn "smindf3"
18710 [(set (match_operand:DF 0 "register_operand" "=x")
18711 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18712 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18713 "TARGET_SSE2 && TARGET_SSE_MATH"
18714 "minsd\t{%2, %0|%0, %2}"
18715 [(set_attr "type" "sseadd")
18716 (set_attr "mode" "DF")])
18717
18718 (define_insn "smaxdf3"
18719 [(set (match_operand:DF 0 "register_operand" "=x")
18720 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18721 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18722 "TARGET_SSE2 && TARGET_SSE_MATH"
18723 "maxsd\t{%2, %0|%0, %2}"
18724 [(set_attr "type" "sseadd")
18725 (set_attr "mode" "DF")])
18726
18727 ;; These versions of the min/max patterns implement exactly the operations
18728 ;; min = (op1 < op2 ? op1 : op2)
18729 ;; max = (!(op1 < op2) ? op1 : op2)
18730 ;; Their operands are not commutative, and thus they may be used in the
18731 ;; presence of -0.0 and NaN.
18732
18733 (define_insn "*ieee_sminsf3"
18734 [(set (match_operand:SF 0 "register_operand" "=x")
18735 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18736 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18737 UNSPEC_IEEE_MIN))]
18738 "TARGET_SSE_MATH"
18739 "minss\t{%2, %0|%0, %2}"
18740 [(set_attr "type" "sseadd")
18741 (set_attr "mode" "SF")])
18742
18743 (define_insn "*ieee_smaxsf3"
18744 [(set (match_operand:SF 0 "register_operand" "=x")
18745 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18746 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18747 UNSPEC_IEEE_MAX))]
18748 "TARGET_SSE_MATH"
18749 "maxss\t{%2, %0|%0, %2}"
18750 [(set_attr "type" "sseadd")
18751 (set_attr "mode" "SF")])
18752
18753 (define_insn "*ieee_smindf3"
18754 [(set (match_operand:DF 0 "register_operand" "=x")
18755 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18756 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18757 UNSPEC_IEEE_MIN))]
18758 "TARGET_SSE2 && TARGET_SSE_MATH"
18759 "minsd\t{%2, %0|%0, %2}"
18760 [(set_attr "type" "sseadd")
18761 (set_attr "mode" "DF")])
18762
18763 (define_insn "*ieee_smaxdf3"
18764 [(set (match_operand:DF 0 "register_operand" "=x")
18765 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18766 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18767 UNSPEC_IEEE_MAX))]
18768 "TARGET_SSE2 && TARGET_SSE_MATH"
18769 "maxsd\t{%2, %0|%0, %2}"
18770 [(set_attr "type" "sseadd")
18771 (set_attr "mode" "DF")])
18772
18773 ;; Make two stack loads independent:
18774 ;; fld aa fld aa
18775 ;; fld %st(0) -> fld bb
18776 ;; fmul bb fmul %st(1), %st
18777 ;;
18778 ;; Actually we only match the last two instructions for simplicity.
18779 (define_peephole2
18780 [(set (match_operand 0 "fp_register_operand" "")
18781 (match_operand 1 "fp_register_operand" ""))
18782 (set (match_dup 0)
18783 (match_operator 2 "binary_fp_operator"
18784 [(match_dup 0)
18785 (match_operand 3 "memory_operand" "")]))]
18786 "REGNO (operands[0]) != REGNO (operands[1])"
18787 [(set (match_dup 0) (match_dup 3))
18788 (set (match_dup 0) (match_dup 4))]
18789
18790 ;; The % modifier is not operational anymore in peephole2's, so we have to
18791 ;; swap the operands manually in the case of addition and multiplication.
18792 "if (COMMUTATIVE_ARITH_P (operands[2]))
18793 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18794 operands[0], operands[1]);
18795 else
18796 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18797 operands[1], operands[0]);")
18798
18799 ;; Conditional addition patterns
18800 (define_expand "addqicc"
18801 [(match_operand:QI 0 "register_operand" "")
18802 (match_operand 1 "comparison_operator" "")
18803 (match_operand:QI 2 "register_operand" "")
18804 (match_operand:QI 3 "const_int_operand" "")]
18805 ""
18806 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18807
18808 (define_expand "addhicc"
18809 [(match_operand:HI 0 "register_operand" "")
18810 (match_operand 1 "comparison_operator" "")
18811 (match_operand:HI 2 "register_operand" "")
18812 (match_operand:HI 3 "const_int_operand" "")]
18813 ""
18814 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18815
18816 (define_expand "addsicc"
18817 [(match_operand:SI 0 "register_operand" "")
18818 (match_operand 1 "comparison_operator" "")
18819 (match_operand:SI 2 "register_operand" "")
18820 (match_operand:SI 3 "const_int_operand" "")]
18821 ""
18822 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18823
18824 (define_expand "adddicc"
18825 [(match_operand:DI 0 "register_operand" "")
18826 (match_operand 1 "comparison_operator" "")
18827 (match_operand:DI 2 "register_operand" "")
18828 (match_operand:DI 3 "const_int_operand" "")]
18829 "TARGET_64BIT"
18830 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18831
18832 \f
18833 ;; Misc patterns (?)
18834
18835 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18836 ;; Otherwise there will be nothing to keep
18837 ;;
18838 ;; [(set (reg ebp) (reg esp))]
18839 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18840 ;; (clobber (eflags)]
18841 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18842 ;;
18843 ;; in proper program order.
18844 (define_insn "pro_epilogue_adjust_stack_1"
18845 [(set (match_operand:SI 0 "register_operand" "=r,r")
18846 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18847 (match_operand:SI 2 "immediate_operand" "i,i")))
18848 (clobber (reg:CC FLAGS_REG))
18849 (clobber (mem:BLK (scratch)))]
18850 "!TARGET_64BIT"
18851 {
18852 switch (get_attr_type (insn))
18853 {
18854 case TYPE_IMOV:
18855 return "mov{l}\t{%1, %0|%0, %1}";
18856
18857 case TYPE_ALU:
18858 if (CONST_INT_P (operands[2])
18859 && (INTVAL (operands[2]) == 128
18860 || (INTVAL (operands[2]) < 0
18861 && INTVAL (operands[2]) != -128)))
18862 {
18863 operands[2] = GEN_INT (-INTVAL (operands[2]));
18864 return "sub{l}\t{%2, %0|%0, %2}";
18865 }
18866 return "add{l}\t{%2, %0|%0, %2}";
18867
18868 case TYPE_LEA:
18869 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18870 return "lea{l}\t{%a2, %0|%0, %a2}";
18871
18872 default:
18873 gcc_unreachable ();
18874 }
18875 }
18876 [(set (attr "type")
18877 (cond [(eq_attr "alternative" "0")
18878 (const_string "alu")
18879 (match_operand:SI 2 "const0_operand" "")
18880 (const_string "imov")
18881 ]
18882 (const_string "lea")))
18883 (set_attr "mode" "SI")])
18884
18885 (define_insn "pro_epilogue_adjust_stack_rex64"
18886 [(set (match_operand:DI 0 "register_operand" "=r,r")
18887 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18888 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18889 (clobber (reg:CC FLAGS_REG))
18890 (clobber (mem:BLK (scratch)))]
18891 "TARGET_64BIT"
18892 {
18893 switch (get_attr_type (insn))
18894 {
18895 case TYPE_IMOV:
18896 return "mov{q}\t{%1, %0|%0, %1}";
18897
18898 case TYPE_ALU:
18899 if (CONST_INT_P (operands[2])
18900 /* Avoid overflows. */
18901 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18902 && (INTVAL (operands[2]) == 128
18903 || (INTVAL (operands[2]) < 0
18904 && INTVAL (operands[2]) != -128)))
18905 {
18906 operands[2] = GEN_INT (-INTVAL (operands[2]));
18907 return "sub{q}\t{%2, %0|%0, %2}";
18908 }
18909 return "add{q}\t{%2, %0|%0, %2}";
18910
18911 case TYPE_LEA:
18912 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18913 return "lea{q}\t{%a2, %0|%0, %a2}";
18914
18915 default:
18916 gcc_unreachable ();
18917 }
18918 }
18919 [(set (attr "type")
18920 (cond [(eq_attr "alternative" "0")
18921 (const_string "alu")
18922 (match_operand:DI 2 "const0_operand" "")
18923 (const_string "imov")
18924 ]
18925 (const_string "lea")))
18926 (set_attr "mode" "DI")])
18927
18928 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18929 [(set (match_operand:DI 0 "register_operand" "=r,r")
18930 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18931 (match_operand:DI 3 "immediate_operand" "i,i")))
18932 (use (match_operand:DI 2 "register_operand" "r,r"))
18933 (clobber (reg:CC FLAGS_REG))
18934 (clobber (mem:BLK (scratch)))]
18935 "TARGET_64BIT"
18936 {
18937 switch (get_attr_type (insn))
18938 {
18939 case TYPE_ALU:
18940 return "add{q}\t{%2, %0|%0, %2}";
18941
18942 case TYPE_LEA:
18943 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18944 return "lea{q}\t{%a2, %0|%0, %a2}";
18945
18946 default:
18947 gcc_unreachable ();
18948 }
18949 }
18950 [(set_attr "type" "alu,lea")
18951 (set_attr "mode" "DI")])
18952
18953 (define_expand "allocate_stack_worker"
18954 [(match_operand:SI 0 "register_operand" "")]
18955 "TARGET_STACK_PROBE"
18956 {
18957 if (reload_completed)
18958 {
18959 if (TARGET_64BIT)
18960 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18961 else
18962 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18963 }
18964 else
18965 {
18966 if (TARGET_64BIT)
18967 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18968 else
18969 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18970 }
18971 DONE;
18972 })
18973
18974 (define_insn "allocate_stack_worker_1"
18975 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18976 UNSPECV_STACK_PROBE)
18977 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18978 (clobber (match_scratch:SI 1 "=0"))
18979 (clobber (reg:CC FLAGS_REG))]
18980 "!TARGET_64BIT && TARGET_STACK_PROBE"
18981 "call\t__alloca"
18982 [(set_attr "type" "multi")
18983 (set_attr "length" "5")])
18984
18985 (define_expand "allocate_stack_worker_postreload"
18986 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18987 UNSPECV_STACK_PROBE)
18988 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18989 (clobber (match_dup 0))
18990 (clobber (reg:CC FLAGS_REG))])]
18991 ""
18992 "")
18993
18994 (define_insn "allocate_stack_worker_rex64"
18995 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18996 UNSPECV_STACK_PROBE)
18997 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18998 (clobber (match_scratch:DI 1 "=0"))
18999 (clobber (reg:CC FLAGS_REG))]
19000 "TARGET_64BIT && TARGET_STACK_PROBE"
19001 "call\t__alloca"
19002 [(set_attr "type" "multi")
19003 (set_attr "length" "5")])
19004
19005 (define_expand "allocate_stack_worker_rex64_postreload"
19006 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19007 UNSPECV_STACK_PROBE)
19008 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19009 (clobber (match_dup 0))
19010 (clobber (reg:CC FLAGS_REG))])]
19011 ""
19012 "")
19013
19014 (define_expand "allocate_stack"
19015 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19016 (minus:SI (reg:SI SP_REG)
19017 (match_operand:SI 1 "general_operand" "")))
19018 (clobber (reg:CC FLAGS_REG))])
19019 (parallel [(set (reg:SI SP_REG)
19020 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19021 (clobber (reg:CC FLAGS_REG))])]
19022 "TARGET_STACK_PROBE"
19023 {
19024 #ifdef CHECK_STACK_LIMIT
19025 if (CONST_INT_P (operands[1])
19026 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19027 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19028 operands[1]));
19029 else
19030 #endif
19031 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19032 operands[1])));
19033
19034 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19035 DONE;
19036 })
19037
19038 (define_expand "builtin_setjmp_receiver"
19039 [(label_ref (match_operand 0 "" ""))]
19040 "!TARGET_64BIT && flag_pic"
19041 {
19042 if (TARGET_MACHO)
19043 {
19044 rtx xops[3];
19045 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19046 rtx label_rtx = gen_label_rtx ();
19047 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19048 xops[0] = xops[1] = picreg;
19049 xops[2] = gen_rtx_CONST (SImode,
19050 gen_rtx_MINUS (SImode,
19051 gen_rtx_LABEL_REF (SImode, label_rtx),
19052 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19053 ix86_expand_binary_operator (MINUS, SImode, xops);
19054 }
19055 else
19056 emit_insn (gen_set_got (pic_offset_table_rtx));
19057 DONE;
19058 })
19059 \f
19060 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19061
19062 (define_split
19063 [(set (match_operand 0 "register_operand" "")
19064 (match_operator 3 "promotable_binary_operator"
19065 [(match_operand 1 "register_operand" "")
19066 (match_operand 2 "aligned_operand" "")]))
19067 (clobber (reg:CC FLAGS_REG))]
19068 "! TARGET_PARTIAL_REG_STALL && reload_completed
19069 && ((GET_MODE (operands[0]) == HImode
19070 && ((!optimize_size && !TARGET_FAST_PREFIX)
19071 /* ??? next two lines just !satisfies_constraint_K (...) */
19072 || !CONST_INT_P (operands[2])
19073 || satisfies_constraint_K (operands[2])))
19074 || (GET_MODE (operands[0]) == QImode
19075 && (TARGET_PROMOTE_QImode || optimize_size)))"
19076 [(parallel [(set (match_dup 0)
19077 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19078 (clobber (reg:CC FLAGS_REG))])]
19079 "operands[0] = gen_lowpart (SImode, operands[0]);
19080 operands[1] = gen_lowpart (SImode, operands[1]);
19081 if (GET_CODE (operands[3]) != ASHIFT)
19082 operands[2] = gen_lowpart (SImode, operands[2]);
19083 PUT_MODE (operands[3], SImode);")
19084
19085 ; Promote the QImode tests, as i386 has encoding of the AND
19086 ; instruction with 32-bit sign-extended immediate and thus the
19087 ; instruction size is unchanged, except in the %eax case for
19088 ; which it is increased by one byte, hence the ! optimize_size.
19089 (define_split
19090 [(set (match_operand 0 "flags_reg_operand" "")
19091 (match_operator 2 "compare_operator"
19092 [(and (match_operand 3 "aligned_operand" "")
19093 (match_operand 4 "const_int_operand" ""))
19094 (const_int 0)]))
19095 (set (match_operand 1 "register_operand" "")
19096 (and (match_dup 3) (match_dup 4)))]
19097 "! TARGET_PARTIAL_REG_STALL && reload_completed
19098 /* Ensure that the operand will remain sign-extended immediate. */
19099 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19100 && ! optimize_size
19101 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19102 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19103 [(parallel [(set (match_dup 0)
19104 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19105 (const_int 0)]))
19106 (set (match_dup 1)
19107 (and:SI (match_dup 3) (match_dup 4)))])]
19108 {
19109 operands[4]
19110 = gen_int_mode (INTVAL (operands[4])
19111 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19112 operands[1] = gen_lowpart (SImode, operands[1]);
19113 operands[3] = gen_lowpart (SImode, operands[3]);
19114 })
19115
19116 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19117 ; the TEST instruction with 32-bit sign-extended immediate and thus
19118 ; the instruction size would at least double, which is not what we
19119 ; want even with ! optimize_size.
19120 (define_split
19121 [(set (match_operand 0 "flags_reg_operand" "")
19122 (match_operator 1 "compare_operator"
19123 [(and (match_operand:HI 2 "aligned_operand" "")
19124 (match_operand:HI 3 "const_int_operand" ""))
19125 (const_int 0)]))]
19126 "! TARGET_PARTIAL_REG_STALL && reload_completed
19127 /* Ensure that the operand will remain sign-extended immediate. */
19128 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19129 && ! TARGET_FAST_PREFIX
19130 && ! optimize_size"
19131 [(set (match_dup 0)
19132 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19133 (const_int 0)]))]
19134 {
19135 operands[3]
19136 = gen_int_mode (INTVAL (operands[3])
19137 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19138 operands[2] = gen_lowpart (SImode, operands[2]);
19139 })
19140
19141 (define_split
19142 [(set (match_operand 0 "register_operand" "")
19143 (neg (match_operand 1 "register_operand" "")))
19144 (clobber (reg:CC FLAGS_REG))]
19145 "! TARGET_PARTIAL_REG_STALL && reload_completed
19146 && (GET_MODE (operands[0]) == HImode
19147 || (GET_MODE (operands[0]) == QImode
19148 && (TARGET_PROMOTE_QImode || optimize_size)))"
19149 [(parallel [(set (match_dup 0)
19150 (neg:SI (match_dup 1)))
19151 (clobber (reg:CC FLAGS_REG))])]
19152 "operands[0] = gen_lowpart (SImode, operands[0]);
19153 operands[1] = gen_lowpart (SImode, operands[1]);")
19154
19155 (define_split
19156 [(set (match_operand 0 "register_operand" "")
19157 (not (match_operand 1 "register_operand" "")))]
19158 "! TARGET_PARTIAL_REG_STALL && reload_completed
19159 && (GET_MODE (operands[0]) == HImode
19160 || (GET_MODE (operands[0]) == QImode
19161 && (TARGET_PROMOTE_QImode || optimize_size)))"
19162 [(set (match_dup 0)
19163 (not:SI (match_dup 1)))]
19164 "operands[0] = gen_lowpart (SImode, operands[0]);
19165 operands[1] = gen_lowpart (SImode, operands[1]);")
19166
19167 (define_split
19168 [(set (match_operand 0 "register_operand" "")
19169 (if_then_else (match_operator 1 "comparison_operator"
19170 [(reg FLAGS_REG) (const_int 0)])
19171 (match_operand 2 "register_operand" "")
19172 (match_operand 3 "register_operand" "")))]
19173 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19174 && (GET_MODE (operands[0]) == HImode
19175 || (GET_MODE (operands[0]) == QImode
19176 && (TARGET_PROMOTE_QImode || optimize_size)))"
19177 [(set (match_dup 0)
19178 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19179 "operands[0] = gen_lowpart (SImode, operands[0]);
19180 operands[2] = gen_lowpart (SImode, operands[2]);
19181 operands[3] = gen_lowpart (SImode, operands[3]);")
19182
19183 \f
19184 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19185 ;; transform a complex memory operation into two memory to register operations.
19186
19187 ;; Don't push memory operands
19188 (define_peephole2
19189 [(set (match_operand:SI 0 "push_operand" "")
19190 (match_operand:SI 1 "memory_operand" ""))
19191 (match_scratch:SI 2 "r")]
19192 "!optimize_size && !TARGET_PUSH_MEMORY
19193 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19194 [(set (match_dup 2) (match_dup 1))
19195 (set (match_dup 0) (match_dup 2))]
19196 "")
19197
19198 (define_peephole2
19199 [(set (match_operand:DI 0 "push_operand" "")
19200 (match_operand:DI 1 "memory_operand" ""))
19201 (match_scratch:DI 2 "r")]
19202 "!optimize_size && !TARGET_PUSH_MEMORY
19203 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19204 [(set (match_dup 2) (match_dup 1))
19205 (set (match_dup 0) (match_dup 2))]
19206 "")
19207
19208 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19209 ;; SImode pushes.
19210 (define_peephole2
19211 [(set (match_operand:SF 0 "push_operand" "")
19212 (match_operand:SF 1 "memory_operand" ""))
19213 (match_scratch:SF 2 "r")]
19214 "!optimize_size && !TARGET_PUSH_MEMORY
19215 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19216 [(set (match_dup 2) (match_dup 1))
19217 (set (match_dup 0) (match_dup 2))]
19218 "")
19219
19220 (define_peephole2
19221 [(set (match_operand:HI 0 "push_operand" "")
19222 (match_operand:HI 1 "memory_operand" ""))
19223 (match_scratch:HI 2 "r")]
19224 "!optimize_size && !TARGET_PUSH_MEMORY
19225 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19226 [(set (match_dup 2) (match_dup 1))
19227 (set (match_dup 0) (match_dup 2))]
19228 "")
19229
19230 (define_peephole2
19231 [(set (match_operand:QI 0 "push_operand" "")
19232 (match_operand:QI 1 "memory_operand" ""))
19233 (match_scratch:QI 2 "q")]
19234 "!optimize_size && !TARGET_PUSH_MEMORY
19235 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19236 [(set (match_dup 2) (match_dup 1))
19237 (set (match_dup 0) (match_dup 2))]
19238 "")
19239
19240 ;; Don't move an immediate directly to memory when the instruction
19241 ;; gets too big.
19242 (define_peephole2
19243 [(match_scratch:SI 1 "r")
19244 (set (match_operand:SI 0 "memory_operand" "")
19245 (const_int 0))]
19246 "! optimize_size
19247 && ! TARGET_USE_MOV0
19248 && TARGET_SPLIT_LONG_MOVES
19249 && get_attr_length (insn) >= ix86_cost->large_insn
19250 && peep2_regno_dead_p (0, FLAGS_REG)"
19251 [(parallel [(set (match_dup 1) (const_int 0))
19252 (clobber (reg:CC FLAGS_REG))])
19253 (set (match_dup 0) (match_dup 1))]
19254 "")
19255
19256 (define_peephole2
19257 [(match_scratch:HI 1 "r")
19258 (set (match_operand:HI 0 "memory_operand" "")
19259 (const_int 0))]
19260 "! optimize_size
19261 && ! TARGET_USE_MOV0
19262 && TARGET_SPLIT_LONG_MOVES
19263 && get_attr_length (insn) >= ix86_cost->large_insn
19264 && peep2_regno_dead_p (0, FLAGS_REG)"
19265 [(parallel [(set (match_dup 2) (const_int 0))
19266 (clobber (reg:CC FLAGS_REG))])
19267 (set (match_dup 0) (match_dup 1))]
19268 "operands[2] = gen_lowpart (SImode, operands[1]);")
19269
19270 (define_peephole2
19271 [(match_scratch:QI 1 "q")
19272 (set (match_operand:QI 0 "memory_operand" "")
19273 (const_int 0))]
19274 "! optimize_size
19275 && ! TARGET_USE_MOV0
19276 && TARGET_SPLIT_LONG_MOVES
19277 && get_attr_length (insn) >= ix86_cost->large_insn
19278 && peep2_regno_dead_p (0, FLAGS_REG)"
19279 [(parallel [(set (match_dup 2) (const_int 0))
19280 (clobber (reg:CC FLAGS_REG))])
19281 (set (match_dup 0) (match_dup 1))]
19282 "operands[2] = gen_lowpart (SImode, operands[1]);")
19283
19284 (define_peephole2
19285 [(match_scratch:SI 2 "r")
19286 (set (match_operand:SI 0 "memory_operand" "")
19287 (match_operand:SI 1 "immediate_operand" ""))]
19288 "! optimize_size
19289 && get_attr_length (insn) >= ix86_cost->large_insn
19290 && TARGET_SPLIT_LONG_MOVES"
19291 [(set (match_dup 2) (match_dup 1))
19292 (set (match_dup 0) (match_dup 2))]
19293 "")
19294
19295 (define_peephole2
19296 [(match_scratch:HI 2 "r")
19297 (set (match_operand:HI 0 "memory_operand" "")
19298 (match_operand:HI 1 "immediate_operand" ""))]
19299 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19300 && TARGET_SPLIT_LONG_MOVES"
19301 [(set (match_dup 2) (match_dup 1))
19302 (set (match_dup 0) (match_dup 2))]
19303 "")
19304
19305 (define_peephole2
19306 [(match_scratch:QI 2 "q")
19307 (set (match_operand:QI 0 "memory_operand" "")
19308 (match_operand:QI 1 "immediate_operand" ""))]
19309 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19310 && TARGET_SPLIT_LONG_MOVES"
19311 [(set (match_dup 2) (match_dup 1))
19312 (set (match_dup 0) (match_dup 2))]
19313 "")
19314
19315 ;; Don't compare memory with zero, load and use a test instead.
19316 (define_peephole2
19317 [(set (match_operand 0 "flags_reg_operand" "")
19318 (match_operator 1 "compare_operator"
19319 [(match_operand:SI 2 "memory_operand" "")
19320 (const_int 0)]))
19321 (match_scratch:SI 3 "r")]
19322 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19323 [(set (match_dup 3) (match_dup 2))
19324 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19325 "")
19326
19327 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19328 ;; Don't split NOTs with a displacement operand, because resulting XOR
19329 ;; will not be pairable anyway.
19330 ;;
19331 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19332 ;; represented using a modRM byte. The XOR replacement is long decoded,
19333 ;; so this split helps here as well.
19334 ;;
19335 ;; Note: Can't do this as a regular split because we can't get proper
19336 ;; lifetime information then.
19337
19338 (define_peephole2
19339 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19340 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19341 "!optimize_size
19342 && peep2_regno_dead_p (0, FLAGS_REG)
19343 && ((TARGET_PENTIUM
19344 && (!MEM_P (operands[0])
19345 || !memory_displacement_operand (operands[0], SImode)))
19346 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19347 [(parallel [(set (match_dup 0)
19348 (xor:SI (match_dup 1) (const_int -1)))
19349 (clobber (reg:CC FLAGS_REG))])]
19350 "")
19351
19352 (define_peephole2
19353 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19354 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19355 "!optimize_size
19356 && peep2_regno_dead_p (0, FLAGS_REG)
19357 && ((TARGET_PENTIUM
19358 && (!MEM_P (operands[0])
19359 || !memory_displacement_operand (operands[0], HImode)))
19360 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19361 [(parallel [(set (match_dup 0)
19362 (xor:HI (match_dup 1) (const_int -1)))
19363 (clobber (reg:CC FLAGS_REG))])]
19364 "")
19365
19366 (define_peephole2
19367 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19368 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19369 "!optimize_size
19370 && peep2_regno_dead_p (0, FLAGS_REG)
19371 && ((TARGET_PENTIUM
19372 && (!MEM_P (operands[0])
19373 || !memory_displacement_operand (operands[0], QImode)))
19374 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19375 [(parallel [(set (match_dup 0)
19376 (xor:QI (match_dup 1) (const_int -1)))
19377 (clobber (reg:CC FLAGS_REG))])]
19378 "")
19379
19380 ;; Non pairable "test imm, reg" instructions can be translated to
19381 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19382 ;; byte opcode instead of two, have a short form for byte operands),
19383 ;; so do it for other CPUs as well. Given that the value was dead,
19384 ;; this should not create any new dependencies. Pass on the sub-word
19385 ;; versions if we're concerned about partial register stalls.
19386
19387 (define_peephole2
19388 [(set (match_operand 0 "flags_reg_operand" "")
19389 (match_operator 1 "compare_operator"
19390 [(and:SI (match_operand:SI 2 "register_operand" "")
19391 (match_operand:SI 3 "immediate_operand" ""))
19392 (const_int 0)]))]
19393 "ix86_match_ccmode (insn, CCNOmode)
19394 && (true_regnum (operands[2]) != 0
19395 || satisfies_constraint_K (operands[3]))
19396 && peep2_reg_dead_p (1, operands[2])"
19397 [(parallel
19398 [(set (match_dup 0)
19399 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19400 (const_int 0)]))
19401 (set (match_dup 2)
19402 (and:SI (match_dup 2) (match_dup 3)))])]
19403 "")
19404
19405 ;; We don't need to handle HImode case, because it will be promoted to SImode
19406 ;; on ! TARGET_PARTIAL_REG_STALL
19407
19408 (define_peephole2
19409 [(set (match_operand 0 "flags_reg_operand" "")
19410 (match_operator 1 "compare_operator"
19411 [(and:QI (match_operand:QI 2 "register_operand" "")
19412 (match_operand:QI 3 "immediate_operand" ""))
19413 (const_int 0)]))]
19414 "! TARGET_PARTIAL_REG_STALL
19415 && ix86_match_ccmode (insn, CCNOmode)
19416 && true_regnum (operands[2]) != 0
19417 && peep2_reg_dead_p (1, operands[2])"
19418 [(parallel
19419 [(set (match_dup 0)
19420 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19421 (const_int 0)]))
19422 (set (match_dup 2)
19423 (and:QI (match_dup 2) (match_dup 3)))])]
19424 "")
19425
19426 (define_peephole2
19427 [(set (match_operand 0 "flags_reg_operand" "")
19428 (match_operator 1 "compare_operator"
19429 [(and:SI
19430 (zero_extract:SI
19431 (match_operand 2 "ext_register_operand" "")
19432 (const_int 8)
19433 (const_int 8))
19434 (match_operand 3 "const_int_operand" ""))
19435 (const_int 0)]))]
19436 "! TARGET_PARTIAL_REG_STALL
19437 && ix86_match_ccmode (insn, CCNOmode)
19438 && true_regnum (operands[2]) != 0
19439 && peep2_reg_dead_p (1, operands[2])"
19440 [(parallel [(set (match_dup 0)
19441 (match_op_dup 1
19442 [(and:SI
19443 (zero_extract:SI
19444 (match_dup 2)
19445 (const_int 8)
19446 (const_int 8))
19447 (match_dup 3))
19448 (const_int 0)]))
19449 (set (zero_extract:SI (match_dup 2)
19450 (const_int 8)
19451 (const_int 8))
19452 (and:SI
19453 (zero_extract:SI
19454 (match_dup 2)
19455 (const_int 8)
19456 (const_int 8))
19457 (match_dup 3)))])]
19458 "")
19459
19460 ;; Don't do logical operations with memory inputs.
19461 (define_peephole2
19462 [(match_scratch:SI 2 "r")
19463 (parallel [(set (match_operand:SI 0 "register_operand" "")
19464 (match_operator:SI 3 "arith_or_logical_operator"
19465 [(match_dup 0)
19466 (match_operand:SI 1 "memory_operand" "")]))
19467 (clobber (reg:CC FLAGS_REG))])]
19468 "! optimize_size && ! TARGET_READ_MODIFY"
19469 [(set (match_dup 2) (match_dup 1))
19470 (parallel [(set (match_dup 0)
19471 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19472 (clobber (reg:CC FLAGS_REG))])]
19473 "")
19474
19475 (define_peephole2
19476 [(match_scratch:SI 2 "r")
19477 (parallel [(set (match_operand:SI 0 "register_operand" "")
19478 (match_operator:SI 3 "arith_or_logical_operator"
19479 [(match_operand:SI 1 "memory_operand" "")
19480 (match_dup 0)]))
19481 (clobber (reg:CC FLAGS_REG))])]
19482 "! optimize_size && ! TARGET_READ_MODIFY"
19483 [(set (match_dup 2) (match_dup 1))
19484 (parallel [(set (match_dup 0)
19485 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19486 (clobber (reg:CC FLAGS_REG))])]
19487 "")
19488
19489 ; Don't do logical operations with memory outputs
19490 ;
19491 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19492 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19493 ; the same decoder scheduling characteristics as the original.
19494
19495 (define_peephole2
19496 [(match_scratch:SI 2 "r")
19497 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19498 (match_operator:SI 3 "arith_or_logical_operator"
19499 [(match_dup 0)
19500 (match_operand:SI 1 "nonmemory_operand" "")]))
19501 (clobber (reg:CC FLAGS_REG))])]
19502 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19503 [(set (match_dup 2) (match_dup 0))
19504 (parallel [(set (match_dup 2)
19505 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19506 (clobber (reg:CC FLAGS_REG))])
19507 (set (match_dup 0) (match_dup 2))]
19508 "")
19509
19510 (define_peephole2
19511 [(match_scratch:SI 2 "r")
19512 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19513 (match_operator:SI 3 "arith_or_logical_operator"
19514 [(match_operand:SI 1 "nonmemory_operand" "")
19515 (match_dup 0)]))
19516 (clobber (reg:CC FLAGS_REG))])]
19517 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19518 [(set (match_dup 2) (match_dup 0))
19519 (parallel [(set (match_dup 2)
19520 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19521 (clobber (reg:CC FLAGS_REG))])
19522 (set (match_dup 0) (match_dup 2))]
19523 "")
19524
19525 ;; Attempt to always use XOR for zeroing registers.
19526 (define_peephole2
19527 [(set (match_operand 0 "register_operand" "")
19528 (match_operand 1 "const0_operand" ""))]
19529 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19530 && (! TARGET_USE_MOV0 || optimize_size)
19531 && GENERAL_REG_P (operands[0])
19532 && peep2_regno_dead_p (0, FLAGS_REG)"
19533 [(parallel [(set (match_dup 0) (const_int 0))
19534 (clobber (reg:CC FLAGS_REG))])]
19535 {
19536 operands[0] = gen_lowpart (word_mode, operands[0]);
19537 })
19538
19539 (define_peephole2
19540 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19541 (const_int 0))]
19542 "(GET_MODE (operands[0]) == QImode
19543 || GET_MODE (operands[0]) == HImode)
19544 && (! TARGET_USE_MOV0 || optimize_size)
19545 && peep2_regno_dead_p (0, FLAGS_REG)"
19546 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19547 (clobber (reg:CC FLAGS_REG))])])
19548
19549 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19550 (define_peephole2
19551 [(set (match_operand 0 "register_operand" "")
19552 (const_int -1))]
19553 "(GET_MODE (operands[0]) == HImode
19554 || GET_MODE (operands[0]) == SImode
19555 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19556 && (optimize_size || TARGET_PENTIUM)
19557 && peep2_regno_dead_p (0, FLAGS_REG)"
19558 [(parallel [(set (match_dup 0) (const_int -1))
19559 (clobber (reg:CC FLAGS_REG))])]
19560 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19561 operands[0]);")
19562
19563 ;; Attempt to convert simple leas to adds. These can be created by
19564 ;; move expanders.
19565 (define_peephole2
19566 [(set (match_operand:SI 0 "register_operand" "")
19567 (plus:SI (match_dup 0)
19568 (match_operand:SI 1 "nonmemory_operand" "")))]
19569 "peep2_regno_dead_p (0, FLAGS_REG)"
19570 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19571 (clobber (reg:CC FLAGS_REG))])]
19572 "")
19573
19574 (define_peephole2
19575 [(set (match_operand:SI 0 "register_operand" "")
19576 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19577 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19578 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19579 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19580 (clobber (reg:CC FLAGS_REG))])]
19581 "operands[2] = gen_lowpart (SImode, operands[2]);")
19582
19583 (define_peephole2
19584 [(set (match_operand:DI 0 "register_operand" "")
19585 (plus:DI (match_dup 0)
19586 (match_operand:DI 1 "x86_64_general_operand" "")))]
19587 "peep2_regno_dead_p (0, FLAGS_REG)"
19588 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19589 (clobber (reg:CC FLAGS_REG))])]
19590 "")
19591
19592 (define_peephole2
19593 [(set (match_operand:SI 0 "register_operand" "")
19594 (mult:SI (match_dup 0)
19595 (match_operand:SI 1 "const_int_operand" "")))]
19596 "exact_log2 (INTVAL (operands[1])) >= 0
19597 && peep2_regno_dead_p (0, FLAGS_REG)"
19598 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19599 (clobber (reg:CC FLAGS_REG))])]
19600 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19601
19602 (define_peephole2
19603 [(set (match_operand:DI 0 "register_operand" "")
19604 (mult:DI (match_dup 0)
19605 (match_operand:DI 1 "const_int_operand" "")))]
19606 "exact_log2 (INTVAL (operands[1])) >= 0
19607 && peep2_regno_dead_p (0, FLAGS_REG)"
19608 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19609 (clobber (reg:CC FLAGS_REG))])]
19610 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19611
19612 (define_peephole2
19613 [(set (match_operand:SI 0 "register_operand" "")
19614 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19615 (match_operand:DI 2 "const_int_operand" "")) 0))]
19616 "exact_log2 (INTVAL (operands[2])) >= 0
19617 && REGNO (operands[0]) == REGNO (operands[1])
19618 && peep2_regno_dead_p (0, FLAGS_REG)"
19619 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19620 (clobber (reg:CC FLAGS_REG))])]
19621 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19622
19623 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19624 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19625 ;; many CPUs it is also faster, since special hardware to avoid esp
19626 ;; dependencies is present.
19627
19628 ;; While some of these conversions may be done using splitters, we use peepholes
19629 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19630
19631 ;; Convert prologue esp subtractions to push.
19632 ;; We need register to push. In order to keep verify_flow_info happy we have
19633 ;; two choices
19634 ;; - use scratch and clobber it in order to avoid dependencies
19635 ;; - use already live register
19636 ;; We can't use the second way right now, since there is no reliable way how to
19637 ;; verify that given register is live. First choice will also most likely in
19638 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19639 ;; call clobbered registers are dead. We may want to use base pointer as an
19640 ;; alternative when no register is available later.
19641
19642 (define_peephole2
19643 [(match_scratch:SI 0 "r")
19644 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19645 (clobber (reg:CC FLAGS_REG))
19646 (clobber (mem:BLK (scratch)))])]
19647 "optimize_size || !TARGET_SUB_ESP_4"
19648 [(clobber (match_dup 0))
19649 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19650 (clobber (mem:BLK (scratch)))])])
19651
19652 (define_peephole2
19653 [(match_scratch:SI 0 "r")
19654 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19655 (clobber (reg:CC FLAGS_REG))
19656 (clobber (mem:BLK (scratch)))])]
19657 "optimize_size || !TARGET_SUB_ESP_8"
19658 [(clobber (match_dup 0))
19659 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19660 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19661 (clobber (mem:BLK (scratch)))])])
19662
19663 ;; Convert esp subtractions to push.
19664 (define_peephole2
19665 [(match_scratch:SI 0 "r")
19666 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19667 (clobber (reg:CC FLAGS_REG))])]
19668 "optimize_size || !TARGET_SUB_ESP_4"
19669 [(clobber (match_dup 0))
19670 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19671
19672 (define_peephole2
19673 [(match_scratch:SI 0 "r")
19674 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19675 (clobber (reg:CC FLAGS_REG))])]
19676 "optimize_size || !TARGET_SUB_ESP_8"
19677 [(clobber (match_dup 0))
19678 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19679 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19680
19681 ;; Convert epilogue deallocator to pop.
19682 (define_peephole2
19683 [(match_scratch:SI 0 "r")
19684 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19685 (clobber (reg:CC FLAGS_REG))
19686 (clobber (mem:BLK (scratch)))])]
19687 "optimize_size || !TARGET_ADD_ESP_4"
19688 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19689 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19690 (clobber (mem:BLK (scratch)))])]
19691 "")
19692
19693 ;; Two pops case is tricky, since pop causes dependency on destination register.
19694 ;; We use two registers if available.
19695 (define_peephole2
19696 [(match_scratch:SI 0 "r")
19697 (match_scratch:SI 1 "r")
19698 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19699 (clobber (reg:CC FLAGS_REG))
19700 (clobber (mem:BLK (scratch)))])]
19701 "optimize_size || !TARGET_ADD_ESP_8"
19702 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19703 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19704 (clobber (mem:BLK (scratch)))])
19705 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19706 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19707 "")
19708
19709 (define_peephole2
19710 [(match_scratch:SI 0 "r")
19711 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19712 (clobber (reg:CC FLAGS_REG))
19713 (clobber (mem:BLK (scratch)))])]
19714 "optimize_size"
19715 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19716 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19717 (clobber (mem:BLK (scratch)))])
19718 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19719 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19720 "")
19721
19722 ;; Convert esp additions to pop.
19723 (define_peephole2
19724 [(match_scratch:SI 0 "r")
19725 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19726 (clobber (reg:CC FLAGS_REG))])]
19727 ""
19728 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19729 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19730 "")
19731
19732 ;; Two pops case is tricky, since pop causes dependency on destination register.
19733 ;; We use two registers if available.
19734 (define_peephole2
19735 [(match_scratch:SI 0 "r")
19736 (match_scratch:SI 1 "r")
19737 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19738 (clobber (reg:CC FLAGS_REG))])]
19739 ""
19740 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19741 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19742 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19743 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19744 "")
19745
19746 (define_peephole2
19747 [(match_scratch:SI 0 "r")
19748 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19749 (clobber (reg:CC FLAGS_REG))])]
19750 "optimize_size"
19751 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19752 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19753 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19754 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19755 "")
19756 \f
19757 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19758 ;; required and register dies. Similarly for 128 to plus -128.
19759 (define_peephole2
19760 [(set (match_operand 0 "flags_reg_operand" "")
19761 (match_operator 1 "compare_operator"
19762 [(match_operand 2 "register_operand" "")
19763 (match_operand 3 "const_int_operand" "")]))]
19764 "(INTVAL (operands[3]) == -1
19765 || INTVAL (operands[3]) == 1
19766 || INTVAL (operands[3]) == 128)
19767 && ix86_match_ccmode (insn, CCGCmode)
19768 && peep2_reg_dead_p (1, operands[2])"
19769 [(parallel [(set (match_dup 0)
19770 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19771 (clobber (match_dup 2))])]
19772 "")
19773 \f
19774 (define_peephole2
19775 [(match_scratch:DI 0 "r")
19776 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19777 (clobber (reg:CC FLAGS_REG))
19778 (clobber (mem:BLK (scratch)))])]
19779 "optimize_size || !TARGET_SUB_ESP_4"
19780 [(clobber (match_dup 0))
19781 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19782 (clobber (mem:BLK (scratch)))])])
19783
19784 (define_peephole2
19785 [(match_scratch:DI 0 "r")
19786 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19787 (clobber (reg:CC FLAGS_REG))
19788 (clobber (mem:BLK (scratch)))])]
19789 "optimize_size || !TARGET_SUB_ESP_8"
19790 [(clobber (match_dup 0))
19791 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19792 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19793 (clobber (mem:BLK (scratch)))])])
19794
19795 ;; Convert esp subtractions to push.
19796 (define_peephole2
19797 [(match_scratch:DI 0 "r")
19798 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19799 (clobber (reg:CC FLAGS_REG))])]
19800 "optimize_size || !TARGET_SUB_ESP_4"
19801 [(clobber (match_dup 0))
19802 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19803
19804 (define_peephole2
19805 [(match_scratch:DI 0 "r")
19806 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19807 (clobber (reg:CC FLAGS_REG))])]
19808 "optimize_size || !TARGET_SUB_ESP_8"
19809 [(clobber (match_dup 0))
19810 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19811 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19812
19813 ;; Convert epilogue deallocator to pop.
19814 (define_peephole2
19815 [(match_scratch:DI 0 "r")
19816 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19817 (clobber (reg:CC FLAGS_REG))
19818 (clobber (mem:BLK (scratch)))])]
19819 "optimize_size || !TARGET_ADD_ESP_4"
19820 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19821 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19822 (clobber (mem:BLK (scratch)))])]
19823 "")
19824
19825 ;; Two pops case is tricky, since pop causes dependency on destination register.
19826 ;; We use two registers if available.
19827 (define_peephole2
19828 [(match_scratch:DI 0 "r")
19829 (match_scratch:DI 1 "r")
19830 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19831 (clobber (reg:CC FLAGS_REG))
19832 (clobber (mem:BLK (scratch)))])]
19833 "optimize_size || !TARGET_ADD_ESP_8"
19834 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19835 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19836 (clobber (mem:BLK (scratch)))])
19837 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19838 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19839 "")
19840
19841 (define_peephole2
19842 [(match_scratch:DI 0 "r")
19843 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19844 (clobber (reg:CC FLAGS_REG))
19845 (clobber (mem:BLK (scratch)))])]
19846 "optimize_size"
19847 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19848 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19849 (clobber (mem:BLK (scratch)))])
19850 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19851 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19852 "")
19853
19854 ;; Convert esp additions to pop.
19855 (define_peephole2
19856 [(match_scratch:DI 0 "r")
19857 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19858 (clobber (reg:CC FLAGS_REG))])]
19859 ""
19860 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19861 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19862 "")
19863
19864 ;; Two pops case is tricky, since pop causes dependency on destination register.
19865 ;; We use two registers if available.
19866 (define_peephole2
19867 [(match_scratch:DI 0 "r")
19868 (match_scratch:DI 1 "r")
19869 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19870 (clobber (reg:CC FLAGS_REG))])]
19871 ""
19872 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19873 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19874 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19875 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19876 "")
19877
19878 (define_peephole2
19879 [(match_scratch:DI 0 "r")
19880 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19881 (clobber (reg:CC FLAGS_REG))])]
19882 "optimize_size"
19883 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19884 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19885 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19886 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19887 "")
19888 \f
19889 ;; Convert imul by three, five and nine into lea
19890 (define_peephole2
19891 [(parallel
19892 [(set (match_operand:SI 0 "register_operand" "")
19893 (mult:SI (match_operand:SI 1 "register_operand" "")
19894 (match_operand:SI 2 "const_int_operand" "")))
19895 (clobber (reg:CC FLAGS_REG))])]
19896 "INTVAL (operands[2]) == 3
19897 || INTVAL (operands[2]) == 5
19898 || INTVAL (operands[2]) == 9"
19899 [(set (match_dup 0)
19900 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19901 (match_dup 1)))]
19902 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19903
19904 (define_peephole2
19905 [(parallel
19906 [(set (match_operand:SI 0 "register_operand" "")
19907 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19908 (match_operand:SI 2 "const_int_operand" "")))
19909 (clobber (reg:CC FLAGS_REG))])]
19910 "!optimize_size
19911 && (INTVAL (operands[2]) == 3
19912 || INTVAL (operands[2]) == 5
19913 || INTVAL (operands[2]) == 9)"
19914 [(set (match_dup 0) (match_dup 1))
19915 (set (match_dup 0)
19916 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19917 (match_dup 0)))]
19918 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19919
19920 (define_peephole2
19921 [(parallel
19922 [(set (match_operand:DI 0 "register_operand" "")
19923 (mult:DI (match_operand:DI 1 "register_operand" "")
19924 (match_operand:DI 2 "const_int_operand" "")))
19925 (clobber (reg:CC FLAGS_REG))])]
19926 "TARGET_64BIT
19927 && (INTVAL (operands[2]) == 3
19928 || INTVAL (operands[2]) == 5
19929 || INTVAL (operands[2]) == 9)"
19930 [(set (match_dup 0)
19931 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19932 (match_dup 1)))]
19933 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19934
19935 (define_peephole2
19936 [(parallel
19937 [(set (match_operand:DI 0 "register_operand" "")
19938 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19939 (match_operand:DI 2 "const_int_operand" "")))
19940 (clobber (reg:CC FLAGS_REG))])]
19941 "TARGET_64BIT
19942 && !optimize_size
19943 && (INTVAL (operands[2]) == 3
19944 || INTVAL (operands[2]) == 5
19945 || INTVAL (operands[2]) == 9)"
19946 [(set (match_dup 0) (match_dup 1))
19947 (set (match_dup 0)
19948 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19949 (match_dup 0)))]
19950 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19951
19952 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19953 ;; imul $32bit_imm, reg, reg is direct decoded.
19954 (define_peephole2
19955 [(match_scratch:DI 3 "r")
19956 (parallel [(set (match_operand:DI 0 "register_operand" "")
19957 (mult:DI (match_operand:DI 1 "memory_operand" "")
19958 (match_operand:DI 2 "immediate_operand" "")))
19959 (clobber (reg:CC FLAGS_REG))])]
19960 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19961 && !satisfies_constraint_K (operands[2])"
19962 [(set (match_dup 3) (match_dup 1))
19963 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19964 (clobber (reg:CC FLAGS_REG))])]
19965 "")
19966
19967 (define_peephole2
19968 [(match_scratch:SI 3 "r")
19969 (parallel [(set (match_operand:SI 0 "register_operand" "")
19970 (mult:SI (match_operand:SI 1 "memory_operand" "")
19971 (match_operand:SI 2 "immediate_operand" "")))
19972 (clobber (reg:CC FLAGS_REG))])]
19973 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19974 && !satisfies_constraint_K (operands[2])"
19975 [(set (match_dup 3) (match_dup 1))
19976 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19977 (clobber (reg:CC FLAGS_REG))])]
19978 "")
19979
19980 (define_peephole2
19981 [(match_scratch:SI 3 "r")
19982 (parallel [(set (match_operand:DI 0 "register_operand" "")
19983 (zero_extend:DI
19984 (mult:SI (match_operand:SI 1 "memory_operand" "")
19985 (match_operand:SI 2 "immediate_operand" ""))))
19986 (clobber (reg:CC FLAGS_REG))])]
19987 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19988 && !satisfies_constraint_K (operands[2])"
19989 [(set (match_dup 3) (match_dup 1))
19990 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19991 (clobber (reg:CC FLAGS_REG))])]
19992 "")
19993
19994 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19995 ;; Convert it into imul reg, reg
19996 ;; It would be better to force assembler to encode instruction using long
19997 ;; immediate, but there is apparently no way to do so.
19998 (define_peephole2
19999 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20000 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20001 (match_operand:DI 2 "const_int_operand" "")))
20002 (clobber (reg:CC FLAGS_REG))])
20003 (match_scratch:DI 3 "r")]
20004 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20005 && satisfies_constraint_K (operands[2])"
20006 [(set (match_dup 3) (match_dup 2))
20007 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20008 (clobber (reg:CC FLAGS_REG))])]
20009 {
20010 if (!rtx_equal_p (operands[0], operands[1]))
20011 emit_move_insn (operands[0], operands[1]);
20012 })
20013
20014 (define_peephole2
20015 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20016 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20017 (match_operand:SI 2 "const_int_operand" "")))
20018 (clobber (reg:CC FLAGS_REG))])
20019 (match_scratch:SI 3 "r")]
20020 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20021 && satisfies_constraint_K (operands[2])"
20022 [(set (match_dup 3) (match_dup 2))
20023 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20024 (clobber (reg:CC FLAGS_REG))])]
20025 {
20026 if (!rtx_equal_p (operands[0], operands[1]))
20027 emit_move_insn (operands[0], operands[1]);
20028 })
20029
20030 (define_peephole2
20031 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20032 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20033 (match_operand:HI 2 "immediate_operand" "")))
20034 (clobber (reg:CC FLAGS_REG))])
20035 (match_scratch:HI 3 "r")]
20036 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20037 [(set (match_dup 3) (match_dup 2))
20038 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20039 (clobber (reg:CC FLAGS_REG))])]
20040 {
20041 if (!rtx_equal_p (operands[0], operands[1]))
20042 emit_move_insn (operands[0], operands[1]);
20043 })
20044
20045 ;; After splitting up read-modify operations, array accesses with memory
20046 ;; operands might end up in form:
20047 ;; sall $2, %eax
20048 ;; movl 4(%esp), %edx
20049 ;; addl %edx, %eax
20050 ;; instead of pre-splitting:
20051 ;; sall $2, %eax
20052 ;; addl 4(%esp), %eax
20053 ;; Turn it into:
20054 ;; movl 4(%esp), %edx
20055 ;; leal (%edx,%eax,4), %eax
20056
20057 (define_peephole2
20058 [(parallel [(set (match_operand 0 "register_operand" "")
20059 (ashift (match_operand 1 "register_operand" "")
20060 (match_operand 2 "const_int_operand" "")))
20061 (clobber (reg:CC FLAGS_REG))])
20062 (set (match_operand 3 "register_operand")
20063 (match_operand 4 "x86_64_general_operand" ""))
20064 (parallel [(set (match_operand 5 "register_operand" "")
20065 (plus (match_operand 6 "register_operand" "")
20066 (match_operand 7 "register_operand" "")))
20067 (clobber (reg:CC FLAGS_REG))])]
20068 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20069 /* Validate MODE for lea. */
20070 && ((!TARGET_PARTIAL_REG_STALL
20071 && (GET_MODE (operands[0]) == QImode
20072 || GET_MODE (operands[0]) == HImode))
20073 || GET_MODE (operands[0]) == SImode
20074 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20075 /* We reorder load and the shift. */
20076 && !rtx_equal_p (operands[1], operands[3])
20077 && !reg_overlap_mentioned_p (operands[0], operands[4])
20078 /* Last PLUS must consist of operand 0 and 3. */
20079 && !rtx_equal_p (operands[0], operands[3])
20080 && (rtx_equal_p (operands[3], operands[6])
20081 || rtx_equal_p (operands[3], operands[7]))
20082 && (rtx_equal_p (operands[0], operands[6])
20083 || rtx_equal_p (operands[0], operands[7]))
20084 /* The intermediate operand 0 must die or be same as output. */
20085 && (rtx_equal_p (operands[0], operands[5])
20086 || peep2_reg_dead_p (3, operands[0]))"
20087 [(set (match_dup 3) (match_dup 4))
20088 (set (match_dup 0) (match_dup 1))]
20089 {
20090 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20091 int scale = 1 << INTVAL (operands[2]);
20092 rtx index = gen_lowpart (Pmode, operands[1]);
20093 rtx base = gen_lowpart (Pmode, operands[3]);
20094 rtx dest = gen_lowpart (mode, operands[5]);
20095
20096 operands[1] = gen_rtx_PLUS (Pmode, base,
20097 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20098 if (mode != Pmode)
20099 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20100 operands[0] = dest;
20101 })
20102 \f
20103 ;; Call-value patterns last so that the wildcard operand does not
20104 ;; disrupt insn-recog's switch tables.
20105
20106 (define_insn "*call_value_pop_0"
20107 [(set (match_operand 0 "" "")
20108 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20109 (match_operand:SI 2 "" "")))
20110 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20111 (match_operand:SI 3 "immediate_operand" "")))]
20112 "!TARGET_64BIT"
20113 {
20114 if (SIBLING_CALL_P (insn))
20115 return "jmp\t%P1";
20116 else
20117 return "call\t%P1";
20118 }
20119 [(set_attr "type" "callv")])
20120
20121 (define_insn "*call_value_pop_1"
20122 [(set (match_operand 0 "" "")
20123 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20124 (match_operand:SI 2 "" "")))
20125 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20126 (match_operand:SI 3 "immediate_operand" "i")))]
20127 "!TARGET_64BIT"
20128 {
20129 if (constant_call_address_operand (operands[1], Pmode))
20130 {
20131 if (SIBLING_CALL_P (insn))
20132 return "jmp\t%P1";
20133 else
20134 return "call\t%P1";
20135 }
20136 if (SIBLING_CALL_P (insn))
20137 return "jmp\t%A1";
20138 else
20139 return "call\t%A1";
20140 }
20141 [(set_attr "type" "callv")])
20142
20143 (define_insn "*call_value_0"
20144 [(set (match_operand 0 "" "")
20145 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20146 (match_operand:SI 2 "" "")))]
20147 "!TARGET_64BIT"
20148 {
20149 if (SIBLING_CALL_P (insn))
20150 return "jmp\t%P1";
20151 else
20152 return "call\t%P1";
20153 }
20154 [(set_attr "type" "callv")])
20155
20156 (define_insn "*call_value_0_rex64"
20157 [(set (match_operand 0 "" "")
20158 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20159 (match_operand:DI 2 "const_int_operand" "")))]
20160 "TARGET_64BIT"
20161 {
20162 if (SIBLING_CALL_P (insn))
20163 return "jmp\t%P1";
20164 else
20165 return "call\t%P1";
20166 }
20167 [(set_attr "type" "callv")])
20168
20169 (define_insn "*call_value_1"
20170 [(set (match_operand 0 "" "")
20171 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20172 (match_operand:SI 2 "" "")))]
20173 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20174 {
20175 if (constant_call_address_operand (operands[1], Pmode))
20176 return "call\t%P1";
20177 return "call\t%A1";
20178 }
20179 [(set_attr "type" "callv")])
20180
20181 (define_insn "*sibcall_value_1"
20182 [(set (match_operand 0 "" "")
20183 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20184 (match_operand:SI 2 "" "")))]
20185 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20186 {
20187 if (constant_call_address_operand (operands[1], Pmode))
20188 return "jmp\t%P1";
20189 return "jmp\t%A1";
20190 }
20191 [(set_attr "type" "callv")])
20192
20193 (define_insn "*call_value_1_rex64"
20194 [(set (match_operand 0 "" "")
20195 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20196 (match_operand:DI 2 "" "")))]
20197 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20198 {
20199 if (constant_call_address_operand (operands[1], Pmode))
20200 return "call\t%P1";
20201 return "call\t%A1";
20202 }
20203 [(set_attr "type" "callv")])
20204
20205 (define_insn "*sibcall_value_1_rex64"
20206 [(set (match_operand 0 "" "")
20207 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20208 (match_operand:DI 2 "" "")))]
20209 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20210 "jmp\t%P1"
20211 [(set_attr "type" "callv")])
20212
20213 (define_insn "*sibcall_value_1_rex64_v"
20214 [(set (match_operand 0 "" "")
20215 (call (mem:QI (reg:DI R11_REG))
20216 (match_operand:DI 1 "" "")))]
20217 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20218 "jmp\t*%%r11"
20219 [(set_attr "type" "callv")])
20220 \f
20221 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20222 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20223 ;; caught for use by garbage collectors and the like. Using an insn that
20224 ;; maps to SIGILL makes it more likely the program will rightfully die.
20225 ;; Keeping with tradition, "6" is in honor of #UD.
20226 (define_insn "trap"
20227 [(trap_if (const_int 1) (const_int 6))]
20228 ""
20229 { return ASM_SHORT "0x0b0f"; }
20230 [(set_attr "length" "2")])
20231
20232 (define_expand "sse_prologue_save"
20233 [(parallel [(set (match_operand:BLK 0 "" "")
20234 (unspec:BLK [(reg:DI 21)
20235 (reg:DI 22)
20236 (reg:DI 23)
20237 (reg:DI 24)
20238 (reg:DI 25)
20239 (reg:DI 26)
20240 (reg:DI 27)
20241 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20242 (use (match_operand:DI 1 "register_operand" ""))
20243 (use (match_operand:DI 2 "immediate_operand" ""))
20244 (use (label_ref:DI (match_operand 3 "" "")))])]
20245 "TARGET_64BIT"
20246 "")
20247
20248 (define_insn "*sse_prologue_save_insn"
20249 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20250 (match_operand:DI 4 "const_int_operand" "n")))
20251 (unspec:BLK [(reg:DI 21)
20252 (reg:DI 22)
20253 (reg:DI 23)
20254 (reg:DI 24)
20255 (reg:DI 25)
20256 (reg:DI 26)
20257 (reg:DI 27)
20258 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20259 (use (match_operand:DI 1 "register_operand" "r"))
20260 (use (match_operand:DI 2 "const_int_operand" "i"))
20261 (use (label_ref:DI (match_operand 3 "" "X")))]
20262 "TARGET_64BIT
20263 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20264 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20265 "*
20266 {
20267 int i;
20268 operands[0] = gen_rtx_MEM (Pmode,
20269 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20270 output_asm_insn (\"jmp\\t%A1\", operands);
20271 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20272 {
20273 operands[4] = adjust_address (operands[0], DImode, i*16);
20274 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20275 PUT_MODE (operands[4], TImode);
20276 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20277 output_asm_insn (\"rex\", operands);
20278 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20279 }
20280 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20281 CODE_LABEL_NUMBER (operands[3]));
20282 return \"\";
20283 }
20284 "
20285 [(set_attr "type" "other")
20286 (set_attr "length_immediate" "0")
20287 (set_attr "length_address" "0")
20288 (set_attr "length" "135")
20289 (set_attr "memory" "store")
20290 (set_attr "modrm" "0")
20291 (set_attr "mode" "DI")])
20292
20293 (define_expand "prefetch"
20294 [(prefetch (match_operand 0 "address_operand" "")
20295 (match_operand:SI 1 "const_int_operand" "")
20296 (match_operand:SI 2 "const_int_operand" ""))]
20297 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20298 {
20299 int rw = INTVAL (operands[1]);
20300 int locality = INTVAL (operands[2]);
20301
20302 gcc_assert (rw == 0 || rw == 1);
20303 gcc_assert (locality >= 0 && locality <= 3);
20304 gcc_assert (GET_MODE (operands[0]) == Pmode
20305 || GET_MODE (operands[0]) == VOIDmode);
20306
20307 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20308 supported by SSE counterpart or the SSE prefetch is not available
20309 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20310 of locality. */
20311 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20312 operands[2] = GEN_INT (3);
20313 else
20314 operands[1] = const0_rtx;
20315 })
20316
20317 (define_insn "*prefetch_sse"
20318 [(prefetch (match_operand:SI 0 "address_operand" "p")
20319 (const_int 0)
20320 (match_operand:SI 1 "const_int_operand" ""))]
20321 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20322 {
20323 static const char * const patterns[4] = {
20324 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20325 };
20326
20327 int locality = INTVAL (operands[1]);
20328 gcc_assert (locality >= 0 && locality <= 3);
20329
20330 return patterns[locality];
20331 }
20332 [(set_attr "type" "sse")
20333 (set_attr "memory" "none")])
20334
20335 (define_insn "*prefetch_sse_rex"
20336 [(prefetch (match_operand:DI 0 "address_operand" "p")
20337 (const_int 0)
20338 (match_operand:SI 1 "const_int_operand" ""))]
20339 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20340 {
20341 static const char * const patterns[4] = {
20342 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20343 };
20344
20345 int locality = INTVAL (operands[1]);
20346 gcc_assert (locality >= 0 && locality <= 3);
20347
20348 return patterns[locality];
20349 }
20350 [(set_attr "type" "sse")
20351 (set_attr "memory" "none")])
20352
20353 (define_insn "*prefetch_3dnow"
20354 [(prefetch (match_operand:SI 0 "address_operand" "p")
20355 (match_operand:SI 1 "const_int_operand" "n")
20356 (const_int 3))]
20357 "TARGET_3DNOW && !TARGET_64BIT"
20358 {
20359 if (INTVAL (operands[1]) == 0)
20360 return "prefetch\t%a0";
20361 else
20362 return "prefetchw\t%a0";
20363 }
20364 [(set_attr "type" "mmx")
20365 (set_attr "memory" "none")])
20366
20367 (define_insn "*prefetch_3dnow_rex"
20368 [(prefetch (match_operand:DI 0 "address_operand" "p")
20369 (match_operand:SI 1 "const_int_operand" "n")
20370 (const_int 3))]
20371 "TARGET_3DNOW && TARGET_64BIT"
20372 {
20373 if (INTVAL (operands[1]) == 0)
20374 return "prefetch\t%a0";
20375 else
20376 return "prefetchw\t%a0";
20377 }
20378 [(set_attr "type" "mmx")
20379 (set_attr "memory" "none")])
20380
20381 (define_expand "stack_protect_set"
20382 [(match_operand 0 "memory_operand" "")
20383 (match_operand 1 "memory_operand" "")]
20384 ""
20385 {
20386 #ifdef TARGET_THREAD_SSP_OFFSET
20387 if (TARGET_64BIT)
20388 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20389 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20390 else
20391 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20392 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20393 #else
20394 if (TARGET_64BIT)
20395 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20396 else
20397 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20398 #endif
20399 DONE;
20400 })
20401
20402 (define_insn "stack_protect_set_si"
20403 [(set (match_operand:SI 0 "memory_operand" "=m")
20404 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20405 (set (match_scratch:SI 2 "=&r") (const_int 0))
20406 (clobber (reg:CC FLAGS_REG))]
20407 ""
20408 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20409 [(set_attr "type" "multi")])
20410
20411 (define_insn "stack_protect_set_di"
20412 [(set (match_operand:DI 0 "memory_operand" "=m")
20413 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20414 (set (match_scratch:DI 2 "=&r") (const_int 0))
20415 (clobber (reg:CC FLAGS_REG))]
20416 "TARGET_64BIT"
20417 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20418 [(set_attr "type" "multi")])
20419
20420 (define_insn "stack_tls_protect_set_si"
20421 [(set (match_operand:SI 0 "memory_operand" "=m")
20422 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20423 (set (match_scratch:SI 2 "=&r") (const_int 0))
20424 (clobber (reg:CC FLAGS_REG))]
20425 ""
20426 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20427 [(set_attr "type" "multi")])
20428
20429 (define_insn "stack_tls_protect_set_di"
20430 [(set (match_operand:DI 0 "memory_operand" "=m")
20431 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20432 (set (match_scratch:DI 2 "=&r") (const_int 0))
20433 (clobber (reg:CC FLAGS_REG))]
20434 "TARGET_64BIT"
20435 {
20436 /* The kernel uses a different segment register for performance reasons; a
20437 system call would not have to trash the userspace segment register,
20438 which would be expensive */
20439 if (ix86_cmodel != CM_KERNEL)
20440 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20441 else
20442 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20443 }
20444 [(set_attr "type" "multi")])
20445
20446 (define_expand "stack_protect_test"
20447 [(match_operand 0 "memory_operand" "")
20448 (match_operand 1 "memory_operand" "")
20449 (match_operand 2 "" "")]
20450 ""
20451 {
20452 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20453 ix86_compare_op0 = operands[0];
20454 ix86_compare_op1 = operands[1];
20455 ix86_compare_emitted = flags;
20456
20457 #ifdef TARGET_THREAD_SSP_OFFSET
20458 if (TARGET_64BIT)
20459 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20460 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20461 else
20462 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20463 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20464 #else
20465 if (TARGET_64BIT)
20466 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20467 else
20468 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20469 #endif
20470 emit_jump_insn (gen_beq (operands[2]));
20471 DONE;
20472 })
20473
20474 (define_insn "stack_protect_test_si"
20475 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20476 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20477 (match_operand:SI 2 "memory_operand" "m")]
20478 UNSPEC_SP_TEST))
20479 (clobber (match_scratch:SI 3 "=&r"))]
20480 ""
20481 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20482 [(set_attr "type" "multi")])
20483
20484 (define_insn "stack_protect_test_di"
20485 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20486 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20487 (match_operand:DI 2 "memory_operand" "m")]
20488 UNSPEC_SP_TEST))
20489 (clobber (match_scratch:DI 3 "=&r"))]
20490 "TARGET_64BIT"
20491 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20492 [(set_attr "type" "multi")])
20493
20494 (define_insn "stack_tls_protect_test_si"
20495 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20496 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20497 (match_operand:SI 2 "const_int_operand" "i")]
20498 UNSPEC_SP_TLS_TEST))
20499 (clobber (match_scratch:SI 3 "=r"))]
20500 ""
20501 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20502 [(set_attr "type" "multi")])
20503
20504 (define_insn "stack_tls_protect_test_di"
20505 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20506 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20507 (match_operand:DI 2 "const_int_operand" "i")]
20508 UNSPEC_SP_TLS_TEST))
20509 (clobber (match_scratch:DI 3 "=r"))]
20510 "TARGET_64BIT"
20511 {
20512 /* The kernel uses a different segment register for performance reasons; a
20513 system call would not have to trash the userspace segment register,
20514 which would be expensive */
20515 if (ix86_cmodel != CM_KERNEL)
20516 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20517 else
20518 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20519 }
20520 [(set_attr "type" "multi")])
20521
20522 (include "mmx.md")
20523 (include "sse.md")
20524 (include "sync.md")