genopinit.c (optabs): Change lfloor_optab and lceil_optab to conversion 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
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;; operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
66 (UNSPEC_STACK_ALLOC 11)
67 (UNSPEC_SET_GOT 12)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_REG_SAVE 14)
70 (UNSPEC_DEF_CFA 15)
71
72 ; TLS support
73 (UNSPEC_TP 16)
74 (UNSPEC_TLS_GD 17)
75 (UNSPEC_TLS_LD_BASE 18)
76 (UNSPEC_TLSDESC 19)
77
78 ; Other random patterns
79 (UNSPEC_SCAS 20)
80 (UNSPEC_FNSTSW 21)
81 (UNSPEC_SAHF 22)
82 (UNSPEC_FSTCW 23)
83 (UNSPEC_ADD_CARRY 24)
84 (UNSPEC_FLDCW 25)
85 (UNSPEC_REP 26)
86 (UNSPEC_EH_RETURN 27)
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 30)
91 (UNSPEC_MASKMOV 31)
92 (UNSPEC_MOVMSK 32)
93 (UNSPEC_MOVNT 33)
94 (UNSPEC_MOVU 34)
95 (UNSPEC_RCP 35)
96 (UNSPEC_RSQRT 36)
97 (UNSPEC_SFENCE 37)
98 (UNSPEC_NOP 38) ; prevents combiner cleverness
99 (UNSPEC_PFRCP 39)
100 (UNSPEC_PFRCPIT1 40)
101 (UNSPEC_PFRCPIT2 41)
102 (UNSPEC_PFRSQRT 42)
103 (UNSPEC_PFRSQIT1 43)
104 (UNSPEC_MFENCE 44)
105 (UNSPEC_LFENCE 45)
106 (UNSPEC_PSADBW 46)
107 (UNSPEC_LDDQU 47)
108
109 ; Generic math support
110 (UNSPEC_COPYSIGN 50)
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
113
114 ; x87 Floating point
115 (UNSPEC_SIN 60)
116 (UNSPEC_COS 61)
117 (UNSPEC_FPATAN 62)
118 (UNSPEC_FYL2X 63)
119 (UNSPEC_FYL2XP1 64)
120 (UNSPEC_FRNDINT 65)
121 (UNSPEC_FIST 66)
122 (UNSPEC_F2XM1 67)
123
124 ; x87 Rounding
125 (UNSPEC_FRNDINT_FLOOR 70)
126 (UNSPEC_FRNDINT_CEIL 71)
127 (UNSPEC_FRNDINT_TRUNC 72)
128 (UNSPEC_FRNDINT_MASK_PM 73)
129 (UNSPEC_FIST_FLOOR 74)
130 (UNSPEC_FIST_CEIL 75)
131
132 ; x87 Double output FP
133 (UNSPEC_SINCOS_COS 80)
134 (UNSPEC_SINCOS_SIN 81)
135 (UNSPEC_TAN_ONE 82)
136 (UNSPEC_TAN_TAN 83)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
141 (UNSPEC_FPREM_F 88)
142 (UNSPEC_FPREM_U 89)
143 (UNSPEC_FPREM1_F 90)
144 (UNSPEC_FPREM1_U 91)
145
146 ; SSP patterns
147 (UNSPEC_SP_SET 100)
148 (UNSPEC_SP_TEST 101)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
151
152 ; SSSE3
153 (UNSPEC_PSHUFB 120)
154 (UNSPEC_PSIGN 121)
155 (UNSPEC_PALIGNR 122)
156 ])
157
158 (define_constants
159 [(UNSPECV_BLOCKAGE 0)
160 (UNSPECV_STACK_PROBE 1)
161 (UNSPECV_EMMS 2)
162 (UNSPECV_LDMXCSR 3)
163 (UNSPECV_STMXCSR 4)
164 (UNSPECV_FEMMS 5)
165 (UNSPECV_CLFLUSH 6)
166 (UNSPECV_ALIGN 7)
167 (UNSPECV_MONITOR 8)
168 (UNSPECV_MWAIT 9)
169 (UNSPECV_CMPXCHG_1 10)
170 (UNSPECV_CMPXCHG_2 11)
171 (UNSPECV_XCHG 12)
172 (UNSPECV_LOCK 13)
173 ])
174
175 ;; Registers by name.
176 (define_constants
177 [(BP_REG 6)
178 (SP_REG 7)
179 (FLAGS_REG 17)
180 (FPSR_REG 18)
181 (FPCR_REG 19)
182 (DIRFLAG_REG 20)
183 (R11_REG 41)
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,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,cld,
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,cld,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,cld,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,cld,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,cld")
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 ;; All integer modes handled by x87 fisttp operator.
465 (define_mode_macro X87MODEI [HI SI DI])
466
467 ;; All integer modes handled by integer x87 operators.
468 (define_mode_macro X87MODEI12 [HI SI])
469
470 ;; All SSE floating point modes
471 (define_mode_macro SSEMODEF [SF DF])
472
473 ;; All integer modes handled by SSE cvtts?2si* operators.
474 (define_mode_macro SSEMODEI24 [SI DI])
475
476 \f
477 ;; Scheduling descriptions
478
479 (include "pentium.md")
480 (include "ppro.md")
481 (include "k6.md")
482 (include "athlon.md")
483 (include "geode.md")
484
485 \f
486 ;; Operand and operator predicates and constraints
487
488 (include "predicates.md")
489 (include "constraints.md")
490
491 \f
492 ;; Compare instructions.
493
494 ;; All compare insns have expanders that save the operands away without
495 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
496 ;; after the cmp) will actually emit the cmpM.
497
498 (define_expand "cmpti"
499 [(set (reg:CC FLAGS_REG)
500 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
501 (match_operand:TI 1 "x86_64_general_operand" "")))]
502 "TARGET_64BIT"
503 {
504 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
505 operands[0] = force_reg (TImode, operands[0]);
506 ix86_compare_op0 = operands[0];
507 ix86_compare_op1 = operands[1];
508 DONE;
509 })
510
511 (define_expand "cmpdi"
512 [(set (reg:CC FLAGS_REG)
513 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
514 (match_operand:DI 1 "x86_64_general_operand" "")))]
515 ""
516 {
517 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
518 operands[0] = force_reg (DImode, operands[0]);
519 ix86_compare_op0 = operands[0];
520 ix86_compare_op1 = operands[1];
521 DONE;
522 })
523
524 (define_expand "cmpsi"
525 [(set (reg:CC FLAGS_REG)
526 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
527 (match_operand:SI 1 "general_operand" "")))]
528 ""
529 {
530 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
531 operands[0] = force_reg (SImode, operands[0]);
532 ix86_compare_op0 = operands[0];
533 ix86_compare_op1 = operands[1];
534 DONE;
535 })
536
537 (define_expand "cmphi"
538 [(set (reg:CC FLAGS_REG)
539 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
540 (match_operand:HI 1 "general_operand" "")))]
541 ""
542 {
543 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
544 operands[0] = force_reg (HImode, operands[0]);
545 ix86_compare_op0 = operands[0];
546 ix86_compare_op1 = operands[1];
547 DONE;
548 })
549
550 (define_expand "cmpqi"
551 [(set (reg:CC FLAGS_REG)
552 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
553 (match_operand:QI 1 "general_operand" "")))]
554 "TARGET_QIMODE_MATH"
555 {
556 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
557 operands[0] = force_reg (QImode, operands[0]);
558 ix86_compare_op0 = operands[0];
559 ix86_compare_op1 = operands[1];
560 DONE;
561 })
562
563 (define_insn "cmpdi_ccno_1_rex64"
564 [(set (reg FLAGS_REG)
565 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
566 (match_operand:DI 1 "const0_operand" "n,n")))]
567 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
568 "@
569 test{q}\t{%0, %0|%0, %0}
570 cmp{q}\t{%1, %0|%0, %1}"
571 [(set_attr "type" "test,icmp")
572 (set_attr "length_immediate" "0,1")
573 (set_attr "mode" "DI")])
574
575 (define_insn "*cmpdi_minus_1_rex64"
576 [(set (reg FLAGS_REG)
577 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
578 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
579 (const_int 0)))]
580 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
581 "cmp{q}\t{%1, %0|%0, %1}"
582 [(set_attr "type" "icmp")
583 (set_attr "mode" "DI")])
584
585 (define_expand "cmpdi_1_rex64"
586 [(set (reg:CC FLAGS_REG)
587 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
588 (match_operand:DI 1 "general_operand" "")))]
589 "TARGET_64BIT"
590 "")
591
592 (define_insn "cmpdi_1_insn_rex64"
593 [(set (reg FLAGS_REG)
594 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
595 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
596 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
597 "cmp{q}\t{%1, %0|%0, %1}"
598 [(set_attr "type" "icmp")
599 (set_attr "mode" "DI")])
600
601
602 (define_insn "*cmpsi_ccno_1"
603 [(set (reg FLAGS_REG)
604 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
605 (match_operand:SI 1 "const0_operand" "n,n")))]
606 "ix86_match_ccmode (insn, CCNOmode)"
607 "@
608 test{l}\t{%0, %0|%0, %0}
609 cmp{l}\t{%1, %0|%0, %1}"
610 [(set_attr "type" "test,icmp")
611 (set_attr "length_immediate" "0,1")
612 (set_attr "mode" "SI")])
613
614 (define_insn "*cmpsi_minus_1"
615 [(set (reg FLAGS_REG)
616 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
617 (match_operand:SI 1 "general_operand" "ri,mr"))
618 (const_int 0)))]
619 "ix86_match_ccmode (insn, CCGOCmode)"
620 "cmp{l}\t{%1, %0|%0, %1}"
621 [(set_attr "type" "icmp")
622 (set_attr "mode" "SI")])
623
624 (define_expand "cmpsi_1"
625 [(set (reg:CC FLAGS_REG)
626 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
627 (match_operand:SI 1 "general_operand" "ri,mr")))]
628 ""
629 "")
630
631 (define_insn "*cmpsi_1_insn"
632 [(set (reg FLAGS_REG)
633 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
634 (match_operand:SI 1 "general_operand" "ri,mr")))]
635 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
636 && ix86_match_ccmode (insn, CCmode)"
637 "cmp{l}\t{%1, %0|%0, %1}"
638 [(set_attr "type" "icmp")
639 (set_attr "mode" "SI")])
640
641 (define_insn "*cmphi_ccno_1"
642 [(set (reg FLAGS_REG)
643 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
644 (match_operand:HI 1 "const0_operand" "n,n")))]
645 "ix86_match_ccmode (insn, CCNOmode)"
646 "@
647 test{w}\t{%0, %0|%0, %0}
648 cmp{w}\t{%1, %0|%0, %1}"
649 [(set_attr "type" "test,icmp")
650 (set_attr "length_immediate" "0,1")
651 (set_attr "mode" "HI")])
652
653 (define_insn "*cmphi_minus_1"
654 [(set (reg FLAGS_REG)
655 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
656 (match_operand:HI 1 "general_operand" "ri,mr"))
657 (const_int 0)))]
658 "ix86_match_ccmode (insn, CCGOCmode)"
659 "cmp{w}\t{%1, %0|%0, %1}"
660 [(set_attr "type" "icmp")
661 (set_attr "mode" "HI")])
662
663 (define_insn "*cmphi_1"
664 [(set (reg FLAGS_REG)
665 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
666 (match_operand:HI 1 "general_operand" "ri,mr")))]
667 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
668 && ix86_match_ccmode (insn, CCmode)"
669 "cmp{w}\t{%1, %0|%0, %1}"
670 [(set_attr "type" "icmp")
671 (set_attr "mode" "HI")])
672
673 (define_insn "*cmpqi_ccno_1"
674 [(set (reg FLAGS_REG)
675 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
676 (match_operand:QI 1 "const0_operand" "n,n")))]
677 "ix86_match_ccmode (insn, CCNOmode)"
678 "@
679 test{b}\t{%0, %0|%0, %0}
680 cmp{b}\t{$0, %0|%0, 0}"
681 [(set_attr "type" "test,icmp")
682 (set_attr "length_immediate" "0,1")
683 (set_attr "mode" "QI")])
684
685 (define_insn "*cmpqi_1"
686 [(set (reg FLAGS_REG)
687 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
688 (match_operand:QI 1 "general_operand" "qi,mq")))]
689 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
690 && ix86_match_ccmode (insn, CCmode)"
691 "cmp{b}\t{%1, %0|%0, %1}"
692 [(set_attr "type" "icmp")
693 (set_attr "mode" "QI")])
694
695 (define_insn "*cmpqi_minus_1"
696 [(set (reg FLAGS_REG)
697 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
698 (match_operand:QI 1 "general_operand" "qi,mq"))
699 (const_int 0)))]
700 "ix86_match_ccmode (insn, CCGOCmode)"
701 "cmp{b}\t{%1, %0|%0, %1}"
702 [(set_attr "type" "icmp")
703 (set_attr "mode" "QI")])
704
705 (define_insn "*cmpqi_ext_1"
706 [(set (reg FLAGS_REG)
707 (compare
708 (match_operand:QI 0 "general_operand" "Qm")
709 (subreg:QI
710 (zero_extract:SI
711 (match_operand 1 "ext_register_operand" "Q")
712 (const_int 8)
713 (const_int 8)) 0)))]
714 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
715 "cmp{b}\t{%h1, %0|%0, %h1}"
716 [(set_attr "type" "icmp")
717 (set_attr "mode" "QI")])
718
719 (define_insn "*cmpqi_ext_1_rex64"
720 [(set (reg FLAGS_REG)
721 (compare
722 (match_operand:QI 0 "register_operand" "Q")
723 (subreg:QI
724 (zero_extract:SI
725 (match_operand 1 "ext_register_operand" "Q")
726 (const_int 8)
727 (const_int 8)) 0)))]
728 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
729 "cmp{b}\t{%h1, %0|%0, %h1}"
730 [(set_attr "type" "icmp")
731 (set_attr "mode" "QI")])
732
733 (define_insn "*cmpqi_ext_2"
734 [(set (reg FLAGS_REG)
735 (compare
736 (subreg:QI
737 (zero_extract:SI
738 (match_operand 0 "ext_register_operand" "Q")
739 (const_int 8)
740 (const_int 8)) 0)
741 (match_operand:QI 1 "const0_operand" "n")))]
742 "ix86_match_ccmode (insn, CCNOmode)"
743 "test{b}\t%h0, %h0"
744 [(set_attr "type" "test")
745 (set_attr "length_immediate" "0")
746 (set_attr "mode" "QI")])
747
748 (define_expand "cmpqi_ext_3"
749 [(set (reg:CC FLAGS_REG)
750 (compare:CC
751 (subreg:QI
752 (zero_extract:SI
753 (match_operand 0 "ext_register_operand" "")
754 (const_int 8)
755 (const_int 8)) 0)
756 (match_operand:QI 1 "general_operand" "")))]
757 ""
758 "")
759
760 (define_insn "cmpqi_ext_3_insn"
761 [(set (reg FLAGS_REG)
762 (compare
763 (subreg:QI
764 (zero_extract:SI
765 (match_operand 0 "ext_register_operand" "Q")
766 (const_int 8)
767 (const_int 8)) 0)
768 (match_operand:QI 1 "general_operand" "Qmn")))]
769 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
770 "cmp{b}\t{%1, %h0|%h0, %1}"
771 [(set_attr "type" "icmp")
772 (set_attr "mode" "QI")])
773
774 (define_insn "cmpqi_ext_3_insn_rex64"
775 [(set (reg FLAGS_REG)
776 (compare
777 (subreg:QI
778 (zero_extract:SI
779 (match_operand 0 "ext_register_operand" "Q")
780 (const_int 8)
781 (const_int 8)) 0)
782 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
783 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
784 "cmp{b}\t{%1, %h0|%h0, %1}"
785 [(set_attr "type" "icmp")
786 (set_attr "mode" "QI")])
787
788 (define_insn "*cmpqi_ext_4"
789 [(set (reg FLAGS_REG)
790 (compare
791 (subreg:QI
792 (zero_extract:SI
793 (match_operand 0 "ext_register_operand" "Q")
794 (const_int 8)
795 (const_int 8)) 0)
796 (subreg:QI
797 (zero_extract:SI
798 (match_operand 1 "ext_register_operand" "Q")
799 (const_int 8)
800 (const_int 8)) 0)))]
801 "ix86_match_ccmode (insn, CCmode)"
802 "cmp{b}\t{%h1, %h0|%h0, %h1}"
803 [(set_attr "type" "icmp")
804 (set_attr "mode" "QI")])
805
806 ;; These implement float point compares.
807 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
808 ;; which would allow mix and match FP modes on the compares. Which is what
809 ;; the old patterns did, but with many more of them.
810
811 (define_expand "cmpxf"
812 [(set (reg:CC FLAGS_REG)
813 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
814 (match_operand:XF 1 "nonmemory_operand" "")))]
815 "TARGET_80387"
816 {
817 ix86_compare_op0 = operands[0];
818 ix86_compare_op1 = operands[1];
819 DONE;
820 })
821
822 (define_expand "cmpdf"
823 [(set (reg:CC FLAGS_REG)
824 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
825 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
826 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
827 {
828 ix86_compare_op0 = operands[0];
829 ix86_compare_op1 = operands[1];
830 DONE;
831 })
832
833 (define_expand "cmpsf"
834 [(set (reg:CC FLAGS_REG)
835 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
836 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
837 "TARGET_80387 || TARGET_SSE_MATH"
838 {
839 ix86_compare_op0 = operands[0];
840 ix86_compare_op1 = operands[1];
841 DONE;
842 })
843
844 ;; FP compares, step 1:
845 ;; Set the FP condition codes.
846 ;;
847 ;; CCFPmode compare with exceptions
848 ;; CCFPUmode compare with no exceptions
849
850 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
851 ;; used to manage the reg stack popping would not be preserved.
852
853 (define_insn "*cmpfp_0"
854 [(set (match_operand:HI 0 "register_operand" "=a")
855 (unspec:HI
856 [(compare:CCFP
857 (match_operand 1 "register_operand" "f")
858 (match_operand 2 "const0_operand" "X"))]
859 UNSPEC_FNSTSW))]
860 "TARGET_80387
861 && FLOAT_MODE_P (GET_MODE (operands[1]))
862 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
863 "* return output_fp_compare (insn, operands, 0, 0);"
864 [(set_attr "type" "multi")
865 (set_attr "unit" "i387")
866 (set (attr "mode")
867 (cond [(match_operand:SF 1 "" "")
868 (const_string "SF")
869 (match_operand:DF 1 "" "")
870 (const_string "DF")
871 ]
872 (const_string "XF")))])
873
874 (define_insn "*cmpfp_sf"
875 [(set (match_operand:HI 0 "register_operand" "=a")
876 (unspec:HI
877 [(compare:CCFP
878 (match_operand:SF 1 "register_operand" "f")
879 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
880 UNSPEC_FNSTSW))]
881 "TARGET_80387"
882 "* return output_fp_compare (insn, operands, 0, 0);"
883 [(set_attr "type" "multi")
884 (set_attr "unit" "i387")
885 (set_attr "mode" "SF")])
886
887 (define_insn "*cmpfp_df"
888 [(set (match_operand:HI 0 "register_operand" "=a")
889 (unspec:HI
890 [(compare:CCFP
891 (match_operand:DF 1 "register_operand" "f")
892 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
893 UNSPEC_FNSTSW))]
894 "TARGET_80387"
895 "* return output_fp_compare (insn, operands, 0, 0);"
896 [(set_attr "type" "multi")
897 (set_attr "unit" "i387")
898 (set_attr "mode" "DF")])
899
900 (define_insn "*cmpfp_xf"
901 [(set (match_operand:HI 0 "register_operand" "=a")
902 (unspec:HI
903 [(compare:CCFP
904 (match_operand:XF 1 "register_operand" "f")
905 (match_operand:XF 2 "register_operand" "f"))]
906 UNSPEC_FNSTSW))]
907 "TARGET_80387"
908 "* return output_fp_compare (insn, operands, 0, 0);"
909 [(set_attr "type" "multi")
910 (set_attr "unit" "i387")
911 (set_attr "mode" "XF")])
912
913 (define_insn "*cmpfp_u"
914 [(set (match_operand:HI 0 "register_operand" "=a")
915 (unspec:HI
916 [(compare:CCFPU
917 (match_operand 1 "register_operand" "f")
918 (match_operand 2 "register_operand" "f"))]
919 UNSPEC_FNSTSW))]
920 "TARGET_80387
921 && FLOAT_MODE_P (GET_MODE (operands[1]))
922 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
923 "* return output_fp_compare (insn, operands, 0, 1);"
924 [(set_attr "type" "multi")
925 (set_attr "unit" "i387")
926 (set (attr "mode")
927 (cond [(match_operand:SF 1 "" "")
928 (const_string "SF")
929 (match_operand:DF 1 "" "")
930 (const_string "DF")
931 ]
932 (const_string "XF")))])
933
934 (define_insn "*cmpfp_<mode>"
935 [(set (match_operand:HI 0 "register_operand" "=a")
936 (unspec:HI
937 [(compare:CCFP
938 (match_operand 1 "register_operand" "f")
939 (match_operator 3 "float_operator"
940 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
941 UNSPEC_FNSTSW))]
942 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
943 && FLOAT_MODE_P (GET_MODE (operands[1]))
944 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
945 "* return output_fp_compare (insn, operands, 0, 0);"
946 [(set_attr "type" "multi")
947 (set_attr "unit" "i387")
948 (set_attr "fp_int_src" "true")
949 (set_attr "mode" "<MODE>")])
950
951 ;; FP compares, step 2
952 ;; Move the fpsw to ax.
953
954 (define_insn "x86_fnstsw_1"
955 [(set (match_operand:HI 0 "register_operand" "=a")
956 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
957 "TARGET_80387"
958 "fnstsw\t%0"
959 [(set_attr "length" "2")
960 (set_attr "mode" "SI")
961 (set_attr "unit" "i387")])
962
963 ;; FP compares, step 3
964 ;; Get ax into flags, general case.
965
966 (define_insn "x86_sahf_1"
967 [(set (reg:CC FLAGS_REG)
968 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
969 "!TARGET_64BIT"
970 "sahf"
971 [(set_attr "length" "1")
972 (set_attr "athlon_decode" "vector")
973 (set_attr "mode" "SI")])
974
975 ;; Pentium Pro can do steps 1 through 3 in one go.
976
977 (define_insn "*cmpfp_i_mixed"
978 [(set (reg:CCFP FLAGS_REG)
979 (compare:CCFP (match_operand 0 "register_operand" "f,x")
980 (match_operand 1 "nonimmediate_operand" "f,xm")))]
981 "TARGET_MIX_SSE_I387
982 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
983 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
984 "* return output_fp_compare (insn, operands, 1, 0);"
985 [(set_attr "type" "fcmp,ssecomi")
986 (set (attr "mode")
987 (if_then_else (match_operand:SF 1 "" "")
988 (const_string "SF")
989 (const_string "DF")))
990 (set_attr "athlon_decode" "vector")])
991
992 (define_insn "*cmpfp_i_sse"
993 [(set (reg:CCFP FLAGS_REG)
994 (compare:CCFP (match_operand 0 "register_operand" "x")
995 (match_operand 1 "nonimmediate_operand" "xm")))]
996 "TARGET_SSE_MATH
997 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
998 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
999 "* return output_fp_compare (insn, operands, 1, 0);"
1000 [(set_attr "type" "ssecomi")
1001 (set (attr "mode")
1002 (if_then_else (match_operand:SF 1 "" "")
1003 (const_string "SF")
1004 (const_string "DF")))
1005 (set_attr "athlon_decode" "vector")])
1006
1007 (define_insn "*cmpfp_i_i387"
1008 [(set (reg:CCFP FLAGS_REG)
1009 (compare:CCFP (match_operand 0 "register_operand" "f")
1010 (match_operand 1 "register_operand" "f")))]
1011 "TARGET_80387 && TARGET_CMOVE
1012 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1013 && FLOAT_MODE_P (GET_MODE (operands[0]))
1014 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1015 "* return output_fp_compare (insn, operands, 1, 0);"
1016 [(set_attr "type" "fcmp")
1017 (set (attr "mode")
1018 (cond [(match_operand:SF 1 "" "")
1019 (const_string "SF")
1020 (match_operand:DF 1 "" "")
1021 (const_string "DF")
1022 ]
1023 (const_string "XF")))
1024 (set_attr "athlon_decode" "vector")])
1025
1026 (define_insn "*cmpfp_iu_mixed"
1027 [(set (reg:CCFPU FLAGS_REG)
1028 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1029 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1030 "TARGET_MIX_SSE_I387
1031 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1032 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033 "* return output_fp_compare (insn, operands, 1, 1);"
1034 [(set_attr "type" "fcmp,ssecomi")
1035 (set (attr "mode")
1036 (if_then_else (match_operand:SF 1 "" "")
1037 (const_string "SF")
1038 (const_string "DF")))
1039 (set_attr "athlon_decode" "vector")])
1040
1041 (define_insn "*cmpfp_iu_sse"
1042 [(set (reg:CCFPU FLAGS_REG)
1043 (compare:CCFPU (match_operand 0 "register_operand" "x")
1044 (match_operand 1 "nonimmediate_operand" "xm")))]
1045 "TARGET_SSE_MATH
1046 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1047 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1048 "* return output_fp_compare (insn, operands, 1, 1);"
1049 [(set_attr "type" "ssecomi")
1050 (set (attr "mode")
1051 (if_then_else (match_operand:SF 1 "" "")
1052 (const_string "SF")
1053 (const_string "DF")))
1054 (set_attr "athlon_decode" "vector")])
1055
1056 (define_insn "*cmpfp_iu_387"
1057 [(set (reg:CCFPU FLAGS_REG)
1058 (compare:CCFPU (match_operand 0 "register_operand" "f")
1059 (match_operand 1 "register_operand" "f")))]
1060 "TARGET_80387 && TARGET_CMOVE
1061 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1062 && FLOAT_MODE_P (GET_MODE (operands[0]))
1063 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1064 "* return output_fp_compare (insn, operands, 1, 1);"
1065 [(set_attr "type" "fcmp")
1066 (set (attr "mode")
1067 (cond [(match_operand:SF 1 "" "")
1068 (const_string "SF")
1069 (match_operand:DF 1 "" "")
1070 (const_string "DF")
1071 ]
1072 (const_string "XF")))
1073 (set_attr "athlon_decode" "vector")])
1074 \f
1075 ;; Move instructions.
1076
1077 ;; General case of fullword move.
1078
1079 (define_expand "movsi"
1080 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1081 (match_operand:SI 1 "general_operand" ""))]
1082 ""
1083 "ix86_expand_move (SImode, operands); DONE;")
1084
1085 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1086 ;; general_operand.
1087 ;;
1088 ;; %%% We don't use a post-inc memory reference because x86 is not a
1089 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1090 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1091 ;; targets without our curiosities, and it is just as easy to represent
1092 ;; this differently.
1093
1094 (define_insn "*pushsi2"
1095 [(set (match_operand:SI 0 "push_operand" "=<")
1096 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1097 "!TARGET_64BIT"
1098 "push{l}\t%1"
1099 [(set_attr "type" "push")
1100 (set_attr "mode" "SI")])
1101
1102 ;; For 64BIT abi we always round up to 8 bytes.
1103 (define_insn "*pushsi2_rex64"
1104 [(set (match_operand:SI 0 "push_operand" "=X")
1105 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1106 "TARGET_64BIT"
1107 "push{q}\t%q1"
1108 [(set_attr "type" "push")
1109 (set_attr "mode" "SI")])
1110
1111 (define_insn "*pushsi2_prologue"
1112 [(set (match_operand:SI 0 "push_operand" "=<")
1113 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1114 (clobber (mem:BLK (scratch)))]
1115 "!TARGET_64BIT"
1116 "push{l}\t%1"
1117 [(set_attr "type" "push")
1118 (set_attr "mode" "SI")])
1119
1120 (define_insn "*popsi1_epilogue"
1121 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1122 (mem:SI (reg:SI SP_REG)))
1123 (set (reg:SI SP_REG)
1124 (plus:SI (reg:SI SP_REG) (const_int 4)))
1125 (clobber (mem:BLK (scratch)))]
1126 "!TARGET_64BIT"
1127 "pop{l}\t%0"
1128 [(set_attr "type" "pop")
1129 (set_attr "mode" "SI")])
1130
1131 (define_insn "popsi1"
1132 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1133 (mem:SI (reg:SI SP_REG)))
1134 (set (reg:SI SP_REG)
1135 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1136 "!TARGET_64BIT"
1137 "pop{l}\t%0"
1138 [(set_attr "type" "pop")
1139 (set_attr "mode" "SI")])
1140
1141 (define_insn "*movsi_xor"
1142 [(set (match_operand:SI 0 "register_operand" "=r")
1143 (match_operand:SI 1 "const0_operand" "i"))
1144 (clobber (reg:CC FLAGS_REG))]
1145 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1146 "xor{l}\t{%0, %0|%0, %0}"
1147 [(set_attr "type" "alu1")
1148 (set_attr "mode" "SI")
1149 (set_attr "length_immediate" "0")])
1150
1151 (define_insn "*movsi_or"
1152 [(set (match_operand:SI 0 "register_operand" "=r")
1153 (match_operand:SI 1 "immediate_operand" "i"))
1154 (clobber (reg:CC FLAGS_REG))]
1155 "reload_completed
1156 && operands[1] == constm1_rtx
1157 && (TARGET_PENTIUM || optimize_size)"
1158 {
1159 operands[1] = constm1_rtx;
1160 return "or{l}\t{%1, %0|%0, %1}";
1161 }
1162 [(set_attr "type" "alu1")
1163 (set_attr "mode" "SI")
1164 (set_attr "length_immediate" "1")])
1165
1166 (define_insn "*movsi_1"
1167 [(set (match_operand:SI 0 "nonimmediate_operand"
1168 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1169 (match_operand:SI 1 "general_operand"
1170 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1171 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1172 {
1173 switch (get_attr_type (insn))
1174 {
1175 case TYPE_SSELOG1:
1176 if (get_attr_mode (insn) == MODE_TI)
1177 return "pxor\t%0, %0";
1178 return "xorps\t%0, %0";
1179
1180 case TYPE_SSEMOV:
1181 switch (get_attr_mode (insn))
1182 {
1183 case MODE_TI:
1184 return "movdqa\t{%1, %0|%0, %1}";
1185 case MODE_V4SF:
1186 return "movaps\t{%1, %0|%0, %1}";
1187 case MODE_SI:
1188 return "movd\t{%1, %0|%0, %1}";
1189 case MODE_SF:
1190 return "movss\t{%1, %0|%0, %1}";
1191 default:
1192 gcc_unreachable ();
1193 }
1194
1195 case TYPE_MMXADD:
1196 return "pxor\t%0, %0";
1197
1198 case TYPE_MMXMOV:
1199 if (get_attr_mode (insn) == MODE_DI)
1200 return "movq\t{%1, %0|%0, %1}";
1201 return "movd\t{%1, %0|%0, %1}";
1202
1203 case TYPE_LEA:
1204 return "lea{l}\t{%1, %0|%0, %1}";
1205
1206 default:
1207 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1208 return "mov{l}\t{%1, %0|%0, %1}";
1209 }
1210 }
1211 [(set (attr "type")
1212 (cond [(eq_attr "alternative" "2")
1213 (const_string "mmxadd")
1214 (eq_attr "alternative" "3,4,5")
1215 (const_string "mmxmov")
1216 (eq_attr "alternative" "6")
1217 (const_string "sselog1")
1218 (eq_attr "alternative" "7,8,9,10,11")
1219 (const_string "ssemov")
1220 (match_operand:DI 1 "pic_32bit_operand" "")
1221 (const_string "lea")
1222 ]
1223 (const_string "imov")))
1224 (set (attr "mode")
1225 (cond [(eq_attr "alternative" "2,3")
1226 (const_string "DI")
1227 (eq_attr "alternative" "6,7")
1228 (if_then_else
1229 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1230 (const_string "V4SF")
1231 (const_string "TI"))
1232 (and (eq_attr "alternative" "8,9,10,11")
1233 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1234 (const_string "SF")
1235 ]
1236 (const_string "SI")))])
1237
1238 ;; Stores and loads of ax to arbitrary constant address.
1239 ;; We fake an second form of instruction to force reload to load address
1240 ;; into register when rax is not available
1241 (define_insn "*movabssi_1_rex64"
1242 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1243 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1244 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1245 "@
1246 movabs{l}\t{%1, %P0|%P0, %1}
1247 mov{l}\t{%1, %a0|%a0, %1}"
1248 [(set_attr "type" "imov")
1249 (set_attr "modrm" "0,*")
1250 (set_attr "length_address" "8,0")
1251 (set_attr "length_immediate" "0,*")
1252 (set_attr "memory" "store")
1253 (set_attr "mode" "SI")])
1254
1255 (define_insn "*movabssi_2_rex64"
1256 [(set (match_operand:SI 0 "register_operand" "=a,r")
1257 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1258 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1259 "@
1260 movabs{l}\t{%P1, %0|%0, %P1}
1261 mov{l}\t{%a1, %0|%0, %a1}"
1262 [(set_attr "type" "imov")
1263 (set_attr "modrm" "0,*")
1264 (set_attr "length_address" "8,0")
1265 (set_attr "length_immediate" "0")
1266 (set_attr "memory" "load")
1267 (set_attr "mode" "SI")])
1268
1269 (define_insn "*swapsi"
1270 [(set (match_operand:SI 0 "register_operand" "+r")
1271 (match_operand:SI 1 "register_operand" "+r"))
1272 (set (match_dup 1)
1273 (match_dup 0))]
1274 ""
1275 "xchg{l}\t%1, %0"
1276 [(set_attr "type" "imov")
1277 (set_attr "mode" "SI")
1278 (set_attr "pent_pair" "np")
1279 (set_attr "athlon_decode" "vector")])
1280
1281 (define_expand "movhi"
1282 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1283 (match_operand:HI 1 "general_operand" ""))]
1284 ""
1285 "ix86_expand_move (HImode, operands); DONE;")
1286
1287 (define_insn "*pushhi2"
1288 [(set (match_operand:HI 0 "push_operand" "=X")
1289 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1290 "!TARGET_64BIT"
1291 "push{l}\t%k1"
1292 [(set_attr "type" "push")
1293 (set_attr "mode" "SI")])
1294
1295 ;; For 64BIT abi we always round up to 8 bytes.
1296 (define_insn "*pushhi2_rex64"
1297 [(set (match_operand:HI 0 "push_operand" "=X")
1298 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1299 "TARGET_64BIT"
1300 "push{q}\t%q1"
1301 [(set_attr "type" "push")
1302 (set_attr "mode" "DI")])
1303
1304 (define_insn "*movhi_1"
1305 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1306 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1307 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1308 {
1309 switch (get_attr_type (insn))
1310 {
1311 case TYPE_IMOVX:
1312 /* movzwl is faster than movw on p2 due to partial word stalls,
1313 though not as fast as an aligned movl. */
1314 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1315 default:
1316 if (get_attr_mode (insn) == MODE_SI)
1317 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1318 else
1319 return "mov{w}\t{%1, %0|%0, %1}";
1320 }
1321 }
1322 [(set (attr "type")
1323 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1324 (const_string "imov")
1325 (and (eq_attr "alternative" "0")
1326 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1327 (const_int 0))
1328 (eq (symbol_ref "TARGET_HIMODE_MATH")
1329 (const_int 0))))
1330 (const_string "imov")
1331 (and (eq_attr "alternative" "1,2")
1332 (match_operand:HI 1 "aligned_operand" ""))
1333 (const_string "imov")
1334 (and (ne (symbol_ref "TARGET_MOVX")
1335 (const_int 0))
1336 (eq_attr "alternative" "0,2"))
1337 (const_string "imovx")
1338 ]
1339 (const_string "imov")))
1340 (set (attr "mode")
1341 (cond [(eq_attr "type" "imovx")
1342 (const_string "SI")
1343 (and (eq_attr "alternative" "1,2")
1344 (match_operand:HI 1 "aligned_operand" ""))
1345 (const_string "SI")
1346 (and (eq_attr "alternative" "0")
1347 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1348 (const_int 0))
1349 (eq (symbol_ref "TARGET_HIMODE_MATH")
1350 (const_int 0))))
1351 (const_string "SI")
1352 ]
1353 (const_string "HI")))])
1354
1355 ;; Stores and loads of ax to arbitrary constant address.
1356 ;; We fake an second form of instruction to force reload to load address
1357 ;; into register when rax is not available
1358 (define_insn "*movabshi_1_rex64"
1359 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1360 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1361 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1362 "@
1363 movabs{w}\t{%1, %P0|%P0, %1}
1364 mov{w}\t{%1, %a0|%a0, %1}"
1365 [(set_attr "type" "imov")
1366 (set_attr "modrm" "0,*")
1367 (set_attr "length_address" "8,0")
1368 (set_attr "length_immediate" "0,*")
1369 (set_attr "memory" "store")
1370 (set_attr "mode" "HI")])
1371
1372 (define_insn "*movabshi_2_rex64"
1373 [(set (match_operand:HI 0 "register_operand" "=a,r")
1374 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1375 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1376 "@
1377 movabs{w}\t{%P1, %0|%0, %P1}
1378 mov{w}\t{%a1, %0|%0, %a1}"
1379 [(set_attr "type" "imov")
1380 (set_attr "modrm" "0,*")
1381 (set_attr "length_address" "8,0")
1382 (set_attr "length_immediate" "0")
1383 (set_attr "memory" "load")
1384 (set_attr "mode" "HI")])
1385
1386 (define_insn "*swaphi_1"
1387 [(set (match_operand:HI 0 "register_operand" "+r")
1388 (match_operand:HI 1 "register_operand" "+r"))
1389 (set (match_dup 1)
1390 (match_dup 0))]
1391 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1392 "xchg{l}\t%k1, %k0"
1393 [(set_attr "type" "imov")
1394 (set_attr "mode" "SI")
1395 (set_attr "pent_pair" "np")
1396 (set_attr "athlon_decode" "vector")])
1397
1398 (define_insn "*swaphi_2"
1399 [(set (match_operand:HI 0 "register_operand" "+r")
1400 (match_operand:HI 1 "register_operand" "+r"))
1401 (set (match_dup 1)
1402 (match_dup 0))]
1403 "TARGET_PARTIAL_REG_STALL"
1404 "xchg{w}\t%1, %0"
1405 [(set_attr "type" "imov")
1406 (set_attr "mode" "HI")
1407 (set_attr "pent_pair" "np")
1408 (set_attr "athlon_decode" "vector")])
1409
1410 (define_expand "movstricthi"
1411 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1412 (match_operand:HI 1 "general_operand" ""))]
1413 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1414 {
1415 /* Don't generate memory->memory moves, go through a register */
1416 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1417 operands[1] = force_reg (HImode, operands[1]);
1418 })
1419
1420 (define_insn "*movstricthi_1"
1421 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1422 (match_operand:HI 1 "general_operand" "rn,m"))]
1423 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1424 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1425 "mov{w}\t{%1, %0|%0, %1}"
1426 [(set_attr "type" "imov")
1427 (set_attr "mode" "HI")])
1428
1429 (define_insn "*movstricthi_xor"
1430 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1431 (match_operand:HI 1 "const0_operand" "i"))
1432 (clobber (reg:CC FLAGS_REG))]
1433 "reload_completed
1434 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1435 "xor{w}\t{%0, %0|%0, %0}"
1436 [(set_attr "type" "alu1")
1437 (set_attr "mode" "HI")
1438 (set_attr "length_immediate" "0")])
1439
1440 (define_expand "movqi"
1441 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1442 (match_operand:QI 1 "general_operand" ""))]
1443 ""
1444 "ix86_expand_move (QImode, operands); DONE;")
1445
1446 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1447 ;; "push a byte". But actually we use pushl, which has the effect
1448 ;; of rounding the amount pushed up to a word.
1449
1450 (define_insn "*pushqi2"
1451 [(set (match_operand:QI 0 "push_operand" "=X")
1452 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1453 "!TARGET_64BIT"
1454 "push{l}\t%k1"
1455 [(set_attr "type" "push")
1456 (set_attr "mode" "SI")])
1457
1458 ;; For 64BIT abi we always round up to 8 bytes.
1459 (define_insn "*pushqi2_rex64"
1460 [(set (match_operand:QI 0 "push_operand" "=X")
1461 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1462 "TARGET_64BIT"
1463 "push{q}\t%q1"
1464 [(set_attr "type" "push")
1465 (set_attr "mode" "DI")])
1466
1467 ;; Situation is quite tricky about when to choose full sized (SImode) move
1468 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1469 ;; partial register dependency machines (such as AMD Athlon), where QImode
1470 ;; moves issue extra dependency and for partial register stalls machines
1471 ;; that don't use QImode patterns (and QImode move cause stall on the next
1472 ;; instruction).
1473 ;;
1474 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1475 ;; register stall machines with, where we use QImode instructions, since
1476 ;; partial register stall can be caused there. Then we use movzx.
1477 (define_insn "*movqi_1"
1478 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1479 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1480 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1481 {
1482 switch (get_attr_type (insn))
1483 {
1484 case TYPE_IMOVX:
1485 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1486 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1487 default:
1488 if (get_attr_mode (insn) == MODE_SI)
1489 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1490 else
1491 return "mov{b}\t{%1, %0|%0, %1}";
1492 }
1493 }
1494 [(set (attr "type")
1495 (cond [(and (eq_attr "alternative" "5")
1496 (not (match_operand:QI 1 "aligned_operand" "")))
1497 (const_string "imovx")
1498 (ne (symbol_ref "optimize_size") (const_int 0))
1499 (const_string "imov")
1500 (and (eq_attr "alternative" "3")
1501 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1502 (const_int 0))
1503 (eq (symbol_ref "TARGET_QIMODE_MATH")
1504 (const_int 0))))
1505 (const_string "imov")
1506 (eq_attr "alternative" "3,5")
1507 (const_string "imovx")
1508 (and (ne (symbol_ref "TARGET_MOVX")
1509 (const_int 0))
1510 (eq_attr "alternative" "2"))
1511 (const_string "imovx")
1512 ]
1513 (const_string "imov")))
1514 (set (attr "mode")
1515 (cond [(eq_attr "alternative" "3,4,5")
1516 (const_string "SI")
1517 (eq_attr "alternative" "6")
1518 (const_string "QI")
1519 (eq_attr "type" "imovx")
1520 (const_string "SI")
1521 (and (eq_attr "type" "imov")
1522 (and (eq_attr "alternative" "0,1")
1523 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1524 (const_int 0))
1525 (and (eq (symbol_ref "optimize_size")
1526 (const_int 0))
1527 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1528 (const_int 0))))))
1529 (const_string "SI")
1530 ;; Avoid partial register stalls when not using QImode arithmetic
1531 (and (eq_attr "type" "imov")
1532 (and (eq_attr "alternative" "0,1")
1533 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1534 (const_int 0))
1535 (eq (symbol_ref "TARGET_QIMODE_MATH")
1536 (const_int 0)))))
1537 (const_string "SI")
1538 ]
1539 (const_string "QI")))])
1540
1541 (define_expand "reload_outqi"
1542 [(parallel [(match_operand:QI 0 "" "=m")
1543 (match_operand:QI 1 "register_operand" "r")
1544 (match_operand:QI 2 "register_operand" "=&q")])]
1545 ""
1546 {
1547 rtx op0, op1, op2;
1548 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1549
1550 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1551 if (! q_regs_operand (op1, QImode))
1552 {
1553 emit_insn (gen_movqi (op2, op1));
1554 op1 = op2;
1555 }
1556 emit_insn (gen_movqi (op0, op1));
1557 DONE;
1558 })
1559
1560 (define_insn "*swapqi_1"
1561 [(set (match_operand:QI 0 "register_operand" "+r")
1562 (match_operand:QI 1 "register_operand" "+r"))
1563 (set (match_dup 1)
1564 (match_dup 0))]
1565 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1566 "xchg{l}\t%k1, %k0"
1567 [(set_attr "type" "imov")
1568 (set_attr "mode" "SI")
1569 (set_attr "pent_pair" "np")
1570 (set_attr "athlon_decode" "vector")])
1571
1572 (define_insn "*swapqi_2"
1573 [(set (match_operand:QI 0 "register_operand" "+q")
1574 (match_operand:QI 1 "register_operand" "+q"))
1575 (set (match_dup 1)
1576 (match_dup 0))]
1577 "TARGET_PARTIAL_REG_STALL"
1578 "xchg{b}\t%1, %0"
1579 [(set_attr "type" "imov")
1580 (set_attr "mode" "QI")
1581 (set_attr "pent_pair" "np")
1582 (set_attr "athlon_decode" "vector")])
1583
1584 (define_expand "movstrictqi"
1585 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1586 (match_operand:QI 1 "general_operand" ""))]
1587 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1588 {
1589 /* Don't generate memory->memory moves, go through a register. */
1590 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1591 operands[1] = force_reg (QImode, operands[1]);
1592 })
1593
1594 (define_insn "*movstrictqi_1"
1595 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1596 (match_operand:QI 1 "general_operand" "*qn,m"))]
1597 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1598 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1599 "mov{b}\t{%1, %0|%0, %1}"
1600 [(set_attr "type" "imov")
1601 (set_attr "mode" "QI")])
1602
1603 (define_insn "*movstrictqi_xor"
1604 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1605 (match_operand:QI 1 "const0_operand" "i"))
1606 (clobber (reg:CC FLAGS_REG))]
1607 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1608 "xor{b}\t{%0, %0|%0, %0}"
1609 [(set_attr "type" "alu1")
1610 (set_attr "mode" "QI")
1611 (set_attr "length_immediate" "0")])
1612
1613 (define_insn "*movsi_extv_1"
1614 [(set (match_operand:SI 0 "register_operand" "=R")
1615 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1616 (const_int 8)
1617 (const_int 8)))]
1618 ""
1619 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1620 [(set_attr "type" "imovx")
1621 (set_attr "mode" "SI")])
1622
1623 (define_insn "*movhi_extv_1"
1624 [(set (match_operand:HI 0 "register_operand" "=R")
1625 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1626 (const_int 8)
1627 (const_int 8)))]
1628 ""
1629 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1630 [(set_attr "type" "imovx")
1631 (set_attr "mode" "SI")])
1632
1633 (define_insn "*movqi_extv_1"
1634 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1635 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1636 (const_int 8)
1637 (const_int 8)))]
1638 "!TARGET_64BIT"
1639 {
1640 switch (get_attr_type (insn))
1641 {
1642 case TYPE_IMOVX:
1643 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1644 default:
1645 return "mov{b}\t{%h1, %0|%0, %h1}";
1646 }
1647 }
1648 [(set (attr "type")
1649 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1650 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1651 (ne (symbol_ref "TARGET_MOVX")
1652 (const_int 0))))
1653 (const_string "imovx")
1654 (const_string "imov")))
1655 (set (attr "mode")
1656 (if_then_else (eq_attr "type" "imovx")
1657 (const_string "SI")
1658 (const_string "QI")))])
1659
1660 (define_insn "*movqi_extv_1_rex64"
1661 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1662 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1663 (const_int 8)
1664 (const_int 8)))]
1665 "TARGET_64BIT"
1666 {
1667 switch (get_attr_type (insn))
1668 {
1669 case TYPE_IMOVX:
1670 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1671 default:
1672 return "mov{b}\t{%h1, %0|%0, %h1}";
1673 }
1674 }
1675 [(set (attr "type")
1676 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678 (ne (symbol_ref "TARGET_MOVX")
1679 (const_int 0))))
1680 (const_string "imovx")
1681 (const_string "imov")))
1682 (set (attr "mode")
1683 (if_then_else (eq_attr "type" "imovx")
1684 (const_string "SI")
1685 (const_string "QI")))])
1686
1687 ;; Stores and loads of ax to arbitrary constant address.
1688 ;; We fake an second form of instruction to force reload to load address
1689 ;; into register when rax is not available
1690 (define_insn "*movabsqi_1_rex64"
1691 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1692 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1693 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1694 "@
1695 movabs{b}\t{%1, %P0|%P0, %1}
1696 mov{b}\t{%1, %a0|%a0, %1}"
1697 [(set_attr "type" "imov")
1698 (set_attr "modrm" "0,*")
1699 (set_attr "length_address" "8,0")
1700 (set_attr "length_immediate" "0,*")
1701 (set_attr "memory" "store")
1702 (set_attr "mode" "QI")])
1703
1704 (define_insn "*movabsqi_2_rex64"
1705 [(set (match_operand:QI 0 "register_operand" "=a,r")
1706 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1707 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1708 "@
1709 movabs{b}\t{%P1, %0|%0, %P1}
1710 mov{b}\t{%a1, %0|%0, %a1}"
1711 [(set_attr "type" "imov")
1712 (set_attr "modrm" "0,*")
1713 (set_attr "length_address" "8,0")
1714 (set_attr "length_immediate" "0")
1715 (set_attr "memory" "load")
1716 (set_attr "mode" "QI")])
1717
1718 (define_insn "*movdi_extzv_1"
1719 [(set (match_operand:DI 0 "register_operand" "=R")
1720 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1721 (const_int 8)
1722 (const_int 8)))]
1723 "TARGET_64BIT"
1724 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1725 [(set_attr "type" "imovx")
1726 (set_attr "mode" "DI")])
1727
1728 (define_insn "*movsi_extzv_1"
1729 [(set (match_operand:SI 0 "register_operand" "=R")
1730 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1731 (const_int 8)
1732 (const_int 8)))]
1733 ""
1734 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1735 [(set_attr "type" "imovx")
1736 (set_attr "mode" "SI")])
1737
1738 (define_insn "*movqi_extzv_2"
1739 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1740 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1741 (const_int 8)
1742 (const_int 8)) 0))]
1743 "!TARGET_64BIT"
1744 {
1745 switch (get_attr_type (insn))
1746 {
1747 case TYPE_IMOVX:
1748 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1749 default:
1750 return "mov{b}\t{%h1, %0|%0, %h1}";
1751 }
1752 }
1753 [(set (attr "type")
1754 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1755 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1756 (ne (symbol_ref "TARGET_MOVX")
1757 (const_int 0))))
1758 (const_string "imovx")
1759 (const_string "imov")))
1760 (set (attr "mode")
1761 (if_then_else (eq_attr "type" "imovx")
1762 (const_string "SI")
1763 (const_string "QI")))])
1764
1765 (define_insn "*movqi_extzv_2_rex64"
1766 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1767 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1768 (const_int 8)
1769 (const_int 8)) 0))]
1770 "TARGET_64BIT"
1771 {
1772 switch (get_attr_type (insn))
1773 {
1774 case TYPE_IMOVX:
1775 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1776 default:
1777 return "mov{b}\t{%h1, %0|%0, %h1}";
1778 }
1779 }
1780 [(set (attr "type")
1781 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1782 (ne (symbol_ref "TARGET_MOVX")
1783 (const_int 0)))
1784 (const_string "imovx")
1785 (const_string "imov")))
1786 (set (attr "mode")
1787 (if_then_else (eq_attr "type" "imovx")
1788 (const_string "SI")
1789 (const_string "QI")))])
1790
1791 (define_insn "movsi_insv_1"
1792 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1793 (const_int 8)
1794 (const_int 8))
1795 (match_operand:SI 1 "general_operand" "Qmn"))]
1796 "!TARGET_64BIT"
1797 "mov{b}\t{%b1, %h0|%h0, %b1}"
1798 [(set_attr "type" "imov")
1799 (set_attr "mode" "QI")])
1800
1801 (define_insn "movdi_insv_1_rex64"
1802 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1803 (const_int 8)
1804 (const_int 8))
1805 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1806 "TARGET_64BIT"
1807 "mov{b}\t{%b1, %h0|%h0, %b1}"
1808 [(set_attr "type" "imov")
1809 (set_attr "mode" "QI")])
1810
1811 (define_insn "*movqi_insv_2"
1812 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1813 (const_int 8)
1814 (const_int 8))
1815 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1816 (const_int 8)))]
1817 ""
1818 "mov{b}\t{%h1, %h0|%h0, %h1}"
1819 [(set_attr "type" "imov")
1820 (set_attr "mode" "QI")])
1821
1822 (define_expand "movdi"
1823 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1824 (match_operand:DI 1 "general_operand" ""))]
1825 ""
1826 "ix86_expand_move (DImode, operands); DONE;")
1827
1828 (define_insn "*pushdi"
1829 [(set (match_operand:DI 0 "push_operand" "=<")
1830 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1831 "!TARGET_64BIT"
1832 "#")
1833
1834 (define_insn "*pushdi2_rex64"
1835 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1836 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1837 "TARGET_64BIT"
1838 "@
1839 push{q}\t%1
1840 #"
1841 [(set_attr "type" "push,multi")
1842 (set_attr "mode" "DI")])
1843
1844 ;; Convert impossible pushes of immediate to existing instructions.
1845 ;; First try to get scratch register and go through it. In case this
1846 ;; fails, push sign extended lower part first and then overwrite
1847 ;; upper part by 32bit move.
1848 (define_peephole2
1849 [(match_scratch:DI 2 "r")
1850 (set (match_operand:DI 0 "push_operand" "")
1851 (match_operand:DI 1 "immediate_operand" ""))]
1852 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1853 && !x86_64_immediate_operand (operands[1], DImode)"
1854 [(set (match_dup 2) (match_dup 1))
1855 (set (match_dup 0) (match_dup 2))]
1856 "")
1857
1858 ;; We need to define this as both peepholer and splitter for case
1859 ;; peephole2 pass is not run.
1860 ;; "&& 1" is needed to keep it from matching the previous pattern.
1861 (define_peephole2
1862 [(set (match_operand:DI 0 "push_operand" "")
1863 (match_operand:DI 1 "immediate_operand" ""))]
1864 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1865 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1866 [(set (match_dup 0) (match_dup 1))
1867 (set (match_dup 2) (match_dup 3))]
1868 "split_di (operands + 1, 1, operands + 2, operands + 3);
1869 operands[1] = gen_lowpart (DImode, operands[2]);
1870 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1871 GEN_INT (4)));
1872 ")
1873
1874 (define_split
1875 [(set (match_operand:DI 0 "push_operand" "")
1876 (match_operand:DI 1 "immediate_operand" ""))]
1877 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1878 ? flow2_completed : reload_completed)
1879 && !symbolic_operand (operands[1], DImode)
1880 && !x86_64_immediate_operand (operands[1], DImode)"
1881 [(set (match_dup 0) (match_dup 1))
1882 (set (match_dup 2) (match_dup 3))]
1883 "split_di (operands + 1, 1, operands + 2, operands + 3);
1884 operands[1] = gen_lowpart (DImode, operands[2]);
1885 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1886 GEN_INT (4)));
1887 ")
1888
1889 (define_insn "*pushdi2_prologue_rex64"
1890 [(set (match_operand:DI 0 "push_operand" "=<")
1891 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1892 (clobber (mem:BLK (scratch)))]
1893 "TARGET_64BIT"
1894 "push{q}\t%1"
1895 [(set_attr "type" "push")
1896 (set_attr "mode" "DI")])
1897
1898 (define_insn "*popdi1_epilogue_rex64"
1899 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1900 (mem:DI (reg:DI SP_REG)))
1901 (set (reg:DI SP_REG)
1902 (plus:DI (reg:DI SP_REG) (const_int 8)))
1903 (clobber (mem:BLK (scratch)))]
1904 "TARGET_64BIT"
1905 "pop{q}\t%0"
1906 [(set_attr "type" "pop")
1907 (set_attr "mode" "DI")])
1908
1909 (define_insn "popdi1"
1910 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1911 (mem:DI (reg:DI SP_REG)))
1912 (set (reg:DI SP_REG)
1913 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1914 "TARGET_64BIT"
1915 "pop{q}\t%0"
1916 [(set_attr "type" "pop")
1917 (set_attr "mode" "DI")])
1918
1919 (define_insn "*movdi_xor_rex64"
1920 [(set (match_operand:DI 0 "register_operand" "=r")
1921 (match_operand:DI 1 "const0_operand" "i"))
1922 (clobber (reg:CC FLAGS_REG))]
1923 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1924 && reload_completed"
1925 "xor{l}\t{%k0, %k0|%k0, %k0}"
1926 [(set_attr "type" "alu1")
1927 (set_attr "mode" "SI")
1928 (set_attr "length_immediate" "0")])
1929
1930 (define_insn "*movdi_or_rex64"
1931 [(set (match_operand:DI 0 "register_operand" "=r")
1932 (match_operand:DI 1 "const_int_operand" "i"))
1933 (clobber (reg:CC FLAGS_REG))]
1934 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1935 && reload_completed
1936 && operands[1] == constm1_rtx"
1937 {
1938 operands[1] = constm1_rtx;
1939 return "or{q}\t{%1, %0|%0, %1}";
1940 }
1941 [(set_attr "type" "alu1")
1942 (set_attr "mode" "DI")
1943 (set_attr "length_immediate" "1")])
1944
1945 (define_insn "*movdi_2"
1946 [(set (match_operand:DI 0 "nonimmediate_operand"
1947 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1948 (match_operand:DI 1 "general_operand"
1949 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1950 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1951 "@
1952 #
1953 #
1954 pxor\t%0, %0
1955 movq\t{%1, %0|%0, %1}
1956 movq\t{%1, %0|%0, %1}
1957 pxor\t%0, %0
1958 movq\t{%1, %0|%0, %1}
1959 movdqa\t{%1, %0|%0, %1}
1960 movq\t{%1, %0|%0, %1}
1961 xorps\t%0, %0
1962 movlps\t{%1, %0|%0, %1}
1963 movaps\t{%1, %0|%0, %1}
1964 movlps\t{%1, %0|%0, %1}"
1965 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1966 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1967
1968 (define_split
1969 [(set (match_operand:DI 0 "push_operand" "")
1970 (match_operand:DI 1 "general_operand" ""))]
1971 "!TARGET_64BIT && reload_completed
1972 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1973 [(const_int 0)]
1974 "ix86_split_long_move (operands); DONE;")
1975
1976 ;; %%% This multiword shite has got to go.
1977 (define_split
1978 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1979 (match_operand:DI 1 "general_operand" ""))]
1980 "!TARGET_64BIT && reload_completed
1981 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1982 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1983 [(const_int 0)]
1984 "ix86_split_long_move (operands); DONE;")
1985
1986 (define_insn "*movdi_1_rex64"
1987 [(set (match_operand:DI 0 "nonimmediate_operand"
1988 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1989 (match_operand:DI 1 "general_operand"
1990 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1991 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1992 {
1993 switch (get_attr_type (insn))
1994 {
1995 case TYPE_SSECVT:
1996 if (which_alternative == 13)
1997 return "movq2dq\t{%1, %0|%0, %1}";
1998 else
1999 return "movdq2q\t{%1, %0|%0, %1}";
2000 case TYPE_SSEMOV:
2001 if (get_attr_mode (insn) == MODE_TI)
2002 return "movdqa\t{%1, %0|%0, %1}";
2003 /* FALLTHRU */
2004 case TYPE_MMXMOV:
2005 /* Moves from and into integer register is done using movd opcode with
2006 REX prefix. */
2007 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2008 return "movd\t{%1, %0|%0, %1}";
2009 return "movq\t{%1, %0|%0, %1}";
2010 case TYPE_SSELOG1:
2011 case TYPE_MMXADD:
2012 return "pxor\t%0, %0";
2013 case TYPE_MULTI:
2014 return "#";
2015 case TYPE_LEA:
2016 return "lea{q}\t{%a1, %0|%0, %a1}";
2017 default:
2018 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2019 if (get_attr_mode (insn) == MODE_SI)
2020 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2021 else if (which_alternative == 2)
2022 return "movabs{q}\t{%1, %0|%0, %1}";
2023 else
2024 return "mov{q}\t{%1, %0|%0, %1}";
2025 }
2026 }
2027 [(set (attr "type")
2028 (cond [(eq_attr "alternative" "5")
2029 (const_string "mmxadd")
2030 (eq_attr "alternative" "6,7,8")
2031 (const_string "mmxmov")
2032 (eq_attr "alternative" "9")
2033 (const_string "sselog1")
2034 (eq_attr "alternative" "10,11,12")
2035 (const_string "ssemov")
2036 (eq_attr "alternative" "13,14")
2037 (const_string "ssecvt")
2038 (eq_attr "alternative" "4")
2039 (const_string "multi")
2040 (match_operand:DI 1 "pic_32bit_operand" "")
2041 (const_string "lea")
2042 ]
2043 (const_string "imov")))
2044 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2045 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2046 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2047
2048 ;; Stores and loads of ax to arbitrary constant address.
2049 ;; We fake an second form of instruction to force reload to load address
2050 ;; into register when rax is not available
2051 (define_insn "*movabsdi_1_rex64"
2052 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2053 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2054 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2055 "@
2056 movabs{q}\t{%1, %P0|%P0, %1}
2057 mov{q}\t{%1, %a0|%a0, %1}"
2058 [(set_attr "type" "imov")
2059 (set_attr "modrm" "0,*")
2060 (set_attr "length_address" "8,0")
2061 (set_attr "length_immediate" "0,*")
2062 (set_attr "memory" "store")
2063 (set_attr "mode" "DI")])
2064
2065 (define_insn "*movabsdi_2_rex64"
2066 [(set (match_operand:DI 0 "register_operand" "=a,r")
2067 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2068 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2069 "@
2070 movabs{q}\t{%P1, %0|%0, %P1}
2071 mov{q}\t{%a1, %0|%0, %a1}"
2072 [(set_attr "type" "imov")
2073 (set_attr "modrm" "0,*")
2074 (set_attr "length_address" "8,0")
2075 (set_attr "length_immediate" "0")
2076 (set_attr "memory" "load")
2077 (set_attr "mode" "DI")])
2078
2079 ;; Convert impossible stores of immediate to existing instructions.
2080 ;; First try to get scratch register and go through it. In case this
2081 ;; fails, move by 32bit parts.
2082 (define_peephole2
2083 [(match_scratch:DI 2 "r")
2084 (set (match_operand:DI 0 "memory_operand" "")
2085 (match_operand:DI 1 "immediate_operand" ""))]
2086 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2087 && !x86_64_immediate_operand (operands[1], DImode)"
2088 [(set (match_dup 2) (match_dup 1))
2089 (set (match_dup 0) (match_dup 2))]
2090 "")
2091
2092 ;; We need to define this as both peepholer and splitter for case
2093 ;; peephole2 pass is not run.
2094 ;; "&& 1" is needed to keep it from matching the previous pattern.
2095 (define_peephole2
2096 [(set (match_operand:DI 0 "memory_operand" "")
2097 (match_operand:DI 1 "immediate_operand" ""))]
2098 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2099 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2100 [(set (match_dup 2) (match_dup 3))
2101 (set (match_dup 4) (match_dup 5))]
2102 "split_di (operands, 2, operands + 2, operands + 4);")
2103
2104 (define_split
2105 [(set (match_operand:DI 0 "memory_operand" "")
2106 (match_operand:DI 1 "immediate_operand" ""))]
2107 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2108 ? flow2_completed : reload_completed)
2109 && !symbolic_operand (operands[1], DImode)
2110 && !x86_64_immediate_operand (operands[1], DImode)"
2111 [(set (match_dup 2) (match_dup 3))
2112 (set (match_dup 4) (match_dup 5))]
2113 "split_di (operands, 2, operands + 2, operands + 4);")
2114
2115 (define_insn "*swapdi_rex64"
2116 [(set (match_operand:DI 0 "register_operand" "+r")
2117 (match_operand:DI 1 "register_operand" "+r"))
2118 (set (match_dup 1)
2119 (match_dup 0))]
2120 "TARGET_64BIT"
2121 "xchg{q}\t%1, %0"
2122 [(set_attr "type" "imov")
2123 (set_attr "mode" "DI")
2124 (set_attr "pent_pair" "np")
2125 (set_attr "athlon_decode" "vector")])
2126
2127 (define_expand "movti"
2128 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2129 (match_operand:TI 1 "nonimmediate_operand" ""))]
2130 "TARGET_SSE || TARGET_64BIT"
2131 {
2132 if (TARGET_64BIT)
2133 ix86_expand_move (TImode, operands);
2134 else
2135 ix86_expand_vector_move (TImode, operands);
2136 DONE;
2137 })
2138
2139 (define_insn "*movti_internal"
2140 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2141 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2142 "TARGET_SSE && !TARGET_64BIT
2143 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2144 {
2145 switch (which_alternative)
2146 {
2147 case 0:
2148 if (get_attr_mode (insn) == MODE_V4SF)
2149 return "xorps\t%0, %0";
2150 else
2151 return "pxor\t%0, %0";
2152 case 1:
2153 case 2:
2154 if (get_attr_mode (insn) == MODE_V4SF)
2155 return "movaps\t{%1, %0|%0, %1}";
2156 else
2157 return "movdqa\t{%1, %0|%0, %1}";
2158 default:
2159 gcc_unreachable ();
2160 }
2161 }
2162 [(set_attr "type" "sselog1,ssemov,ssemov")
2163 (set (attr "mode")
2164 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2165 (ne (symbol_ref "optimize_size") (const_int 0)))
2166 (const_string "V4SF")
2167 (and (eq_attr "alternative" "2")
2168 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2169 (const_int 0)))
2170 (const_string "V4SF")]
2171 (const_string "TI")))])
2172
2173 (define_insn "*movti_rex64"
2174 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2175 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2176 "TARGET_64BIT
2177 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2178 {
2179 switch (which_alternative)
2180 {
2181 case 0:
2182 case 1:
2183 return "#";
2184 case 2:
2185 if (get_attr_mode (insn) == MODE_V4SF)
2186 return "xorps\t%0, %0";
2187 else
2188 return "pxor\t%0, %0";
2189 case 3:
2190 case 4:
2191 if (get_attr_mode (insn) == MODE_V4SF)
2192 return "movaps\t{%1, %0|%0, %1}";
2193 else
2194 return "movdqa\t{%1, %0|%0, %1}";
2195 default:
2196 gcc_unreachable ();
2197 }
2198 }
2199 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2200 (set (attr "mode")
2201 (cond [(eq_attr "alternative" "2,3")
2202 (if_then_else
2203 (ne (symbol_ref "optimize_size")
2204 (const_int 0))
2205 (const_string "V4SF")
2206 (const_string "TI"))
2207 (eq_attr "alternative" "4")
2208 (if_then_else
2209 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2210 (const_int 0))
2211 (ne (symbol_ref "optimize_size")
2212 (const_int 0)))
2213 (const_string "V4SF")
2214 (const_string "TI"))]
2215 (const_string "DI")))])
2216
2217 (define_split
2218 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2219 (match_operand:TI 1 "general_operand" ""))]
2220 "reload_completed && !SSE_REG_P (operands[0])
2221 && !SSE_REG_P (operands[1])"
2222 [(const_int 0)]
2223 "ix86_split_long_move (operands); DONE;")
2224
2225 (define_expand "movsf"
2226 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2227 (match_operand:SF 1 "general_operand" ""))]
2228 ""
2229 "ix86_expand_move (SFmode, operands); DONE;")
2230
2231 (define_insn "*pushsf"
2232 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2233 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2234 "!TARGET_64BIT"
2235 {
2236 /* Anything else should be already split before reg-stack. */
2237 gcc_assert (which_alternative == 1);
2238 return "push{l}\t%1";
2239 }
2240 [(set_attr "type" "multi,push,multi")
2241 (set_attr "unit" "i387,*,*")
2242 (set_attr "mode" "SF,SI,SF")])
2243
2244 (define_insn "*pushsf_rex64"
2245 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2246 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2247 "TARGET_64BIT"
2248 {
2249 /* Anything else should be already split before reg-stack. */
2250 gcc_assert (which_alternative == 1);
2251 return "push{q}\t%q1";
2252 }
2253 [(set_attr "type" "multi,push,multi")
2254 (set_attr "unit" "i387,*,*")
2255 (set_attr "mode" "SF,DI,SF")])
2256
2257 (define_split
2258 [(set (match_operand:SF 0 "push_operand" "")
2259 (match_operand:SF 1 "memory_operand" ""))]
2260 "reload_completed
2261 && GET_CODE (operands[1]) == MEM
2262 && constant_pool_reference_p (operands[1])"
2263 [(set (match_dup 0)
2264 (match_dup 1))]
2265 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2266
2267
2268 ;; %%% Kill this when call knows how to work this out.
2269 (define_split
2270 [(set (match_operand:SF 0 "push_operand" "")
2271 (match_operand:SF 1 "any_fp_register_operand" ""))]
2272 "!TARGET_64BIT"
2273 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2274 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2275
2276 (define_split
2277 [(set (match_operand:SF 0 "push_operand" "")
2278 (match_operand:SF 1 "any_fp_register_operand" ""))]
2279 "TARGET_64BIT"
2280 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2281 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2282
2283 (define_insn "*movsf_1"
2284 [(set (match_operand:SF 0 "nonimmediate_operand"
2285 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2286 (match_operand:SF 1 "general_operand"
2287 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2288 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2289 && (reload_in_progress || reload_completed
2290 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2291 || GET_CODE (operands[1]) != CONST_DOUBLE
2292 || memory_operand (operands[0], SFmode))"
2293 {
2294 switch (which_alternative)
2295 {
2296 case 0:
2297 return output_387_reg_move (insn, operands);
2298
2299 case 1:
2300 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2301 return "fstp%z0\t%y0";
2302 else
2303 return "fst%z0\t%y0";
2304
2305 case 2:
2306 return standard_80387_constant_opcode (operands[1]);
2307
2308 case 3:
2309 case 4:
2310 return "mov{l}\t{%1, %0|%0, %1}";
2311 case 5:
2312 if (get_attr_mode (insn) == MODE_TI)
2313 return "pxor\t%0, %0";
2314 else
2315 return "xorps\t%0, %0";
2316 case 6:
2317 if (get_attr_mode (insn) == MODE_V4SF)
2318 return "movaps\t{%1, %0|%0, %1}";
2319 else
2320 return "movss\t{%1, %0|%0, %1}";
2321 case 7:
2322 case 8:
2323 return "movss\t{%1, %0|%0, %1}";
2324
2325 case 9:
2326 case 10:
2327 return "movd\t{%1, %0|%0, %1}";
2328
2329 case 11:
2330 return "movq\t{%1, %0|%0, %1}";
2331
2332 default:
2333 gcc_unreachable ();
2334 }
2335 }
2336 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2337 (set (attr "mode")
2338 (cond [(eq_attr "alternative" "3,4,9,10")
2339 (const_string "SI")
2340 (eq_attr "alternative" "5")
2341 (if_then_else
2342 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2343 (const_int 0))
2344 (ne (symbol_ref "TARGET_SSE2")
2345 (const_int 0)))
2346 (eq (symbol_ref "optimize_size")
2347 (const_int 0)))
2348 (const_string "TI")
2349 (const_string "V4SF"))
2350 /* For architectures resolving dependencies on
2351 whole SSE registers use APS move to break dependency
2352 chains, otherwise use short move to avoid extra work.
2353
2354 Do the same for architectures resolving dependencies on
2355 the parts. While in DF mode it is better to always handle
2356 just register parts, the SF mode is different due to lack
2357 of instructions to load just part of the register. It is
2358 better to maintain the whole registers in single format
2359 to avoid problems on using packed logical operations. */
2360 (eq_attr "alternative" "6")
2361 (if_then_else
2362 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2363 (const_int 0))
2364 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2365 (const_int 0)))
2366 (const_string "V4SF")
2367 (const_string "SF"))
2368 (eq_attr "alternative" "11")
2369 (const_string "DI")]
2370 (const_string "SF")))])
2371
2372 (define_insn "*swapsf"
2373 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2374 (match_operand:SF 1 "fp_register_operand" "+f"))
2375 (set (match_dup 1)
2376 (match_dup 0))]
2377 "reload_completed || TARGET_80387"
2378 {
2379 if (STACK_TOP_P (operands[0]))
2380 return "fxch\t%1";
2381 else
2382 return "fxch\t%0";
2383 }
2384 [(set_attr "type" "fxch")
2385 (set_attr "mode" "SF")])
2386
2387 (define_expand "movdf"
2388 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2389 (match_operand:DF 1 "general_operand" ""))]
2390 ""
2391 "ix86_expand_move (DFmode, operands); DONE;")
2392
2393 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2394 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2395 ;; On the average, pushdf using integers can be still shorter. Allow this
2396 ;; pattern for optimize_size too.
2397
2398 (define_insn "*pushdf_nointeger"
2399 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2400 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2401 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2402 {
2403 /* This insn should be already split before reg-stack. */
2404 gcc_unreachable ();
2405 }
2406 [(set_attr "type" "multi")
2407 (set_attr "unit" "i387,*,*,*")
2408 (set_attr "mode" "DF,SI,SI,DF")])
2409
2410 (define_insn "*pushdf_integer"
2411 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2412 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2413 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2414 {
2415 /* This insn should be already split before reg-stack. */
2416 gcc_unreachable ();
2417 }
2418 [(set_attr "type" "multi")
2419 (set_attr "unit" "i387,*,*")
2420 (set_attr "mode" "DF,SI,DF")])
2421
2422 ;; %%% Kill this when call knows how to work this out.
2423 (define_split
2424 [(set (match_operand:DF 0 "push_operand" "")
2425 (match_operand:DF 1 "any_fp_register_operand" ""))]
2426 "!TARGET_64BIT && reload_completed"
2427 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2428 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2429 "")
2430
2431 (define_split
2432 [(set (match_operand:DF 0 "push_operand" "")
2433 (match_operand:DF 1 "any_fp_register_operand" ""))]
2434 "TARGET_64BIT && reload_completed"
2435 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2436 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2437 "")
2438
2439 (define_split
2440 [(set (match_operand:DF 0 "push_operand" "")
2441 (match_operand:DF 1 "general_operand" ""))]
2442 "reload_completed"
2443 [(const_int 0)]
2444 "ix86_split_long_move (operands); DONE;")
2445
2446 ;; Moving is usually shorter when only FP registers are used. This separate
2447 ;; movdf pattern avoids the use of integer registers for FP operations
2448 ;; when optimizing for size.
2449
2450 (define_insn "*movdf_nointeger"
2451 [(set (match_operand:DF 0 "nonimmediate_operand"
2452 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2453 (match_operand:DF 1 "general_operand"
2454 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2455 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2456 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2457 && (reload_in_progress || reload_completed
2458 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2459 || GET_CODE (operands[1]) != CONST_DOUBLE
2460 || memory_operand (operands[0], DFmode))"
2461 {
2462 switch (which_alternative)
2463 {
2464 case 0:
2465 return output_387_reg_move (insn, operands);
2466
2467 case 1:
2468 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2469 return "fstp%z0\t%y0";
2470 else
2471 return "fst%z0\t%y0";
2472
2473 case 2:
2474 return standard_80387_constant_opcode (operands[1]);
2475
2476 case 3:
2477 case 4:
2478 return "#";
2479 case 5:
2480 switch (get_attr_mode (insn))
2481 {
2482 case MODE_V4SF:
2483 return "xorps\t%0, %0";
2484 case MODE_V2DF:
2485 return "xorpd\t%0, %0";
2486 case MODE_TI:
2487 return "pxor\t%0, %0";
2488 default:
2489 gcc_unreachable ();
2490 }
2491 case 6:
2492 case 7:
2493 case 8:
2494 switch (get_attr_mode (insn))
2495 {
2496 case MODE_V4SF:
2497 return "movaps\t{%1, %0|%0, %1}";
2498 case MODE_V2DF:
2499 return "movapd\t{%1, %0|%0, %1}";
2500 case MODE_TI:
2501 return "movdqa\t{%1, %0|%0, %1}";
2502 case MODE_DI:
2503 return "movq\t{%1, %0|%0, %1}";
2504 case MODE_DF:
2505 return "movsd\t{%1, %0|%0, %1}";
2506 case MODE_V1DF:
2507 return "movlpd\t{%1, %0|%0, %1}";
2508 case MODE_V2SF:
2509 return "movlps\t{%1, %0|%0, %1}";
2510 default:
2511 gcc_unreachable ();
2512 }
2513
2514 default:
2515 gcc_unreachable ();
2516 }
2517 }
2518 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2519 (set (attr "mode")
2520 (cond [(eq_attr "alternative" "0,1,2")
2521 (const_string "DF")
2522 (eq_attr "alternative" "3,4")
2523 (const_string "SI")
2524
2525 /* For SSE1, we have many fewer alternatives. */
2526 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2527 (cond [(eq_attr "alternative" "5,6")
2528 (const_string "V4SF")
2529 ]
2530 (const_string "V2SF"))
2531
2532 /* xorps is one byte shorter. */
2533 (eq_attr "alternative" "5")
2534 (cond [(ne (symbol_ref "optimize_size")
2535 (const_int 0))
2536 (const_string "V4SF")
2537 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2538 (const_int 0))
2539 (const_string "TI")
2540 ]
2541 (const_string "V2DF"))
2542
2543 /* For architectures resolving dependencies on
2544 whole SSE registers use APD move to break dependency
2545 chains, otherwise use short move to avoid extra work.
2546
2547 movaps encodes one byte shorter. */
2548 (eq_attr "alternative" "6")
2549 (cond
2550 [(ne (symbol_ref "optimize_size")
2551 (const_int 0))
2552 (const_string "V4SF")
2553 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2554 (const_int 0))
2555 (const_string "V2DF")
2556 ]
2557 (const_string "DF"))
2558 /* For architectures resolving dependencies on register
2559 parts we may avoid extra work to zero out upper part
2560 of register. */
2561 (eq_attr "alternative" "7")
2562 (if_then_else
2563 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2564 (const_int 0))
2565 (const_string "V1DF")
2566 (const_string "DF"))
2567 ]
2568 (const_string "DF")))])
2569
2570 (define_insn "*movdf_integer"
2571 [(set (match_operand:DF 0 "nonimmediate_operand"
2572 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2573 (match_operand:DF 1 "general_operand"
2574 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2575 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2576 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2577 && (reload_in_progress || reload_completed
2578 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2579 || GET_CODE (operands[1]) != CONST_DOUBLE
2580 || memory_operand (operands[0], DFmode))"
2581 {
2582 switch (which_alternative)
2583 {
2584 case 0:
2585 return output_387_reg_move (insn, operands);
2586
2587 case 1:
2588 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2589 return "fstp%z0\t%y0";
2590 else
2591 return "fst%z0\t%y0";
2592
2593 case 2:
2594 return standard_80387_constant_opcode (operands[1]);
2595
2596 case 3:
2597 case 4:
2598 return "#";
2599
2600 case 5:
2601 switch (get_attr_mode (insn))
2602 {
2603 case MODE_V4SF:
2604 return "xorps\t%0, %0";
2605 case MODE_V2DF:
2606 return "xorpd\t%0, %0";
2607 case MODE_TI:
2608 return "pxor\t%0, %0";
2609 default:
2610 gcc_unreachable ();
2611 }
2612 case 6:
2613 case 7:
2614 case 8:
2615 switch (get_attr_mode (insn))
2616 {
2617 case MODE_V4SF:
2618 return "movaps\t{%1, %0|%0, %1}";
2619 case MODE_V2DF:
2620 return "movapd\t{%1, %0|%0, %1}";
2621 case MODE_TI:
2622 return "movdqa\t{%1, %0|%0, %1}";
2623 case MODE_DI:
2624 return "movq\t{%1, %0|%0, %1}";
2625 case MODE_DF:
2626 return "movsd\t{%1, %0|%0, %1}";
2627 case MODE_V1DF:
2628 return "movlpd\t{%1, %0|%0, %1}";
2629 case MODE_V2SF:
2630 return "movlps\t{%1, %0|%0, %1}";
2631 default:
2632 gcc_unreachable ();
2633 }
2634
2635 default:
2636 gcc_unreachable();
2637 }
2638 }
2639 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2640 (set (attr "mode")
2641 (cond [(eq_attr "alternative" "0,1,2")
2642 (const_string "DF")
2643 (eq_attr "alternative" "3,4")
2644 (const_string "SI")
2645
2646 /* For SSE1, we have many fewer alternatives. */
2647 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2648 (cond [(eq_attr "alternative" "5,6")
2649 (const_string "V4SF")
2650 ]
2651 (const_string "V2SF"))
2652
2653 /* xorps is one byte shorter. */
2654 (eq_attr "alternative" "5")
2655 (cond [(ne (symbol_ref "optimize_size")
2656 (const_int 0))
2657 (const_string "V4SF")
2658 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2659 (const_int 0))
2660 (const_string "TI")
2661 ]
2662 (const_string "V2DF"))
2663
2664 /* For architectures resolving dependencies on
2665 whole SSE registers use APD move to break dependency
2666 chains, otherwise use short move to avoid extra work.
2667
2668 movaps encodes one byte shorter. */
2669 (eq_attr "alternative" "6")
2670 (cond
2671 [(ne (symbol_ref "optimize_size")
2672 (const_int 0))
2673 (const_string "V4SF")
2674 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2675 (const_int 0))
2676 (const_string "V2DF")
2677 ]
2678 (const_string "DF"))
2679 /* For architectures resolving dependencies on register
2680 parts we may avoid extra work to zero out upper part
2681 of register. */
2682 (eq_attr "alternative" "7")
2683 (if_then_else
2684 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2685 (const_int 0))
2686 (const_string "V1DF")
2687 (const_string "DF"))
2688 ]
2689 (const_string "DF")))])
2690
2691 (define_split
2692 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2693 (match_operand:DF 1 "general_operand" ""))]
2694 "reload_completed
2695 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2696 && ! (ANY_FP_REG_P (operands[0]) ||
2697 (GET_CODE (operands[0]) == SUBREG
2698 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2699 && ! (ANY_FP_REG_P (operands[1]) ||
2700 (GET_CODE (operands[1]) == SUBREG
2701 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2702 [(const_int 0)]
2703 "ix86_split_long_move (operands); DONE;")
2704
2705 (define_insn "*swapdf"
2706 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2707 (match_operand:DF 1 "fp_register_operand" "+f"))
2708 (set (match_dup 1)
2709 (match_dup 0))]
2710 "reload_completed || TARGET_80387"
2711 {
2712 if (STACK_TOP_P (operands[0]))
2713 return "fxch\t%1";
2714 else
2715 return "fxch\t%0";
2716 }
2717 [(set_attr "type" "fxch")
2718 (set_attr "mode" "DF")])
2719
2720 (define_expand "movxf"
2721 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2722 (match_operand:XF 1 "general_operand" ""))]
2723 ""
2724 "ix86_expand_move (XFmode, operands); DONE;")
2725
2726 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2727 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2728 ;; Pushing using integer instructions is longer except for constants
2729 ;; and direct memory references.
2730 ;; (assuming that any given constant is pushed only once, but this ought to be
2731 ;; handled elsewhere).
2732
2733 (define_insn "*pushxf_nointeger"
2734 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2735 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2736 "optimize_size"
2737 {
2738 /* This insn should be already split before reg-stack. */
2739 gcc_unreachable ();
2740 }
2741 [(set_attr "type" "multi")
2742 (set_attr "unit" "i387,*,*")
2743 (set_attr "mode" "XF,SI,SI")])
2744
2745 (define_insn "*pushxf_integer"
2746 [(set (match_operand:XF 0 "push_operand" "=<,<")
2747 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2748 "!optimize_size"
2749 {
2750 /* This insn should be already split before reg-stack. */
2751 gcc_unreachable ();
2752 }
2753 [(set_attr "type" "multi")
2754 (set_attr "unit" "i387,*")
2755 (set_attr "mode" "XF,SI")])
2756
2757 (define_split
2758 [(set (match_operand 0 "push_operand" "")
2759 (match_operand 1 "general_operand" ""))]
2760 "reload_completed
2761 && (GET_MODE (operands[0]) == XFmode
2762 || GET_MODE (operands[0]) == DFmode)
2763 && !ANY_FP_REG_P (operands[1])"
2764 [(const_int 0)]
2765 "ix86_split_long_move (operands); DONE;")
2766
2767 (define_split
2768 [(set (match_operand:XF 0 "push_operand" "")
2769 (match_operand:XF 1 "any_fp_register_operand" ""))]
2770 "!TARGET_64BIT"
2771 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2772 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2773 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774
2775 (define_split
2776 [(set (match_operand:XF 0 "push_operand" "")
2777 (match_operand:XF 1 "any_fp_register_operand" ""))]
2778 "TARGET_64BIT"
2779 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2780 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2781 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2782
2783 ;; Do not use integer registers when optimizing for size
2784 (define_insn "*movxf_nointeger"
2785 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2786 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2787 "optimize_size
2788 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789 && (reload_in_progress || reload_completed
2790 || GET_CODE (operands[1]) != CONST_DOUBLE
2791 || memory_operand (operands[0], XFmode))"
2792 {
2793 switch (which_alternative)
2794 {
2795 case 0:
2796 return output_387_reg_move (insn, operands);
2797
2798 case 1:
2799 /* There is no non-popping store to memory for XFmode. So if
2800 we need one, follow the store with a load. */
2801 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2802 return "fstp%z0\t%y0\;fld%z0\t%y0";
2803 else
2804 return "fstp%z0\t%y0";
2805
2806 case 2:
2807 return standard_80387_constant_opcode (operands[1]);
2808
2809 case 3: case 4:
2810 return "#";
2811 default:
2812 gcc_unreachable ();
2813 }
2814 }
2815 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2816 (set_attr "mode" "XF,XF,XF,SI,SI")])
2817
2818 (define_insn "*movxf_integer"
2819 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2820 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2821 "!optimize_size
2822 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2823 && (reload_in_progress || reload_completed
2824 || GET_CODE (operands[1]) != CONST_DOUBLE
2825 || memory_operand (operands[0], XFmode))"
2826 {
2827 switch (which_alternative)
2828 {
2829 case 0:
2830 return output_387_reg_move (insn, operands);
2831
2832 case 1:
2833 /* There is no non-popping store to memory for XFmode. So if
2834 we need one, follow the store with a load. */
2835 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2836 return "fstp%z0\t%y0\;fld%z0\t%y0";
2837 else
2838 return "fstp%z0\t%y0";
2839
2840 case 2:
2841 return standard_80387_constant_opcode (operands[1]);
2842
2843 case 3: case 4:
2844 return "#";
2845
2846 default:
2847 gcc_unreachable ();
2848 }
2849 }
2850 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2851 (set_attr "mode" "XF,XF,XF,SI,SI")])
2852
2853 (define_split
2854 [(set (match_operand 0 "nonimmediate_operand" "")
2855 (match_operand 1 "general_operand" ""))]
2856 "reload_completed
2857 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2858 && GET_MODE (operands[0]) == XFmode
2859 && ! (ANY_FP_REG_P (operands[0]) ||
2860 (GET_CODE (operands[0]) == SUBREG
2861 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2862 && ! (ANY_FP_REG_P (operands[1]) ||
2863 (GET_CODE (operands[1]) == SUBREG
2864 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2865 [(const_int 0)]
2866 "ix86_split_long_move (operands); DONE;")
2867
2868 (define_split
2869 [(set (match_operand 0 "register_operand" "")
2870 (match_operand 1 "memory_operand" ""))]
2871 "reload_completed
2872 && GET_CODE (operands[1]) == MEM
2873 && (GET_MODE (operands[0]) == XFmode
2874 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2875 && constant_pool_reference_p (operands[1])"
2876 [(set (match_dup 0) (match_dup 1))]
2877 {
2878 rtx c = avoid_constant_pool_reference (operands[1]);
2879 rtx r = operands[0];
2880
2881 if (GET_CODE (r) == SUBREG)
2882 r = SUBREG_REG (r);
2883
2884 if (SSE_REG_P (r))
2885 {
2886 if (!standard_sse_constant_p (c))
2887 FAIL;
2888 }
2889 else if (FP_REG_P (r))
2890 {
2891 if (!standard_80387_constant_p (c))
2892 FAIL;
2893 }
2894 else if (MMX_REG_P (r))
2895 FAIL;
2896
2897 operands[1] = c;
2898 })
2899
2900 (define_insn "swapxf"
2901 [(set (match_operand:XF 0 "register_operand" "+f")
2902 (match_operand:XF 1 "register_operand" "+f"))
2903 (set (match_dup 1)
2904 (match_dup 0))]
2905 "TARGET_80387"
2906 {
2907 if (STACK_TOP_P (operands[0]))
2908 return "fxch\t%1";
2909 else
2910 return "fxch\t%0";
2911 }
2912 [(set_attr "type" "fxch")
2913 (set_attr "mode" "XF")])
2914
2915 (define_expand "movtf"
2916 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2917 (match_operand:TF 1 "nonimmediate_operand" ""))]
2918 "TARGET_64BIT"
2919 {
2920 ix86_expand_move (TFmode, operands);
2921 DONE;
2922 })
2923
2924 (define_insn "*movtf_internal"
2925 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2926 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2927 "TARGET_64BIT
2928 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2929 {
2930 switch (which_alternative)
2931 {
2932 case 0:
2933 case 1:
2934 return "#";
2935 case 2:
2936 if (get_attr_mode (insn) == MODE_V4SF)
2937 return "xorps\t%0, %0";
2938 else
2939 return "pxor\t%0, %0";
2940 case 3:
2941 case 4:
2942 if (get_attr_mode (insn) == MODE_V4SF)
2943 return "movaps\t{%1, %0|%0, %1}";
2944 else
2945 return "movdqa\t{%1, %0|%0, %1}";
2946 default:
2947 gcc_unreachable ();
2948 }
2949 }
2950 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2951 (set (attr "mode")
2952 (cond [(eq_attr "alternative" "2,3")
2953 (if_then_else
2954 (ne (symbol_ref "optimize_size")
2955 (const_int 0))
2956 (const_string "V4SF")
2957 (const_string "TI"))
2958 (eq_attr "alternative" "4")
2959 (if_then_else
2960 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2961 (const_int 0))
2962 (ne (symbol_ref "optimize_size")
2963 (const_int 0)))
2964 (const_string "V4SF")
2965 (const_string "TI"))]
2966 (const_string "DI")))])
2967
2968 (define_split
2969 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2970 (match_operand:TF 1 "general_operand" ""))]
2971 "reload_completed && !SSE_REG_P (operands[0])
2972 && !SSE_REG_P (operands[1])"
2973 [(const_int 0)]
2974 "ix86_split_long_move (operands); DONE;")
2975 \f
2976 ;; Zero extension instructions
2977
2978 (define_expand "zero_extendhisi2"
2979 [(set (match_operand:SI 0 "register_operand" "")
2980 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2981 ""
2982 {
2983 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2984 {
2985 operands[1] = force_reg (HImode, operands[1]);
2986 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2987 DONE;
2988 }
2989 })
2990
2991 (define_insn "zero_extendhisi2_and"
2992 [(set (match_operand:SI 0 "register_operand" "=r")
2993 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2994 (clobber (reg:CC FLAGS_REG))]
2995 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2996 "#"
2997 [(set_attr "type" "alu1")
2998 (set_attr "mode" "SI")])
2999
3000 (define_split
3001 [(set (match_operand:SI 0 "register_operand" "")
3002 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3003 (clobber (reg:CC FLAGS_REG))]
3004 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3005 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3006 (clobber (reg:CC FLAGS_REG))])]
3007 "")
3008
3009 (define_insn "*zero_extendhisi2_movzwl"
3010 [(set (match_operand:SI 0 "register_operand" "=r")
3011 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3012 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3013 "movz{wl|x}\t{%1, %0|%0, %1}"
3014 [(set_attr "type" "imovx")
3015 (set_attr "mode" "SI")])
3016
3017 (define_expand "zero_extendqihi2"
3018 [(parallel
3019 [(set (match_operand:HI 0 "register_operand" "")
3020 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3021 (clobber (reg:CC FLAGS_REG))])]
3022 ""
3023 "")
3024
3025 (define_insn "*zero_extendqihi2_and"
3026 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3027 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3028 (clobber (reg:CC FLAGS_REG))]
3029 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3030 "#"
3031 [(set_attr "type" "alu1")
3032 (set_attr "mode" "HI")])
3033
3034 (define_insn "*zero_extendqihi2_movzbw_and"
3035 [(set (match_operand:HI 0 "register_operand" "=r,r")
3036 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3037 (clobber (reg:CC FLAGS_REG))]
3038 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3039 "#"
3040 [(set_attr "type" "imovx,alu1")
3041 (set_attr "mode" "HI")])
3042
3043 ; zero extend to SImode here to avoid partial register stalls
3044 (define_insn "*zero_extendqihi2_movzbl"
3045 [(set (match_operand:HI 0 "register_operand" "=r")
3046 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3047 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3048 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3049 [(set_attr "type" "imovx")
3050 (set_attr "mode" "SI")])
3051
3052 ;; For the movzbw case strip only the clobber
3053 (define_split
3054 [(set (match_operand:HI 0 "register_operand" "")
3055 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3056 (clobber (reg:CC FLAGS_REG))]
3057 "reload_completed
3058 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3059 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3060 [(set (match_operand:HI 0 "register_operand" "")
3061 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3062
3063 ;; When source and destination does not overlap, clear destination
3064 ;; first and then do the movb
3065 (define_split
3066 [(set (match_operand:HI 0 "register_operand" "")
3067 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3068 (clobber (reg:CC FLAGS_REG))]
3069 "reload_completed
3070 && ANY_QI_REG_P (operands[0])
3071 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3072 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3073 [(set (match_dup 0) (const_int 0))
3074 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3075 "operands[2] = gen_lowpart (QImode, operands[0]);")
3076
3077 ;; Rest is handled by single and.
3078 (define_split
3079 [(set (match_operand:HI 0 "register_operand" "")
3080 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3081 (clobber (reg:CC FLAGS_REG))]
3082 "reload_completed
3083 && true_regnum (operands[0]) == true_regnum (operands[1])"
3084 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3085 (clobber (reg:CC FLAGS_REG))])]
3086 "")
3087
3088 (define_expand "zero_extendqisi2"
3089 [(parallel
3090 [(set (match_operand:SI 0 "register_operand" "")
3091 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3092 (clobber (reg:CC FLAGS_REG))])]
3093 ""
3094 "")
3095
3096 (define_insn "*zero_extendqisi2_and"
3097 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3098 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3099 (clobber (reg:CC FLAGS_REG))]
3100 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3101 "#"
3102 [(set_attr "type" "alu1")
3103 (set_attr "mode" "SI")])
3104
3105 (define_insn "*zero_extendqisi2_movzbw_and"
3106 [(set (match_operand:SI 0 "register_operand" "=r,r")
3107 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3108 (clobber (reg:CC FLAGS_REG))]
3109 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3110 "#"
3111 [(set_attr "type" "imovx,alu1")
3112 (set_attr "mode" "SI")])
3113
3114 (define_insn "*zero_extendqisi2_movzbw"
3115 [(set (match_operand:SI 0 "register_operand" "=r")
3116 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3117 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3118 "movz{bl|x}\t{%1, %0|%0, %1}"
3119 [(set_attr "type" "imovx")
3120 (set_attr "mode" "SI")])
3121
3122 ;; For the movzbl case strip only the clobber
3123 (define_split
3124 [(set (match_operand:SI 0 "register_operand" "")
3125 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3126 (clobber (reg:CC FLAGS_REG))]
3127 "reload_completed
3128 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3129 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3130 [(set (match_dup 0)
3131 (zero_extend:SI (match_dup 1)))])
3132
3133 ;; When source and destination does not overlap, clear destination
3134 ;; first and then do the movb
3135 (define_split
3136 [(set (match_operand:SI 0 "register_operand" "")
3137 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3138 (clobber (reg:CC FLAGS_REG))]
3139 "reload_completed
3140 && ANY_QI_REG_P (operands[0])
3141 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3142 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3143 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3144 [(set (match_dup 0) (const_int 0))
3145 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3146 "operands[2] = gen_lowpart (QImode, operands[0]);")
3147
3148 ;; Rest is handled by single and.
3149 (define_split
3150 [(set (match_operand:SI 0 "register_operand" "")
3151 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3152 (clobber (reg:CC FLAGS_REG))]
3153 "reload_completed
3154 && true_regnum (operands[0]) == true_regnum (operands[1])"
3155 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3156 (clobber (reg:CC FLAGS_REG))])]
3157 "")
3158
3159 ;; %%% Kill me once multi-word ops are sane.
3160 (define_expand "zero_extendsidi2"
3161 [(set (match_operand:DI 0 "register_operand" "=r")
3162 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3163 ""
3164 "if (!TARGET_64BIT)
3165 {
3166 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3167 DONE;
3168 }
3169 ")
3170
3171 (define_insn "zero_extendsidi2_32"
3172 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3173 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3174 (clobber (reg:CC FLAGS_REG))]
3175 "!TARGET_64BIT"
3176 "@
3177 #
3178 #
3179 #
3180 movd\t{%1, %0|%0, %1}
3181 movd\t{%1, %0|%0, %1}"
3182 [(set_attr "mode" "SI,SI,SI,DI,TI")
3183 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3184
3185 (define_insn "zero_extendsidi2_rex64"
3186 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3187 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3188 "TARGET_64BIT"
3189 "@
3190 mov\t{%k1, %k0|%k0, %k1}
3191 #
3192 movd\t{%1, %0|%0, %1}
3193 movd\t{%1, %0|%0, %1}"
3194 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3195 (set_attr "mode" "SI,DI,SI,SI")])
3196
3197 (define_split
3198 [(set (match_operand:DI 0 "memory_operand" "")
3199 (zero_extend:DI (match_dup 0)))]
3200 "TARGET_64BIT"
3201 [(set (match_dup 4) (const_int 0))]
3202 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3203
3204 (define_split
3205 [(set (match_operand:DI 0 "register_operand" "")
3206 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3207 (clobber (reg:CC FLAGS_REG))]
3208 "!TARGET_64BIT && reload_completed
3209 && true_regnum (operands[0]) == true_regnum (operands[1])"
3210 [(set (match_dup 4) (const_int 0))]
3211 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3212
3213 (define_split
3214 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3215 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3216 (clobber (reg:CC FLAGS_REG))]
3217 "!TARGET_64BIT && reload_completed
3218 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3219 [(set (match_dup 3) (match_dup 1))
3220 (set (match_dup 4) (const_int 0))]
3221 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3222
3223 (define_insn "zero_extendhidi2"
3224 [(set (match_operand:DI 0 "register_operand" "=r")
3225 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3226 "TARGET_64BIT"
3227 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3228 [(set_attr "type" "imovx")
3229 (set_attr "mode" "DI")])
3230
3231 (define_insn "zero_extendqidi2"
3232 [(set (match_operand:DI 0 "register_operand" "=r")
3233 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3234 "TARGET_64BIT"
3235 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3236 [(set_attr "type" "imovx")
3237 (set_attr "mode" "DI")])
3238 \f
3239 ;; Sign extension instructions
3240
3241 (define_expand "extendsidi2"
3242 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3243 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3244 (clobber (reg:CC FLAGS_REG))
3245 (clobber (match_scratch:SI 2 ""))])]
3246 ""
3247 {
3248 if (TARGET_64BIT)
3249 {
3250 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3251 DONE;
3252 }
3253 })
3254
3255 (define_insn "*extendsidi2_1"
3256 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3257 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3258 (clobber (reg:CC FLAGS_REG))
3259 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3260 "!TARGET_64BIT"
3261 "#")
3262
3263 (define_insn "extendsidi2_rex64"
3264 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3265 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3266 "TARGET_64BIT"
3267 "@
3268 {cltq|cdqe}
3269 movs{lq|x}\t{%1,%0|%0, %1}"
3270 [(set_attr "type" "imovx")
3271 (set_attr "mode" "DI")
3272 (set_attr "prefix_0f" "0")
3273 (set_attr "modrm" "0,1")])
3274
3275 (define_insn "extendhidi2"
3276 [(set (match_operand:DI 0 "register_operand" "=r")
3277 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3278 "TARGET_64BIT"
3279 "movs{wq|x}\t{%1,%0|%0, %1}"
3280 [(set_attr "type" "imovx")
3281 (set_attr "mode" "DI")])
3282
3283 (define_insn "extendqidi2"
3284 [(set (match_operand:DI 0 "register_operand" "=r")
3285 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3286 "TARGET_64BIT"
3287 "movs{bq|x}\t{%1,%0|%0, %1}"
3288 [(set_attr "type" "imovx")
3289 (set_attr "mode" "DI")])
3290
3291 ;; Extend to memory case when source register does die.
3292 (define_split
3293 [(set (match_operand:DI 0 "memory_operand" "")
3294 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3295 (clobber (reg:CC FLAGS_REG))
3296 (clobber (match_operand:SI 2 "register_operand" ""))]
3297 "(reload_completed
3298 && dead_or_set_p (insn, operands[1])
3299 && !reg_mentioned_p (operands[1], operands[0]))"
3300 [(set (match_dup 3) (match_dup 1))
3301 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3302 (clobber (reg:CC FLAGS_REG))])
3303 (set (match_dup 4) (match_dup 1))]
3304 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3305
3306 ;; Extend to memory case when source register does not die.
3307 (define_split
3308 [(set (match_operand:DI 0 "memory_operand" "")
3309 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3310 (clobber (reg:CC FLAGS_REG))
3311 (clobber (match_operand:SI 2 "register_operand" ""))]
3312 "reload_completed"
3313 [(const_int 0)]
3314 {
3315 split_di (&operands[0], 1, &operands[3], &operands[4]);
3316
3317 emit_move_insn (operands[3], operands[1]);
3318
3319 /* Generate a cltd if possible and doing so it profitable. */
3320 if (true_regnum (operands[1]) == 0
3321 && true_regnum (operands[2]) == 1
3322 && (optimize_size || TARGET_USE_CLTD))
3323 {
3324 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3325 }
3326 else
3327 {
3328 emit_move_insn (operands[2], operands[1]);
3329 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3330 }
3331 emit_move_insn (operands[4], operands[2]);
3332 DONE;
3333 })
3334
3335 ;; Extend to register case. Optimize case where source and destination
3336 ;; registers match and cases where we can use cltd.
3337 (define_split
3338 [(set (match_operand:DI 0 "register_operand" "")
3339 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3340 (clobber (reg:CC FLAGS_REG))
3341 (clobber (match_scratch:SI 2 ""))]
3342 "reload_completed"
3343 [(const_int 0)]
3344 {
3345 split_di (&operands[0], 1, &operands[3], &operands[4]);
3346
3347 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3348 emit_move_insn (operands[3], operands[1]);
3349
3350 /* Generate a cltd if possible and doing so it profitable. */
3351 if (true_regnum (operands[3]) == 0
3352 && (optimize_size || TARGET_USE_CLTD))
3353 {
3354 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3355 DONE;
3356 }
3357
3358 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3359 emit_move_insn (operands[4], operands[1]);
3360
3361 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3362 DONE;
3363 })
3364
3365 (define_insn "extendhisi2"
3366 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3367 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3368 ""
3369 {
3370 switch (get_attr_prefix_0f (insn))
3371 {
3372 case 0:
3373 return "{cwtl|cwde}";
3374 default:
3375 return "movs{wl|x}\t{%1,%0|%0, %1}";
3376 }
3377 }
3378 [(set_attr "type" "imovx")
3379 (set_attr "mode" "SI")
3380 (set (attr "prefix_0f")
3381 ;; movsx is short decodable while cwtl is vector decoded.
3382 (if_then_else (and (eq_attr "cpu" "!k6")
3383 (eq_attr "alternative" "0"))
3384 (const_string "0")
3385 (const_string "1")))
3386 (set (attr "modrm")
3387 (if_then_else (eq_attr "prefix_0f" "0")
3388 (const_string "0")
3389 (const_string "1")))])
3390
3391 (define_insn "*extendhisi2_zext"
3392 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3393 (zero_extend:DI
3394 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3395 "TARGET_64BIT"
3396 {
3397 switch (get_attr_prefix_0f (insn))
3398 {
3399 case 0:
3400 return "{cwtl|cwde}";
3401 default:
3402 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3403 }
3404 }
3405 [(set_attr "type" "imovx")
3406 (set_attr "mode" "SI")
3407 (set (attr "prefix_0f")
3408 ;; movsx is short decodable while cwtl is vector decoded.
3409 (if_then_else (and (eq_attr "cpu" "!k6")
3410 (eq_attr "alternative" "0"))
3411 (const_string "0")
3412 (const_string "1")))
3413 (set (attr "modrm")
3414 (if_then_else (eq_attr "prefix_0f" "0")
3415 (const_string "0")
3416 (const_string "1")))])
3417
3418 (define_insn "extendqihi2"
3419 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3420 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3421 ""
3422 {
3423 switch (get_attr_prefix_0f (insn))
3424 {
3425 case 0:
3426 return "{cbtw|cbw}";
3427 default:
3428 return "movs{bw|x}\t{%1,%0|%0, %1}";
3429 }
3430 }
3431 [(set_attr "type" "imovx")
3432 (set_attr "mode" "HI")
3433 (set (attr "prefix_0f")
3434 ;; movsx is short decodable while cwtl is vector decoded.
3435 (if_then_else (and (eq_attr "cpu" "!k6")
3436 (eq_attr "alternative" "0"))
3437 (const_string "0")
3438 (const_string "1")))
3439 (set (attr "modrm")
3440 (if_then_else (eq_attr "prefix_0f" "0")
3441 (const_string "0")
3442 (const_string "1")))])
3443
3444 (define_insn "extendqisi2"
3445 [(set (match_operand:SI 0 "register_operand" "=r")
3446 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3447 ""
3448 "movs{bl|x}\t{%1,%0|%0, %1}"
3449 [(set_attr "type" "imovx")
3450 (set_attr "mode" "SI")])
3451
3452 (define_insn "*extendqisi2_zext"
3453 [(set (match_operand:DI 0 "register_operand" "=r")
3454 (zero_extend:DI
3455 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3456 "TARGET_64BIT"
3457 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3458 [(set_attr "type" "imovx")
3459 (set_attr "mode" "SI")])
3460 \f
3461 ;; Conversions between float and double.
3462
3463 ;; These are all no-ops in the model used for the 80387. So just
3464 ;; emit moves.
3465
3466 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3467 (define_insn "*dummy_extendsfdf2"
3468 [(set (match_operand:DF 0 "push_operand" "=<")
3469 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3470 "0"
3471 "#")
3472
3473 (define_split
3474 [(set (match_operand:DF 0 "push_operand" "")
3475 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3476 "!TARGET_64BIT"
3477 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3478 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3479
3480 (define_split
3481 [(set (match_operand:DF 0 "push_operand" "")
3482 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3483 "TARGET_64BIT"
3484 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3485 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3486
3487 (define_insn "*dummy_extendsfxf2"
3488 [(set (match_operand:XF 0 "push_operand" "=<")
3489 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3490 "0"
3491 "#")
3492
3493 (define_split
3494 [(set (match_operand:XF 0 "push_operand" "")
3495 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3496 ""
3497 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3498 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3499 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3500
3501 (define_split
3502 [(set (match_operand:XF 0 "push_operand" "")
3503 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3504 "TARGET_64BIT"
3505 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3506 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3507 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3508
3509 (define_split
3510 [(set (match_operand:XF 0 "push_operand" "")
3511 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3512 ""
3513 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3514 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3515 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3516
3517 (define_split
3518 [(set (match_operand:XF 0 "push_operand" "")
3519 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3520 "TARGET_64BIT"
3521 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3522 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3523 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3524
3525 (define_expand "extendsfdf2"
3526 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3527 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3528 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3529 {
3530 /* ??? Needed for compress_float_constant since all fp constants
3531 are LEGITIMATE_CONSTANT_P. */
3532 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3533 {
3534 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3535 && standard_80387_constant_p (operands[1]) > 0)
3536 {
3537 operands[1] = simplify_const_unary_operation
3538 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3539 emit_move_insn_1 (operands[0], operands[1]);
3540 DONE;
3541 }
3542 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3543 }
3544 })
3545
3546 (define_insn "*extendsfdf2_mixed"
3547 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3548 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3549 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3550 {
3551 switch (which_alternative)
3552 {
3553 case 0:
3554 return output_387_reg_move (insn, operands);
3555
3556 case 1:
3557 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3558 return "fstp%z0\t%y0";
3559 else
3560 return "fst%z0\t%y0";
3561
3562 case 2:
3563 return "cvtss2sd\t{%1, %0|%0, %1}";
3564
3565 default:
3566 gcc_unreachable ();
3567 }
3568 }
3569 [(set_attr "type" "fmov,fmov,ssecvt")
3570 (set_attr "mode" "SF,XF,DF")])
3571
3572 (define_insn "*extendsfdf2_sse"
3573 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3574 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3575 "TARGET_SSE2 && TARGET_SSE_MATH"
3576 "cvtss2sd\t{%1, %0|%0, %1}"
3577 [(set_attr "type" "ssecvt")
3578 (set_attr "mode" "DF")])
3579
3580 (define_insn "*extendsfdf2_i387"
3581 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3582 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3583 "TARGET_80387"
3584 {
3585 switch (which_alternative)
3586 {
3587 case 0:
3588 return output_387_reg_move (insn, operands);
3589
3590 case 1:
3591 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3592 return "fstp%z0\t%y0";
3593 else
3594 return "fst%z0\t%y0";
3595
3596 default:
3597 gcc_unreachable ();
3598 }
3599 }
3600 [(set_attr "type" "fmov")
3601 (set_attr "mode" "SF,XF")])
3602
3603 (define_expand "extendsfxf2"
3604 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3605 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3606 "TARGET_80387"
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 (standard_80387_constant_p (operands[1]) > 0)
3613 {
3614 operands[1] = simplify_const_unary_operation
3615 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3616 emit_move_insn_1 (operands[0], operands[1]);
3617 DONE;
3618 }
3619 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3620 }
3621 })
3622
3623 (define_insn "*extendsfxf2_i387"
3624 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3625 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3626 "TARGET_80387"
3627 {
3628 switch (which_alternative)
3629 {
3630 case 0:
3631 return output_387_reg_move (insn, operands);
3632
3633 case 1:
3634 /* There is no non-popping store to memory for XFmode. So if
3635 we need one, follow the store with a load. */
3636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637 return "fstp%z0\t%y0";
3638 else
3639 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3640
3641 default:
3642 gcc_unreachable ();
3643 }
3644 }
3645 [(set_attr "type" "fmov")
3646 (set_attr "mode" "SF,XF")])
3647
3648 (define_expand "extenddfxf2"
3649 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3650 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3651 "TARGET_80387"
3652 {
3653 /* ??? Needed for compress_float_constant since all fp constants
3654 are LEGITIMATE_CONSTANT_P. */
3655 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3656 {
3657 if (standard_80387_constant_p (operands[1]) > 0)
3658 {
3659 operands[1] = simplify_const_unary_operation
3660 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3661 emit_move_insn_1 (operands[0], operands[1]);
3662 DONE;
3663 }
3664 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3665 }
3666 })
3667
3668 (define_insn "*extenddfxf2_i387"
3669 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3670 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3671 "TARGET_80387"
3672 {
3673 switch (which_alternative)
3674 {
3675 case 0:
3676 return output_387_reg_move (insn, operands);
3677
3678 case 1:
3679 /* There is no non-popping store to memory for XFmode. So if
3680 we need one, follow the store with a load. */
3681 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3682 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3683 else
3684 return "fstp%z0\t%y0";
3685
3686 default:
3687 gcc_unreachable ();
3688 }
3689 }
3690 [(set_attr "type" "fmov")
3691 (set_attr "mode" "DF,XF")])
3692
3693 ;; %%% This seems bad bad news.
3694 ;; This cannot output into an f-reg because there is no way to be sure
3695 ;; of truncating in that case. Otherwise this is just like a simple move
3696 ;; insn. So we pretend we can output to a reg in order to get better
3697 ;; register preferencing, but we really use a stack slot.
3698
3699 ;; Conversion from DFmode to SFmode.
3700
3701 (define_expand "truncdfsf2"
3702 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3703 (float_truncate:SF
3704 (match_operand:DF 1 "nonimmediate_operand" "")))]
3705 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3706 {
3707 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3708 ;
3709 else if (flag_unsafe_math_optimizations)
3710 ;
3711 else
3712 {
3713 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3714 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3715 DONE;
3716 }
3717 })
3718
3719 (define_expand "truncdfsf2_with_temp"
3720 [(parallel [(set (match_operand:SF 0 "" "")
3721 (float_truncate:SF (match_operand:DF 1 "" "")))
3722 (clobber (match_operand:SF 2 "" ""))])]
3723 "")
3724
3725 (define_insn "*truncdfsf_fast_mixed"
3726 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3727 (float_truncate:SF
3728 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3729 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3730 {
3731 switch (which_alternative)
3732 {
3733 case 0:
3734 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3735 return "fstp%z0\t%y0";
3736 else
3737 return "fst%z0\t%y0";
3738 case 1:
3739 return output_387_reg_move (insn, operands);
3740 case 2:
3741 return "cvtsd2ss\t{%1, %0|%0, %1}";
3742 default:
3743 gcc_unreachable ();
3744 }
3745 }
3746 [(set_attr "type" "fmov,fmov,ssecvt")
3747 (set_attr "mode" "SF")])
3748
3749 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3750 ;; because nothing we do here is unsafe.
3751 (define_insn "*truncdfsf_fast_sse"
3752 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3753 (float_truncate:SF
3754 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3755 "TARGET_SSE2 && TARGET_SSE_MATH"
3756 "cvtsd2ss\t{%1, %0|%0, %1}"
3757 [(set_attr "type" "ssecvt")
3758 (set_attr "mode" "SF")])
3759
3760 (define_insn "*truncdfsf_fast_i387"
3761 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3762 (float_truncate:SF
3763 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3764 "TARGET_80387 && flag_unsafe_math_optimizations"
3765 "* return output_387_reg_move (insn, operands);"
3766 [(set_attr "type" "fmov")
3767 (set_attr "mode" "SF")])
3768
3769 (define_insn "*truncdfsf_mixed"
3770 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3771 (float_truncate:SF
3772 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3773 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3774 "TARGET_MIX_SSE_I387"
3775 {
3776 switch (which_alternative)
3777 {
3778 case 0:
3779 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3780 return "fstp%z0\t%y0";
3781 else
3782 return "fst%z0\t%y0";
3783 case 1:
3784 return "#";
3785 case 2:
3786 return "cvtsd2ss\t{%1, %0|%0, %1}";
3787 default:
3788 gcc_unreachable ();
3789 }
3790 }
3791 [(set_attr "type" "fmov,multi,ssecvt")
3792 (set_attr "unit" "*,i387,*")
3793 (set_attr "mode" "SF")])
3794
3795 (define_insn "*truncdfsf_i387"
3796 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3797 (float_truncate:SF
3798 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3799 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3800 "TARGET_80387"
3801 {
3802 switch (which_alternative)
3803 {
3804 case 0:
3805 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3806 return "fstp%z0\t%y0";
3807 else
3808 return "fst%z0\t%y0";
3809 case 1:
3810 return "#";
3811 default:
3812 gcc_unreachable ();
3813 }
3814 }
3815 [(set_attr "type" "fmov,multi")
3816 (set_attr "unit" "*,i387")
3817 (set_attr "mode" "SF")])
3818
3819 (define_insn "*truncdfsf2_i387_1"
3820 [(set (match_operand:SF 0 "memory_operand" "=m")
3821 (float_truncate:SF
3822 (match_operand:DF 1 "register_operand" "f")))]
3823 "TARGET_80387
3824 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3825 && !TARGET_MIX_SSE_I387"
3826 {
3827 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3828 return "fstp%z0\t%y0";
3829 else
3830 return "fst%z0\t%y0";
3831 }
3832 [(set_attr "type" "fmov")
3833 (set_attr "mode" "SF")])
3834
3835 (define_split
3836 [(set (match_operand:SF 0 "register_operand" "")
3837 (float_truncate:SF
3838 (match_operand:DF 1 "fp_register_operand" "")))
3839 (clobber (match_operand 2 "" ""))]
3840 "reload_completed"
3841 [(set (match_dup 2) (match_dup 1))
3842 (set (match_dup 0) (match_dup 2))]
3843 {
3844 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3845 })
3846
3847 ;; Conversion from XFmode to SFmode.
3848
3849 (define_expand "truncxfsf2"
3850 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3851 (float_truncate:SF
3852 (match_operand:XF 1 "register_operand" "")))
3853 (clobber (match_dup 2))])]
3854 "TARGET_80387"
3855 {
3856 if (flag_unsafe_math_optimizations)
3857 {
3858 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3859 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3860 if (reg != operands[0])
3861 emit_move_insn (operands[0], reg);
3862 DONE;
3863 }
3864 else
3865 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3866 })
3867
3868 (define_insn "*truncxfsf2_mixed"
3869 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3870 (float_truncate:SF
3871 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3872 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3873 "TARGET_MIX_SSE_I387"
3874 {
3875 gcc_assert (!which_alternative);
3876 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3877 return "fstp%z0\t%y0";
3878 else
3879 return "fst%z0\t%y0";
3880 }
3881 [(set_attr "type" "fmov,multi,multi,multi")
3882 (set_attr "unit" "*,i387,i387,i387")
3883 (set_attr "mode" "SF")])
3884
3885 (define_insn "truncxfsf2_i387_noop"
3886 [(set (match_operand:SF 0 "register_operand" "=f")
3887 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3888 "TARGET_80387 && flag_unsafe_math_optimizations"
3889 {
3890 return output_387_reg_move (insn, operands);
3891 }
3892 [(set_attr "type" "fmov")
3893 (set_attr "mode" "SF")])
3894
3895 (define_insn "*truncxfsf2_i387"
3896 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3897 (float_truncate:SF
3898 (match_operand:XF 1 "register_operand" "f,f,f")))
3899 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3900 "TARGET_80387"
3901 {
3902 gcc_assert (!which_alternative);
3903 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3904 return "fstp%z0\t%y0";
3905 else
3906 return "fst%z0\t%y0";
3907 }
3908 [(set_attr "type" "fmov,multi,multi")
3909 (set_attr "unit" "*,i387,i387")
3910 (set_attr "mode" "SF")])
3911
3912 (define_insn "*truncxfsf2_i387_1"
3913 [(set (match_operand:SF 0 "memory_operand" "=m")
3914 (float_truncate:SF
3915 (match_operand:XF 1 "register_operand" "f")))]
3916 "TARGET_80387"
3917 {
3918 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3919 return "fstp%z0\t%y0";
3920 else
3921 return "fst%z0\t%y0";
3922 }
3923 [(set_attr "type" "fmov")
3924 (set_attr "mode" "SF")])
3925
3926 (define_split
3927 [(set (match_operand:SF 0 "register_operand" "")
3928 (float_truncate:SF
3929 (match_operand:XF 1 "register_operand" "")))
3930 (clobber (match_operand:SF 2 "memory_operand" ""))]
3931 "TARGET_80387 && reload_completed"
3932 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3933 (set (match_dup 0) (match_dup 2))]
3934 "")
3935
3936 (define_split
3937 [(set (match_operand:SF 0 "memory_operand" "")
3938 (float_truncate:SF
3939 (match_operand:XF 1 "register_operand" "")))
3940 (clobber (match_operand:SF 2 "memory_operand" ""))]
3941 "TARGET_80387"
3942 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3943 "")
3944
3945 ;; Conversion from XFmode to DFmode.
3946
3947 (define_expand "truncxfdf2"
3948 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3949 (float_truncate:DF
3950 (match_operand:XF 1 "register_operand" "")))
3951 (clobber (match_dup 2))])]
3952 "TARGET_80387"
3953 {
3954 if (flag_unsafe_math_optimizations)
3955 {
3956 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3957 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3958 if (reg != operands[0])
3959 emit_move_insn (operands[0], reg);
3960 DONE;
3961 }
3962 else
3963 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3964 })
3965
3966 (define_insn "*truncxfdf2_mixed"
3967 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3968 (float_truncate:DF
3969 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3970 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3971 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3972 {
3973 gcc_assert (!which_alternative);
3974 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3975 return "fstp%z0\t%y0";
3976 else
3977 return "fst%z0\t%y0";
3978 }
3979 [(set_attr "type" "fmov,multi,multi,multi")
3980 (set_attr "unit" "*,i387,i387,i387")
3981 (set_attr "mode" "DF")])
3982
3983 (define_insn "truncxfdf2_i387_noop"
3984 [(set (match_operand:DF 0 "register_operand" "=f")
3985 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3986 "TARGET_80387 && flag_unsafe_math_optimizations"
3987 {
3988 return output_387_reg_move (insn, operands);
3989 }
3990 [(set_attr "type" "fmov")
3991 (set_attr "mode" "DF")])
3992
3993 (define_insn "*truncxfdf2_i387"
3994 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
3995 (float_truncate:DF
3996 (match_operand:XF 1 "register_operand" "f,f,f")))
3997 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3998 "TARGET_80387"
3999 {
4000 gcc_assert (!which_alternative);
4001 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4002 return "fstp%z0\t%y0";
4003 else
4004 return "fst%z0\t%y0";
4005 }
4006 [(set_attr "type" "fmov,multi,multi")
4007 (set_attr "unit" "*,i387,i387")
4008 (set_attr "mode" "DF")])
4009
4010 (define_insn "*truncxfdf2_i387_1"
4011 [(set (match_operand:DF 0 "memory_operand" "=m")
4012 (float_truncate:DF
4013 (match_operand:XF 1 "register_operand" "f")))]
4014 "TARGET_80387"
4015 {
4016 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4017 return "fstp%z0\t%y0";
4018 else
4019 return "fst%z0\t%y0";
4020 }
4021 [(set_attr "type" "fmov")
4022 (set_attr "mode" "DF")])
4023
4024 (define_split
4025 [(set (match_operand:DF 0 "register_operand" "")
4026 (float_truncate:DF
4027 (match_operand:XF 1 "register_operand" "")))
4028 (clobber (match_operand:DF 2 "memory_operand" ""))]
4029 "TARGET_80387 && reload_completed"
4030 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4031 (set (match_dup 0) (match_dup 2))]
4032 "")
4033
4034 (define_split
4035 [(set (match_operand:DF 0 "memory_operand" "")
4036 (float_truncate:DF
4037 (match_operand:XF 1 "register_operand" "")))
4038 (clobber (match_operand:DF 2 "memory_operand" ""))]
4039 "TARGET_80387"
4040 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4041 "")
4042 \f
4043 ;; Signed conversion to DImode.
4044
4045 (define_expand "fix_truncxfdi2"
4046 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4047 (fix:DI (match_operand:XF 1 "register_operand" "")))
4048 (clobber (reg:CC FLAGS_REG))])]
4049 "TARGET_80387"
4050 {
4051 if (TARGET_FISTTP)
4052 {
4053 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4054 DONE;
4055 }
4056 })
4057
4058 (define_expand "fix_trunc<mode>di2"
4059 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4060 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4061 (clobber (reg:CC FLAGS_REG))])]
4062 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4063 {
4064 if (TARGET_FISTTP
4065 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4066 {
4067 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4068 DONE;
4069 }
4070 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4071 {
4072 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4073 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4074 if (out != operands[0])
4075 emit_move_insn (operands[0], out);
4076 DONE;
4077 }
4078 })
4079
4080 ;; Signed conversion to SImode.
4081
4082 (define_expand "fix_truncxfsi2"
4083 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4084 (fix:SI (match_operand:XF 1 "register_operand" "")))
4085 (clobber (reg:CC FLAGS_REG))])]
4086 "TARGET_80387"
4087 {
4088 if (TARGET_FISTTP)
4089 {
4090 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4091 DONE;
4092 }
4093 })
4094
4095 (define_expand "fix_trunc<mode>si2"
4096 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4097 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4098 (clobber (reg:CC FLAGS_REG))])]
4099 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4100 {
4101 if (TARGET_FISTTP
4102 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4103 {
4104 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4105 DONE;
4106 }
4107 if (SSE_FLOAT_MODE_P (<MODE>mode))
4108 {
4109 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4110 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4111 if (out != operands[0])
4112 emit_move_insn (operands[0], out);
4113 DONE;
4114 }
4115 })
4116
4117 ;; Signed conversion to HImode.
4118
4119 (define_expand "fix_trunc<mode>hi2"
4120 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4121 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4122 (clobber (reg:CC FLAGS_REG))])]
4123 "TARGET_80387
4124 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4125 {
4126 if (TARGET_FISTTP)
4127 {
4128 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4129 DONE;
4130 }
4131 })
4132
4133 ;; When SSE is available, it is always faster to use it!
4134 (define_insn "fix_truncsfdi_sse"
4135 [(set (match_operand:DI 0 "register_operand" "=r,r")
4136 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4137 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4138 "cvttss2si{q}\t{%1, %0|%0, %1}"
4139 [(set_attr "type" "sseicvt")
4140 (set_attr "mode" "SF")
4141 (set_attr "athlon_decode" "double,vector")])
4142
4143 (define_insn "fix_truncdfdi_sse"
4144 [(set (match_operand:DI 0 "register_operand" "=r,r")
4145 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4146 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4147 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4148 [(set_attr "type" "sseicvt")
4149 (set_attr "mode" "DF")
4150 (set_attr "athlon_decode" "double,vector")])
4151
4152 (define_insn "fix_truncsfsi_sse"
4153 [(set (match_operand:SI 0 "register_operand" "=r,r")
4154 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4155 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4156 "cvttss2si\t{%1, %0|%0, %1}"
4157 [(set_attr "type" "sseicvt")
4158 (set_attr "mode" "DF")
4159 (set_attr "athlon_decode" "double,vector")])
4160
4161 (define_insn "fix_truncdfsi_sse"
4162 [(set (match_operand:SI 0 "register_operand" "=r,r")
4163 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4164 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4165 "cvttsd2si\t{%1, %0|%0, %1}"
4166 [(set_attr "type" "sseicvt")
4167 (set_attr "mode" "DF")
4168 (set_attr "athlon_decode" "double,vector")])
4169
4170 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4171 (define_peephole2
4172 [(set (match_operand:DF 0 "register_operand" "")
4173 (match_operand:DF 1 "memory_operand" ""))
4174 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4175 (fix:SSEMODEI24 (match_dup 0)))]
4176 "!TARGET_K8
4177 && peep2_reg_dead_p (2, operands[0])"
4178 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4179 "")
4180
4181 (define_peephole2
4182 [(set (match_operand:SF 0 "register_operand" "")
4183 (match_operand:SF 1 "memory_operand" ""))
4184 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4185 (fix:SSEMODEI24 (match_dup 0)))]
4186 "!TARGET_K8
4187 && peep2_reg_dead_p (2, operands[0])"
4188 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4189 "")
4190
4191 ;; Avoid vector decoded forms of the instruction.
4192 (define_peephole2
4193 [(match_scratch:DF 2 "Y")
4194 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4195 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4196 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4197 [(set (match_dup 2) (match_dup 1))
4198 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4199 "")
4200
4201 (define_peephole2
4202 [(match_scratch:SF 2 "x")
4203 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4204 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4205 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4206 [(set (match_dup 2) (match_dup 1))
4207 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4208 "")
4209
4210 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4211 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4212 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4213 "TARGET_FISTTP
4214 && FLOAT_MODE_P (GET_MODE (operands[1]))
4215 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4216 && (TARGET_64BIT || <MODE>mode != DImode))
4217 && TARGET_SSE_MATH)
4218 && !(reload_completed || reload_in_progress)"
4219 "#"
4220 "&& 1"
4221 [(const_int 0)]
4222 {
4223 if (memory_operand (operands[0], VOIDmode))
4224 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4225 else
4226 {
4227 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4228 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4229 operands[1],
4230 operands[2]));
4231 }
4232 DONE;
4233 }
4234 [(set_attr "type" "fisttp")
4235 (set_attr "mode" "<MODE>")])
4236
4237 (define_insn "fix_trunc<mode>_i387_fisttp"
4238 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4239 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4240 (clobber (match_scratch:XF 2 "=&1f"))]
4241 "TARGET_FISTTP
4242 && FLOAT_MODE_P (GET_MODE (operands[1]))
4243 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4244 && (TARGET_64BIT || <MODE>mode != DImode))
4245 && TARGET_SSE_MATH)"
4246 "* return output_fix_trunc (insn, operands, 1);"
4247 [(set_attr "type" "fisttp")
4248 (set_attr "mode" "<MODE>")])
4249
4250 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4251 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4252 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4253 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4254 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4255 "TARGET_FISTTP
4256 && FLOAT_MODE_P (GET_MODE (operands[1]))
4257 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4258 && (TARGET_64BIT || <MODE>mode != DImode))
4259 && TARGET_SSE_MATH)"
4260 "#"
4261 [(set_attr "type" "fisttp")
4262 (set_attr "mode" "<MODE>")])
4263
4264 (define_split
4265 [(set (match_operand:X87MODEI 0 "register_operand" "")
4266 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4267 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4268 (clobber (match_scratch 3 ""))]
4269 "reload_completed"
4270 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4271 (clobber (match_dup 3))])
4272 (set (match_dup 0) (match_dup 2))]
4273 "")
4274
4275 (define_split
4276 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4277 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4278 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4279 (clobber (match_scratch 3 ""))]
4280 "reload_completed"
4281 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4282 (clobber (match_dup 3))])]
4283 "")
4284
4285 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4286 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4287 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4288 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4289 ;; function in i386.c.
4290 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4291 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4292 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4293 (clobber (reg:CC FLAGS_REG))]
4294 "TARGET_80387 && !TARGET_FISTTP
4295 && FLOAT_MODE_P (GET_MODE (operands[1]))
4296 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4297 && (TARGET_64BIT || <MODE>mode != DImode))
4298 && !(reload_completed || reload_in_progress)"
4299 "#"
4300 "&& 1"
4301 [(const_int 0)]
4302 {
4303 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4304
4305 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4306 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4307 if (memory_operand (operands[0], VOIDmode))
4308 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4309 operands[2], operands[3]));
4310 else
4311 {
4312 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4313 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4314 operands[2], operands[3],
4315 operands[4]));
4316 }
4317 DONE;
4318 }
4319 [(set_attr "type" "fistp")
4320 (set_attr "i387_cw" "trunc")
4321 (set_attr "mode" "<MODE>")])
4322
4323 (define_insn "fix_truncdi_i387"
4324 [(set (match_operand:DI 0 "memory_operand" "=m")
4325 (fix:DI (match_operand 1 "register_operand" "f")))
4326 (use (match_operand:HI 2 "memory_operand" "m"))
4327 (use (match_operand:HI 3 "memory_operand" "m"))
4328 (clobber (match_scratch:XF 4 "=&1f"))]
4329 "TARGET_80387 && !TARGET_FISTTP
4330 && FLOAT_MODE_P (GET_MODE (operands[1]))
4331 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4332 "* return output_fix_trunc (insn, operands, 0);"
4333 [(set_attr "type" "fistp")
4334 (set_attr "i387_cw" "trunc")
4335 (set_attr "mode" "DI")])
4336
4337 (define_insn "fix_truncdi_i387_with_temp"
4338 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4339 (fix:DI (match_operand 1 "register_operand" "f,f")))
4340 (use (match_operand:HI 2 "memory_operand" "m,m"))
4341 (use (match_operand:HI 3 "memory_operand" "m,m"))
4342 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4343 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4344 "TARGET_80387 && !TARGET_FISTTP
4345 && FLOAT_MODE_P (GET_MODE (operands[1]))
4346 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4347 "#"
4348 [(set_attr "type" "fistp")
4349 (set_attr "i387_cw" "trunc")
4350 (set_attr "mode" "DI")])
4351
4352 (define_split
4353 [(set (match_operand:DI 0 "register_operand" "")
4354 (fix:DI (match_operand 1 "register_operand" "")))
4355 (use (match_operand:HI 2 "memory_operand" ""))
4356 (use (match_operand:HI 3 "memory_operand" ""))
4357 (clobber (match_operand:DI 4 "memory_operand" ""))
4358 (clobber (match_scratch 5 ""))]
4359 "reload_completed"
4360 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4361 (use (match_dup 2))
4362 (use (match_dup 3))
4363 (clobber (match_dup 5))])
4364 (set (match_dup 0) (match_dup 4))]
4365 "")
4366
4367 (define_split
4368 [(set (match_operand:DI 0 "memory_operand" "")
4369 (fix:DI (match_operand 1 "register_operand" "")))
4370 (use (match_operand:HI 2 "memory_operand" ""))
4371 (use (match_operand:HI 3 "memory_operand" ""))
4372 (clobber (match_operand:DI 4 "memory_operand" ""))
4373 (clobber (match_scratch 5 ""))]
4374 "reload_completed"
4375 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4376 (use (match_dup 2))
4377 (use (match_dup 3))
4378 (clobber (match_dup 5))])]
4379 "")
4380
4381 (define_insn "fix_trunc<mode>_i387"
4382 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4383 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4384 (use (match_operand:HI 2 "memory_operand" "m"))
4385 (use (match_operand:HI 3 "memory_operand" "m"))]
4386 "TARGET_80387 && !TARGET_FISTTP
4387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4388 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4389 "* return output_fix_trunc (insn, operands, 0);"
4390 [(set_attr "type" "fistp")
4391 (set_attr "i387_cw" "trunc")
4392 (set_attr "mode" "<MODE>")])
4393
4394 (define_insn "fix_trunc<mode>_i387_with_temp"
4395 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4396 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4397 (use (match_operand:HI 2 "memory_operand" "m,m"))
4398 (use (match_operand:HI 3 "memory_operand" "m,m"))
4399 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4400 "TARGET_80387 && !TARGET_FISTTP
4401 && FLOAT_MODE_P (GET_MODE (operands[1]))
4402 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4403 "#"
4404 [(set_attr "type" "fistp")
4405 (set_attr "i387_cw" "trunc")
4406 (set_attr "mode" "<MODE>")])
4407
4408 (define_split
4409 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4410 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4411 (use (match_operand:HI 2 "memory_operand" ""))
4412 (use (match_operand:HI 3 "memory_operand" ""))
4413 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4414 "reload_completed"
4415 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4416 (use (match_dup 2))
4417 (use (match_dup 3))])
4418 (set (match_dup 0) (match_dup 4))]
4419 "")
4420
4421 (define_split
4422 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4423 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4424 (use (match_operand:HI 2 "memory_operand" ""))
4425 (use (match_operand:HI 3 "memory_operand" ""))
4426 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4427 "reload_completed"
4428 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4429 (use (match_dup 2))
4430 (use (match_dup 3))])]
4431 "")
4432
4433 (define_insn "x86_fnstcw_1"
4434 [(set (match_operand:HI 0 "memory_operand" "=m")
4435 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4436 "TARGET_80387"
4437 "fnstcw\t%0"
4438 [(set_attr "length" "2")
4439 (set_attr "mode" "HI")
4440 (set_attr "unit" "i387")])
4441
4442 (define_insn "x86_fldcw_1"
4443 [(set (reg:HI FPCR_REG)
4444 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4445 "TARGET_80387"
4446 "fldcw\t%0"
4447 [(set_attr "length" "2")
4448 (set_attr "mode" "HI")
4449 (set_attr "unit" "i387")
4450 (set_attr "athlon_decode" "vector")])
4451 \f
4452 ;; Conversion between fixed point and floating point.
4453
4454 ;; Even though we only accept memory inputs, the backend _really_
4455 ;; wants to be able to do this between registers.
4456
4457 (define_expand "floathisf2"
4458 [(set (match_operand:SF 0 "register_operand" "")
4459 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4460 "TARGET_80387 || TARGET_SSE_MATH"
4461 {
4462 if (TARGET_SSE_MATH)
4463 {
4464 emit_insn (gen_floatsisf2 (operands[0],
4465 convert_to_mode (SImode, operands[1], 0)));
4466 DONE;
4467 }
4468 })
4469
4470 (define_insn "*floathisf2_i387"
4471 [(set (match_operand:SF 0 "register_operand" "=f,f")
4472 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4473 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4474 "@
4475 fild%z1\t%1
4476 #"
4477 [(set_attr "type" "fmov,multi")
4478 (set_attr "mode" "SF")
4479 (set_attr "unit" "*,i387")
4480 (set_attr "fp_int_src" "true")])
4481
4482 (define_expand "floatsisf2"
4483 [(set (match_operand:SF 0 "register_operand" "")
4484 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4485 "TARGET_80387 || TARGET_SSE_MATH"
4486 "")
4487
4488 (define_insn "*floatsisf2_mixed"
4489 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4490 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4491 "TARGET_MIX_SSE_I387"
4492 "@
4493 fild%z1\t%1
4494 #
4495 cvtsi2ss\t{%1, %0|%0, %1}
4496 cvtsi2ss\t{%1, %0|%0, %1}"
4497 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4498 (set_attr "mode" "SF")
4499 (set_attr "unit" "*,i387,*,*")
4500 (set_attr "athlon_decode" "*,*,vector,double")
4501 (set_attr "fp_int_src" "true")])
4502
4503 (define_insn "*floatsisf2_sse"
4504 [(set (match_operand:SF 0 "register_operand" "=x,x")
4505 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4506 "TARGET_SSE_MATH"
4507 "cvtsi2ss\t{%1, %0|%0, %1}"
4508 [(set_attr "type" "sseicvt")
4509 (set_attr "mode" "SF")
4510 (set_attr "athlon_decode" "vector,double")
4511 (set_attr "fp_int_src" "true")])
4512
4513 (define_insn "*floatsisf2_i387"
4514 [(set (match_operand:SF 0 "register_operand" "=f,f")
4515 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4516 "TARGET_80387"
4517 "@
4518 fild%z1\t%1
4519 #"
4520 [(set_attr "type" "fmov,multi")
4521 (set_attr "mode" "SF")
4522 (set_attr "unit" "*,i387")
4523 (set_attr "fp_int_src" "true")])
4524
4525 (define_expand "floatdisf2"
4526 [(set (match_operand:SF 0 "register_operand" "")
4527 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4528 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4529 "")
4530
4531 (define_insn "*floatdisf2_mixed"
4532 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4533 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4534 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4535 "@
4536 fild%z1\t%1
4537 #
4538 cvtsi2ss{q}\t{%1, %0|%0, %1}
4539 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4540 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4541 (set_attr "mode" "SF")
4542 (set_attr "unit" "*,i387,*,*")
4543 (set_attr "athlon_decode" "*,*,vector,double")
4544 (set_attr "fp_int_src" "true")])
4545
4546 (define_insn "*floatdisf2_sse"
4547 [(set (match_operand:SF 0 "register_operand" "=x,x")
4548 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4549 "TARGET_64BIT && TARGET_SSE_MATH"
4550 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4551 [(set_attr "type" "sseicvt")
4552 (set_attr "mode" "SF")
4553 (set_attr "athlon_decode" "vector,double")
4554 (set_attr "fp_int_src" "true")])
4555
4556 (define_insn "*floatdisf2_i387"
4557 [(set (match_operand:SF 0 "register_operand" "=f,f")
4558 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4559 "TARGET_80387"
4560 "@
4561 fild%z1\t%1
4562 #"
4563 [(set_attr "type" "fmov,multi")
4564 (set_attr "mode" "SF")
4565 (set_attr "unit" "*,i387")
4566 (set_attr "fp_int_src" "true")])
4567
4568 (define_expand "floathidf2"
4569 [(set (match_operand:DF 0 "register_operand" "")
4570 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4571 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4572 {
4573 if (TARGET_SSE2 && TARGET_SSE_MATH)
4574 {
4575 emit_insn (gen_floatsidf2 (operands[0],
4576 convert_to_mode (SImode, operands[1], 0)));
4577 DONE;
4578 }
4579 })
4580
4581 (define_insn "*floathidf2_i387"
4582 [(set (match_operand:DF 0 "register_operand" "=f,f")
4583 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4584 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4585 "@
4586 fild%z1\t%1
4587 #"
4588 [(set_attr "type" "fmov,multi")
4589 (set_attr "mode" "DF")
4590 (set_attr "unit" "*,i387")
4591 (set_attr "fp_int_src" "true")])
4592
4593 (define_expand "floatsidf2"
4594 [(set (match_operand:DF 0 "register_operand" "")
4595 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4596 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4597 "")
4598
4599 (define_insn "*floatsidf2_mixed"
4600 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4601 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4602 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4603 "@
4604 fild%z1\t%1
4605 #
4606 cvtsi2sd\t{%1, %0|%0, %1}
4607 cvtsi2sd\t{%1, %0|%0, %1}"
4608 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4609 (set_attr "mode" "DF")
4610 (set_attr "unit" "*,i387,*,*")
4611 (set_attr "athlon_decode" "*,*,double,direct")
4612 (set_attr "fp_int_src" "true")])
4613
4614 (define_insn "*floatsidf2_sse"
4615 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4616 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4617 "TARGET_SSE2 && TARGET_SSE_MATH"
4618 "cvtsi2sd\t{%1, %0|%0, %1}"
4619 [(set_attr "type" "sseicvt")
4620 (set_attr "mode" "DF")
4621 (set_attr "athlon_decode" "double,direct")
4622 (set_attr "fp_int_src" "true")])
4623
4624 (define_insn "*floatsidf2_i387"
4625 [(set (match_operand:DF 0 "register_operand" "=f,f")
4626 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4627 "TARGET_80387"
4628 "@
4629 fild%z1\t%1
4630 #"
4631 [(set_attr "type" "fmov,multi")
4632 (set_attr "mode" "DF")
4633 (set_attr "unit" "*,i387")
4634 (set_attr "fp_int_src" "true")])
4635
4636 (define_expand "floatdidf2"
4637 [(set (match_operand:DF 0 "register_operand" "")
4638 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4639 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4640 "")
4641
4642 (define_insn "*floatdidf2_mixed"
4643 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4644 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4645 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4646 "@
4647 fild%z1\t%1
4648 #
4649 cvtsi2sd{q}\t{%1, %0|%0, %1}
4650 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4651 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4652 (set_attr "mode" "DF")
4653 (set_attr "unit" "*,i387,*,*")
4654 (set_attr "athlon_decode" "*,*,double,direct")
4655 (set_attr "fp_int_src" "true")])
4656
4657 (define_insn "*floatdidf2_sse"
4658 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4659 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4660 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4661 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4662 [(set_attr "type" "sseicvt")
4663 (set_attr "mode" "DF")
4664 (set_attr "athlon_decode" "double,direct")
4665 (set_attr "fp_int_src" "true")])
4666
4667 (define_insn "*floatdidf2_i387"
4668 [(set (match_operand:DF 0 "register_operand" "=f,f")
4669 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4670 "TARGET_80387"
4671 "@
4672 fild%z1\t%1
4673 #"
4674 [(set_attr "type" "fmov,multi")
4675 (set_attr "mode" "DF")
4676 (set_attr "unit" "*,i387")
4677 (set_attr "fp_int_src" "true")])
4678
4679 (define_insn "floathixf2"
4680 [(set (match_operand:XF 0 "register_operand" "=f,f")
4681 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4682 "TARGET_80387"
4683 "@
4684 fild%z1\t%1
4685 #"
4686 [(set_attr "type" "fmov,multi")
4687 (set_attr "mode" "XF")
4688 (set_attr "unit" "*,i387")
4689 (set_attr "fp_int_src" "true")])
4690
4691 (define_insn "floatsixf2"
4692 [(set (match_operand:XF 0 "register_operand" "=f,f")
4693 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4694 "TARGET_80387"
4695 "@
4696 fild%z1\t%1
4697 #"
4698 [(set_attr "type" "fmov,multi")
4699 (set_attr "mode" "XF")
4700 (set_attr "unit" "*,i387")
4701 (set_attr "fp_int_src" "true")])
4702
4703 (define_insn "floatdixf2"
4704 [(set (match_operand:XF 0 "register_operand" "=f,f")
4705 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4706 "TARGET_80387"
4707 "@
4708 fild%z1\t%1
4709 #"
4710 [(set_attr "type" "fmov,multi")
4711 (set_attr "mode" "XF")
4712 (set_attr "unit" "*,i387")
4713 (set_attr "fp_int_src" "true")])
4714
4715 ;; %%% Kill these when reload knows how to do it.
4716 (define_split
4717 [(set (match_operand 0 "fp_register_operand" "")
4718 (float (match_operand 1 "register_operand" "")))]
4719 "reload_completed
4720 && TARGET_80387
4721 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4722 [(const_int 0)]
4723 {
4724 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4725 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4726 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4727 ix86_free_from_memory (GET_MODE (operands[1]));
4728 DONE;
4729 })
4730
4731 (define_expand "floatunssisf2"
4732 [(use (match_operand:SF 0 "register_operand" ""))
4733 (use (match_operand:SI 1 "register_operand" ""))]
4734 "!TARGET_64BIT && TARGET_SSE_MATH"
4735 "x86_emit_floatuns (operands); DONE;")
4736
4737 (define_expand "floatunsdisf2"
4738 [(use (match_operand:SF 0 "register_operand" ""))
4739 (use (match_operand:DI 1 "register_operand" ""))]
4740 "TARGET_64BIT && TARGET_SSE_MATH"
4741 "x86_emit_floatuns (operands); DONE;")
4742
4743 (define_expand "floatunsdidf2"
4744 [(use (match_operand:DF 0 "register_operand" ""))
4745 (use (match_operand:DI 1 "register_operand" ""))]
4746 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4747 "x86_emit_floatuns (operands); DONE;")
4748 \f
4749 ;; SSE extract/set expanders
4750
4751 \f
4752 ;; Add instructions
4753
4754 ;; %%% splits for addditi3
4755
4756 (define_expand "addti3"
4757 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4758 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4759 (match_operand:TI 2 "x86_64_general_operand" "")))
4760 (clobber (reg:CC FLAGS_REG))]
4761 "TARGET_64BIT"
4762 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4763
4764 (define_insn "*addti3_1"
4765 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4766 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4767 (match_operand:TI 2 "general_operand" "roiF,riF")))
4768 (clobber (reg:CC FLAGS_REG))]
4769 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4770 "#")
4771
4772 (define_split
4773 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4774 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4775 (match_operand:TI 2 "general_operand" "")))
4776 (clobber (reg:CC FLAGS_REG))]
4777 "TARGET_64BIT && reload_completed"
4778 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4779 UNSPEC_ADD_CARRY))
4780 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4781 (parallel [(set (match_dup 3)
4782 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4783 (match_dup 4))
4784 (match_dup 5)))
4785 (clobber (reg:CC FLAGS_REG))])]
4786 "split_ti (operands+0, 1, operands+0, operands+3);
4787 split_ti (operands+1, 1, operands+1, operands+4);
4788 split_ti (operands+2, 1, operands+2, operands+5);")
4789
4790 ;; %%% splits for addsidi3
4791 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4792 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4793 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4794
4795 (define_expand "adddi3"
4796 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4797 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4798 (match_operand:DI 2 "x86_64_general_operand" "")))
4799 (clobber (reg:CC FLAGS_REG))]
4800 ""
4801 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4802
4803 (define_insn "*adddi3_1"
4804 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4805 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4806 (match_operand:DI 2 "general_operand" "roiF,riF")))
4807 (clobber (reg:CC FLAGS_REG))]
4808 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4809 "#")
4810
4811 (define_split
4812 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4813 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4814 (match_operand:DI 2 "general_operand" "")))
4815 (clobber (reg:CC FLAGS_REG))]
4816 "!TARGET_64BIT && reload_completed"
4817 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4818 UNSPEC_ADD_CARRY))
4819 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4820 (parallel [(set (match_dup 3)
4821 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4822 (match_dup 4))
4823 (match_dup 5)))
4824 (clobber (reg:CC FLAGS_REG))])]
4825 "split_di (operands+0, 1, operands+0, operands+3);
4826 split_di (operands+1, 1, operands+1, operands+4);
4827 split_di (operands+2, 1, operands+2, operands+5);")
4828
4829 (define_insn "adddi3_carry_rex64"
4830 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4831 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4832 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4833 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4834 (clobber (reg:CC FLAGS_REG))]
4835 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4836 "adc{q}\t{%2, %0|%0, %2}"
4837 [(set_attr "type" "alu")
4838 (set_attr "pent_pair" "pu")
4839 (set_attr "mode" "DI")])
4840
4841 (define_insn "*adddi3_cc_rex64"
4842 [(set (reg:CC FLAGS_REG)
4843 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4844 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4845 UNSPEC_ADD_CARRY))
4846 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4847 (plus:DI (match_dup 1) (match_dup 2)))]
4848 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4849 "add{q}\t{%2, %0|%0, %2}"
4850 [(set_attr "type" "alu")
4851 (set_attr "mode" "DI")])
4852
4853 (define_insn "addqi3_carry"
4854 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4855 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4856 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4857 (match_operand:QI 2 "general_operand" "qi,qm")))
4858 (clobber (reg:CC FLAGS_REG))]
4859 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4860 "adc{b}\t{%2, %0|%0, %2}"
4861 [(set_attr "type" "alu")
4862 (set_attr "pent_pair" "pu")
4863 (set_attr "mode" "QI")])
4864
4865 (define_insn "addhi3_carry"
4866 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4867 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4868 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4869 (match_operand:HI 2 "general_operand" "ri,rm")))
4870 (clobber (reg:CC FLAGS_REG))]
4871 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4872 "adc{w}\t{%2, %0|%0, %2}"
4873 [(set_attr "type" "alu")
4874 (set_attr "pent_pair" "pu")
4875 (set_attr "mode" "HI")])
4876
4877 (define_insn "addsi3_carry"
4878 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4879 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4880 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4881 (match_operand:SI 2 "general_operand" "ri,rm")))
4882 (clobber (reg:CC FLAGS_REG))]
4883 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4884 "adc{l}\t{%2, %0|%0, %2}"
4885 [(set_attr "type" "alu")
4886 (set_attr "pent_pair" "pu")
4887 (set_attr "mode" "SI")])
4888
4889 (define_insn "*addsi3_carry_zext"
4890 [(set (match_operand:DI 0 "register_operand" "=r")
4891 (zero_extend:DI
4892 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4893 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4894 (match_operand:SI 2 "general_operand" "rim"))))
4895 (clobber (reg:CC FLAGS_REG))]
4896 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4897 "adc{l}\t{%2, %k0|%k0, %2}"
4898 [(set_attr "type" "alu")
4899 (set_attr "pent_pair" "pu")
4900 (set_attr "mode" "SI")])
4901
4902 (define_insn "*addsi3_cc"
4903 [(set (reg:CC FLAGS_REG)
4904 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4905 (match_operand:SI 2 "general_operand" "ri,rm")]
4906 UNSPEC_ADD_CARRY))
4907 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4908 (plus:SI (match_dup 1) (match_dup 2)))]
4909 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4910 "add{l}\t{%2, %0|%0, %2}"
4911 [(set_attr "type" "alu")
4912 (set_attr "mode" "SI")])
4913
4914 (define_insn "addqi3_cc"
4915 [(set (reg:CC FLAGS_REG)
4916 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4917 (match_operand:QI 2 "general_operand" "qi,qm")]
4918 UNSPEC_ADD_CARRY))
4919 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4920 (plus:QI (match_dup 1) (match_dup 2)))]
4921 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4922 "add{b}\t{%2, %0|%0, %2}"
4923 [(set_attr "type" "alu")
4924 (set_attr "mode" "QI")])
4925
4926 (define_expand "addsi3"
4927 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4928 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4929 (match_operand:SI 2 "general_operand" "")))
4930 (clobber (reg:CC FLAGS_REG))])]
4931 ""
4932 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4933
4934 (define_insn "*lea_1"
4935 [(set (match_operand:SI 0 "register_operand" "=r")
4936 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4937 "!TARGET_64BIT"
4938 "lea{l}\t{%a1, %0|%0, %a1}"
4939 [(set_attr "type" "lea")
4940 (set_attr "mode" "SI")])
4941
4942 (define_insn "*lea_1_rex64"
4943 [(set (match_operand:SI 0 "register_operand" "=r")
4944 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4945 "TARGET_64BIT"
4946 "lea{l}\t{%a1, %0|%0, %a1}"
4947 [(set_attr "type" "lea")
4948 (set_attr "mode" "SI")])
4949
4950 (define_insn "*lea_1_zext"
4951 [(set (match_operand:DI 0 "register_operand" "=r")
4952 (zero_extend:DI
4953 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4954 "TARGET_64BIT"
4955 "lea{l}\t{%a1, %k0|%k0, %a1}"
4956 [(set_attr "type" "lea")
4957 (set_attr "mode" "SI")])
4958
4959 (define_insn "*lea_2_rex64"
4960 [(set (match_operand:DI 0 "register_operand" "=r")
4961 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4962 "TARGET_64BIT"
4963 "lea{q}\t{%a1, %0|%0, %a1}"
4964 [(set_attr "type" "lea")
4965 (set_attr "mode" "DI")])
4966
4967 ;; The lea patterns for non-Pmodes needs to be matched by several
4968 ;; insns converted to real lea by splitters.
4969
4970 (define_insn_and_split "*lea_general_1"
4971 [(set (match_operand 0 "register_operand" "=r")
4972 (plus (plus (match_operand 1 "index_register_operand" "l")
4973 (match_operand 2 "register_operand" "r"))
4974 (match_operand 3 "immediate_operand" "i")))]
4975 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4976 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4977 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4978 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4979 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4980 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4981 || GET_MODE (operands[3]) == VOIDmode)"
4982 "#"
4983 "&& reload_completed"
4984 [(const_int 0)]
4985 {
4986 rtx pat;
4987 operands[0] = gen_lowpart (SImode, operands[0]);
4988 operands[1] = gen_lowpart (Pmode, operands[1]);
4989 operands[2] = gen_lowpart (Pmode, operands[2]);
4990 operands[3] = gen_lowpart (Pmode, operands[3]);
4991 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4992 operands[3]);
4993 if (Pmode != SImode)
4994 pat = gen_rtx_SUBREG (SImode, pat, 0);
4995 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4996 DONE;
4997 }
4998 [(set_attr "type" "lea")
4999 (set_attr "mode" "SI")])
5000
5001 (define_insn_and_split "*lea_general_1_zext"
5002 [(set (match_operand:DI 0 "register_operand" "=r")
5003 (zero_extend:DI
5004 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5005 (match_operand:SI 2 "register_operand" "r"))
5006 (match_operand:SI 3 "immediate_operand" "i"))))]
5007 "TARGET_64BIT"
5008 "#"
5009 "&& reload_completed"
5010 [(set (match_dup 0)
5011 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5012 (match_dup 2))
5013 (match_dup 3)) 0)))]
5014 {
5015 operands[1] = gen_lowpart (Pmode, operands[1]);
5016 operands[2] = gen_lowpart (Pmode, operands[2]);
5017 operands[3] = gen_lowpart (Pmode, operands[3]);
5018 }
5019 [(set_attr "type" "lea")
5020 (set_attr "mode" "SI")])
5021
5022 (define_insn_and_split "*lea_general_2"
5023 [(set (match_operand 0 "register_operand" "=r")
5024 (plus (mult (match_operand 1 "index_register_operand" "l")
5025 (match_operand 2 "const248_operand" "i"))
5026 (match_operand 3 "nonmemory_operand" "ri")))]
5027 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5028 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5029 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5030 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5031 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5032 || GET_MODE (operands[3]) == VOIDmode)"
5033 "#"
5034 "&& reload_completed"
5035 [(const_int 0)]
5036 {
5037 rtx pat;
5038 operands[0] = gen_lowpart (SImode, operands[0]);
5039 operands[1] = gen_lowpart (Pmode, operands[1]);
5040 operands[3] = gen_lowpart (Pmode, operands[3]);
5041 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5042 operands[3]);
5043 if (Pmode != SImode)
5044 pat = gen_rtx_SUBREG (SImode, pat, 0);
5045 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5046 DONE;
5047 }
5048 [(set_attr "type" "lea")
5049 (set_attr "mode" "SI")])
5050
5051 (define_insn_and_split "*lea_general_2_zext"
5052 [(set (match_operand:DI 0 "register_operand" "=r")
5053 (zero_extend:DI
5054 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5055 (match_operand:SI 2 "const248_operand" "n"))
5056 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5057 "TARGET_64BIT"
5058 "#"
5059 "&& reload_completed"
5060 [(set (match_dup 0)
5061 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5062 (match_dup 2))
5063 (match_dup 3)) 0)))]
5064 {
5065 operands[1] = gen_lowpart (Pmode, operands[1]);
5066 operands[3] = gen_lowpart (Pmode, operands[3]);
5067 }
5068 [(set_attr "type" "lea")
5069 (set_attr "mode" "SI")])
5070
5071 (define_insn_and_split "*lea_general_3"
5072 [(set (match_operand 0 "register_operand" "=r")
5073 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5074 (match_operand 2 "const248_operand" "i"))
5075 (match_operand 3 "register_operand" "r"))
5076 (match_operand 4 "immediate_operand" "i")))]
5077 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5078 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5079 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5080 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5081 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5082 "#"
5083 "&& reload_completed"
5084 [(const_int 0)]
5085 {
5086 rtx pat;
5087 operands[0] = gen_lowpart (SImode, operands[0]);
5088 operands[1] = gen_lowpart (Pmode, operands[1]);
5089 operands[3] = gen_lowpart (Pmode, operands[3]);
5090 operands[4] = gen_lowpart (Pmode, operands[4]);
5091 pat = gen_rtx_PLUS (Pmode,
5092 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5093 operands[2]),
5094 operands[3]),
5095 operands[4]);
5096 if (Pmode != SImode)
5097 pat = gen_rtx_SUBREG (SImode, pat, 0);
5098 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5099 DONE;
5100 }
5101 [(set_attr "type" "lea")
5102 (set_attr "mode" "SI")])
5103
5104 (define_insn_and_split "*lea_general_3_zext"
5105 [(set (match_operand:DI 0 "register_operand" "=r")
5106 (zero_extend:DI
5107 (plus:SI (plus:SI (mult:SI
5108 (match_operand:SI 1 "index_register_operand" "l")
5109 (match_operand:SI 2 "const248_operand" "n"))
5110 (match_operand:SI 3 "register_operand" "r"))
5111 (match_operand:SI 4 "immediate_operand" "i"))))]
5112 "TARGET_64BIT"
5113 "#"
5114 "&& reload_completed"
5115 [(set (match_dup 0)
5116 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5117 (match_dup 2))
5118 (match_dup 3))
5119 (match_dup 4)) 0)))]
5120 {
5121 operands[1] = gen_lowpart (Pmode, operands[1]);
5122 operands[3] = gen_lowpart (Pmode, operands[3]);
5123 operands[4] = gen_lowpart (Pmode, operands[4]);
5124 }
5125 [(set_attr "type" "lea")
5126 (set_attr "mode" "SI")])
5127
5128 (define_insn "*adddi_1_rex64"
5129 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5130 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5131 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5132 (clobber (reg:CC FLAGS_REG))]
5133 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5134 {
5135 switch (get_attr_type (insn))
5136 {
5137 case TYPE_LEA:
5138 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5139 return "lea{q}\t{%a2, %0|%0, %a2}";
5140
5141 case TYPE_INCDEC:
5142 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5143 if (operands[2] == const1_rtx)
5144 return "inc{q}\t%0";
5145 else
5146 {
5147 gcc_assert (operands[2] == constm1_rtx);
5148 return "dec{q}\t%0";
5149 }
5150
5151 default:
5152 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5153
5154 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5155 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5156 if (GET_CODE (operands[2]) == CONST_INT
5157 /* Avoid overflows. */
5158 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5159 && (INTVAL (operands[2]) == 128
5160 || (INTVAL (operands[2]) < 0
5161 && INTVAL (operands[2]) != -128)))
5162 {
5163 operands[2] = GEN_INT (-INTVAL (operands[2]));
5164 return "sub{q}\t{%2, %0|%0, %2}";
5165 }
5166 return "add{q}\t{%2, %0|%0, %2}";
5167 }
5168 }
5169 [(set (attr "type")
5170 (cond [(eq_attr "alternative" "2")
5171 (const_string "lea")
5172 ; Current assemblers are broken and do not allow @GOTOFF in
5173 ; ought but a memory context.
5174 (match_operand:DI 2 "pic_symbolic_operand" "")
5175 (const_string "lea")
5176 (match_operand:DI 2 "incdec_operand" "")
5177 (const_string "incdec")
5178 ]
5179 (const_string "alu")))
5180 (set_attr "mode" "DI")])
5181
5182 ;; Convert lea to the lea pattern to avoid flags dependency.
5183 (define_split
5184 [(set (match_operand:DI 0 "register_operand" "")
5185 (plus:DI (match_operand:DI 1 "register_operand" "")
5186 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5187 (clobber (reg:CC FLAGS_REG))]
5188 "TARGET_64BIT && reload_completed
5189 && true_regnum (operands[0]) != true_regnum (operands[1])"
5190 [(set (match_dup 0)
5191 (plus:DI (match_dup 1)
5192 (match_dup 2)))]
5193 "")
5194
5195 (define_insn "*adddi_2_rex64"
5196 [(set (reg FLAGS_REG)
5197 (compare
5198 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5199 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5200 (const_int 0)))
5201 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5202 (plus:DI (match_dup 1) (match_dup 2)))]
5203 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5204 && ix86_binary_operator_ok (PLUS, DImode, operands)
5205 /* Current assemblers are broken and do not allow @GOTOFF in
5206 ought but a memory context. */
5207 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5208 {
5209 switch (get_attr_type (insn))
5210 {
5211 case TYPE_INCDEC:
5212 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5213 if (operands[2] == const1_rtx)
5214 return "inc{q}\t%0";
5215 else
5216 {
5217 gcc_assert (operands[2] == constm1_rtx);
5218 return "dec{q}\t%0";
5219 }
5220
5221 default:
5222 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5223 /* ???? We ought to handle there the 32bit case too
5224 - do we need new constraint? */
5225 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5226 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5227 if (GET_CODE (operands[2]) == CONST_INT
5228 /* Avoid overflows. */
5229 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5230 && (INTVAL (operands[2]) == 128
5231 || (INTVAL (operands[2]) < 0
5232 && INTVAL (operands[2]) != -128)))
5233 {
5234 operands[2] = GEN_INT (-INTVAL (operands[2]));
5235 return "sub{q}\t{%2, %0|%0, %2}";
5236 }
5237 return "add{q}\t{%2, %0|%0, %2}";
5238 }
5239 }
5240 [(set (attr "type")
5241 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5242 (const_string "incdec")
5243 (const_string "alu")))
5244 (set_attr "mode" "DI")])
5245
5246 (define_insn "*adddi_3_rex64"
5247 [(set (reg FLAGS_REG)
5248 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5249 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5250 (clobber (match_scratch:DI 0 "=r"))]
5251 "TARGET_64BIT
5252 && ix86_match_ccmode (insn, CCZmode)
5253 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5254 /* Current assemblers are broken and do not allow @GOTOFF in
5255 ought but a memory context. */
5256 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5257 {
5258 switch (get_attr_type (insn))
5259 {
5260 case TYPE_INCDEC:
5261 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5262 if (operands[2] == const1_rtx)
5263 return "inc{q}\t%0";
5264 else
5265 {
5266 gcc_assert (operands[2] == constm1_rtx);
5267 return "dec{q}\t%0";
5268 }
5269
5270 default:
5271 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5272 /* ???? We ought to handle there the 32bit case too
5273 - do we need new constraint? */
5274 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5275 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5276 if (GET_CODE (operands[2]) == CONST_INT
5277 /* Avoid overflows. */
5278 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5279 && (INTVAL (operands[2]) == 128
5280 || (INTVAL (operands[2]) < 0
5281 && INTVAL (operands[2]) != -128)))
5282 {
5283 operands[2] = GEN_INT (-INTVAL (operands[2]));
5284 return "sub{q}\t{%2, %0|%0, %2}";
5285 }
5286 return "add{q}\t{%2, %0|%0, %2}";
5287 }
5288 }
5289 [(set (attr "type")
5290 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5291 (const_string "incdec")
5292 (const_string "alu")))
5293 (set_attr "mode" "DI")])
5294
5295 ; For comparisons against 1, -1 and 128, we may generate better code
5296 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5297 ; is matched then. We can't accept general immediate, because for
5298 ; case of overflows, the result is messed up.
5299 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5300 ; when negated.
5301 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5302 ; only for comparisons not depending on it.
5303 (define_insn "*adddi_4_rex64"
5304 [(set (reg FLAGS_REG)
5305 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5306 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5307 (clobber (match_scratch:DI 0 "=rm"))]
5308 "TARGET_64BIT
5309 && ix86_match_ccmode (insn, CCGCmode)"
5310 {
5311 switch (get_attr_type (insn))
5312 {
5313 case TYPE_INCDEC:
5314 if (operands[2] == constm1_rtx)
5315 return "inc{q}\t%0";
5316 else
5317 {
5318 gcc_assert (operands[2] == const1_rtx);
5319 return "dec{q}\t%0";
5320 }
5321
5322 default:
5323 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5324 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5325 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5326 if ((INTVAL (operands[2]) == -128
5327 || (INTVAL (operands[2]) > 0
5328 && INTVAL (operands[2]) != 128))
5329 /* Avoid overflows. */
5330 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5331 return "sub{q}\t{%2, %0|%0, %2}";
5332 operands[2] = GEN_INT (-INTVAL (operands[2]));
5333 return "add{q}\t{%2, %0|%0, %2}";
5334 }
5335 }
5336 [(set (attr "type")
5337 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5338 (const_string "incdec")
5339 (const_string "alu")))
5340 (set_attr "mode" "DI")])
5341
5342 (define_insn "*adddi_5_rex64"
5343 [(set (reg FLAGS_REG)
5344 (compare
5345 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5346 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5347 (const_int 0)))
5348 (clobber (match_scratch:DI 0 "=r"))]
5349 "TARGET_64BIT
5350 && ix86_match_ccmode (insn, CCGOCmode)
5351 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5352 /* Current assemblers are broken and do not allow @GOTOFF in
5353 ought but a memory context. */
5354 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5355 {
5356 switch (get_attr_type (insn))
5357 {
5358 case TYPE_INCDEC:
5359 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5360 if (operands[2] == const1_rtx)
5361 return "inc{q}\t%0";
5362 else
5363 {
5364 gcc_assert (operands[2] == constm1_rtx);
5365 return "dec{q}\t%0";
5366 }
5367
5368 default:
5369 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5370 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5371 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5372 if (GET_CODE (operands[2]) == CONST_INT
5373 /* Avoid overflows. */
5374 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5375 && (INTVAL (operands[2]) == 128
5376 || (INTVAL (operands[2]) < 0
5377 && INTVAL (operands[2]) != -128)))
5378 {
5379 operands[2] = GEN_INT (-INTVAL (operands[2]));
5380 return "sub{q}\t{%2, %0|%0, %2}";
5381 }
5382 return "add{q}\t{%2, %0|%0, %2}";
5383 }
5384 }
5385 [(set (attr "type")
5386 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5387 (const_string "incdec")
5388 (const_string "alu")))
5389 (set_attr "mode" "DI")])
5390
5391
5392 (define_insn "*addsi_1"
5393 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5394 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5395 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5396 (clobber (reg:CC FLAGS_REG))]
5397 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5398 {
5399 switch (get_attr_type (insn))
5400 {
5401 case TYPE_LEA:
5402 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5403 return "lea{l}\t{%a2, %0|%0, %a2}";
5404
5405 case TYPE_INCDEC:
5406 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5407 if (operands[2] == const1_rtx)
5408 return "inc{l}\t%0";
5409 else
5410 {
5411 gcc_assert (operands[2] == constm1_rtx);
5412 return "dec{l}\t%0";
5413 }
5414
5415 default:
5416 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5417
5418 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5419 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5420 if (GET_CODE (operands[2]) == CONST_INT
5421 && (INTVAL (operands[2]) == 128
5422 || (INTVAL (operands[2]) < 0
5423 && INTVAL (operands[2]) != -128)))
5424 {
5425 operands[2] = GEN_INT (-INTVAL (operands[2]));
5426 return "sub{l}\t{%2, %0|%0, %2}";
5427 }
5428 return "add{l}\t{%2, %0|%0, %2}";
5429 }
5430 }
5431 [(set (attr "type")
5432 (cond [(eq_attr "alternative" "2")
5433 (const_string "lea")
5434 ; Current assemblers are broken and do not allow @GOTOFF in
5435 ; ought but a memory context.
5436 (match_operand:SI 2 "pic_symbolic_operand" "")
5437 (const_string "lea")
5438 (match_operand:SI 2 "incdec_operand" "")
5439 (const_string "incdec")
5440 ]
5441 (const_string "alu")))
5442 (set_attr "mode" "SI")])
5443
5444 ;; Convert lea to the lea pattern to avoid flags dependency.
5445 (define_split
5446 [(set (match_operand 0 "register_operand" "")
5447 (plus (match_operand 1 "register_operand" "")
5448 (match_operand 2 "nonmemory_operand" "")))
5449 (clobber (reg:CC FLAGS_REG))]
5450 "reload_completed
5451 && true_regnum (operands[0]) != true_regnum (operands[1])"
5452 [(const_int 0)]
5453 {
5454 rtx pat;
5455 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5456 may confuse gen_lowpart. */
5457 if (GET_MODE (operands[0]) != Pmode)
5458 {
5459 operands[1] = gen_lowpart (Pmode, operands[1]);
5460 operands[2] = gen_lowpart (Pmode, operands[2]);
5461 }
5462 operands[0] = gen_lowpart (SImode, operands[0]);
5463 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5464 if (Pmode != SImode)
5465 pat = gen_rtx_SUBREG (SImode, pat, 0);
5466 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5467 DONE;
5468 })
5469
5470 ;; It may seem that nonimmediate operand is proper one for operand 1.
5471 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5472 ;; we take care in ix86_binary_operator_ok to not allow two memory
5473 ;; operands so proper swapping will be done in reload. This allow
5474 ;; patterns constructed from addsi_1 to match.
5475 (define_insn "addsi_1_zext"
5476 [(set (match_operand:DI 0 "register_operand" "=r,r")
5477 (zero_extend:DI
5478 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5479 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5480 (clobber (reg:CC FLAGS_REG))]
5481 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5482 {
5483 switch (get_attr_type (insn))
5484 {
5485 case TYPE_LEA:
5486 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5487 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5488
5489 case TYPE_INCDEC:
5490 if (operands[2] == const1_rtx)
5491 return "inc{l}\t%k0";
5492 else
5493 {
5494 gcc_assert (operands[2] == constm1_rtx);
5495 return "dec{l}\t%k0";
5496 }
5497
5498 default:
5499 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5500 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5501 if (GET_CODE (operands[2]) == CONST_INT
5502 && (INTVAL (operands[2]) == 128
5503 || (INTVAL (operands[2]) < 0
5504 && INTVAL (operands[2]) != -128)))
5505 {
5506 operands[2] = GEN_INT (-INTVAL (operands[2]));
5507 return "sub{l}\t{%2, %k0|%k0, %2}";
5508 }
5509 return "add{l}\t{%2, %k0|%k0, %2}";
5510 }
5511 }
5512 [(set (attr "type")
5513 (cond [(eq_attr "alternative" "1")
5514 (const_string "lea")
5515 ; Current assemblers are broken and do not allow @GOTOFF in
5516 ; ought but a memory context.
5517 (match_operand:SI 2 "pic_symbolic_operand" "")
5518 (const_string "lea")
5519 (match_operand:SI 2 "incdec_operand" "")
5520 (const_string "incdec")
5521 ]
5522 (const_string "alu")))
5523 (set_attr "mode" "SI")])
5524
5525 ;; Convert lea to the lea pattern to avoid flags dependency.
5526 (define_split
5527 [(set (match_operand:DI 0 "register_operand" "")
5528 (zero_extend:DI
5529 (plus:SI (match_operand:SI 1 "register_operand" "")
5530 (match_operand:SI 2 "nonmemory_operand" ""))))
5531 (clobber (reg:CC FLAGS_REG))]
5532 "TARGET_64BIT && reload_completed
5533 && true_regnum (operands[0]) != true_regnum (operands[1])"
5534 [(set (match_dup 0)
5535 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5536 {
5537 operands[1] = gen_lowpart (Pmode, operands[1]);
5538 operands[2] = gen_lowpart (Pmode, operands[2]);
5539 })
5540
5541 (define_insn "*addsi_2"
5542 [(set (reg FLAGS_REG)
5543 (compare
5544 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5545 (match_operand:SI 2 "general_operand" "rmni,rni"))
5546 (const_int 0)))
5547 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5548 (plus:SI (match_dup 1) (match_dup 2)))]
5549 "ix86_match_ccmode (insn, CCGOCmode)
5550 && ix86_binary_operator_ok (PLUS, SImode, operands)
5551 /* Current assemblers are broken and do not allow @GOTOFF in
5552 ought but a memory context. */
5553 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5554 {
5555 switch (get_attr_type (insn))
5556 {
5557 case TYPE_INCDEC:
5558 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5559 if (operands[2] == const1_rtx)
5560 return "inc{l}\t%0";
5561 else
5562 {
5563 gcc_assert (operands[2] == constm1_rtx);
5564 return "dec{l}\t%0";
5565 }
5566
5567 default:
5568 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5569 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5570 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5571 if (GET_CODE (operands[2]) == CONST_INT
5572 && (INTVAL (operands[2]) == 128
5573 || (INTVAL (operands[2]) < 0
5574 && INTVAL (operands[2]) != -128)))
5575 {
5576 operands[2] = GEN_INT (-INTVAL (operands[2]));
5577 return "sub{l}\t{%2, %0|%0, %2}";
5578 }
5579 return "add{l}\t{%2, %0|%0, %2}";
5580 }
5581 }
5582 [(set (attr "type")
5583 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5584 (const_string "incdec")
5585 (const_string "alu")))
5586 (set_attr "mode" "SI")])
5587
5588 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5589 (define_insn "*addsi_2_zext"
5590 [(set (reg FLAGS_REG)
5591 (compare
5592 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5593 (match_operand:SI 2 "general_operand" "rmni"))
5594 (const_int 0)))
5595 (set (match_operand:DI 0 "register_operand" "=r")
5596 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5597 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5598 && ix86_binary_operator_ok (PLUS, SImode, operands)
5599 /* Current assemblers are broken and do not allow @GOTOFF in
5600 ought but a memory context. */
5601 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5602 {
5603 switch (get_attr_type (insn))
5604 {
5605 case TYPE_INCDEC:
5606 if (operands[2] == const1_rtx)
5607 return "inc{l}\t%k0";
5608 else
5609 {
5610 gcc_assert (operands[2] == constm1_rtx);
5611 return "dec{l}\t%k0";
5612 }
5613
5614 default:
5615 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5616 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5617 if (GET_CODE (operands[2]) == CONST_INT
5618 && (INTVAL (operands[2]) == 128
5619 || (INTVAL (operands[2]) < 0
5620 && INTVAL (operands[2]) != -128)))
5621 {
5622 operands[2] = GEN_INT (-INTVAL (operands[2]));
5623 return "sub{l}\t{%2, %k0|%k0, %2}";
5624 }
5625 return "add{l}\t{%2, %k0|%k0, %2}";
5626 }
5627 }
5628 [(set (attr "type")
5629 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5630 (const_string "incdec")
5631 (const_string "alu")))
5632 (set_attr "mode" "SI")])
5633
5634 (define_insn "*addsi_3"
5635 [(set (reg FLAGS_REG)
5636 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5637 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5638 (clobber (match_scratch:SI 0 "=r"))]
5639 "ix86_match_ccmode (insn, CCZmode)
5640 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5641 /* Current assemblers are broken and do not allow @GOTOFF in
5642 ought but a memory context. */
5643 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5644 {
5645 switch (get_attr_type (insn))
5646 {
5647 case TYPE_INCDEC:
5648 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5649 if (operands[2] == const1_rtx)
5650 return "inc{l}\t%0";
5651 else
5652 {
5653 gcc_assert (operands[2] == constm1_rtx);
5654 return "dec{l}\t%0";
5655 }
5656
5657 default:
5658 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5659 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5660 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5661 if (GET_CODE (operands[2]) == CONST_INT
5662 && (INTVAL (operands[2]) == 128
5663 || (INTVAL (operands[2]) < 0
5664 && INTVAL (operands[2]) != -128)))
5665 {
5666 operands[2] = GEN_INT (-INTVAL (operands[2]));
5667 return "sub{l}\t{%2, %0|%0, %2}";
5668 }
5669 return "add{l}\t{%2, %0|%0, %2}";
5670 }
5671 }
5672 [(set (attr "type")
5673 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674 (const_string "incdec")
5675 (const_string "alu")))
5676 (set_attr "mode" "SI")])
5677
5678 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5679 (define_insn "*addsi_3_zext"
5680 [(set (reg FLAGS_REG)
5681 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5682 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5683 (set (match_operand:DI 0 "register_operand" "=r")
5684 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5685 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5686 && ix86_binary_operator_ok (PLUS, SImode, operands)
5687 /* Current assemblers are broken and do not allow @GOTOFF in
5688 ought but a memory context. */
5689 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5690 {
5691 switch (get_attr_type (insn))
5692 {
5693 case TYPE_INCDEC:
5694 if (operands[2] == const1_rtx)
5695 return "inc{l}\t%k0";
5696 else
5697 {
5698 gcc_assert (operands[2] == constm1_rtx);
5699 return "dec{l}\t%k0";
5700 }
5701
5702 default:
5703 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5704 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5705 if (GET_CODE (operands[2]) == CONST_INT
5706 && (INTVAL (operands[2]) == 128
5707 || (INTVAL (operands[2]) < 0
5708 && INTVAL (operands[2]) != -128)))
5709 {
5710 operands[2] = GEN_INT (-INTVAL (operands[2]));
5711 return "sub{l}\t{%2, %k0|%k0, %2}";
5712 }
5713 return "add{l}\t{%2, %k0|%k0, %2}";
5714 }
5715 }
5716 [(set (attr "type")
5717 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5718 (const_string "incdec")
5719 (const_string "alu")))
5720 (set_attr "mode" "SI")])
5721
5722 ; For comparisons against 1, -1 and 128, we may generate better code
5723 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5724 ; is matched then. We can't accept general immediate, because for
5725 ; case of overflows, the result is messed up.
5726 ; This pattern also don't hold of 0x80000000, since the value overflows
5727 ; when negated.
5728 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5729 ; only for comparisons not depending on it.
5730 (define_insn "*addsi_4"
5731 [(set (reg FLAGS_REG)
5732 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5733 (match_operand:SI 2 "const_int_operand" "n")))
5734 (clobber (match_scratch:SI 0 "=rm"))]
5735 "ix86_match_ccmode (insn, CCGCmode)
5736 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5737 {
5738 switch (get_attr_type (insn))
5739 {
5740 case TYPE_INCDEC:
5741 if (operands[2] == constm1_rtx)
5742 return "inc{l}\t%0";
5743 else
5744 {
5745 gcc_assert (operands[2] == const1_rtx);
5746 return "dec{l}\t%0";
5747 }
5748
5749 default:
5750 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5751 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5752 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5753 if ((INTVAL (operands[2]) == -128
5754 || (INTVAL (operands[2]) > 0
5755 && INTVAL (operands[2]) != 128)))
5756 return "sub{l}\t{%2, %0|%0, %2}";
5757 operands[2] = GEN_INT (-INTVAL (operands[2]));
5758 return "add{l}\t{%2, %0|%0, %2}";
5759 }
5760 }
5761 [(set (attr "type")
5762 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5763 (const_string "incdec")
5764 (const_string "alu")))
5765 (set_attr "mode" "SI")])
5766
5767 (define_insn "*addsi_5"
5768 [(set (reg FLAGS_REG)
5769 (compare
5770 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5771 (match_operand:SI 2 "general_operand" "rmni"))
5772 (const_int 0)))
5773 (clobber (match_scratch:SI 0 "=r"))]
5774 "ix86_match_ccmode (insn, CCGOCmode)
5775 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5776 /* Current assemblers are broken and do not allow @GOTOFF in
5777 ought but a memory context. */
5778 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5779 {
5780 switch (get_attr_type (insn))
5781 {
5782 case TYPE_INCDEC:
5783 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784 if (operands[2] == const1_rtx)
5785 return "inc{l}\t%0";
5786 else
5787 {
5788 gcc_assert (operands[2] == constm1_rtx);
5789 return "dec{l}\t%0";
5790 }
5791
5792 default:
5793 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5794 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5795 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5796 if (GET_CODE (operands[2]) == CONST_INT
5797 && (INTVAL (operands[2]) == 128
5798 || (INTVAL (operands[2]) < 0
5799 && INTVAL (operands[2]) != -128)))
5800 {
5801 operands[2] = GEN_INT (-INTVAL (operands[2]));
5802 return "sub{l}\t{%2, %0|%0, %2}";
5803 }
5804 return "add{l}\t{%2, %0|%0, %2}";
5805 }
5806 }
5807 [(set (attr "type")
5808 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5809 (const_string "incdec")
5810 (const_string "alu")))
5811 (set_attr "mode" "SI")])
5812
5813 (define_expand "addhi3"
5814 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5815 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5816 (match_operand:HI 2 "general_operand" "")))
5817 (clobber (reg:CC FLAGS_REG))])]
5818 "TARGET_HIMODE_MATH"
5819 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5820
5821 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5822 ;; type optimizations enabled by define-splits. This is not important
5823 ;; for PII, and in fact harmful because of partial register stalls.
5824
5825 (define_insn "*addhi_1_lea"
5826 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5827 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5828 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5829 (clobber (reg:CC FLAGS_REG))]
5830 "!TARGET_PARTIAL_REG_STALL
5831 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5832 {
5833 switch (get_attr_type (insn))
5834 {
5835 case TYPE_LEA:
5836 return "#";
5837 case TYPE_INCDEC:
5838 if (operands[2] == const1_rtx)
5839 return "inc{w}\t%0";
5840 else
5841 {
5842 gcc_assert (operands[2] == constm1_rtx);
5843 return "dec{w}\t%0";
5844 }
5845
5846 default:
5847 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5848 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5849 if (GET_CODE (operands[2]) == CONST_INT
5850 && (INTVAL (operands[2]) == 128
5851 || (INTVAL (operands[2]) < 0
5852 && INTVAL (operands[2]) != -128)))
5853 {
5854 operands[2] = GEN_INT (-INTVAL (operands[2]));
5855 return "sub{w}\t{%2, %0|%0, %2}";
5856 }
5857 return "add{w}\t{%2, %0|%0, %2}";
5858 }
5859 }
5860 [(set (attr "type")
5861 (if_then_else (eq_attr "alternative" "2")
5862 (const_string "lea")
5863 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5864 (const_string "incdec")
5865 (const_string "alu"))))
5866 (set_attr "mode" "HI,HI,SI")])
5867
5868 (define_insn "*addhi_1"
5869 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5870 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5871 (match_operand:HI 2 "general_operand" "ri,rm")))
5872 (clobber (reg:CC FLAGS_REG))]
5873 "TARGET_PARTIAL_REG_STALL
5874 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5875 {
5876 switch (get_attr_type (insn))
5877 {
5878 case TYPE_INCDEC:
5879 if (operands[2] == const1_rtx)
5880 return "inc{w}\t%0";
5881 else
5882 {
5883 gcc_assert (operands[2] == constm1_rtx);
5884 return "dec{w}\t%0";
5885 }
5886
5887 default:
5888 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5889 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5890 if (GET_CODE (operands[2]) == CONST_INT
5891 && (INTVAL (operands[2]) == 128
5892 || (INTVAL (operands[2]) < 0
5893 && INTVAL (operands[2]) != -128)))
5894 {
5895 operands[2] = GEN_INT (-INTVAL (operands[2]));
5896 return "sub{w}\t{%2, %0|%0, %2}";
5897 }
5898 return "add{w}\t{%2, %0|%0, %2}";
5899 }
5900 }
5901 [(set (attr "type")
5902 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5903 (const_string "incdec")
5904 (const_string "alu")))
5905 (set_attr "mode" "HI")])
5906
5907 (define_insn "*addhi_2"
5908 [(set (reg FLAGS_REG)
5909 (compare
5910 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5911 (match_operand:HI 2 "general_operand" "rmni,rni"))
5912 (const_int 0)))
5913 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5914 (plus:HI (match_dup 1) (match_dup 2)))]
5915 "ix86_match_ccmode (insn, CCGOCmode)
5916 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5917 {
5918 switch (get_attr_type (insn))
5919 {
5920 case TYPE_INCDEC:
5921 if (operands[2] == const1_rtx)
5922 return "inc{w}\t%0";
5923 else
5924 {
5925 gcc_assert (operands[2] == constm1_rtx);
5926 return "dec{w}\t%0";
5927 }
5928
5929 default:
5930 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5931 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5932 if (GET_CODE (operands[2]) == CONST_INT
5933 && (INTVAL (operands[2]) == 128
5934 || (INTVAL (operands[2]) < 0
5935 && INTVAL (operands[2]) != -128)))
5936 {
5937 operands[2] = GEN_INT (-INTVAL (operands[2]));
5938 return "sub{w}\t{%2, %0|%0, %2}";
5939 }
5940 return "add{w}\t{%2, %0|%0, %2}";
5941 }
5942 }
5943 [(set (attr "type")
5944 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5945 (const_string "incdec")
5946 (const_string "alu")))
5947 (set_attr "mode" "HI")])
5948
5949 (define_insn "*addhi_3"
5950 [(set (reg FLAGS_REG)
5951 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5952 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5953 (clobber (match_scratch:HI 0 "=r"))]
5954 "ix86_match_ccmode (insn, CCZmode)
5955 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5956 {
5957 switch (get_attr_type (insn))
5958 {
5959 case TYPE_INCDEC:
5960 if (operands[2] == const1_rtx)
5961 return "inc{w}\t%0";
5962 else
5963 {
5964 gcc_assert (operands[2] == constm1_rtx);
5965 return "dec{w}\t%0";
5966 }
5967
5968 default:
5969 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5970 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5971 if (GET_CODE (operands[2]) == CONST_INT
5972 && (INTVAL (operands[2]) == 128
5973 || (INTVAL (operands[2]) < 0
5974 && INTVAL (operands[2]) != -128)))
5975 {
5976 operands[2] = GEN_INT (-INTVAL (operands[2]));
5977 return "sub{w}\t{%2, %0|%0, %2}";
5978 }
5979 return "add{w}\t{%2, %0|%0, %2}";
5980 }
5981 }
5982 [(set (attr "type")
5983 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5984 (const_string "incdec")
5985 (const_string "alu")))
5986 (set_attr "mode" "HI")])
5987
5988 ; See comments above addsi_4 for details.
5989 (define_insn "*addhi_4"
5990 [(set (reg FLAGS_REG)
5991 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5992 (match_operand:HI 2 "const_int_operand" "n")))
5993 (clobber (match_scratch:HI 0 "=rm"))]
5994 "ix86_match_ccmode (insn, CCGCmode)
5995 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5996 {
5997 switch (get_attr_type (insn))
5998 {
5999 case TYPE_INCDEC:
6000 if (operands[2] == constm1_rtx)
6001 return "inc{w}\t%0";
6002 else
6003 {
6004 gcc_assert (operands[2] == const1_rtx);
6005 return "dec{w}\t%0";
6006 }
6007
6008 default:
6009 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6010 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6011 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6012 if ((INTVAL (operands[2]) == -128
6013 || (INTVAL (operands[2]) > 0
6014 && INTVAL (operands[2]) != 128)))
6015 return "sub{w}\t{%2, %0|%0, %2}";
6016 operands[2] = GEN_INT (-INTVAL (operands[2]));
6017 return "add{w}\t{%2, %0|%0, %2}";
6018 }
6019 }
6020 [(set (attr "type")
6021 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6022 (const_string "incdec")
6023 (const_string "alu")))
6024 (set_attr "mode" "SI")])
6025
6026
6027 (define_insn "*addhi_5"
6028 [(set (reg FLAGS_REG)
6029 (compare
6030 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6031 (match_operand:HI 2 "general_operand" "rmni"))
6032 (const_int 0)))
6033 (clobber (match_scratch:HI 0 "=r"))]
6034 "ix86_match_ccmode (insn, CCGOCmode)
6035 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6036 {
6037 switch (get_attr_type (insn))
6038 {
6039 case TYPE_INCDEC:
6040 if (operands[2] == const1_rtx)
6041 return "inc{w}\t%0";
6042 else
6043 {
6044 gcc_assert (operands[2] == constm1_rtx);
6045 return "dec{w}\t%0";
6046 }
6047
6048 default:
6049 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6050 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6051 if (GET_CODE (operands[2]) == CONST_INT
6052 && (INTVAL (operands[2]) == 128
6053 || (INTVAL (operands[2]) < 0
6054 && INTVAL (operands[2]) != -128)))
6055 {
6056 operands[2] = GEN_INT (-INTVAL (operands[2]));
6057 return "sub{w}\t{%2, %0|%0, %2}";
6058 }
6059 return "add{w}\t{%2, %0|%0, %2}";
6060 }
6061 }
6062 [(set (attr "type")
6063 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6064 (const_string "incdec")
6065 (const_string "alu")))
6066 (set_attr "mode" "HI")])
6067
6068 (define_expand "addqi3"
6069 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6070 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6071 (match_operand:QI 2 "general_operand" "")))
6072 (clobber (reg:CC FLAGS_REG))])]
6073 "TARGET_QIMODE_MATH"
6074 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6075
6076 ;; %%% Potential partial reg stall on alternative 2. What to do?
6077 (define_insn "*addqi_1_lea"
6078 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6079 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6080 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6081 (clobber (reg:CC FLAGS_REG))]
6082 "!TARGET_PARTIAL_REG_STALL
6083 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6084 {
6085 int widen = (which_alternative == 2);
6086 switch (get_attr_type (insn))
6087 {
6088 case TYPE_LEA:
6089 return "#";
6090 case TYPE_INCDEC:
6091 if (operands[2] == const1_rtx)
6092 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6093 else
6094 {
6095 gcc_assert (operands[2] == constm1_rtx);
6096 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6097 }
6098
6099 default:
6100 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6102 if (GET_CODE (operands[2]) == CONST_INT
6103 && (INTVAL (operands[2]) == 128
6104 || (INTVAL (operands[2]) < 0
6105 && INTVAL (operands[2]) != -128)))
6106 {
6107 operands[2] = GEN_INT (-INTVAL (operands[2]));
6108 if (widen)
6109 return "sub{l}\t{%2, %k0|%k0, %2}";
6110 else
6111 return "sub{b}\t{%2, %0|%0, %2}";
6112 }
6113 if (widen)
6114 return "add{l}\t{%k2, %k0|%k0, %k2}";
6115 else
6116 return "add{b}\t{%2, %0|%0, %2}";
6117 }
6118 }
6119 [(set (attr "type")
6120 (if_then_else (eq_attr "alternative" "3")
6121 (const_string "lea")
6122 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6123 (const_string "incdec")
6124 (const_string "alu"))))
6125 (set_attr "mode" "QI,QI,SI,SI")])
6126
6127 (define_insn "*addqi_1"
6128 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6129 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6130 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6131 (clobber (reg:CC FLAGS_REG))]
6132 "TARGET_PARTIAL_REG_STALL
6133 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6134 {
6135 int widen = (which_alternative == 2);
6136 switch (get_attr_type (insn))
6137 {
6138 case TYPE_INCDEC:
6139 if (operands[2] == const1_rtx)
6140 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6141 else
6142 {
6143 gcc_assert (operands[2] == constm1_rtx);
6144 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6145 }
6146
6147 default:
6148 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6149 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6150 if (GET_CODE (operands[2]) == CONST_INT
6151 && (INTVAL (operands[2]) == 128
6152 || (INTVAL (operands[2]) < 0
6153 && INTVAL (operands[2]) != -128)))
6154 {
6155 operands[2] = GEN_INT (-INTVAL (operands[2]));
6156 if (widen)
6157 return "sub{l}\t{%2, %k0|%k0, %2}";
6158 else
6159 return "sub{b}\t{%2, %0|%0, %2}";
6160 }
6161 if (widen)
6162 return "add{l}\t{%k2, %k0|%k0, %k2}";
6163 else
6164 return "add{b}\t{%2, %0|%0, %2}";
6165 }
6166 }
6167 [(set (attr "type")
6168 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6169 (const_string "incdec")
6170 (const_string "alu")))
6171 (set_attr "mode" "QI,QI,SI")])
6172
6173 (define_insn "*addqi_1_slp"
6174 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6175 (plus:QI (match_dup 0)
6176 (match_operand:QI 1 "general_operand" "qn,qnm")))
6177 (clobber (reg:CC FLAGS_REG))]
6178 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6179 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6180 {
6181 switch (get_attr_type (insn))
6182 {
6183 case TYPE_INCDEC:
6184 if (operands[1] == const1_rtx)
6185 return "inc{b}\t%0";
6186 else
6187 {
6188 gcc_assert (operands[1] == constm1_rtx);
6189 return "dec{b}\t%0";
6190 }
6191
6192 default:
6193 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6194 if (GET_CODE (operands[1]) == CONST_INT
6195 && INTVAL (operands[1]) < 0)
6196 {
6197 operands[1] = GEN_INT (-INTVAL (operands[1]));
6198 return "sub{b}\t{%1, %0|%0, %1}";
6199 }
6200 return "add{b}\t{%1, %0|%0, %1}";
6201 }
6202 }
6203 [(set (attr "type")
6204 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6205 (const_string "incdec")
6206 (const_string "alu1")))
6207 (set (attr "memory")
6208 (if_then_else (match_operand 1 "memory_operand" "")
6209 (const_string "load")
6210 (const_string "none")))
6211 (set_attr "mode" "QI")])
6212
6213 (define_insn "*addqi_2"
6214 [(set (reg FLAGS_REG)
6215 (compare
6216 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6217 (match_operand:QI 2 "general_operand" "qmni,qni"))
6218 (const_int 0)))
6219 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6220 (plus:QI (match_dup 1) (match_dup 2)))]
6221 "ix86_match_ccmode (insn, CCGOCmode)
6222 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6223 {
6224 switch (get_attr_type (insn))
6225 {
6226 case TYPE_INCDEC:
6227 if (operands[2] == const1_rtx)
6228 return "inc{b}\t%0";
6229 else
6230 {
6231 gcc_assert (operands[2] == constm1_rtx
6232 || (GET_CODE (operands[2]) == CONST_INT
6233 && INTVAL (operands[2]) == 255));
6234 return "dec{b}\t%0";
6235 }
6236
6237 default:
6238 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6239 if (GET_CODE (operands[2]) == CONST_INT
6240 && INTVAL (operands[2]) < 0)
6241 {
6242 operands[2] = GEN_INT (-INTVAL (operands[2]));
6243 return "sub{b}\t{%2, %0|%0, %2}";
6244 }
6245 return "add{b}\t{%2, %0|%0, %2}";
6246 }
6247 }
6248 [(set (attr "type")
6249 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250 (const_string "incdec")
6251 (const_string "alu")))
6252 (set_attr "mode" "QI")])
6253
6254 (define_insn "*addqi_3"
6255 [(set (reg FLAGS_REG)
6256 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6257 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6258 (clobber (match_scratch:QI 0 "=q"))]
6259 "ix86_match_ccmode (insn, CCZmode)
6260 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6261 {
6262 switch (get_attr_type (insn))
6263 {
6264 case TYPE_INCDEC:
6265 if (operands[2] == const1_rtx)
6266 return "inc{b}\t%0";
6267 else
6268 {
6269 gcc_assert (operands[2] == constm1_rtx
6270 || (GET_CODE (operands[2]) == CONST_INT
6271 && INTVAL (operands[2]) == 255));
6272 return "dec{b}\t%0";
6273 }
6274
6275 default:
6276 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6277 if (GET_CODE (operands[2]) == CONST_INT
6278 && INTVAL (operands[2]) < 0)
6279 {
6280 operands[2] = GEN_INT (-INTVAL (operands[2]));
6281 return "sub{b}\t{%2, %0|%0, %2}";
6282 }
6283 return "add{b}\t{%2, %0|%0, %2}";
6284 }
6285 }
6286 [(set (attr "type")
6287 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6288 (const_string "incdec")
6289 (const_string "alu")))
6290 (set_attr "mode" "QI")])
6291
6292 ; See comments above addsi_4 for details.
6293 (define_insn "*addqi_4"
6294 [(set (reg FLAGS_REG)
6295 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6296 (match_operand:QI 2 "const_int_operand" "n")))
6297 (clobber (match_scratch:QI 0 "=qm"))]
6298 "ix86_match_ccmode (insn, CCGCmode)
6299 && (INTVAL (operands[2]) & 0xff) != 0x80"
6300 {
6301 switch (get_attr_type (insn))
6302 {
6303 case TYPE_INCDEC:
6304 if (operands[2] == constm1_rtx
6305 || (GET_CODE (operands[2]) == CONST_INT
6306 && INTVAL (operands[2]) == 255))
6307 return "inc{b}\t%0";
6308 else
6309 {
6310 gcc_assert (operands[2] == const1_rtx);
6311 return "dec{b}\t%0";
6312 }
6313
6314 default:
6315 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6316 if (INTVAL (operands[2]) < 0)
6317 {
6318 operands[2] = GEN_INT (-INTVAL (operands[2]));
6319 return "add{b}\t{%2, %0|%0, %2}";
6320 }
6321 return "sub{b}\t{%2, %0|%0, %2}";
6322 }
6323 }
6324 [(set (attr "type")
6325 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6326 (const_string "incdec")
6327 (const_string "alu")))
6328 (set_attr "mode" "QI")])
6329
6330
6331 (define_insn "*addqi_5"
6332 [(set (reg FLAGS_REG)
6333 (compare
6334 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6335 (match_operand:QI 2 "general_operand" "qmni"))
6336 (const_int 0)))
6337 (clobber (match_scratch:QI 0 "=q"))]
6338 "ix86_match_ccmode (insn, CCGOCmode)
6339 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6340 {
6341 switch (get_attr_type (insn))
6342 {
6343 case TYPE_INCDEC:
6344 if (operands[2] == const1_rtx)
6345 return "inc{b}\t%0";
6346 else
6347 {
6348 gcc_assert (operands[2] == constm1_rtx
6349 || (GET_CODE (operands[2]) == CONST_INT
6350 && INTVAL (operands[2]) == 255));
6351 return "dec{b}\t%0";
6352 }
6353
6354 default:
6355 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6356 if (GET_CODE (operands[2]) == CONST_INT
6357 && INTVAL (operands[2]) < 0)
6358 {
6359 operands[2] = GEN_INT (-INTVAL (operands[2]));
6360 return "sub{b}\t{%2, %0|%0, %2}";
6361 }
6362 return "add{b}\t{%2, %0|%0, %2}";
6363 }
6364 }
6365 [(set (attr "type")
6366 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6367 (const_string "incdec")
6368 (const_string "alu")))
6369 (set_attr "mode" "QI")])
6370
6371
6372 (define_insn "addqi_ext_1"
6373 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6374 (const_int 8)
6375 (const_int 8))
6376 (plus:SI
6377 (zero_extract:SI
6378 (match_operand 1 "ext_register_operand" "0")
6379 (const_int 8)
6380 (const_int 8))
6381 (match_operand:QI 2 "general_operand" "Qmn")))
6382 (clobber (reg:CC FLAGS_REG))]
6383 "!TARGET_64BIT"
6384 {
6385 switch (get_attr_type (insn))
6386 {
6387 case TYPE_INCDEC:
6388 if (operands[2] == const1_rtx)
6389 return "inc{b}\t%h0";
6390 else
6391 {
6392 gcc_assert (operands[2] == constm1_rtx
6393 || (GET_CODE (operands[2]) == CONST_INT
6394 && INTVAL (operands[2]) == 255));
6395 return "dec{b}\t%h0";
6396 }
6397
6398 default:
6399 return "add{b}\t{%2, %h0|%h0, %2}";
6400 }
6401 }
6402 [(set (attr "type")
6403 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6404 (const_string "incdec")
6405 (const_string "alu")))
6406 (set_attr "mode" "QI")])
6407
6408 (define_insn "*addqi_ext_1_rex64"
6409 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6410 (const_int 8)
6411 (const_int 8))
6412 (plus:SI
6413 (zero_extract:SI
6414 (match_operand 1 "ext_register_operand" "0")
6415 (const_int 8)
6416 (const_int 8))
6417 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6418 (clobber (reg:CC FLAGS_REG))]
6419 "TARGET_64BIT"
6420 {
6421 switch (get_attr_type (insn))
6422 {
6423 case TYPE_INCDEC:
6424 if (operands[2] == const1_rtx)
6425 return "inc{b}\t%h0";
6426 else
6427 {
6428 gcc_assert (operands[2] == constm1_rtx
6429 || (GET_CODE (operands[2]) == CONST_INT
6430 && INTVAL (operands[2]) == 255));
6431 return "dec{b}\t%h0";
6432 }
6433
6434 default:
6435 return "add{b}\t{%2, %h0|%h0, %2}";
6436 }
6437 }
6438 [(set (attr "type")
6439 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6440 (const_string "incdec")
6441 (const_string "alu")))
6442 (set_attr "mode" "QI")])
6443
6444 (define_insn "*addqi_ext_2"
6445 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6446 (const_int 8)
6447 (const_int 8))
6448 (plus:SI
6449 (zero_extract:SI
6450 (match_operand 1 "ext_register_operand" "%0")
6451 (const_int 8)
6452 (const_int 8))
6453 (zero_extract:SI
6454 (match_operand 2 "ext_register_operand" "Q")
6455 (const_int 8)
6456 (const_int 8))))
6457 (clobber (reg:CC FLAGS_REG))]
6458 ""
6459 "add{b}\t{%h2, %h0|%h0, %h2}"
6460 [(set_attr "type" "alu")
6461 (set_attr "mode" "QI")])
6462
6463 ;; The patterns that match these are at the end of this file.
6464
6465 (define_expand "addxf3"
6466 [(set (match_operand:XF 0 "register_operand" "")
6467 (plus:XF (match_operand:XF 1 "register_operand" "")
6468 (match_operand:XF 2 "register_operand" "")))]
6469 "TARGET_80387"
6470 "")
6471
6472 (define_expand "adddf3"
6473 [(set (match_operand:DF 0 "register_operand" "")
6474 (plus:DF (match_operand:DF 1 "register_operand" "")
6475 (match_operand:DF 2 "nonimmediate_operand" "")))]
6476 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6477 "")
6478
6479 (define_expand "addsf3"
6480 [(set (match_operand:SF 0 "register_operand" "")
6481 (plus:SF (match_operand:SF 1 "register_operand" "")
6482 (match_operand:SF 2 "nonimmediate_operand" "")))]
6483 "TARGET_80387 || TARGET_SSE_MATH"
6484 "")
6485 \f
6486 ;; Subtract instructions
6487
6488 ;; %%% splits for subditi3
6489
6490 (define_expand "subti3"
6491 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6492 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6493 (match_operand:TI 2 "x86_64_general_operand" "")))
6494 (clobber (reg:CC FLAGS_REG))])]
6495 "TARGET_64BIT"
6496 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6497
6498 (define_insn "*subti3_1"
6499 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6500 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6501 (match_operand:TI 2 "general_operand" "roiF,riF")))
6502 (clobber (reg:CC FLAGS_REG))]
6503 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6504 "#")
6505
6506 (define_split
6507 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6508 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6509 (match_operand:TI 2 "general_operand" "")))
6510 (clobber (reg:CC FLAGS_REG))]
6511 "TARGET_64BIT && reload_completed"
6512 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6513 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6514 (parallel [(set (match_dup 3)
6515 (minus:DI (match_dup 4)
6516 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6517 (match_dup 5))))
6518 (clobber (reg:CC FLAGS_REG))])]
6519 "split_ti (operands+0, 1, operands+0, operands+3);
6520 split_ti (operands+1, 1, operands+1, operands+4);
6521 split_ti (operands+2, 1, operands+2, operands+5);")
6522
6523 ;; %%% splits for subsidi3
6524
6525 (define_expand "subdi3"
6526 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6527 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6528 (match_operand:DI 2 "x86_64_general_operand" "")))
6529 (clobber (reg:CC FLAGS_REG))])]
6530 ""
6531 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6532
6533 (define_insn "*subdi3_1"
6534 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6535 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6536 (match_operand:DI 2 "general_operand" "roiF,riF")))
6537 (clobber (reg:CC FLAGS_REG))]
6538 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6539 "#")
6540
6541 (define_split
6542 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6543 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6544 (match_operand:DI 2 "general_operand" "")))
6545 (clobber (reg:CC FLAGS_REG))]
6546 "!TARGET_64BIT && reload_completed"
6547 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6548 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6549 (parallel [(set (match_dup 3)
6550 (minus:SI (match_dup 4)
6551 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6552 (match_dup 5))))
6553 (clobber (reg:CC FLAGS_REG))])]
6554 "split_di (operands+0, 1, operands+0, operands+3);
6555 split_di (operands+1, 1, operands+1, operands+4);
6556 split_di (operands+2, 1, operands+2, operands+5);")
6557
6558 (define_insn "subdi3_carry_rex64"
6559 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6560 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6561 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6562 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6563 (clobber (reg:CC FLAGS_REG))]
6564 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6565 "sbb{q}\t{%2, %0|%0, %2}"
6566 [(set_attr "type" "alu")
6567 (set_attr "pent_pair" "pu")
6568 (set_attr "mode" "DI")])
6569
6570 (define_insn "*subdi_1_rex64"
6571 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6572 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6573 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6574 (clobber (reg:CC FLAGS_REG))]
6575 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6576 "sub{q}\t{%2, %0|%0, %2}"
6577 [(set_attr "type" "alu")
6578 (set_attr "mode" "DI")])
6579
6580 (define_insn "*subdi_2_rex64"
6581 [(set (reg FLAGS_REG)
6582 (compare
6583 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6584 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6585 (const_int 0)))
6586 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6587 (minus:DI (match_dup 1) (match_dup 2)))]
6588 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6589 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6590 "sub{q}\t{%2, %0|%0, %2}"
6591 [(set_attr "type" "alu")
6592 (set_attr "mode" "DI")])
6593
6594 (define_insn "*subdi_3_rex63"
6595 [(set (reg FLAGS_REG)
6596 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6597 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6598 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6599 (minus:DI (match_dup 1) (match_dup 2)))]
6600 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6601 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6602 "sub{q}\t{%2, %0|%0, %2}"
6603 [(set_attr "type" "alu")
6604 (set_attr "mode" "DI")])
6605
6606 (define_insn "subqi3_carry"
6607 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6608 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6609 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6610 (match_operand:QI 2 "general_operand" "qi,qm"))))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6613 "sbb{b}\t{%2, %0|%0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "pent_pair" "pu")
6616 (set_attr "mode" "QI")])
6617
6618 (define_insn "subhi3_carry"
6619 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6620 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6621 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6622 (match_operand:HI 2 "general_operand" "ri,rm"))))
6623 (clobber (reg:CC FLAGS_REG))]
6624 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6625 "sbb{w}\t{%2, %0|%0, %2}"
6626 [(set_attr "type" "alu")
6627 (set_attr "pent_pair" "pu")
6628 (set_attr "mode" "HI")])
6629
6630 (define_insn "subsi3_carry"
6631 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6632 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6633 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6634 (match_operand:SI 2 "general_operand" "ri,rm"))))
6635 (clobber (reg:CC FLAGS_REG))]
6636 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6637 "sbb{l}\t{%2, %0|%0, %2}"
6638 [(set_attr "type" "alu")
6639 (set_attr "pent_pair" "pu")
6640 (set_attr "mode" "SI")])
6641
6642 (define_insn "subsi3_carry_zext"
6643 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6644 (zero_extend:DI
6645 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6646 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6647 (match_operand:SI 2 "general_operand" "ri,rm")))))
6648 (clobber (reg:CC FLAGS_REG))]
6649 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650 "sbb{l}\t{%2, %k0|%k0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "pent_pair" "pu")
6653 (set_attr "mode" "SI")])
6654
6655 (define_expand "subsi3"
6656 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6657 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6658 (match_operand:SI 2 "general_operand" "")))
6659 (clobber (reg:CC FLAGS_REG))])]
6660 ""
6661 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6662
6663 (define_insn "*subsi_1"
6664 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6665 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6666 (match_operand:SI 2 "general_operand" "ri,rm")))
6667 (clobber (reg:CC FLAGS_REG))]
6668 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6669 "sub{l}\t{%2, %0|%0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "mode" "SI")])
6672
6673 (define_insn "*subsi_1_zext"
6674 [(set (match_operand:DI 0 "register_operand" "=r")
6675 (zero_extend:DI
6676 (minus:SI (match_operand:SI 1 "register_operand" "0")
6677 (match_operand:SI 2 "general_operand" "rim"))))
6678 (clobber (reg:CC FLAGS_REG))]
6679 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6680 "sub{l}\t{%2, %k0|%k0, %2}"
6681 [(set_attr "type" "alu")
6682 (set_attr "mode" "SI")])
6683
6684 (define_insn "*subsi_2"
6685 [(set (reg FLAGS_REG)
6686 (compare
6687 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6688 (match_operand:SI 2 "general_operand" "ri,rm"))
6689 (const_int 0)))
6690 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6691 (minus:SI (match_dup 1) (match_dup 2)))]
6692 "ix86_match_ccmode (insn, CCGOCmode)
6693 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6694 "sub{l}\t{%2, %0|%0, %2}"
6695 [(set_attr "type" "alu")
6696 (set_attr "mode" "SI")])
6697
6698 (define_insn "*subsi_2_zext"
6699 [(set (reg FLAGS_REG)
6700 (compare
6701 (minus:SI (match_operand:SI 1 "register_operand" "0")
6702 (match_operand:SI 2 "general_operand" "rim"))
6703 (const_int 0)))
6704 (set (match_operand:DI 0 "register_operand" "=r")
6705 (zero_extend:DI
6706 (minus:SI (match_dup 1)
6707 (match_dup 2))))]
6708 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6709 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6710 "sub{l}\t{%2, %k0|%k0, %2}"
6711 [(set_attr "type" "alu")
6712 (set_attr "mode" "SI")])
6713
6714 (define_insn "*subsi_3"
6715 [(set (reg FLAGS_REG)
6716 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6717 (match_operand:SI 2 "general_operand" "ri,rm")))
6718 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6719 (minus:SI (match_dup 1) (match_dup 2)))]
6720 "ix86_match_ccmode (insn, CCmode)
6721 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6722 "sub{l}\t{%2, %0|%0, %2}"
6723 [(set_attr "type" "alu")
6724 (set_attr "mode" "SI")])
6725
6726 (define_insn "*subsi_3_zext"
6727 [(set (reg FLAGS_REG)
6728 (compare (match_operand:SI 1 "register_operand" "0")
6729 (match_operand:SI 2 "general_operand" "rim")))
6730 (set (match_operand:DI 0 "register_operand" "=r")
6731 (zero_extend:DI
6732 (minus:SI (match_dup 1)
6733 (match_dup 2))))]
6734 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6735 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6736 "sub{l}\t{%2, %1|%1, %2}"
6737 [(set_attr "type" "alu")
6738 (set_attr "mode" "DI")])
6739
6740 (define_expand "subhi3"
6741 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6742 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6743 (match_operand:HI 2 "general_operand" "")))
6744 (clobber (reg:CC FLAGS_REG))])]
6745 "TARGET_HIMODE_MATH"
6746 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6747
6748 (define_insn "*subhi_1"
6749 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6750 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6751 (match_operand:HI 2 "general_operand" "ri,rm")))
6752 (clobber (reg:CC FLAGS_REG))]
6753 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6754 "sub{w}\t{%2, %0|%0, %2}"
6755 [(set_attr "type" "alu")
6756 (set_attr "mode" "HI")])
6757
6758 (define_insn "*subhi_2"
6759 [(set (reg FLAGS_REG)
6760 (compare
6761 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6762 (match_operand:HI 2 "general_operand" "ri,rm"))
6763 (const_int 0)))
6764 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6765 (minus:HI (match_dup 1) (match_dup 2)))]
6766 "ix86_match_ccmode (insn, CCGOCmode)
6767 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6768 "sub{w}\t{%2, %0|%0, %2}"
6769 [(set_attr "type" "alu")
6770 (set_attr "mode" "HI")])
6771
6772 (define_insn "*subhi_3"
6773 [(set (reg FLAGS_REG)
6774 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6775 (match_operand:HI 2 "general_operand" "ri,rm")))
6776 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6777 (minus:HI (match_dup 1) (match_dup 2)))]
6778 "ix86_match_ccmode (insn, CCmode)
6779 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6780 "sub{w}\t{%2, %0|%0, %2}"
6781 [(set_attr "type" "alu")
6782 (set_attr "mode" "HI")])
6783
6784 (define_expand "subqi3"
6785 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6786 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6787 (match_operand:QI 2 "general_operand" "")))
6788 (clobber (reg:CC FLAGS_REG))])]
6789 "TARGET_QIMODE_MATH"
6790 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6791
6792 (define_insn "*subqi_1"
6793 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6794 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6795 (match_operand:QI 2 "general_operand" "qn,qmn")))
6796 (clobber (reg:CC FLAGS_REG))]
6797 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6798 "sub{b}\t{%2, %0|%0, %2}"
6799 [(set_attr "type" "alu")
6800 (set_attr "mode" "QI")])
6801
6802 (define_insn "*subqi_1_slp"
6803 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6804 (minus:QI (match_dup 0)
6805 (match_operand:QI 1 "general_operand" "qn,qmn")))
6806 (clobber (reg:CC FLAGS_REG))]
6807 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6808 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6809 "sub{b}\t{%1, %0|%0, %1}"
6810 [(set_attr "type" "alu1")
6811 (set_attr "mode" "QI")])
6812
6813 (define_insn "*subqi_2"
6814 [(set (reg FLAGS_REG)
6815 (compare
6816 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6817 (match_operand:QI 2 "general_operand" "qi,qm"))
6818 (const_int 0)))
6819 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6820 (minus:HI (match_dup 1) (match_dup 2)))]
6821 "ix86_match_ccmode (insn, CCGOCmode)
6822 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6823 "sub{b}\t{%2, %0|%0, %2}"
6824 [(set_attr "type" "alu")
6825 (set_attr "mode" "QI")])
6826
6827 (define_insn "*subqi_3"
6828 [(set (reg FLAGS_REG)
6829 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6830 (match_operand:QI 2 "general_operand" "qi,qm")))
6831 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6832 (minus:HI (match_dup 1) (match_dup 2)))]
6833 "ix86_match_ccmode (insn, CCmode)
6834 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6835 "sub{b}\t{%2, %0|%0, %2}"
6836 [(set_attr "type" "alu")
6837 (set_attr "mode" "QI")])
6838
6839 ;; The patterns that match these are at the end of this file.
6840
6841 (define_expand "subxf3"
6842 [(set (match_operand:XF 0 "register_operand" "")
6843 (minus:XF (match_operand:XF 1 "register_operand" "")
6844 (match_operand:XF 2 "register_operand" "")))]
6845 "TARGET_80387"
6846 "")
6847
6848 (define_expand "subdf3"
6849 [(set (match_operand:DF 0 "register_operand" "")
6850 (minus:DF (match_operand:DF 1 "register_operand" "")
6851 (match_operand:DF 2 "nonimmediate_operand" "")))]
6852 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6853 "")
6854
6855 (define_expand "subsf3"
6856 [(set (match_operand:SF 0 "register_operand" "")
6857 (minus:SF (match_operand:SF 1 "register_operand" "")
6858 (match_operand:SF 2 "nonimmediate_operand" "")))]
6859 "TARGET_80387 || TARGET_SSE_MATH"
6860 "")
6861 \f
6862 ;; Multiply instructions
6863
6864 (define_expand "muldi3"
6865 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6866 (mult:DI (match_operand:DI 1 "register_operand" "")
6867 (match_operand:DI 2 "x86_64_general_operand" "")))
6868 (clobber (reg:CC FLAGS_REG))])]
6869 "TARGET_64BIT"
6870 "")
6871
6872 (define_insn "*muldi3_1_rex64"
6873 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6874 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6875 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6876 (clobber (reg:CC FLAGS_REG))]
6877 "TARGET_64BIT
6878 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6879 "@
6880 imul{q}\t{%2, %1, %0|%0, %1, %2}
6881 imul{q}\t{%2, %1, %0|%0, %1, %2}
6882 imul{q}\t{%2, %0|%0, %2}"
6883 [(set_attr "type" "imul")
6884 (set_attr "prefix_0f" "0,0,1")
6885 (set (attr "athlon_decode")
6886 (cond [(eq_attr "cpu" "athlon")
6887 (const_string "vector")
6888 (eq_attr "alternative" "1")
6889 (const_string "vector")
6890 (and (eq_attr "alternative" "2")
6891 (match_operand 1 "memory_operand" ""))
6892 (const_string "vector")]
6893 (const_string "direct")))
6894 (set_attr "mode" "DI")])
6895
6896 (define_expand "mulsi3"
6897 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6898 (mult:SI (match_operand:SI 1 "register_operand" "")
6899 (match_operand:SI 2 "general_operand" "")))
6900 (clobber (reg:CC FLAGS_REG))])]
6901 ""
6902 "")
6903
6904 (define_insn "*mulsi3_1"
6905 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6906 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6907 (match_operand:SI 2 "general_operand" "K,i,mr")))
6908 (clobber (reg:CC FLAGS_REG))]
6909 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6910 "@
6911 imul{l}\t{%2, %1, %0|%0, %1, %2}
6912 imul{l}\t{%2, %1, %0|%0, %1, %2}
6913 imul{l}\t{%2, %0|%0, %2}"
6914 [(set_attr "type" "imul")
6915 (set_attr "prefix_0f" "0,0,1")
6916 (set (attr "athlon_decode")
6917 (cond [(eq_attr "cpu" "athlon")
6918 (const_string "vector")
6919 (eq_attr "alternative" "1")
6920 (const_string "vector")
6921 (and (eq_attr "alternative" "2")
6922 (match_operand 1 "memory_operand" ""))
6923 (const_string "vector")]
6924 (const_string "direct")))
6925 (set_attr "mode" "SI")])
6926
6927 (define_insn "*mulsi3_1_zext"
6928 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6929 (zero_extend:DI
6930 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6931 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6932 (clobber (reg:CC FLAGS_REG))]
6933 "TARGET_64BIT
6934 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6935 "@
6936 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6937 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6938 imul{l}\t{%2, %k0|%k0, %2}"
6939 [(set_attr "type" "imul")
6940 (set_attr "prefix_0f" "0,0,1")
6941 (set (attr "athlon_decode")
6942 (cond [(eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (eq_attr "alternative" "1")
6945 (const_string "vector")
6946 (and (eq_attr "alternative" "2")
6947 (match_operand 1 "memory_operand" ""))
6948 (const_string "vector")]
6949 (const_string "direct")))
6950 (set_attr "mode" "SI")])
6951
6952 (define_expand "mulhi3"
6953 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6954 (mult:HI (match_operand:HI 1 "register_operand" "")
6955 (match_operand:HI 2 "general_operand" "")))
6956 (clobber (reg:CC FLAGS_REG))])]
6957 "TARGET_HIMODE_MATH"
6958 "")
6959
6960 (define_insn "*mulhi3_1"
6961 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6962 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6963 (match_operand:HI 2 "general_operand" "K,i,mr")))
6964 (clobber (reg:CC FLAGS_REG))]
6965 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6966 "@
6967 imul{w}\t{%2, %1, %0|%0, %1, %2}
6968 imul{w}\t{%2, %1, %0|%0, %1, %2}
6969 imul{w}\t{%2, %0|%0, %2}"
6970 [(set_attr "type" "imul")
6971 (set_attr "prefix_0f" "0,0,1")
6972 (set (attr "athlon_decode")
6973 (cond [(eq_attr "cpu" "athlon")
6974 (const_string "vector")
6975 (eq_attr "alternative" "1,2")
6976 (const_string "vector")]
6977 (const_string "direct")))
6978 (set_attr "mode" "HI")])
6979
6980 (define_expand "mulqi3"
6981 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6982 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6983 (match_operand:QI 2 "register_operand" "")))
6984 (clobber (reg:CC FLAGS_REG))])]
6985 "TARGET_QIMODE_MATH"
6986 "")
6987
6988 (define_insn "*mulqi3_1"
6989 [(set (match_operand:QI 0 "register_operand" "=a")
6990 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6991 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6992 (clobber (reg:CC FLAGS_REG))]
6993 "TARGET_QIMODE_MATH
6994 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6995 "mul{b}\t%2"
6996 [(set_attr "type" "imul")
6997 (set_attr "length_immediate" "0")
6998 (set (attr "athlon_decode")
6999 (if_then_else (eq_attr "cpu" "athlon")
7000 (const_string "vector")
7001 (const_string "direct")))
7002 (set_attr "mode" "QI")])
7003
7004 (define_expand "umulqihi3"
7005 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7006 (mult:HI (zero_extend:HI
7007 (match_operand:QI 1 "nonimmediate_operand" ""))
7008 (zero_extend:HI
7009 (match_operand:QI 2 "register_operand" ""))))
7010 (clobber (reg:CC FLAGS_REG))])]
7011 "TARGET_QIMODE_MATH"
7012 "")
7013
7014 (define_insn "*umulqihi3_1"
7015 [(set (match_operand:HI 0 "register_operand" "=a")
7016 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7017 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7018 (clobber (reg:CC FLAGS_REG))]
7019 "TARGET_QIMODE_MATH
7020 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7021 "mul{b}\t%2"
7022 [(set_attr "type" "imul")
7023 (set_attr "length_immediate" "0")
7024 (set (attr "athlon_decode")
7025 (if_then_else (eq_attr "cpu" "athlon")
7026 (const_string "vector")
7027 (const_string "direct")))
7028 (set_attr "mode" "QI")])
7029
7030 (define_expand "mulqihi3"
7031 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7032 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7033 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7034 (clobber (reg:CC FLAGS_REG))])]
7035 "TARGET_QIMODE_MATH"
7036 "")
7037
7038 (define_insn "*mulqihi3_insn"
7039 [(set (match_operand:HI 0 "register_operand" "=a")
7040 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7041 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7042 (clobber (reg:CC FLAGS_REG))]
7043 "TARGET_QIMODE_MATH
7044 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7045 "imul{b}\t%2"
7046 [(set_attr "type" "imul")
7047 (set_attr "length_immediate" "0")
7048 (set (attr "athlon_decode")
7049 (if_then_else (eq_attr "cpu" "athlon")
7050 (const_string "vector")
7051 (const_string "direct")))
7052 (set_attr "mode" "QI")])
7053
7054 (define_expand "umulditi3"
7055 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7056 (mult:TI (zero_extend:TI
7057 (match_operand:DI 1 "nonimmediate_operand" ""))
7058 (zero_extend:TI
7059 (match_operand:DI 2 "register_operand" ""))))
7060 (clobber (reg:CC FLAGS_REG))])]
7061 "TARGET_64BIT"
7062 "")
7063
7064 (define_insn "*umulditi3_insn"
7065 [(set (match_operand:TI 0 "register_operand" "=A")
7066 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7067 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7068 (clobber (reg:CC FLAGS_REG))]
7069 "TARGET_64BIT
7070 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7071 "mul{q}\t%2"
7072 [(set_attr "type" "imul")
7073 (set_attr "length_immediate" "0")
7074 (set (attr "athlon_decode")
7075 (if_then_else (eq_attr "cpu" "athlon")
7076 (const_string "vector")
7077 (const_string "double")))
7078 (set_attr "mode" "DI")])
7079
7080 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7081 (define_expand "umulsidi3"
7082 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7083 (mult:DI (zero_extend:DI
7084 (match_operand:SI 1 "nonimmediate_operand" ""))
7085 (zero_extend:DI
7086 (match_operand:SI 2 "register_operand" ""))))
7087 (clobber (reg:CC FLAGS_REG))])]
7088 "!TARGET_64BIT"
7089 "")
7090
7091 (define_insn "*umulsidi3_insn"
7092 [(set (match_operand:DI 0 "register_operand" "=A")
7093 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7094 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7095 (clobber (reg:CC FLAGS_REG))]
7096 "!TARGET_64BIT
7097 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7098 "mul{l}\t%2"
7099 [(set_attr "type" "imul")
7100 (set_attr "length_immediate" "0")
7101 (set (attr "athlon_decode")
7102 (if_then_else (eq_attr "cpu" "athlon")
7103 (const_string "vector")
7104 (const_string "double")))
7105 (set_attr "mode" "SI")])
7106
7107 (define_expand "mulditi3"
7108 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7109 (mult:TI (sign_extend:TI
7110 (match_operand:DI 1 "nonimmediate_operand" ""))
7111 (sign_extend:TI
7112 (match_operand:DI 2 "register_operand" ""))))
7113 (clobber (reg:CC FLAGS_REG))])]
7114 "TARGET_64BIT"
7115 "")
7116
7117 (define_insn "*mulditi3_insn"
7118 [(set (match_operand:TI 0 "register_operand" "=A")
7119 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7120 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7121 (clobber (reg:CC FLAGS_REG))]
7122 "TARGET_64BIT
7123 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7124 "imul{q}\t%2"
7125 [(set_attr "type" "imul")
7126 (set_attr "length_immediate" "0")
7127 (set (attr "athlon_decode")
7128 (if_then_else (eq_attr "cpu" "athlon")
7129 (const_string "vector")
7130 (const_string "double")))
7131 (set_attr "mode" "DI")])
7132
7133 (define_expand "mulsidi3"
7134 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7135 (mult:DI (sign_extend:DI
7136 (match_operand:SI 1 "nonimmediate_operand" ""))
7137 (sign_extend:DI
7138 (match_operand:SI 2 "register_operand" ""))))
7139 (clobber (reg:CC FLAGS_REG))])]
7140 "!TARGET_64BIT"
7141 "")
7142
7143 (define_insn "*mulsidi3_insn"
7144 [(set (match_operand:DI 0 "register_operand" "=A")
7145 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7146 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7147 (clobber (reg:CC FLAGS_REG))]
7148 "!TARGET_64BIT
7149 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7150 "imul{l}\t%2"
7151 [(set_attr "type" "imul")
7152 (set_attr "length_immediate" "0")
7153 (set (attr "athlon_decode")
7154 (if_then_else (eq_attr "cpu" "athlon")
7155 (const_string "vector")
7156 (const_string "double")))
7157 (set_attr "mode" "SI")])
7158
7159 (define_expand "umuldi3_highpart"
7160 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7161 (truncate:DI
7162 (lshiftrt:TI
7163 (mult:TI (zero_extend:TI
7164 (match_operand:DI 1 "nonimmediate_operand" ""))
7165 (zero_extend:TI
7166 (match_operand:DI 2 "register_operand" "")))
7167 (const_int 64))))
7168 (clobber (match_scratch:DI 3 ""))
7169 (clobber (reg:CC FLAGS_REG))])]
7170 "TARGET_64BIT"
7171 "")
7172
7173 (define_insn "*umuldi3_highpart_rex64"
7174 [(set (match_operand:DI 0 "register_operand" "=d")
7175 (truncate:DI
7176 (lshiftrt:TI
7177 (mult:TI (zero_extend:TI
7178 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7179 (zero_extend:TI
7180 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7181 (const_int 64))))
7182 (clobber (match_scratch:DI 3 "=1"))
7183 (clobber (reg:CC FLAGS_REG))]
7184 "TARGET_64BIT
7185 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7186 "mul{q}\t%2"
7187 [(set_attr "type" "imul")
7188 (set_attr "length_immediate" "0")
7189 (set (attr "athlon_decode")
7190 (if_then_else (eq_attr "cpu" "athlon")
7191 (const_string "vector")
7192 (const_string "double")))
7193 (set_attr "mode" "DI")])
7194
7195 (define_expand "umulsi3_highpart"
7196 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7197 (truncate:SI
7198 (lshiftrt:DI
7199 (mult:DI (zero_extend:DI
7200 (match_operand:SI 1 "nonimmediate_operand" ""))
7201 (zero_extend:DI
7202 (match_operand:SI 2 "register_operand" "")))
7203 (const_int 32))))
7204 (clobber (match_scratch:SI 3 ""))
7205 (clobber (reg:CC FLAGS_REG))])]
7206 ""
7207 "")
7208
7209 (define_insn "*umulsi3_highpart_insn"
7210 [(set (match_operand:SI 0 "register_operand" "=d")
7211 (truncate:SI
7212 (lshiftrt:DI
7213 (mult:DI (zero_extend:DI
7214 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7215 (zero_extend:DI
7216 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7217 (const_int 32))))
7218 (clobber (match_scratch:SI 3 "=1"))
7219 (clobber (reg:CC FLAGS_REG))]
7220 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7221 "mul{l}\t%2"
7222 [(set_attr "type" "imul")
7223 (set_attr "length_immediate" "0")
7224 (set (attr "athlon_decode")
7225 (if_then_else (eq_attr "cpu" "athlon")
7226 (const_string "vector")
7227 (const_string "double")))
7228 (set_attr "mode" "SI")])
7229
7230 (define_insn "*umulsi3_highpart_zext"
7231 [(set (match_operand:DI 0 "register_operand" "=d")
7232 (zero_extend:DI (truncate:SI
7233 (lshiftrt:DI
7234 (mult:DI (zero_extend:DI
7235 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7236 (zero_extend:DI
7237 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7238 (const_int 32)))))
7239 (clobber (match_scratch:SI 3 "=1"))
7240 (clobber (reg:CC FLAGS_REG))]
7241 "TARGET_64BIT
7242 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7243 "mul{l}\t%2"
7244 [(set_attr "type" "imul")
7245 (set_attr "length_immediate" "0")
7246 (set (attr "athlon_decode")
7247 (if_then_else (eq_attr "cpu" "athlon")
7248 (const_string "vector")
7249 (const_string "double")))
7250 (set_attr "mode" "SI")])
7251
7252 (define_expand "smuldi3_highpart"
7253 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7254 (truncate:DI
7255 (lshiftrt:TI
7256 (mult:TI (sign_extend:TI
7257 (match_operand:DI 1 "nonimmediate_operand" ""))
7258 (sign_extend:TI
7259 (match_operand:DI 2 "register_operand" "")))
7260 (const_int 64))))
7261 (clobber (match_scratch:DI 3 ""))
7262 (clobber (reg:CC FLAGS_REG))])]
7263 "TARGET_64BIT"
7264 "")
7265
7266 (define_insn "*smuldi3_highpart_rex64"
7267 [(set (match_operand:DI 0 "register_operand" "=d")
7268 (truncate:DI
7269 (lshiftrt:TI
7270 (mult:TI (sign_extend:TI
7271 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7272 (sign_extend:TI
7273 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7274 (const_int 64))))
7275 (clobber (match_scratch:DI 3 "=1"))
7276 (clobber (reg:CC FLAGS_REG))]
7277 "TARGET_64BIT
7278 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7279 "imul{q}\t%2"
7280 [(set_attr "type" "imul")
7281 (set (attr "athlon_decode")
7282 (if_then_else (eq_attr "cpu" "athlon")
7283 (const_string "vector")
7284 (const_string "double")))
7285 (set_attr "mode" "DI")])
7286
7287 (define_expand "smulsi3_highpart"
7288 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7289 (truncate:SI
7290 (lshiftrt:DI
7291 (mult:DI (sign_extend:DI
7292 (match_operand:SI 1 "nonimmediate_operand" ""))
7293 (sign_extend:DI
7294 (match_operand:SI 2 "register_operand" "")))
7295 (const_int 32))))
7296 (clobber (match_scratch:SI 3 ""))
7297 (clobber (reg:CC FLAGS_REG))])]
7298 ""
7299 "")
7300
7301 (define_insn "*smulsi3_highpart_insn"
7302 [(set (match_operand:SI 0 "register_operand" "=d")
7303 (truncate:SI
7304 (lshiftrt:DI
7305 (mult:DI (sign_extend:DI
7306 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7307 (sign_extend:DI
7308 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7309 (const_int 32))))
7310 (clobber (match_scratch:SI 3 "=1"))
7311 (clobber (reg:CC FLAGS_REG))]
7312 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7313 "imul{l}\t%2"
7314 [(set_attr "type" "imul")
7315 (set (attr "athlon_decode")
7316 (if_then_else (eq_attr "cpu" "athlon")
7317 (const_string "vector")
7318 (const_string "double")))
7319 (set_attr "mode" "SI")])
7320
7321 (define_insn "*smulsi3_highpart_zext"
7322 [(set (match_operand:DI 0 "register_operand" "=d")
7323 (zero_extend:DI (truncate:SI
7324 (lshiftrt:DI
7325 (mult:DI (sign_extend:DI
7326 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7327 (sign_extend:DI
7328 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7329 (const_int 32)))))
7330 (clobber (match_scratch:SI 3 "=1"))
7331 (clobber (reg:CC FLAGS_REG))]
7332 "TARGET_64BIT
7333 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7334 "imul{l}\t%2"
7335 [(set_attr "type" "imul")
7336 (set (attr "athlon_decode")
7337 (if_then_else (eq_attr "cpu" "athlon")
7338 (const_string "vector")
7339 (const_string "double")))
7340 (set_attr "mode" "SI")])
7341
7342 ;; The patterns that match these are at the end of this file.
7343
7344 (define_expand "mulxf3"
7345 [(set (match_operand:XF 0 "register_operand" "")
7346 (mult:XF (match_operand:XF 1 "register_operand" "")
7347 (match_operand:XF 2 "register_operand" "")))]
7348 "TARGET_80387"
7349 "")
7350
7351 (define_expand "muldf3"
7352 [(set (match_operand:DF 0 "register_operand" "")
7353 (mult:DF (match_operand:DF 1 "register_operand" "")
7354 (match_operand:DF 2 "nonimmediate_operand" "")))]
7355 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7356 "")
7357
7358 (define_expand "mulsf3"
7359 [(set (match_operand:SF 0 "register_operand" "")
7360 (mult:SF (match_operand:SF 1 "register_operand" "")
7361 (match_operand:SF 2 "nonimmediate_operand" "")))]
7362 "TARGET_80387 || TARGET_SSE_MATH"
7363 "")
7364 \f
7365 ;; Divide instructions
7366
7367 (define_insn "divqi3"
7368 [(set (match_operand:QI 0 "register_operand" "=a")
7369 (div:QI (match_operand:HI 1 "register_operand" "0")
7370 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7371 (clobber (reg:CC FLAGS_REG))]
7372 "TARGET_QIMODE_MATH"
7373 "idiv{b}\t%2"
7374 [(set_attr "type" "idiv")
7375 (set_attr "mode" "QI")])
7376
7377 (define_insn "udivqi3"
7378 [(set (match_operand:QI 0 "register_operand" "=a")
7379 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7380 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7381 (clobber (reg:CC FLAGS_REG))]
7382 "TARGET_QIMODE_MATH"
7383 "div{b}\t%2"
7384 [(set_attr "type" "idiv")
7385 (set_attr "mode" "QI")])
7386
7387 ;; The patterns that match these are at the end of this file.
7388
7389 (define_expand "divxf3"
7390 [(set (match_operand:XF 0 "register_operand" "")
7391 (div:XF (match_operand:XF 1 "register_operand" "")
7392 (match_operand:XF 2 "register_operand" "")))]
7393 "TARGET_80387"
7394 "")
7395
7396 (define_expand "divdf3"
7397 [(set (match_operand:DF 0 "register_operand" "")
7398 (div:DF (match_operand:DF 1 "register_operand" "")
7399 (match_operand:DF 2 "nonimmediate_operand" "")))]
7400 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7401 "")
7402
7403 (define_expand "divsf3"
7404 [(set (match_operand:SF 0 "register_operand" "")
7405 (div:SF (match_operand:SF 1 "register_operand" "")
7406 (match_operand:SF 2 "nonimmediate_operand" "")))]
7407 "TARGET_80387 || TARGET_SSE_MATH"
7408 "")
7409 \f
7410 ;; Remainder instructions.
7411
7412 (define_expand "divmoddi4"
7413 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7414 (div:DI (match_operand:DI 1 "register_operand" "")
7415 (match_operand:DI 2 "nonimmediate_operand" "")))
7416 (set (match_operand:DI 3 "register_operand" "")
7417 (mod:DI (match_dup 1) (match_dup 2)))
7418 (clobber (reg:CC FLAGS_REG))])]
7419 "TARGET_64BIT"
7420 "")
7421
7422 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7423 ;; Penalize eax case slightly because it results in worse scheduling
7424 ;; of code.
7425 (define_insn "*divmoddi4_nocltd_rex64"
7426 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7427 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7428 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7429 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7430 (mod:DI (match_dup 2) (match_dup 3)))
7431 (clobber (reg:CC FLAGS_REG))]
7432 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7433 "#"
7434 [(set_attr "type" "multi")])
7435
7436 (define_insn "*divmoddi4_cltd_rex64"
7437 [(set (match_operand:DI 0 "register_operand" "=a")
7438 (div:DI (match_operand:DI 2 "register_operand" "a")
7439 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7440 (set (match_operand:DI 1 "register_operand" "=&d")
7441 (mod:DI (match_dup 2) (match_dup 3)))
7442 (clobber (reg:CC FLAGS_REG))]
7443 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7444 "#"
7445 [(set_attr "type" "multi")])
7446
7447 (define_insn "*divmoddi_noext_rex64"
7448 [(set (match_operand:DI 0 "register_operand" "=a")
7449 (div:DI (match_operand:DI 1 "register_operand" "0")
7450 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7451 (set (match_operand:DI 3 "register_operand" "=d")
7452 (mod:DI (match_dup 1) (match_dup 2)))
7453 (use (match_operand:DI 4 "register_operand" "3"))
7454 (clobber (reg:CC FLAGS_REG))]
7455 "TARGET_64BIT"
7456 "idiv{q}\t%2"
7457 [(set_attr "type" "idiv")
7458 (set_attr "mode" "DI")])
7459
7460 (define_split
7461 [(set (match_operand:DI 0 "register_operand" "")
7462 (div:DI (match_operand:DI 1 "register_operand" "")
7463 (match_operand:DI 2 "nonimmediate_operand" "")))
7464 (set (match_operand:DI 3 "register_operand" "")
7465 (mod:DI (match_dup 1) (match_dup 2)))
7466 (clobber (reg:CC FLAGS_REG))]
7467 "TARGET_64BIT && reload_completed"
7468 [(parallel [(set (match_dup 3)
7469 (ashiftrt:DI (match_dup 4) (const_int 63)))
7470 (clobber (reg:CC FLAGS_REG))])
7471 (parallel [(set (match_dup 0)
7472 (div:DI (reg:DI 0) (match_dup 2)))
7473 (set (match_dup 3)
7474 (mod:DI (reg:DI 0) (match_dup 2)))
7475 (use (match_dup 3))
7476 (clobber (reg:CC FLAGS_REG))])]
7477 {
7478 /* Avoid use of cltd in favor of a mov+shift. */
7479 if (!TARGET_USE_CLTD && !optimize_size)
7480 {
7481 if (true_regnum (operands[1]))
7482 emit_move_insn (operands[0], operands[1]);
7483 else
7484 emit_move_insn (operands[3], operands[1]);
7485 operands[4] = operands[3];
7486 }
7487 else
7488 {
7489 gcc_assert (!true_regnum (operands[1]));
7490 operands[4] = operands[1];
7491 }
7492 })
7493
7494
7495 (define_expand "divmodsi4"
7496 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7497 (div:SI (match_operand:SI 1 "register_operand" "")
7498 (match_operand:SI 2 "nonimmediate_operand" "")))
7499 (set (match_operand:SI 3 "register_operand" "")
7500 (mod:SI (match_dup 1) (match_dup 2)))
7501 (clobber (reg:CC FLAGS_REG))])]
7502 ""
7503 "")
7504
7505 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7506 ;; Penalize eax case slightly because it results in worse scheduling
7507 ;; of code.
7508 (define_insn "*divmodsi4_nocltd"
7509 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7510 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7511 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7512 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7513 (mod:SI (match_dup 2) (match_dup 3)))
7514 (clobber (reg:CC FLAGS_REG))]
7515 "!optimize_size && !TARGET_USE_CLTD"
7516 "#"
7517 [(set_attr "type" "multi")])
7518
7519 (define_insn "*divmodsi4_cltd"
7520 [(set (match_operand:SI 0 "register_operand" "=a")
7521 (div:SI (match_operand:SI 2 "register_operand" "a")
7522 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7523 (set (match_operand:SI 1 "register_operand" "=&d")
7524 (mod:SI (match_dup 2) (match_dup 3)))
7525 (clobber (reg:CC FLAGS_REG))]
7526 "optimize_size || TARGET_USE_CLTD"
7527 "#"
7528 [(set_attr "type" "multi")])
7529
7530 (define_insn "*divmodsi_noext"
7531 [(set (match_operand:SI 0 "register_operand" "=a")
7532 (div:SI (match_operand:SI 1 "register_operand" "0")
7533 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7534 (set (match_operand:SI 3 "register_operand" "=d")
7535 (mod:SI (match_dup 1) (match_dup 2)))
7536 (use (match_operand:SI 4 "register_operand" "3"))
7537 (clobber (reg:CC FLAGS_REG))]
7538 ""
7539 "idiv{l}\t%2"
7540 [(set_attr "type" "idiv")
7541 (set_attr "mode" "SI")])
7542
7543 (define_split
7544 [(set (match_operand:SI 0 "register_operand" "")
7545 (div:SI (match_operand:SI 1 "register_operand" "")
7546 (match_operand:SI 2 "nonimmediate_operand" "")))
7547 (set (match_operand:SI 3 "register_operand" "")
7548 (mod:SI (match_dup 1) (match_dup 2)))
7549 (clobber (reg:CC FLAGS_REG))]
7550 "reload_completed"
7551 [(parallel [(set (match_dup 3)
7552 (ashiftrt:SI (match_dup 4) (const_int 31)))
7553 (clobber (reg:CC FLAGS_REG))])
7554 (parallel [(set (match_dup 0)
7555 (div:SI (reg:SI 0) (match_dup 2)))
7556 (set (match_dup 3)
7557 (mod:SI (reg:SI 0) (match_dup 2)))
7558 (use (match_dup 3))
7559 (clobber (reg:CC FLAGS_REG))])]
7560 {
7561 /* Avoid use of cltd in favor of a mov+shift. */
7562 if (!TARGET_USE_CLTD && !optimize_size)
7563 {
7564 if (true_regnum (operands[1]))
7565 emit_move_insn (operands[0], operands[1]);
7566 else
7567 emit_move_insn (operands[3], operands[1]);
7568 operands[4] = operands[3];
7569 }
7570 else
7571 {
7572 gcc_assert (!true_regnum (operands[1]));
7573 operands[4] = operands[1];
7574 }
7575 })
7576 ;; %%% Split me.
7577 (define_insn "divmodhi4"
7578 [(set (match_operand:HI 0 "register_operand" "=a")
7579 (div:HI (match_operand:HI 1 "register_operand" "0")
7580 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7581 (set (match_operand:HI 3 "register_operand" "=&d")
7582 (mod:HI (match_dup 1) (match_dup 2)))
7583 (clobber (reg:CC FLAGS_REG))]
7584 "TARGET_HIMODE_MATH"
7585 "cwtd\;idiv{w}\t%2"
7586 [(set_attr "type" "multi")
7587 (set_attr "length_immediate" "0")
7588 (set_attr "mode" "SI")])
7589
7590 (define_insn "udivmoddi4"
7591 [(set (match_operand:DI 0 "register_operand" "=a")
7592 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7593 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7594 (set (match_operand:DI 3 "register_operand" "=&d")
7595 (umod:DI (match_dup 1) (match_dup 2)))
7596 (clobber (reg:CC FLAGS_REG))]
7597 "TARGET_64BIT"
7598 "xor{q}\t%3, %3\;div{q}\t%2"
7599 [(set_attr "type" "multi")
7600 (set_attr "length_immediate" "0")
7601 (set_attr "mode" "DI")])
7602
7603 (define_insn "*udivmoddi4_noext"
7604 [(set (match_operand:DI 0 "register_operand" "=a")
7605 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7606 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7607 (set (match_operand:DI 3 "register_operand" "=d")
7608 (umod:DI (match_dup 1) (match_dup 2)))
7609 (use (match_dup 3))
7610 (clobber (reg:CC FLAGS_REG))]
7611 "TARGET_64BIT"
7612 "div{q}\t%2"
7613 [(set_attr "type" "idiv")
7614 (set_attr "mode" "DI")])
7615
7616 (define_split
7617 [(set (match_operand:DI 0 "register_operand" "")
7618 (udiv:DI (match_operand:DI 1 "register_operand" "")
7619 (match_operand:DI 2 "nonimmediate_operand" "")))
7620 (set (match_operand:DI 3 "register_operand" "")
7621 (umod:DI (match_dup 1) (match_dup 2)))
7622 (clobber (reg:CC FLAGS_REG))]
7623 "TARGET_64BIT && reload_completed"
7624 [(set (match_dup 3) (const_int 0))
7625 (parallel [(set (match_dup 0)
7626 (udiv:DI (match_dup 1) (match_dup 2)))
7627 (set (match_dup 3)
7628 (umod:DI (match_dup 1) (match_dup 2)))
7629 (use (match_dup 3))
7630 (clobber (reg:CC FLAGS_REG))])]
7631 "")
7632
7633 (define_insn "udivmodsi4"
7634 [(set (match_operand:SI 0 "register_operand" "=a")
7635 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7636 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7637 (set (match_operand:SI 3 "register_operand" "=&d")
7638 (umod:SI (match_dup 1) (match_dup 2)))
7639 (clobber (reg:CC FLAGS_REG))]
7640 ""
7641 "xor{l}\t%3, %3\;div{l}\t%2"
7642 [(set_attr "type" "multi")
7643 (set_attr "length_immediate" "0")
7644 (set_attr "mode" "SI")])
7645
7646 (define_insn "*udivmodsi4_noext"
7647 [(set (match_operand:SI 0 "register_operand" "=a")
7648 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7649 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7650 (set (match_operand:SI 3 "register_operand" "=d")
7651 (umod:SI (match_dup 1) (match_dup 2)))
7652 (use (match_dup 3))
7653 (clobber (reg:CC FLAGS_REG))]
7654 ""
7655 "div{l}\t%2"
7656 [(set_attr "type" "idiv")
7657 (set_attr "mode" "SI")])
7658
7659 (define_split
7660 [(set (match_operand:SI 0 "register_operand" "")
7661 (udiv:SI (match_operand:SI 1 "register_operand" "")
7662 (match_operand:SI 2 "nonimmediate_operand" "")))
7663 (set (match_operand:SI 3 "register_operand" "")
7664 (umod:SI (match_dup 1) (match_dup 2)))
7665 (clobber (reg:CC FLAGS_REG))]
7666 "reload_completed"
7667 [(set (match_dup 3) (const_int 0))
7668 (parallel [(set (match_dup 0)
7669 (udiv:SI (match_dup 1) (match_dup 2)))
7670 (set (match_dup 3)
7671 (umod:SI (match_dup 1) (match_dup 2)))
7672 (use (match_dup 3))
7673 (clobber (reg:CC FLAGS_REG))])]
7674 "")
7675
7676 (define_expand "udivmodhi4"
7677 [(set (match_dup 4) (const_int 0))
7678 (parallel [(set (match_operand:HI 0 "register_operand" "")
7679 (udiv:HI (match_operand:HI 1 "register_operand" "")
7680 (match_operand:HI 2 "nonimmediate_operand" "")))
7681 (set (match_operand:HI 3 "register_operand" "")
7682 (umod:HI (match_dup 1) (match_dup 2)))
7683 (use (match_dup 4))
7684 (clobber (reg:CC FLAGS_REG))])]
7685 "TARGET_HIMODE_MATH"
7686 "operands[4] = gen_reg_rtx (HImode);")
7687
7688 (define_insn "*udivmodhi_noext"
7689 [(set (match_operand:HI 0 "register_operand" "=a")
7690 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7691 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7692 (set (match_operand:HI 3 "register_operand" "=d")
7693 (umod:HI (match_dup 1) (match_dup 2)))
7694 (use (match_operand:HI 4 "register_operand" "3"))
7695 (clobber (reg:CC FLAGS_REG))]
7696 ""
7697 "div{w}\t%2"
7698 [(set_attr "type" "idiv")
7699 (set_attr "mode" "HI")])
7700
7701 ;; We cannot use div/idiv for double division, because it causes
7702 ;; "division by zero" on the overflow and that's not what we expect
7703 ;; from truncate. Because true (non truncating) double division is
7704 ;; never generated, we can't create this insn anyway.
7705 ;
7706 ;(define_insn ""
7707 ; [(set (match_operand:SI 0 "register_operand" "=a")
7708 ; (truncate:SI
7709 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7710 ; (zero_extend:DI
7711 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7712 ; (set (match_operand:SI 3 "register_operand" "=d")
7713 ; (truncate:SI
7714 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7715 ; (clobber (reg:CC FLAGS_REG))]
7716 ; ""
7717 ; "div{l}\t{%2, %0|%0, %2}"
7718 ; [(set_attr "type" "idiv")])
7719 \f
7720 ;;- Logical AND instructions
7721
7722 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7723 ;; Note that this excludes ah.
7724
7725 (define_insn "*testdi_1_rex64"
7726 [(set (reg FLAGS_REG)
7727 (compare
7728 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7729 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7730 (const_int 0)))]
7731 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7732 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7733 "@
7734 test{l}\t{%k1, %k0|%k0, %k1}
7735 test{l}\t{%k1, %k0|%k0, %k1}
7736 test{q}\t{%1, %0|%0, %1}
7737 test{q}\t{%1, %0|%0, %1}
7738 test{q}\t{%1, %0|%0, %1}"
7739 [(set_attr "type" "test")
7740 (set_attr "modrm" "0,1,0,1,1")
7741 (set_attr "mode" "SI,SI,DI,DI,DI")
7742 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7743
7744 (define_insn "testsi_1"
7745 [(set (reg FLAGS_REG)
7746 (compare
7747 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7748 (match_operand:SI 1 "general_operand" "in,in,rin"))
7749 (const_int 0)))]
7750 "ix86_match_ccmode (insn, CCNOmode)
7751 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7752 "test{l}\t{%1, %0|%0, %1}"
7753 [(set_attr "type" "test")
7754 (set_attr "modrm" "0,1,1")
7755 (set_attr "mode" "SI")
7756 (set_attr "pent_pair" "uv,np,uv")])
7757
7758 (define_expand "testsi_ccno_1"
7759 [(set (reg:CCNO FLAGS_REG)
7760 (compare:CCNO
7761 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7762 (match_operand:SI 1 "nonmemory_operand" ""))
7763 (const_int 0)))]
7764 ""
7765 "")
7766
7767 (define_insn "*testhi_1"
7768 [(set (reg FLAGS_REG)
7769 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7770 (match_operand:HI 1 "general_operand" "n,n,rn"))
7771 (const_int 0)))]
7772 "ix86_match_ccmode (insn, CCNOmode)
7773 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7774 "test{w}\t{%1, %0|%0, %1}"
7775 [(set_attr "type" "test")
7776 (set_attr "modrm" "0,1,1")
7777 (set_attr "mode" "HI")
7778 (set_attr "pent_pair" "uv,np,uv")])
7779
7780 (define_expand "testqi_ccz_1"
7781 [(set (reg:CCZ FLAGS_REG)
7782 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7783 (match_operand:QI 1 "nonmemory_operand" ""))
7784 (const_int 0)))]
7785 ""
7786 "")
7787
7788 (define_insn "*testqi_1_maybe_si"
7789 [(set (reg FLAGS_REG)
7790 (compare
7791 (and:QI
7792 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7793 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7794 (const_int 0)))]
7795 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7796 && ix86_match_ccmode (insn,
7797 GET_CODE (operands[1]) == CONST_INT
7798 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7799 {
7800 if (which_alternative == 3)
7801 {
7802 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7803 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7804 return "test{l}\t{%1, %k0|%k0, %1}";
7805 }
7806 return "test{b}\t{%1, %0|%0, %1}";
7807 }
7808 [(set_attr "type" "test")
7809 (set_attr "modrm" "0,1,1,1")
7810 (set_attr "mode" "QI,QI,QI,SI")
7811 (set_attr "pent_pair" "uv,np,uv,np")])
7812
7813 (define_insn "*testqi_1"
7814 [(set (reg FLAGS_REG)
7815 (compare
7816 (and:QI
7817 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7818 (match_operand:QI 1 "general_operand" "n,n,qn"))
7819 (const_int 0)))]
7820 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7821 && ix86_match_ccmode (insn, CCNOmode)"
7822 "test{b}\t{%1, %0|%0, %1}"
7823 [(set_attr "type" "test")
7824 (set_attr "modrm" "0,1,1")
7825 (set_attr "mode" "QI")
7826 (set_attr "pent_pair" "uv,np,uv")])
7827
7828 (define_expand "testqi_ext_ccno_0"
7829 [(set (reg:CCNO FLAGS_REG)
7830 (compare:CCNO
7831 (and:SI
7832 (zero_extract:SI
7833 (match_operand 0 "ext_register_operand" "")
7834 (const_int 8)
7835 (const_int 8))
7836 (match_operand 1 "const_int_operand" ""))
7837 (const_int 0)))]
7838 ""
7839 "")
7840
7841 (define_insn "*testqi_ext_0"
7842 [(set (reg FLAGS_REG)
7843 (compare
7844 (and:SI
7845 (zero_extract:SI
7846 (match_operand 0 "ext_register_operand" "Q")
7847 (const_int 8)
7848 (const_int 8))
7849 (match_operand 1 "const_int_operand" "n"))
7850 (const_int 0)))]
7851 "ix86_match_ccmode (insn, CCNOmode)"
7852 "test{b}\t{%1, %h0|%h0, %1}"
7853 [(set_attr "type" "test")
7854 (set_attr "mode" "QI")
7855 (set_attr "length_immediate" "1")
7856 (set_attr "pent_pair" "np")])
7857
7858 (define_insn "*testqi_ext_1"
7859 [(set (reg FLAGS_REG)
7860 (compare
7861 (and:SI
7862 (zero_extract:SI
7863 (match_operand 0 "ext_register_operand" "Q")
7864 (const_int 8)
7865 (const_int 8))
7866 (zero_extend:SI
7867 (match_operand:QI 1 "general_operand" "Qm")))
7868 (const_int 0)))]
7869 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7870 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7871 "test{b}\t{%1, %h0|%h0, %1}"
7872 [(set_attr "type" "test")
7873 (set_attr "mode" "QI")])
7874
7875 (define_insn "*testqi_ext_1_rex64"
7876 [(set (reg FLAGS_REG)
7877 (compare
7878 (and:SI
7879 (zero_extract:SI
7880 (match_operand 0 "ext_register_operand" "Q")
7881 (const_int 8)
7882 (const_int 8))
7883 (zero_extend:SI
7884 (match_operand:QI 1 "register_operand" "Q")))
7885 (const_int 0)))]
7886 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7887 "test{b}\t{%1, %h0|%h0, %1}"
7888 [(set_attr "type" "test")
7889 (set_attr "mode" "QI")])
7890
7891 (define_insn "*testqi_ext_2"
7892 [(set (reg FLAGS_REG)
7893 (compare
7894 (and:SI
7895 (zero_extract:SI
7896 (match_operand 0 "ext_register_operand" "Q")
7897 (const_int 8)
7898 (const_int 8))
7899 (zero_extract:SI
7900 (match_operand 1 "ext_register_operand" "Q")
7901 (const_int 8)
7902 (const_int 8)))
7903 (const_int 0)))]
7904 "ix86_match_ccmode (insn, CCNOmode)"
7905 "test{b}\t{%h1, %h0|%h0, %h1}"
7906 [(set_attr "type" "test")
7907 (set_attr "mode" "QI")])
7908
7909 ;; Combine likes to form bit extractions for some tests. Humor it.
7910 (define_insn "*testqi_ext_3"
7911 [(set (reg FLAGS_REG)
7912 (compare (zero_extract:SI
7913 (match_operand 0 "nonimmediate_operand" "rm")
7914 (match_operand:SI 1 "const_int_operand" "")
7915 (match_operand:SI 2 "const_int_operand" ""))
7916 (const_int 0)))]
7917 "ix86_match_ccmode (insn, CCNOmode)
7918 && INTVAL (operands[1]) > 0
7919 && INTVAL (operands[2]) >= 0
7920 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7921 && (GET_MODE (operands[0]) == SImode
7922 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7923 || GET_MODE (operands[0]) == HImode
7924 || GET_MODE (operands[0]) == QImode)"
7925 "#")
7926
7927 (define_insn "*testqi_ext_3_rex64"
7928 [(set (reg FLAGS_REG)
7929 (compare (zero_extract:DI
7930 (match_operand 0 "nonimmediate_operand" "rm")
7931 (match_operand:DI 1 "const_int_operand" "")
7932 (match_operand:DI 2 "const_int_operand" ""))
7933 (const_int 0)))]
7934 "TARGET_64BIT
7935 && ix86_match_ccmode (insn, CCNOmode)
7936 && INTVAL (operands[1]) > 0
7937 && INTVAL (operands[2]) >= 0
7938 /* Ensure that resulting mask is zero or sign extended operand. */
7939 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7940 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7941 && INTVAL (operands[1]) > 32))
7942 && (GET_MODE (operands[0]) == SImode
7943 || GET_MODE (operands[0]) == DImode
7944 || GET_MODE (operands[0]) == HImode
7945 || GET_MODE (operands[0]) == QImode)"
7946 "#")
7947
7948 (define_split
7949 [(set (match_operand 0 "flags_reg_operand" "")
7950 (match_operator 1 "compare_operator"
7951 [(zero_extract
7952 (match_operand 2 "nonimmediate_operand" "")
7953 (match_operand 3 "const_int_operand" "")
7954 (match_operand 4 "const_int_operand" ""))
7955 (const_int 0)]))]
7956 "ix86_match_ccmode (insn, CCNOmode)"
7957 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7958 {
7959 rtx val = operands[2];
7960 HOST_WIDE_INT len = INTVAL (operands[3]);
7961 HOST_WIDE_INT pos = INTVAL (operands[4]);
7962 HOST_WIDE_INT mask;
7963 enum machine_mode mode, submode;
7964
7965 mode = GET_MODE (val);
7966 if (GET_CODE (val) == MEM)
7967 {
7968 /* ??? Combine likes to put non-volatile mem extractions in QImode
7969 no matter the size of the test. So find a mode that works. */
7970 if (! MEM_VOLATILE_P (val))
7971 {
7972 mode = smallest_mode_for_size (pos + len, MODE_INT);
7973 val = adjust_address (val, mode, 0);
7974 }
7975 }
7976 else if (GET_CODE (val) == SUBREG
7977 && (submode = GET_MODE (SUBREG_REG (val)),
7978 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7979 && pos + len <= GET_MODE_BITSIZE (submode))
7980 {
7981 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7982 mode = submode;
7983 val = SUBREG_REG (val);
7984 }
7985 else if (mode == HImode && pos + len <= 8)
7986 {
7987 /* Small HImode tests can be converted to QImode. */
7988 mode = QImode;
7989 val = gen_lowpart (QImode, val);
7990 }
7991
7992 if (len == HOST_BITS_PER_WIDE_INT)
7993 mask = -1;
7994 else
7995 mask = ((HOST_WIDE_INT)1 << len) - 1;
7996 mask <<= pos;
7997
7998 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7999 })
8000
8001 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8002 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8003 ;; this is relatively important trick.
8004 ;; Do the conversion only post-reload to avoid limiting of the register class
8005 ;; to QI regs.
8006 (define_split
8007 [(set (match_operand 0 "flags_reg_operand" "")
8008 (match_operator 1 "compare_operator"
8009 [(and (match_operand 2 "register_operand" "")
8010 (match_operand 3 "const_int_operand" ""))
8011 (const_int 0)]))]
8012 "reload_completed
8013 && QI_REG_P (operands[2])
8014 && GET_MODE (operands[2]) != QImode
8015 && ((ix86_match_ccmode (insn, CCZmode)
8016 && !(INTVAL (operands[3]) & ~(255 << 8)))
8017 || (ix86_match_ccmode (insn, CCNOmode)
8018 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8019 [(set (match_dup 0)
8020 (match_op_dup 1
8021 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8022 (match_dup 3))
8023 (const_int 0)]))]
8024 "operands[2] = gen_lowpart (SImode, operands[2]);
8025 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8026
8027 (define_split
8028 [(set (match_operand 0 "flags_reg_operand" "")
8029 (match_operator 1 "compare_operator"
8030 [(and (match_operand 2 "nonimmediate_operand" "")
8031 (match_operand 3 "const_int_operand" ""))
8032 (const_int 0)]))]
8033 "reload_completed
8034 && GET_MODE (operands[2]) != QImode
8035 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8036 && ((ix86_match_ccmode (insn, CCZmode)
8037 && !(INTVAL (operands[3]) & ~255))
8038 || (ix86_match_ccmode (insn, CCNOmode)
8039 && !(INTVAL (operands[3]) & ~127)))"
8040 [(set (match_dup 0)
8041 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8042 (const_int 0)]))]
8043 "operands[2] = gen_lowpart (QImode, operands[2]);
8044 operands[3] = gen_lowpart (QImode, operands[3]);")
8045
8046
8047 ;; %%% This used to optimize known byte-wide and operations to memory,
8048 ;; and sometimes to QImode registers. If this is considered useful,
8049 ;; it should be done with splitters.
8050
8051 (define_expand "anddi3"
8052 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8053 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8054 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8055 (clobber (reg:CC FLAGS_REG))]
8056 "TARGET_64BIT"
8057 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8058
8059 (define_insn "*anddi_1_rex64"
8060 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8061 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8062 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8063 (clobber (reg:CC FLAGS_REG))]
8064 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8065 {
8066 switch (get_attr_type (insn))
8067 {
8068 case TYPE_IMOVX:
8069 {
8070 enum machine_mode mode;
8071
8072 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8073 if (INTVAL (operands[2]) == 0xff)
8074 mode = QImode;
8075 else
8076 {
8077 gcc_assert (INTVAL (operands[2]) == 0xffff);
8078 mode = HImode;
8079 }
8080
8081 operands[1] = gen_lowpart (mode, operands[1]);
8082 if (mode == QImode)
8083 return "movz{bq|x}\t{%1,%0|%0, %1}";
8084 else
8085 return "movz{wq|x}\t{%1,%0|%0, %1}";
8086 }
8087
8088 default:
8089 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8090 if (get_attr_mode (insn) == MODE_SI)
8091 return "and{l}\t{%k2, %k0|%k0, %k2}";
8092 else
8093 return "and{q}\t{%2, %0|%0, %2}";
8094 }
8095 }
8096 [(set_attr "type" "alu,alu,alu,imovx")
8097 (set_attr "length_immediate" "*,*,*,0")
8098 (set_attr "mode" "SI,DI,DI,DI")])
8099
8100 (define_insn "*anddi_2"
8101 [(set (reg FLAGS_REG)
8102 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8103 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8104 (const_int 0)))
8105 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8106 (and:DI (match_dup 1) (match_dup 2)))]
8107 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8108 && ix86_binary_operator_ok (AND, DImode, operands)"
8109 "@
8110 and{l}\t{%k2, %k0|%k0, %k2}
8111 and{q}\t{%2, %0|%0, %2}
8112 and{q}\t{%2, %0|%0, %2}"
8113 [(set_attr "type" "alu")
8114 (set_attr "mode" "SI,DI,DI")])
8115
8116 (define_expand "andsi3"
8117 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8118 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8119 (match_operand:SI 2 "general_operand" "")))
8120 (clobber (reg:CC FLAGS_REG))]
8121 ""
8122 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8123
8124 (define_insn "*andsi_1"
8125 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8126 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8127 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8128 (clobber (reg:CC FLAGS_REG))]
8129 "ix86_binary_operator_ok (AND, SImode, operands)"
8130 {
8131 switch (get_attr_type (insn))
8132 {
8133 case TYPE_IMOVX:
8134 {
8135 enum machine_mode mode;
8136
8137 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8138 if (INTVAL (operands[2]) == 0xff)
8139 mode = QImode;
8140 else
8141 {
8142 gcc_assert (INTVAL (operands[2]) == 0xffff);
8143 mode = HImode;
8144 }
8145
8146 operands[1] = gen_lowpart (mode, operands[1]);
8147 if (mode == QImode)
8148 return "movz{bl|x}\t{%1,%0|%0, %1}";
8149 else
8150 return "movz{wl|x}\t{%1,%0|%0, %1}";
8151 }
8152
8153 default:
8154 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8155 return "and{l}\t{%2, %0|%0, %2}";
8156 }
8157 }
8158 [(set_attr "type" "alu,alu,imovx")
8159 (set_attr "length_immediate" "*,*,0")
8160 (set_attr "mode" "SI")])
8161
8162 (define_split
8163 [(set (match_operand 0 "register_operand" "")
8164 (and (match_dup 0)
8165 (const_int -65536)))
8166 (clobber (reg:CC FLAGS_REG))]
8167 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8168 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8169 "operands[1] = gen_lowpart (HImode, operands[0]);")
8170
8171 (define_split
8172 [(set (match_operand 0 "ext_register_operand" "")
8173 (and (match_dup 0)
8174 (const_int -256)))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8177 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8178 "operands[1] = gen_lowpart (QImode, operands[0]);")
8179
8180 (define_split
8181 [(set (match_operand 0 "ext_register_operand" "")
8182 (and (match_dup 0)
8183 (const_int -65281)))
8184 (clobber (reg:CC FLAGS_REG))]
8185 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8186 [(parallel [(set (zero_extract:SI (match_dup 0)
8187 (const_int 8)
8188 (const_int 8))
8189 (xor:SI
8190 (zero_extract:SI (match_dup 0)
8191 (const_int 8)
8192 (const_int 8))
8193 (zero_extract:SI (match_dup 0)
8194 (const_int 8)
8195 (const_int 8))))
8196 (clobber (reg:CC FLAGS_REG))])]
8197 "operands[0] = gen_lowpart (SImode, operands[0]);")
8198
8199 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8200 (define_insn "*andsi_1_zext"
8201 [(set (match_operand:DI 0 "register_operand" "=r")
8202 (zero_extend:DI
8203 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8204 (match_operand:SI 2 "general_operand" "rim"))))
8205 (clobber (reg:CC FLAGS_REG))]
8206 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8207 "and{l}\t{%2, %k0|%k0, %2}"
8208 [(set_attr "type" "alu")
8209 (set_attr "mode" "SI")])
8210
8211 (define_insn "*andsi_2"
8212 [(set (reg FLAGS_REG)
8213 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8214 (match_operand:SI 2 "general_operand" "rim,ri"))
8215 (const_int 0)))
8216 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8217 (and:SI (match_dup 1) (match_dup 2)))]
8218 "ix86_match_ccmode (insn, CCNOmode)
8219 && ix86_binary_operator_ok (AND, SImode, operands)"
8220 "and{l}\t{%2, %0|%0, %2}"
8221 [(set_attr "type" "alu")
8222 (set_attr "mode" "SI")])
8223
8224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8225 (define_insn "*andsi_2_zext"
8226 [(set (reg FLAGS_REG)
8227 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8228 (match_operand:SI 2 "general_operand" "rim"))
8229 (const_int 0)))
8230 (set (match_operand:DI 0 "register_operand" "=r")
8231 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8232 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8233 && ix86_binary_operator_ok (AND, SImode, operands)"
8234 "and{l}\t{%2, %k0|%k0, %2}"
8235 [(set_attr "type" "alu")
8236 (set_attr "mode" "SI")])
8237
8238 (define_expand "andhi3"
8239 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8240 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8241 (match_operand:HI 2 "general_operand" "")))
8242 (clobber (reg:CC FLAGS_REG))]
8243 "TARGET_HIMODE_MATH"
8244 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8245
8246 (define_insn "*andhi_1"
8247 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8248 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8249 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8250 (clobber (reg:CC FLAGS_REG))]
8251 "ix86_binary_operator_ok (AND, HImode, operands)"
8252 {
8253 switch (get_attr_type (insn))
8254 {
8255 case TYPE_IMOVX:
8256 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8257 gcc_assert (INTVAL (operands[2]) == 0xff);
8258 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8259
8260 default:
8261 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8262
8263 return "and{w}\t{%2, %0|%0, %2}";
8264 }
8265 }
8266 [(set_attr "type" "alu,alu,imovx")
8267 (set_attr "length_immediate" "*,*,0")
8268 (set_attr "mode" "HI,HI,SI")])
8269
8270 (define_insn "*andhi_2"
8271 [(set (reg FLAGS_REG)
8272 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8273 (match_operand:HI 2 "general_operand" "rim,ri"))
8274 (const_int 0)))
8275 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8276 (and:HI (match_dup 1) (match_dup 2)))]
8277 "ix86_match_ccmode (insn, CCNOmode)
8278 && ix86_binary_operator_ok (AND, HImode, operands)"
8279 "and{w}\t{%2, %0|%0, %2}"
8280 [(set_attr "type" "alu")
8281 (set_attr "mode" "HI")])
8282
8283 (define_expand "andqi3"
8284 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8285 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8286 (match_operand:QI 2 "general_operand" "")))
8287 (clobber (reg:CC FLAGS_REG))]
8288 "TARGET_QIMODE_MATH"
8289 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8290
8291 ;; %%% Potential partial reg stall on alternative 2. What to do?
8292 (define_insn "*andqi_1"
8293 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8294 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8295 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8296 (clobber (reg:CC FLAGS_REG))]
8297 "ix86_binary_operator_ok (AND, QImode, operands)"
8298 "@
8299 and{b}\t{%2, %0|%0, %2}
8300 and{b}\t{%2, %0|%0, %2}
8301 and{l}\t{%k2, %k0|%k0, %k2}"
8302 [(set_attr "type" "alu")
8303 (set_attr "mode" "QI,QI,SI")])
8304
8305 (define_insn "*andqi_1_slp"
8306 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8307 (and:QI (match_dup 0)
8308 (match_operand:QI 1 "general_operand" "qi,qmi")))
8309 (clobber (reg:CC FLAGS_REG))]
8310 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8311 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8312 "and{b}\t{%1, %0|%0, %1}"
8313 [(set_attr "type" "alu1")
8314 (set_attr "mode" "QI")])
8315
8316 (define_insn "*andqi_2_maybe_si"
8317 [(set (reg FLAGS_REG)
8318 (compare (and:QI
8319 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8320 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8321 (const_int 0)))
8322 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8323 (and:QI (match_dup 1) (match_dup 2)))]
8324 "ix86_binary_operator_ok (AND, QImode, operands)
8325 && ix86_match_ccmode (insn,
8326 GET_CODE (operands[2]) == CONST_INT
8327 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8328 {
8329 if (which_alternative == 2)
8330 {
8331 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8332 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8333 return "and{l}\t{%2, %k0|%k0, %2}";
8334 }
8335 return "and{b}\t{%2, %0|%0, %2}";
8336 }
8337 [(set_attr "type" "alu")
8338 (set_attr "mode" "QI,QI,SI")])
8339
8340 (define_insn "*andqi_2"
8341 [(set (reg FLAGS_REG)
8342 (compare (and:QI
8343 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8344 (match_operand:QI 2 "general_operand" "qim,qi"))
8345 (const_int 0)))
8346 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8347 (and:QI (match_dup 1) (match_dup 2)))]
8348 "ix86_match_ccmode (insn, CCNOmode)
8349 && ix86_binary_operator_ok (AND, QImode, operands)"
8350 "and{b}\t{%2, %0|%0, %2}"
8351 [(set_attr "type" "alu")
8352 (set_attr "mode" "QI")])
8353
8354 (define_insn "*andqi_2_slp"
8355 [(set (reg FLAGS_REG)
8356 (compare (and:QI
8357 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8358 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8359 (const_int 0)))
8360 (set (strict_low_part (match_dup 0))
8361 (and:QI (match_dup 0) (match_dup 1)))]
8362 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8363 && ix86_match_ccmode (insn, CCNOmode)
8364 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8365 "and{b}\t{%1, %0|%0, %1}"
8366 [(set_attr "type" "alu1")
8367 (set_attr "mode" "QI")])
8368
8369 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8370 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8371 ;; for a QImode operand, which of course failed.
8372
8373 (define_insn "andqi_ext_0"
8374 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8375 (const_int 8)
8376 (const_int 8))
8377 (and:SI
8378 (zero_extract:SI
8379 (match_operand 1 "ext_register_operand" "0")
8380 (const_int 8)
8381 (const_int 8))
8382 (match_operand 2 "const_int_operand" "n")))
8383 (clobber (reg:CC FLAGS_REG))]
8384 ""
8385 "and{b}\t{%2, %h0|%h0, %2}"
8386 [(set_attr "type" "alu")
8387 (set_attr "length_immediate" "1")
8388 (set_attr "mode" "QI")])
8389
8390 ;; Generated by peephole translating test to and. This shows up
8391 ;; often in fp comparisons.
8392
8393 (define_insn "*andqi_ext_0_cc"
8394 [(set (reg FLAGS_REG)
8395 (compare
8396 (and:SI
8397 (zero_extract:SI
8398 (match_operand 1 "ext_register_operand" "0")
8399 (const_int 8)
8400 (const_int 8))
8401 (match_operand 2 "const_int_operand" "n"))
8402 (const_int 0)))
8403 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8404 (const_int 8)
8405 (const_int 8))
8406 (and:SI
8407 (zero_extract:SI
8408 (match_dup 1)
8409 (const_int 8)
8410 (const_int 8))
8411 (match_dup 2)))]
8412 "ix86_match_ccmode (insn, CCNOmode)"
8413 "and{b}\t{%2, %h0|%h0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "length_immediate" "1")
8416 (set_attr "mode" "QI")])
8417
8418 (define_insn "*andqi_ext_1"
8419 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8420 (const_int 8)
8421 (const_int 8))
8422 (and:SI
8423 (zero_extract:SI
8424 (match_operand 1 "ext_register_operand" "0")
8425 (const_int 8)
8426 (const_int 8))
8427 (zero_extend:SI
8428 (match_operand:QI 2 "general_operand" "Qm"))))
8429 (clobber (reg:CC FLAGS_REG))]
8430 "!TARGET_64BIT"
8431 "and{b}\t{%2, %h0|%h0, %2}"
8432 [(set_attr "type" "alu")
8433 (set_attr "length_immediate" "0")
8434 (set_attr "mode" "QI")])
8435
8436 (define_insn "*andqi_ext_1_rex64"
8437 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8438 (const_int 8)
8439 (const_int 8))
8440 (and:SI
8441 (zero_extract:SI
8442 (match_operand 1 "ext_register_operand" "0")
8443 (const_int 8)
8444 (const_int 8))
8445 (zero_extend:SI
8446 (match_operand 2 "ext_register_operand" "Q"))))
8447 (clobber (reg:CC FLAGS_REG))]
8448 "TARGET_64BIT"
8449 "and{b}\t{%2, %h0|%h0, %2}"
8450 [(set_attr "type" "alu")
8451 (set_attr "length_immediate" "0")
8452 (set_attr "mode" "QI")])
8453
8454 (define_insn "*andqi_ext_2"
8455 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8456 (const_int 8)
8457 (const_int 8))
8458 (and:SI
8459 (zero_extract:SI
8460 (match_operand 1 "ext_register_operand" "%0")
8461 (const_int 8)
8462 (const_int 8))
8463 (zero_extract:SI
8464 (match_operand 2 "ext_register_operand" "Q")
8465 (const_int 8)
8466 (const_int 8))))
8467 (clobber (reg:CC FLAGS_REG))]
8468 ""
8469 "and{b}\t{%h2, %h0|%h0, %h2}"
8470 [(set_attr "type" "alu")
8471 (set_attr "length_immediate" "0")
8472 (set_attr "mode" "QI")])
8473
8474 ;; Convert wide AND instructions with immediate operand to shorter QImode
8475 ;; equivalents when possible.
8476 ;; Don't do the splitting with memory operands, since it introduces risk
8477 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8478 ;; for size, but that can (should?) be handled by generic code instead.
8479 (define_split
8480 [(set (match_operand 0 "register_operand" "")
8481 (and (match_operand 1 "register_operand" "")
8482 (match_operand 2 "const_int_operand" "")))
8483 (clobber (reg:CC FLAGS_REG))]
8484 "reload_completed
8485 && QI_REG_P (operands[0])
8486 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8487 && !(~INTVAL (operands[2]) & ~(255 << 8))
8488 && GET_MODE (operands[0]) != QImode"
8489 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8490 (and:SI (zero_extract:SI (match_dup 1)
8491 (const_int 8) (const_int 8))
8492 (match_dup 2)))
8493 (clobber (reg:CC FLAGS_REG))])]
8494 "operands[0] = gen_lowpart (SImode, operands[0]);
8495 operands[1] = gen_lowpart (SImode, operands[1]);
8496 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8497
8498 ;; Since AND can be encoded with sign extended immediate, this is only
8499 ;; profitable when 7th bit is not set.
8500 (define_split
8501 [(set (match_operand 0 "register_operand" "")
8502 (and (match_operand 1 "general_operand" "")
8503 (match_operand 2 "const_int_operand" "")))
8504 (clobber (reg:CC FLAGS_REG))]
8505 "reload_completed
8506 && ANY_QI_REG_P (operands[0])
8507 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8508 && !(~INTVAL (operands[2]) & ~255)
8509 && !(INTVAL (operands[2]) & 128)
8510 && GET_MODE (operands[0]) != QImode"
8511 [(parallel [(set (strict_low_part (match_dup 0))
8512 (and:QI (match_dup 1)
8513 (match_dup 2)))
8514 (clobber (reg:CC FLAGS_REG))])]
8515 "operands[0] = gen_lowpart (QImode, operands[0]);
8516 operands[1] = gen_lowpart (QImode, operands[1]);
8517 operands[2] = gen_lowpart (QImode, operands[2]);")
8518 \f
8519 ;; Logical inclusive OR instructions
8520
8521 ;; %%% This used to optimize known byte-wide and operations to memory.
8522 ;; If this is considered useful, it should be done with splitters.
8523
8524 (define_expand "iordi3"
8525 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8526 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8527 (match_operand:DI 2 "x86_64_general_operand" "")))
8528 (clobber (reg:CC FLAGS_REG))]
8529 "TARGET_64BIT"
8530 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8531
8532 (define_insn "*iordi_1_rex64"
8533 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8534 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8535 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8536 (clobber (reg:CC FLAGS_REG))]
8537 "TARGET_64BIT
8538 && ix86_binary_operator_ok (IOR, DImode, operands)"
8539 "or{q}\t{%2, %0|%0, %2}"
8540 [(set_attr "type" "alu")
8541 (set_attr "mode" "DI")])
8542
8543 (define_insn "*iordi_2_rex64"
8544 [(set (reg FLAGS_REG)
8545 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8546 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8547 (const_int 0)))
8548 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8549 (ior:DI (match_dup 1) (match_dup 2)))]
8550 "TARGET_64BIT
8551 && ix86_match_ccmode (insn, CCNOmode)
8552 && ix86_binary_operator_ok (IOR, DImode, operands)"
8553 "or{q}\t{%2, %0|%0, %2}"
8554 [(set_attr "type" "alu")
8555 (set_attr "mode" "DI")])
8556
8557 (define_insn "*iordi_3_rex64"
8558 [(set (reg FLAGS_REG)
8559 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8560 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8561 (const_int 0)))
8562 (clobber (match_scratch:DI 0 "=r"))]
8563 "TARGET_64BIT
8564 && ix86_match_ccmode (insn, CCNOmode)
8565 && ix86_binary_operator_ok (IOR, DImode, operands)"
8566 "or{q}\t{%2, %0|%0, %2}"
8567 [(set_attr "type" "alu")
8568 (set_attr "mode" "DI")])
8569
8570
8571 (define_expand "iorsi3"
8572 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8573 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8574 (match_operand:SI 2 "general_operand" "")))
8575 (clobber (reg:CC FLAGS_REG))]
8576 ""
8577 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8578
8579 (define_insn "*iorsi_1"
8580 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8581 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8582 (match_operand:SI 2 "general_operand" "ri,rmi")))
8583 (clobber (reg:CC FLAGS_REG))]
8584 "ix86_binary_operator_ok (IOR, SImode, operands)"
8585 "or{l}\t{%2, %0|%0, %2}"
8586 [(set_attr "type" "alu")
8587 (set_attr "mode" "SI")])
8588
8589 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8590 (define_insn "*iorsi_1_zext"
8591 [(set (match_operand:DI 0 "register_operand" "=rm")
8592 (zero_extend:DI
8593 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8594 (match_operand:SI 2 "general_operand" "rim"))))
8595 (clobber (reg:CC FLAGS_REG))]
8596 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8597 "or{l}\t{%2, %k0|%k0, %2}"
8598 [(set_attr "type" "alu")
8599 (set_attr "mode" "SI")])
8600
8601 (define_insn "*iorsi_1_zext_imm"
8602 [(set (match_operand:DI 0 "register_operand" "=rm")
8603 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8604 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8605 (clobber (reg:CC FLAGS_REG))]
8606 "TARGET_64BIT"
8607 "or{l}\t{%2, %k0|%k0, %2}"
8608 [(set_attr "type" "alu")
8609 (set_attr "mode" "SI")])
8610
8611 (define_insn "*iorsi_2"
8612 [(set (reg FLAGS_REG)
8613 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8614 (match_operand:SI 2 "general_operand" "rim,ri"))
8615 (const_int 0)))
8616 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8617 (ior:SI (match_dup 1) (match_dup 2)))]
8618 "ix86_match_ccmode (insn, CCNOmode)
8619 && ix86_binary_operator_ok (IOR, SImode, operands)"
8620 "or{l}\t{%2, %0|%0, %2}"
8621 [(set_attr "type" "alu")
8622 (set_attr "mode" "SI")])
8623
8624 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8625 ;; ??? Special case for immediate operand is missing - it is tricky.
8626 (define_insn "*iorsi_2_zext"
8627 [(set (reg FLAGS_REG)
8628 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8629 (match_operand:SI 2 "general_operand" "rim"))
8630 (const_int 0)))
8631 (set (match_operand:DI 0 "register_operand" "=r")
8632 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8633 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8634 && ix86_binary_operator_ok (IOR, SImode, operands)"
8635 "or{l}\t{%2, %k0|%k0, %2}"
8636 [(set_attr "type" "alu")
8637 (set_attr "mode" "SI")])
8638
8639 (define_insn "*iorsi_2_zext_imm"
8640 [(set (reg FLAGS_REG)
8641 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8642 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8643 (const_int 0)))
8644 (set (match_operand:DI 0 "register_operand" "=r")
8645 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8646 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8647 && ix86_binary_operator_ok (IOR, SImode, operands)"
8648 "or{l}\t{%2, %k0|%k0, %2}"
8649 [(set_attr "type" "alu")
8650 (set_attr "mode" "SI")])
8651
8652 (define_insn "*iorsi_3"
8653 [(set (reg FLAGS_REG)
8654 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8655 (match_operand:SI 2 "general_operand" "rim"))
8656 (const_int 0)))
8657 (clobber (match_scratch:SI 0 "=r"))]
8658 "ix86_match_ccmode (insn, CCNOmode)
8659 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8660 "or{l}\t{%2, %0|%0, %2}"
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
8663
8664 (define_expand "iorhi3"
8665 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8666 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8667 (match_operand:HI 2 "general_operand" "")))
8668 (clobber (reg:CC FLAGS_REG))]
8669 "TARGET_HIMODE_MATH"
8670 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8671
8672 (define_insn "*iorhi_1"
8673 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8674 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8675 (match_operand:HI 2 "general_operand" "rmi,ri")))
8676 (clobber (reg:CC FLAGS_REG))]
8677 "ix86_binary_operator_ok (IOR, HImode, operands)"
8678 "or{w}\t{%2, %0|%0, %2}"
8679 [(set_attr "type" "alu")
8680 (set_attr "mode" "HI")])
8681
8682 (define_insn "*iorhi_2"
8683 [(set (reg FLAGS_REG)
8684 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8685 (match_operand:HI 2 "general_operand" "rim,ri"))
8686 (const_int 0)))
8687 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8688 (ior:HI (match_dup 1) (match_dup 2)))]
8689 "ix86_match_ccmode (insn, CCNOmode)
8690 && ix86_binary_operator_ok (IOR, HImode, operands)"
8691 "or{w}\t{%2, %0|%0, %2}"
8692 [(set_attr "type" "alu")
8693 (set_attr "mode" "HI")])
8694
8695 (define_insn "*iorhi_3"
8696 [(set (reg FLAGS_REG)
8697 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8698 (match_operand:HI 2 "general_operand" "rim"))
8699 (const_int 0)))
8700 (clobber (match_scratch:HI 0 "=r"))]
8701 "ix86_match_ccmode (insn, CCNOmode)
8702 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8703 "or{w}\t{%2, %0|%0, %2}"
8704 [(set_attr "type" "alu")
8705 (set_attr "mode" "HI")])
8706
8707 (define_expand "iorqi3"
8708 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8709 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8710 (match_operand:QI 2 "general_operand" "")))
8711 (clobber (reg:CC FLAGS_REG))]
8712 "TARGET_QIMODE_MATH"
8713 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8714
8715 ;; %%% Potential partial reg stall on alternative 2. What to do?
8716 (define_insn "*iorqi_1"
8717 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8718 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8719 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8720 (clobber (reg:CC FLAGS_REG))]
8721 "ix86_binary_operator_ok (IOR, QImode, operands)"
8722 "@
8723 or{b}\t{%2, %0|%0, %2}
8724 or{b}\t{%2, %0|%0, %2}
8725 or{l}\t{%k2, %k0|%k0, %k2}"
8726 [(set_attr "type" "alu")
8727 (set_attr "mode" "QI,QI,SI")])
8728
8729 (define_insn "*iorqi_1_slp"
8730 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8731 (ior:QI (match_dup 0)
8732 (match_operand:QI 1 "general_operand" "qmi,qi")))
8733 (clobber (reg:CC FLAGS_REG))]
8734 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8735 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8736 "or{b}\t{%1, %0|%0, %1}"
8737 [(set_attr "type" "alu1")
8738 (set_attr "mode" "QI")])
8739
8740 (define_insn "*iorqi_2"
8741 [(set (reg FLAGS_REG)
8742 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8743 (match_operand:QI 2 "general_operand" "qim,qi"))
8744 (const_int 0)))
8745 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8746 (ior:QI (match_dup 1) (match_dup 2)))]
8747 "ix86_match_ccmode (insn, CCNOmode)
8748 && ix86_binary_operator_ok (IOR, QImode, operands)"
8749 "or{b}\t{%2, %0|%0, %2}"
8750 [(set_attr "type" "alu")
8751 (set_attr "mode" "QI")])
8752
8753 (define_insn "*iorqi_2_slp"
8754 [(set (reg FLAGS_REG)
8755 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8756 (match_operand:QI 1 "general_operand" "qim,qi"))
8757 (const_int 0)))
8758 (set (strict_low_part (match_dup 0))
8759 (ior:QI (match_dup 0) (match_dup 1)))]
8760 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8761 && ix86_match_ccmode (insn, CCNOmode)
8762 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8763 "or{b}\t{%1, %0|%0, %1}"
8764 [(set_attr "type" "alu1")
8765 (set_attr "mode" "QI")])
8766
8767 (define_insn "*iorqi_3"
8768 [(set (reg FLAGS_REG)
8769 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8770 (match_operand:QI 2 "general_operand" "qim"))
8771 (const_int 0)))
8772 (clobber (match_scratch:QI 0 "=q"))]
8773 "ix86_match_ccmode (insn, CCNOmode)
8774 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8775 "or{b}\t{%2, %0|%0, %2}"
8776 [(set_attr "type" "alu")
8777 (set_attr "mode" "QI")])
8778
8779 (define_insn "iorqi_ext_0"
8780 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8781 (const_int 8)
8782 (const_int 8))
8783 (ior:SI
8784 (zero_extract:SI
8785 (match_operand 1 "ext_register_operand" "0")
8786 (const_int 8)
8787 (const_int 8))
8788 (match_operand 2 "const_int_operand" "n")))
8789 (clobber (reg:CC FLAGS_REG))]
8790 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8791 "or{b}\t{%2, %h0|%h0, %2}"
8792 [(set_attr "type" "alu")
8793 (set_attr "length_immediate" "1")
8794 (set_attr "mode" "QI")])
8795
8796 (define_insn "*iorqi_ext_1"
8797 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8798 (const_int 8)
8799 (const_int 8))
8800 (ior:SI
8801 (zero_extract:SI
8802 (match_operand 1 "ext_register_operand" "0")
8803 (const_int 8)
8804 (const_int 8))
8805 (zero_extend:SI
8806 (match_operand:QI 2 "general_operand" "Qm"))))
8807 (clobber (reg:CC FLAGS_REG))]
8808 "!TARGET_64BIT
8809 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8810 "or{b}\t{%2, %h0|%h0, %2}"
8811 [(set_attr "type" "alu")
8812 (set_attr "length_immediate" "0")
8813 (set_attr "mode" "QI")])
8814
8815 (define_insn "*iorqi_ext_1_rex64"
8816 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8817 (const_int 8)
8818 (const_int 8))
8819 (ior:SI
8820 (zero_extract:SI
8821 (match_operand 1 "ext_register_operand" "0")
8822 (const_int 8)
8823 (const_int 8))
8824 (zero_extend:SI
8825 (match_operand 2 "ext_register_operand" "Q"))))
8826 (clobber (reg:CC FLAGS_REG))]
8827 "TARGET_64BIT
8828 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8829 "or{b}\t{%2, %h0|%h0, %2}"
8830 [(set_attr "type" "alu")
8831 (set_attr "length_immediate" "0")
8832 (set_attr "mode" "QI")])
8833
8834 (define_insn "*iorqi_ext_2"
8835 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8836 (const_int 8)
8837 (const_int 8))
8838 (ior:SI
8839 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8840 (const_int 8)
8841 (const_int 8))
8842 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8843 (const_int 8)
8844 (const_int 8))))
8845 (clobber (reg:CC FLAGS_REG))]
8846 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8847 "ior{b}\t{%h2, %h0|%h0, %h2}"
8848 [(set_attr "type" "alu")
8849 (set_attr "length_immediate" "0")
8850 (set_attr "mode" "QI")])
8851
8852 (define_split
8853 [(set (match_operand 0 "register_operand" "")
8854 (ior (match_operand 1 "register_operand" "")
8855 (match_operand 2 "const_int_operand" "")))
8856 (clobber (reg:CC FLAGS_REG))]
8857 "reload_completed
8858 && QI_REG_P (operands[0])
8859 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8860 && !(INTVAL (operands[2]) & ~(255 << 8))
8861 && GET_MODE (operands[0]) != QImode"
8862 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8863 (ior:SI (zero_extract:SI (match_dup 1)
8864 (const_int 8) (const_int 8))
8865 (match_dup 2)))
8866 (clobber (reg:CC FLAGS_REG))])]
8867 "operands[0] = gen_lowpart (SImode, operands[0]);
8868 operands[1] = gen_lowpart (SImode, operands[1]);
8869 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8870
8871 ;; Since OR can be encoded with sign extended immediate, this is only
8872 ;; profitable when 7th bit is set.
8873 (define_split
8874 [(set (match_operand 0 "register_operand" "")
8875 (ior (match_operand 1 "general_operand" "")
8876 (match_operand 2 "const_int_operand" "")))
8877 (clobber (reg:CC FLAGS_REG))]
8878 "reload_completed
8879 && ANY_QI_REG_P (operands[0])
8880 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8881 && !(INTVAL (operands[2]) & ~255)
8882 && (INTVAL (operands[2]) & 128)
8883 && GET_MODE (operands[0]) != QImode"
8884 [(parallel [(set (strict_low_part (match_dup 0))
8885 (ior:QI (match_dup 1)
8886 (match_dup 2)))
8887 (clobber (reg:CC FLAGS_REG))])]
8888 "operands[0] = gen_lowpart (QImode, operands[0]);
8889 operands[1] = gen_lowpart (QImode, operands[1]);
8890 operands[2] = gen_lowpart (QImode, operands[2]);")
8891 \f
8892 ;; Logical XOR instructions
8893
8894 ;; %%% This used to optimize known byte-wide and operations to memory.
8895 ;; If this is considered useful, it should be done with splitters.
8896
8897 (define_expand "xordi3"
8898 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8899 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8900 (match_operand:DI 2 "x86_64_general_operand" "")))
8901 (clobber (reg:CC FLAGS_REG))]
8902 "TARGET_64BIT"
8903 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8904
8905 (define_insn "*xordi_1_rex64"
8906 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8907 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8908 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8909 (clobber (reg:CC FLAGS_REG))]
8910 "TARGET_64BIT
8911 && ix86_binary_operator_ok (XOR, DImode, operands)"
8912 "@
8913 xor{q}\t{%2, %0|%0, %2}
8914 xor{q}\t{%2, %0|%0, %2}"
8915 [(set_attr "type" "alu")
8916 (set_attr "mode" "DI,DI")])
8917
8918 (define_insn "*xordi_2_rex64"
8919 [(set (reg FLAGS_REG)
8920 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8921 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8922 (const_int 0)))
8923 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8924 (xor:DI (match_dup 1) (match_dup 2)))]
8925 "TARGET_64BIT
8926 && ix86_match_ccmode (insn, CCNOmode)
8927 && ix86_binary_operator_ok (XOR, DImode, operands)"
8928 "@
8929 xor{q}\t{%2, %0|%0, %2}
8930 xor{q}\t{%2, %0|%0, %2}"
8931 [(set_attr "type" "alu")
8932 (set_attr "mode" "DI,DI")])
8933
8934 (define_insn "*xordi_3_rex64"
8935 [(set (reg FLAGS_REG)
8936 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8937 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8938 (const_int 0)))
8939 (clobber (match_scratch:DI 0 "=r"))]
8940 "TARGET_64BIT
8941 && ix86_match_ccmode (insn, CCNOmode)
8942 && ix86_binary_operator_ok (XOR, DImode, operands)"
8943 "xor{q}\t{%2, %0|%0, %2}"
8944 [(set_attr "type" "alu")
8945 (set_attr "mode" "DI")])
8946
8947 (define_expand "xorsi3"
8948 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8949 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8950 (match_operand:SI 2 "general_operand" "")))
8951 (clobber (reg:CC FLAGS_REG))]
8952 ""
8953 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8954
8955 (define_insn "*xorsi_1"
8956 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8957 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8958 (match_operand:SI 2 "general_operand" "ri,rm")))
8959 (clobber (reg:CC FLAGS_REG))]
8960 "ix86_binary_operator_ok (XOR, SImode, operands)"
8961 "xor{l}\t{%2, %0|%0, %2}"
8962 [(set_attr "type" "alu")
8963 (set_attr "mode" "SI")])
8964
8965 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8966 ;; Add speccase for immediates
8967 (define_insn "*xorsi_1_zext"
8968 [(set (match_operand:DI 0 "register_operand" "=r")
8969 (zero_extend:DI
8970 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8971 (match_operand:SI 2 "general_operand" "rim"))))
8972 (clobber (reg:CC FLAGS_REG))]
8973 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8974 "xor{l}\t{%2, %k0|%k0, %2}"
8975 [(set_attr "type" "alu")
8976 (set_attr "mode" "SI")])
8977
8978 (define_insn "*xorsi_1_zext_imm"
8979 [(set (match_operand:DI 0 "register_operand" "=r")
8980 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8981 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8982 (clobber (reg:CC FLAGS_REG))]
8983 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8984 "xor{l}\t{%2, %k0|%k0, %2}"
8985 [(set_attr "type" "alu")
8986 (set_attr "mode" "SI")])
8987
8988 (define_insn "*xorsi_2"
8989 [(set (reg FLAGS_REG)
8990 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8991 (match_operand:SI 2 "general_operand" "rim,ri"))
8992 (const_int 0)))
8993 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8994 (xor:SI (match_dup 1) (match_dup 2)))]
8995 "ix86_match_ccmode (insn, CCNOmode)
8996 && ix86_binary_operator_ok (XOR, SImode, operands)"
8997 "xor{l}\t{%2, %0|%0, %2}"
8998 [(set_attr "type" "alu")
8999 (set_attr "mode" "SI")])
9000
9001 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9002 ;; ??? Special case for immediate operand is missing - it is tricky.
9003 (define_insn "*xorsi_2_zext"
9004 [(set (reg FLAGS_REG)
9005 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9006 (match_operand:SI 2 "general_operand" "rim"))
9007 (const_int 0)))
9008 (set (match_operand:DI 0 "register_operand" "=r")
9009 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9010 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9011 && ix86_binary_operator_ok (XOR, SImode, operands)"
9012 "xor{l}\t{%2, %k0|%k0, %2}"
9013 [(set_attr "type" "alu")
9014 (set_attr "mode" "SI")])
9015
9016 (define_insn "*xorsi_2_zext_imm"
9017 [(set (reg FLAGS_REG)
9018 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9019 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9020 (const_int 0)))
9021 (set (match_operand:DI 0 "register_operand" "=r")
9022 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9023 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9024 && ix86_binary_operator_ok (XOR, SImode, operands)"
9025 "xor{l}\t{%2, %k0|%k0, %2}"
9026 [(set_attr "type" "alu")
9027 (set_attr "mode" "SI")])
9028
9029 (define_insn "*xorsi_3"
9030 [(set (reg FLAGS_REG)
9031 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9032 (match_operand:SI 2 "general_operand" "rim"))
9033 (const_int 0)))
9034 (clobber (match_scratch:SI 0 "=r"))]
9035 "ix86_match_ccmode (insn, CCNOmode)
9036 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9037 "xor{l}\t{%2, %0|%0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "SI")])
9040
9041 (define_expand "xorhi3"
9042 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9043 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9044 (match_operand:HI 2 "general_operand" "")))
9045 (clobber (reg:CC FLAGS_REG))]
9046 "TARGET_HIMODE_MATH"
9047 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9048
9049 (define_insn "*xorhi_1"
9050 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9051 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9052 (match_operand:HI 2 "general_operand" "rmi,ri")))
9053 (clobber (reg:CC FLAGS_REG))]
9054 "ix86_binary_operator_ok (XOR, HImode, operands)"
9055 "xor{w}\t{%2, %0|%0, %2}"
9056 [(set_attr "type" "alu")
9057 (set_attr "mode" "HI")])
9058
9059 (define_insn "*xorhi_2"
9060 [(set (reg FLAGS_REG)
9061 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9062 (match_operand:HI 2 "general_operand" "rim,ri"))
9063 (const_int 0)))
9064 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9065 (xor:HI (match_dup 1) (match_dup 2)))]
9066 "ix86_match_ccmode (insn, CCNOmode)
9067 && ix86_binary_operator_ok (XOR, HImode, operands)"
9068 "xor{w}\t{%2, %0|%0, %2}"
9069 [(set_attr "type" "alu")
9070 (set_attr "mode" "HI")])
9071
9072 (define_insn "*xorhi_3"
9073 [(set (reg FLAGS_REG)
9074 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9075 (match_operand:HI 2 "general_operand" "rim"))
9076 (const_int 0)))
9077 (clobber (match_scratch:HI 0 "=r"))]
9078 "ix86_match_ccmode (insn, CCNOmode)
9079 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9080 "xor{w}\t{%2, %0|%0, %2}"
9081 [(set_attr "type" "alu")
9082 (set_attr "mode" "HI")])
9083
9084 (define_expand "xorqi3"
9085 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9086 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9087 (match_operand:QI 2 "general_operand" "")))
9088 (clobber (reg:CC FLAGS_REG))]
9089 "TARGET_QIMODE_MATH"
9090 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9091
9092 ;; %%% Potential partial reg stall on alternative 2. What to do?
9093 (define_insn "*xorqi_1"
9094 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9095 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9096 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9097 (clobber (reg:CC FLAGS_REG))]
9098 "ix86_binary_operator_ok (XOR, QImode, operands)"
9099 "@
9100 xor{b}\t{%2, %0|%0, %2}
9101 xor{b}\t{%2, %0|%0, %2}
9102 xor{l}\t{%k2, %k0|%k0, %k2}"
9103 [(set_attr "type" "alu")
9104 (set_attr "mode" "QI,QI,SI")])
9105
9106 (define_insn "*xorqi_1_slp"
9107 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9108 (xor:QI (match_dup 0)
9109 (match_operand:QI 1 "general_operand" "qi,qmi")))
9110 (clobber (reg:CC FLAGS_REG))]
9111 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9112 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9113 "xor{b}\t{%1, %0|%0, %1}"
9114 [(set_attr "type" "alu1")
9115 (set_attr "mode" "QI")])
9116
9117 (define_insn "xorqi_ext_0"
9118 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9119 (const_int 8)
9120 (const_int 8))
9121 (xor:SI
9122 (zero_extract:SI
9123 (match_operand 1 "ext_register_operand" "0")
9124 (const_int 8)
9125 (const_int 8))
9126 (match_operand 2 "const_int_operand" "n")))
9127 (clobber (reg:CC FLAGS_REG))]
9128 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9129 "xor{b}\t{%2, %h0|%h0, %2}"
9130 [(set_attr "type" "alu")
9131 (set_attr "length_immediate" "1")
9132 (set_attr "mode" "QI")])
9133
9134 (define_insn "*xorqi_ext_1"
9135 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9136 (const_int 8)
9137 (const_int 8))
9138 (xor:SI
9139 (zero_extract:SI
9140 (match_operand 1 "ext_register_operand" "0")
9141 (const_int 8)
9142 (const_int 8))
9143 (zero_extend:SI
9144 (match_operand:QI 2 "general_operand" "Qm"))))
9145 (clobber (reg:CC FLAGS_REG))]
9146 "!TARGET_64BIT
9147 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9148 "xor{b}\t{%2, %h0|%h0, %2}"
9149 [(set_attr "type" "alu")
9150 (set_attr "length_immediate" "0")
9151 (set_attr "mode" "QI")])
9152
9153 (define_insn "*xorqi_ext_1_rex64"
9154 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9155 (const_int 8)
9156 (const_int 8))
9157 (xor:SI
9158 (zero_extract:SI
9159 (match_operand 1 "ext_register_operand" "0")
9160 (const_int 8)
9161 (const_int 8))
9162 (zero_extend:SI
9163 (match_operand 2 "ext_register_operand" "Q"))))
9164 (clobber (reg:CC FLAGS_REG))]
9165 "TARGET_64BIT
9166 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167 "xor{b}\t{%2, %h0|%h0, %2}"
9168 [(set_attr "type" "alu")
9169 (set_attr "length_immediate" "0")
9170 (set_attr "mode" "QI")])
9171
9172 (define_insn "*xorqi_ext_2"
9173 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9174 (const_int 8)
9175 (const_int 8))
9176 (xor:SI
9177 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9178 (const_int 8)
9179 (const_int 8))
9180 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9181 (const_int 8)
9182 (const_int 8))))
9183 (clobber (reg:CC FLAGS_REG))]
9184 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9185 "xor{b}\t{%h2, %h0|%h0, %h2}"
9186 [(set_attr "type" "alu")
9187 (set_attr "length_immediate" "0")
9188 (set_attr "mode" "QI")])
9189
9190 (define_insn "*xorqi_cc_1"
9191 [(set (reg FLAGS_REG)
9192 (compare
9193 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9194 (match_operand:QI 2 "general_operand" "qim,qi"))
9195 (const_int 0)))
9196 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9197 (xor:QI (match_dup 1) (match_dup 2)))]
9198 "ix86_match_ccmode (insn, CCNOmode)
9199 && ix86_binary_operator_ok (XOR, QImode, operands)"
9200 "xor{b}\t{%2, %0|%0, %2}"
9201 [(set_attr "type" "alu")
9202 (set_attr "mode" "QI")])
9203
9204 (define_insn "*xorqi_2_slp"
9205 [(set (reg FLAGS_REG)
9206 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9207 (match_operand:QI 1 "general_operand" "qim,qi"))
9208 (const_int 0)))
9209 (set (strict_low_part (match_dup 0))
9210 (xor:QI (match_dup 0) (match_dup 1)))]
9211 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9212 && ix86_match_ccmode (insn, CCNOmode)
9213 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9214 "xor{b}\t{%1, %0|%0, %1}"
9215 [(set_attr "type" "alu1")
9216 (set_attr "mode" "QI")])
9217
9218 (define_insn "*xorqi_cc_2"
9219 [(set (reg FLAGS_REG)
9220 (compare
9221 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9222 (match_operand:QI 2 "general_operand" "qim"))
9223 (const_int 0)))
9224 (clobber (match_scratch:QI 0 "=q"))]
9225 "ix86_match_ccmode (insn, CCNOmode)
9226 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9227 "xor{b}\t{%2, %0|%0, %2}"
9228 [(set_attr "type" "alu")
9229 (set_attr "mode" "QI")])
9230
9231 (define_insn "*xorqi_cc_ext_1"
9232 [(set (reg FLAGS_REG)
9233 (compare
9234 (xor:SI
9235 (zero_extract:SI
9236 (match_operand 1 "ext_register_operand" "0")
9237 (const_int 8)
9238 (const_int 8))
9239 (match_operand:QI 2 "general_operand" "qmn"))
9240 (const_int 0)))
9241 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9242 (const_int 8)
9243 (const_int 8))
9244 (xor:SI
9245 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9246 (match_dup 2)))]
9247 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9248 "xor{b}\t{%2, %h0|%h0, %2}"
9249 [(set_attr "type" "alu")
9250 (set_attr "mode" "QI")])
9251
9252 (define_insn "*xorqi_cc_ext_1_rex64"
9253 [(set (reg FLAGS_REG)
9254 (compare
9255 (xor:SI
9256 (zero_extract:SI
9257 (match_operand 1 "ext_register_operand" "0")
9258 (const_int 8)
9259 (const_int 8))
9260 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9261 (const_int 0)))
9262 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9263 (const_int 8)
9264 (const_int 8))
9265 (xor:SI
9266 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9267 (match_dup 2)))]
9268 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9269 "xor{b}\t{%2, %h0|%h0, %2}"
9270 [(set_attr "type" "alu")
9271 (set_attr "mode" "QI")])
9272
9273 (define_expand "xorqi_cc_ext_1"
9274 [(parallel [
9275 (set (reg:CCNO FLAGS_REG)
9276 (compare:CCNO
9277 (xor:SI
9278 (zero_extract:SI
9279 (match_operand 1 "ext_register_operand" "")
9280 (const_int 8)
9281 (const_int 8))
9282 (match_operand:QI 2 "general_operand" ""))
9283 (const_int 0)))
9284 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9285 (const_int 8)
9286 (const_int 8))
9287 (xor:SI
9288 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9289 (match_dup 2)))])]
9290 ""
9291 "")
9292
9293 (define_split
9294 [(set (match_operand 0 "register_operand" "")
9295 (xor (match_operand 1 "register_operand" "")
9296 (match_operand 2 "const_int_operand" "")))
9297 (clobber (reg:CC FLAGS_REG))]
9298 "reload_completed
9299 && QI_REG_P (operands[0])
9300 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9301 && !(INTVAL (operands[2]) & ~(255 << 8))
9302 && GET_MODE (operands[0]) != QImode"
9303 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9304 (xor:SI (zero_extract:SI (match_dup 1)
9305 (const_int 8) (const_int 8))
9306 (match_dup 2)))
9307 (clobber (reg:CC FLAGS_REG))])]
9308 "operands[0] = gen_lowpart (SImode, operands[0]);
9309 operands[1] = gen_lowpart (SImode, operands[1]);
9310 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9311
9312 ;; Since XOR can be encoded with sign extended immediate, this is only
9313 ;; profitable when 7th bit is set.
9314 (define_split
9315 [(set (match_operand 0 "register_operand" "")
9316 (xor (match_operand 1 "general_operand" "")
9317 (match_operand 2 "const_int_operand" "")))
9318 (clobber (reg:CC FLAGS_REG))]
9319 "reload_completed
9320 && ANY_QI_REG_P (operands[0])
9321 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9322 && !(INTVAL (operands[2]) & ~255)
9323 && (INTVAL (operands[2]) & 128)
9324 && GET_MODE (operands[0]) != QImode"
9325 [(parallel [(set (strict_low_part (match_dup 0))
9326 (xor:QI (match_dup 1)
9327 (match_dup 2)))
9328 (clobber (reg:CC FLAGS_REG))])]
9329 "operands[0] = gen_lowpart (QImode, operands[0]);
9330 operands[1] = gen_lowpart (QImode, operands[1]);
9331 operands[2] = gen_lowpart (QImode, operands[2]);")
9332 \f
9333 ;; Negation instructions
9334
9335 (define_expand "negti2"
9336 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9337 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9338 (clobber (reg:CC FLAGS_REG))])]
9339 "TARGET_64BIT"
9340 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9341
9342 (define_insn "*negti2_1"
9343 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9344 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9345 (clobber (reg:CC FLAGS_REG))]
9346 "TARGET_64BIT
9347 && ix86_unary_operator_ok (NEG, TImode, operands)"
9348 "#")
9349
9350 (define_split
9351 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9352 (neg:TI (match_operand:TI 1 "general_operand" "")))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "TARGET_64BIT && reload_completed"
9355 [(parallel
9356 [(set (reg:CCZ FLAGS_REG)
9357 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9358 (set (match_dup 0) (neg:DI (match_dup 2)))])
9359 (parallel
9360 [(set (match_dup 1)
9361 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9362 (match_dup 3))
9363 (const_int 0)))
9364 (clobber (reg:CC FLAGS_REG))])
9365 (parallel
9366 [(set (match_dup 1)
9367 (neg:DI (match_dup 1)))
9368 (clobber (reg:CC FLAGS_REG))])]
9369 "split_ti (operands+1, 1, operands+2, operands+3);
9370 split_ti (operands+0, 1, operands+0, operands+1);")
9371
9372 (define_expand "negdi2"
9373 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9374 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9375 (clobber (reg:CC FLAGS_REG))])]
9376 ""
9377 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9378
9379 (define_insn "*negdi2_1"
9380 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9381 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9382 (clobber (reg:CC FLAGS_REG))]
9383 "!TARGET_64BIT
9384 && ix86_unary_operator_ok (NEG, DImode, operands)"
9385 "#")
9386
9387 (define_split
9388 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9389 (neg:DI (match_operand:DI 1 "general_operand" "")))
9390 (clobber (reg:CC FLAGS_REG))]
9391 "!TARGET_64BIT && reload_completed"
9392 [(parallel
9393 [(set (reg:CCZ FLAGS_REG)
9394 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9395 (set (match_dup 0) (neg:SI (match_dup 2)))])
9396 (parallel
9397 [(set (match_dup 1)
9398 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9399 (match_dup 3))
9400 (const_int 0)))
9401 (clobber (reg:CC FLAGS_REG))])
9402 (parallel
9403 [(set (match_dup 1)
9404 (neg:SI (match_dup 1)))
9405 (clobber (reg:CC FLAGS_REG))])]
9406 "split_di (operands+1, 1, operands+2, operands+3);
9407 split_di (operands+0, 1, operands+0, operands+1);")
9408
9409 (define_insn "*negdi2_1_rex64"
9410 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9411 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9412 (clobber (reg:CC FLAGS_REG))]
9413 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9414 "neg{q}\t%0"
9415 [(set_attr "type" "negnot")
9416 (set_attr "mode" "DI")])
9417
9418 ;; The problem with neg is that it does not perform (compare x 0),
9419 ;; it really performs (compare 0 x), which leaves us with the zero
9420 ;; flag being the only useful item.
9421
9422 (define_insn "*negdi2_cmpz_rex64"
9423 [(set (reg:CCZ FLAGS_REG)
9424 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9425 (const_int 0)))
9426 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9427 (neg:DI (match_dup 1)))]
9428 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9429 "neg{q}\t%0"
9430 [(set_attr "type" "negnot")
9431 (set_attr "mode" "DI")])
9432
9433
9434 (define_expand "negsi2"
9435 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9436 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9437 (clobber (reg:CC FLAGS_REG))])]
9438 ""
9439 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9440
9441 (define_insn "*negsi2_1"
9442 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9443 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9444 (clobber (reg:CC FLAGS_REG))]
9445 "ix86_unary_operator_ok (NEG, SImode, operands)"
9446 "neg{l}\t%0"
9447 [(set_attr "type" "negnot")
9448 (set_attr "mode" "SI")])
9449
9450 ;; Combine is quite creative about this pattern.
9451 (define_insn "*negsi2_1_zext"
9452 [(set (match_operand:DI 0 "register_operand" "=r")
9453 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9454 (const_int 32)))
9455 (const_int 32)))
9456 (clobber (reg:CC FLAGS_REG))]
9457 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9458 "neg{l}\t%k0"
9459 [(set_attr "type" "negnot")
9460 (set_attr "mode" "SI")])
9461
9462 ;; The problem with neg is that it does not perform (compare x 0),
9463 ;; it really performs (compare 0 x), which leaves us with the zero
9464 ;; flag being the only useful item.
9465
9466 (define_insn "*negsi2_cmpz"
9467 [(set (reg:CCZ FLAGS_REG)
9468 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9469 (const_int 0)))
9470 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9471 (neg:SI (match_dup 1)))]
9472 "ix86_unary_operator_ok (NEG, SImode, operands)"
9473 "neg{l}\t%0"
9474 [(set_attr "type" "negnot")
9475 (set_attr "mode" "SI")])
9476
9477 (define_insn "*negsi2_cmpz_zext"
9478 [(set (reg:CCZ FLAGS_REG)
9479 (compare:CCZ (lshiftrt:DI
9480 (neg:DI (ashift:DI
9481 (match_operand:DI 1 "register_operand" "0")
9482 (const_int 32)))
9483 (const_int 32))
9484 (const_int 0)))
9485 (set (match_operand:DI 0 "register_operand" "=r")
9486 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9487 (const_int 32)))
9488 (const_int 32)))]
9489 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9490 "neg{l}\t%k0"
9491 [(set_attr "type" "negnot")
9492 (set_attr "mode" "SI")])
9493
9494 (define_expand "neghi2"
9495 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9496 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9497 (clobber (reg:CC FLAGS_REG))])]
9498 "TARGET_HIMODE_MATH"
9499 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9500
9501 (define_insn "*neghi2_1"
9502 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9503 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9504 (clobber (reg:CC FLAGS_REG))]
9505 "ix86_unary_operator_ok (NEG, HImode, operands)"
9506 "neg{w}\t%0"
9507 [(set_attr "type" "negnot")
9508 (set_attr "mode" "HI")])
9509
9510 (define_insn "*neghi2_cmpz"
9511 [(set (reg:CCZ FLAGS_REG)
9512 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9513 (const_int 0)))
9514 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9515 (neg:HI (match_dup 1)))]
9516 "ix86_unary_operator_ok (NEG, HImode, operands)"
9517 "neg{w}\t%0"
9518 [(set_attr "type" "negnot")
9519 (set_attr "mode" "HI")])
9520
9521 (define_expand "negqi2"
9522 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9523 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9524 (clobber (reg:CC FLAGS_REG))])]
9525 "TARGET_QIMODE_MATH"
9526 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9527
9528 (define_insn "*negqi2_1"
9529 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9530 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9531 (clobber (reg:CC FLAGS_REG))]
9532 "ix86_unary_operator_ok (NEG, QImode, operands)"
9533 "neg{b}\t%0"
9534 [(set_attr "type" "negnot")
9535 (set_attr "mode" "QI")])
9536
9537 (define_insn "*negqi2_cmpz"
9538 [(set (reg:CCZ FLAGS_REG)
9539 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9540 (const_int 0)))
9541 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9542 (neg:QI (match_dup 1)))]
9543 "ix86_unary_operator_ok (NEG, QImode, operands)"
9544 "neg{b}\t%0"
9545 [(set_attr "type" "negnot")
9546 (set_attr "mode" "QI")])
9547
9548 ;; Changing of sign for FP values is doable using integer unit too.
9549
9550 (define_expand "negsf2"
9551 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9552 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9553 "TARGET_80387 || TARGET_SSE_MATH"
9554 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9555
9556 (define_expand "abssf2"
9557 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9558 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9559 "TARGET_80387 || TARGET_SSE_MATH"
9560 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9561
9562 (define_insn "*absnegsf2_mixed"
9563 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9564 (match_operator:SF 3 "absneg_operator"
9565 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9566 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9567 (clobber (reg:CC FLAGS_REG))]
9568 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9569 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9570 "#")
9571
9572 (define_insn "*absnegsf2_sse"
9573 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9574 (match_operator:SF 3 "absneg_operator"
9575 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9576 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9577 (clobber (reg:CC FLAGS_REG))]
9578 "TARGET_SSE_MATH
9579 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9580 "#")
9581
9582 (define_insn "*absnegsf2_i387"
9583 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9584 (match_operator:SF 3 "absneg_operator"
9585 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9586 (use (match_operand 2 "" ""))
9587 (clobber (reg:CC FLAGS_REG))]
9588 "TARGET_80387 && !TARGET_SSE_MATH
9589 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9590 "#")
9591
9592 (define_expand "copysignsf3"
9593 [(match_operand:SF 0 "register_operand" "")
9594 (match_operand:SF 1 "nonmemory_operand" "")
9595 (match_operand:SF 2 "register_operand" "")]
9596 "TARGET_SSE_MATH"
9597 {
9598 ix86_expand_copysign (operands);
9599 DONE;
9600 })
9601
9602 (define_insn_and_split "copysignsf3_const"
9603 [(set (match_operand:SF 0 "register_operand" "=x")
9604 (unspec:SF
9605 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9606 (match_operand:SF 2 "register_operand" "0")
9607 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9608 UNSPEC_COPYSIGN))]
9609 "TARGET_SSE_MATH"
9610 "#"
9611 "&& reload_completed"
9612 [(const_int 0)]
9613 {
9614 ix86_split_copysign_const (operands);
9615 DONE;
9616 })
9617
9618 (define_insn "copysignsf3_var"
9619 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9620 (unspec:SF
9621 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9622 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9623 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9624 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9625 UNSPEC_COPYSIGN))
9626 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9627 "TARGET_SSE_MATH"
9628 "#")
9629
9630 (define_split
9631 [(set (match_operand:SF 0 "register_operand" "")
9632 (unspec:SF
9633 [(match_operand:SF 2 "register_operand" "")
9634 (match_operand:SF 3 "register_operand" "")
9635 (match_operand:V4SF 4 "" "")
9636 (match_operand:V4SF 5 "" "")]
9637 UNSPEC_COPYSIGN))
9638 (clobber (match_scratch:V4SF 1 ""))]
9639 "TARGET_SSE_MATH && reload_completed"
9640 [(const_int 0)]
9641 {
9642 ix86_split_copysign_var (operands);
9643 DONE;
9644 })
9645
9646 (define_expand "negdf2"
9647 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9648 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9649 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9650 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9651
9652 (define_expand "absdf2"
9653 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9654 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9655 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9656 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9657
9658 (define_insn "*absnegdf2_mixed"
9659 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9660 (match_operator:DF 3 "absneg_operator"
9661 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9662 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9665 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9666 "#")
9667
9668 (define_insn "*absnegdf2_sse"
9669 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9670 (match_operator:DF 3 "absneg_operator"
9671 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9672 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9673 (clobber (reg:CC FLAGS_REG))]
9674 "TARGET_SSE2 && TARGET_SSE_MATH
9675 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9676 "#")
9677
9678 (define_insn "*absnegdf2_i387"
9679 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9680 (match_operator:DF 3 "absneg_operator"
9681 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9682 (use (match_operand 2 "" ""))
9683 (clobber (reg:CC FLAGS_REG))]
9684 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9685 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9686 "#")
9687
9688 (define_expand "copysigndf3"
9689 [(match_operand:DF 0 "register_operand" "")
9690 (match_operand:DF 1 "nonmemory_operand" "")
9691 (match_operand:DF 2 "register_operand" "")]
9692 "TARGET_SSE2 && TARGET_SSE_MATH"
9693 {
9694 ix86_expand_copysign (operands);
9695 DONE;
9696 })
9697
9698 (define_insn_and_split "copysigndf3_const"
9699 [(set (match_operand:DF 0 "register_operand" "=x")
9700 (unspec:DF
9701 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9702 (match_operand:DF 2 "register_operand" "0")
9703 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9704 UNSPEC_COPYSIGN))]
9705 "TARGET_SSE2 && TARGET_SSE_MATH"
9706 "#"
9707 "&& reload_completed"
9708 [(const_int 0)]
9709 {
9710 ix86_split_copysign_const (operands);
9711 DONE;
9712 })
9713
9714 (define_insn "copysigndf3_var"
9715 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9716 (unspec:DF
9717 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9718 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9719 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9720 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9721 UNSPEC_COPYSIGN))
9722 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9723 "TARGET_SSE2 && TARGET_SSE_MATH"
9724 "#")
9725
9726 (define_split
9727 [(set (match_operand:DF 0 "register_operand" "")
9728 (unspec:DF
9729 [(match_operand:DF 2 "register_operand" "")
9730 (match_operand:DF 3 "register_operand" "")
9731 (match_operand:V2DF 4 "" "")
9732 (match_operand:V2DF 5 "" "")]
9733 UNSPEC_COPYSIGN))
9734 (clobber (match_scratch:V2DF 1 ""))]
9735 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9736 [(const_int 0)]
9737 {
9738 ix86_split_copysign_var (operands);
9739 DONE;
9740 })
9741
9742 (define_expand "negxf2"
9743 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9744 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9745 "TARGET_80387"
9746 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9747
9748 (define_expand "absxf2"
9749 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9750 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9751 "TARGET_80387"
9752 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9753
9754 (define_insn "*absnegxf2_i387"
9755 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9756 (match_operator:XF 3 "absneg_operator"
9757 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9758 (use (match_operand 2 "" ""))
9759 (clobber (reg:CC FLAGS_REG))]
9760 "TARGET_80387
9761 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9762 "#")
9763
9764 ;; Splitters for fp abs and neg.
9765
9766 (define_split
9767 [(set (match_operand 0 "fp_register_operand" "")
9768 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9769 (use (match_operand 2 "" ""))
9770 (clobber (reg:CC FLAGS_REG))]
9771 "reload_completed"
9772 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9773
9774 (define_split
9775 [(set (match_operand 0 "register_operand" "")
9776 (match_operator 3 "absneg_operator"
9777 [(match_operand 1 "register_operand" "")]))
9778 (use (match_operand 2 "nonimmediate_operand" ""))
9779 (clobber (reg:CC FLAGS_REG))]
9780 "reload_completed && SSE_REG_P (operands[0])"
9781 [(set (match_dup 0) (match_dup 3))]
9782 {
9783 enum machine_mode mode = GET_MODE (operands[0]);
9784 enum machine_mode vmode = GET_MODE (operands[2]);
9785 rtx tmp;
9786
9787 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9788 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9789 if (operands_match_p (operands[0], operands[2]))
9790 {
9791 tmp = operands[1];
9792 operands[1] = operands[2];
9793 operands[2] = tmp;
9794 }
9795 if (GET_CODE (operands[3]) == ABS)
9796 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9797 else
9798 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9799 operands[3] = tmp;
9800 })
9801
9802 (define_split
9803 [(set (match_operand:SF 0 "register_operand" "")
9804 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9805 (use (match_operand:V4SF 2 "" ""))
9806 (clobber (reg:CC FLAGS_REG))]
9807 "reload_completed"
9808 [(parallel [(set (match_dup 0) (match_dup 1))
9809 (clobber (reg:CC FLAGS_REG))])]
9810 {
9811 rtx tmp;
9812 operands[0] = gen_lowpart (SImode, operands[0]);
9813 if (GET_CODE (operands[1]) == ABS)
9814 {
9815 tmp = gen_int_mode (0x7fffffff, SImode);
9816 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9817 }
9818 else
9819 {
9820 tmp = gen_int_mode (0x80000000, SImode);
9821 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9822 }
9823 operands[1] = tmp;
9824 })
9825
9826 (define_split
9827 [(set (match_operand:DF 0 "register_operand" "")
9828 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9829 (use (match_operand 2 "" ""))
9830 (clobber (reg:CC FLAGS_REG))]
9831 "reload_completed"
9832 [(parallel [(set (match_dup 0) (match_dup 1))
9833 (clobber (reg:CC FLAGS_REG))])]
9834 {
9835 rtx tmp;
9836 if (TARGET_64BIT)
9837 {
9838 tmp = gen_lowpart (DImode, operands[0]);
9839 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9840 operands[0] = tmp;
9841
9842 if (GET_CODE (operands[1]) == ABS)
9843 tmp = const0_rtx;
9844 else
9845 tmp = gen_rtx_NOT (DImode, tmp);
9846 }
9847 else
9848 {
9849 operands[0] = gen_highpart (SImode, operands[0]);
9850 if (GET_CODE (operands[1]) == ABS)
9851 {
9852 tmp = gen_int_mode (0x7fffffff, SImode);
9853 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9854 }
9855 else
9856 {
9857 tmp = gen_int_mode (0x80000000, SImode);
9858 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9859 }
9860 }
9861 operands[1] = tmp;
9862 })
9863
9864 (define_split
9865 [(set (match_operand:XF 0 "register_operand" "")
9866 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9867 (use (match_operand 2 "" ""))
9868 (clobber (reg:CC FLAGS_REG))]
9869 "reload_completed"
9870 [(parallel [(set (match_dup 0) (match_dup 1))
9871 (clobber (reg:CC FLAGS_REG))])]
9872 {
9873 rtx tmp;
9874 operands[0] = gen_rtx_REG (SImode,
9875 true_regnum (operands[0])
9876 + (TARGET_64BIT ? 1 : 2));
9877 if (GET_CODE (operands[1]) == ABS)
9878 {
9879 tmp = GEN_INT (0x7fff);
9880 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9881 }
9882 else
9883 {
9884 tmp = GEN_INT (0x8000);
9885 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9886 }
9887 operands[1] = tmp;
9888 })
9889
9890 (define_split
9891 [(set (match_operand 0 "memory_operand" "")
9892 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9893 (use (match_operand 2 "" ""))
9894 (clobber (reg:CC FLAGS_REG))]
9895 "reload_completed"
9896 [(parallel [(set (match_dup 0) (match_dup 1))
9897 (clobber (reg:CC FLAGS_REG))])]
9898 {
9899 enum machine_mode mode = GET_MODE (operands[0]);
9900 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9901 rtx tmp;
9902
9903 operands[0] = adjust_address (operands[0], QImode, size - 1);
9904 if (GET_CODE (operands[1]) == ABS)
9905 {
9906 tmp = gen_int_mode (0x7f, QImode);
9907 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9908 }
9909 else
9910 {
9911 tmp = gen_int_mode (0x80, QImode);
9912 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9913 }
9914 operands[1] = tmp;
9915 })
9916
9917 ;; Conditionalize these after reload. If they match before reload, we
9918 ;; lose the clobber and ability to use integer instructions.
9919
9920 (define_insn "*negsf2_1"
9921 [(set (match_operand:SF 0 "register_operand" "=f")
9922 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9923 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9924 "fchs"
9925 [(set_attr "type" "fsgn")
9926 (set_attr "mode" "SF")])
9927
9928 (define_insn "*negdf2_1"
9929 [(set (match_operand:DF 0 "register_operand" "=f")
9930 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9931 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9932 "fchs"
9933 [(set_attr "type" "fsgn")
9934 (set_attr "mode" "DF")])
9935
9936 (define_insn "*negxf2_1"
9937 [(set (match_operand:XF 0 "register_operand" "=f")
9938 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9939 "TARGET_80387"
9940 "fchs"
9941 [(set_attr "type" "fsgn")
9942 (set_attr "mode" "XF")])
9943
9944 (define_insn "*abssf2_1"
9945 [(set (match_operand:SF 0 "register_operand" "=f")
9946 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9947 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9948 "fabs"
9949 [(set_attr "type" "fsgn")
9950 (set_attr "mode" "SF")])
9951
9952 (define_insn "*absdf2_1"
9953 [(set (match_operand:DF 0 "register_operand" "=f")
9954 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9955 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9956 "fabs"
9957 [(set_attr "type" "fsgn")
9958 (set_attr "mode" "DF")])
9959
9960 (define_insn "*absxf2_1"
9961 [(set (match_operand:XF 0 "register_operand" "=f")
9962 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9963 "TARGET_80387"
9964 "fabs"
9965 [(set_attr "type" "fsgn")
9966 (set_attr "mode" "DF")])
9967
9968 (define_insn "*negextendsfdf2"
9969 [(set (match_operand:DF 0 "register_operand" "=f")
9970 (neg:DF (float_extend:DF
9971 (match_operand:SF 1 "register_operand" "0"))))]
9972 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9973 "fchs"
9974 [(set_attr "type" "fsgn")
9975 (set_attr "mode" "DF")])
9976
9977 (define_insn "*negextenddfxf2"
9978 [(set (match_operand:XF 0 "register_operand" "=f")
9979 (neg:XF (float_extend:XF
9980 (match_operand:DF 1 "register_operand" "0"))))]
9981 "TARGET_80387"
9982 "fchs"
9983 [(set_attr "type" "fsgn")
9984 (set_attr "mode" "XF")])
9985
9986 (define_insn "*negextendsfxf2"
9987 [(set (match_operand:XF 0 "register_operand" "=f")
9988 (neg:XF (float_extend:XF
9989 (match_operand:SF 1 "register_operand" "0"))))]
9990 "TARGET_80387"
9991 "fchs"
9992 [(set_attr "type" "fsgn")
9993 (set_attr "mode" "XF")])
9994
9995 (define_insn "*absextendsfdf2"
9996 [(set (match_operand:DF 0 "register_operand" "=f")
9997 (abs:DF (float_extend:DF
9998 (match_operand:SF 1 "register_operand" "0"))))]
9999 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10000 "fabs"
10001 [(set_attr "type" "fsgn")
10002 (set_attr "mode" "DF")])
10003
10004 (define_insn "*absextenddfxf2"
10005 [(set (match_operand:XF 0 "register_operand" "=f")
10006 (abs:XF (float_extend:XF
10007 (match_operand:DF 1 "register_operand" "0"))))]
10008 "TARGET_80387"
10009 "fabs"
10010 [(set_attr "type" "fsgn")
10011 (set_attr "mode" "XF")])
10012
10013 (define_insn "*absextendsfxf2"
10014 [(set (match_operand:XF 0 "register_operand" "=f")
10015 (abs:XF (float_extend:XF
10016 (match_operand:SF 1 "register_operand" "0"))))]
10017 "TARGET_80387"
10018 "fabs"
10019 [(set_attr "type" "fsgn")
10020 (set_attr "mode" "XF")])
10021 \f
10022 ;; One complement instructions
10023
10024 (define_expand "one_cmpldi2"
10025 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10026 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10027 "TARGET_64BIT"
10028 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10029
10030 (define_insn "*one_cmpldi2_1_rex64"
10031 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10032 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10033 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10034 "not{q}\t%0"
10035 [(set_attr "type" "negnot")
10036 (set_attr "mode" "DI")])
10037
10038 (define_insn "*one_cmpldi2_2_rex64"
10039 [(set (reg FLAGS_REG)
10040 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10041 (const_int 0)))
10042 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10043 (not:DI (match_dup 1)))]
10044 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10045 && ix86_unary_operator_ok (NOT, DImode, operands)"
10046 "#"
10047 [(set_attr "type" "alu1")
10048 (set_attr "mode" "DI")])
10049
10050 (define_split
10051 [(set (match_operand 0 "flags_reg_operand" "")
10052 (match_operator 2 "compare_operator"
10053 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10054 (const_int 0)]))
10055 (set (match_operand:DI 1 "nonimmediate_operand" "")
10056 (not:DI (match_dup 3)))]
10057 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10058 [(parallel [(set (match_dup 0)
10059 (match_op_dup 2
10060 [(xor:DI (match_dup 3) (const_int -1))
10061 (const_int 0)]))
10062 (set (match_dup 1)
10063 (xor:DI (match_dup 3) (const_int -1)))])]
10064 "")
10065
10066 (define_expand "one_cmplsi2"
10067 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10068 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10069 ""
10070 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10071
10072 (define_insn "*one_cmplsi2_1"
10073 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10074 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10075 "ix86_unary_operator_ok (NOT, SImode, operands)"
10076 "not{l}\t%0"
10077 [(set_attr "type" "negnot")
10078 (set_attr "mode" "SI")])
10079
10080 ;; ??? Currently never generated - xor is used instead.
10081 (define_insn "*one_cmplsi2_1_zext"
10082 [(set (match_operand:DI 0 "register_operand" "=r")
10083 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10084 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10085 "not{l}\t%k0"
10086 [(set_attr "type" "negnot")
10087 (set_attr "mode" "SI")])
10088
10089 (define_insn "*one_cmplsi2_2"
10090 [(set (reg FLAGS_REG)
10091 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10092 (const_int 0)))
10093 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10094 (not:SI (match_dup 1)))]
10095 "ix86_match_ccmode (insn, CCNOmode)
10096 && ix86_unary_operator_ok (NOT, SImode, operands)"
10097 "#"
10098 [(set_attr "type" "alu1")
10099 (set_attr "mode" "SI")])
10100
10101 (define_split
10102 [(set (match_operand 0 "flags_reg_operand" "")
10103 (match_operator 2 "compare_operator"
10104 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10105 (const_int 0)]))
10106 (set (match_operand:SI 1 "nonimmediate_operand" "")
10107 (not:SI (match_dup 3)))]
10108 "ix86_match_ccmode (insn, CCNOmode)"
10109 [(parallel [(set (match_dup 0)
10110 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10111 (const_int 0)]))
10112 (set (match_dup 1)
10113 (xor:SI (match_dup 3) (const_int -1)))])]
10114 "")
10115
10116 ;; ??? Currently never generated - xor is used instead.
10117 (define_insn "*one_cmplsi2_2_zext"
10118 [(set (reg FLAGS_REG)
10119 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10120 (const_int 0)))
10121 (set (match_operand:DI 0 "register_operand" "=r")
10122 (zero_extend:DI (not:SI (match_dup 1))))]
10123 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10124 && ix86_unary_operator_ok (NOT, SImode, operands)"
10125 "#"
10126 [(set_attr "type" "alu1")
10127 (set_attr "mode" "SI")])
10128
10129 (define_split
10130 [(set (match_operand 0 "flags_reg_operand" "")
10131 (match_operator 2 "compare_operator"
10132 [(not:SI (match_operand:SI 3 "register_operand" ""))
10133 (const_int 0)]))
10134 (set (match_operand:DI 1 "register_operand" "")
10135 (zero_extend:DI (not:SI (match_dup 3))))]
10136 "ix86_match_ccmode (insn, CCNOmode)"
10137 [(parallel [(set (match_dup 0)
10138 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10139 (const_int 0)]))
10140 (set (match_dup 1)
10141 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10142 "")
10143
10144 (define_expand "one_cmplhi2"
10145 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10146 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10147 "TARGET_HIMODE_MATH"
10148 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10149
10150 (define_insn "*one_cmplhi2_1"
10151 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10152 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10153 "ix86_unary_operator_ok (NOT, HImode, operands)"
10154 "not{w}\t%0"
10155 [(set_attr "type" "negnot")
10156 (set_attr "mode" "HI")])
10157
10158 (define_insn "*one_cmplhi2_2"
10159 [(set (reg FLAGS_REG)
10160 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10161 (const_int 0)))
10162 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10163 (not:HI (match_dup 1)))]
10164 "ix86_match_ccmode (insn, CCNOmode)
10165 && ix86_unary_operator_ok (NEG, HImode, operands)"
10166 "#"
10167 [(set_attr "type" "alu1")
10168 (set_attr "mode" "HI")])
10169
10170 (define_split
10171 [(set (match_operand 0 "flags_reg_operand" "")
10172 (match_operator 2 "compare_operator"
10173 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10174 (const_int 0)]))
10175 (set (match_operand:HI 1 "nonimmediate_operand" "")
10176 (not:HI (match_dup 3)))]
10177 "ix86_match_ccmode (insn, CCNOmode)"
10178 [(parallel [(set (match_dup 0)
10179 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10180 (const_int 0)]))
10181 (set (match_dup 1)
10182 (xor:HI (match_dup 3) (const_int -1)))])]
10183 "")
10184
10185 ;; %%% Potential partial reg stall on alternative 1. What to do?
10186 (define_expand "one_cmplqi2"
10187 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10188 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10189 "TARGET_QIMODE_MATH"
10190 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10191
10192 (define_insn "*one_cmplqi2_1"
10193 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10194 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10195 "ix86_unary_operator_ok (NOT, QImode, operands)"
10196 "@
10197 not{b}\t%0
10198 not{l}\t%k0"
10199 [(set_attr "type" "negnot")
10200 (set_attr "mode" "QI,SI")])
10201
10202 (define_insn "*one_cmplqi2_2"
10203 [(set (reg FLAGS_REG)
10204 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10205 (const_int 0)))
10206 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10207 (not:QI (match_dup 1)))]
10208 "ix86_match_ccmode (insn, CCNOmode)
10209 && ix86_unary_operator_ok (NOT, QImode, operands)"
10210 "#"
10211 [(set_attr "type" "alu1")
10212 (set_attr "mode" "QI")])
10213
10214 (define_split
10215 [(set (match_operand 0 "flags_reg_operand" "")
10216 (match_operator 2 "compare_operator"
10217 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10218 (const_int 0)]))
10219 (set (match_operand:QI 1 "nonimmediate_operand" "")
10220 (not:QI (match_dup 3)))]
10221 "ix86_match_ccmode (insn, CCNOmode)"
10222 [(parallel [(set (match_dup 0)
10223 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10224 (const_int 0)]))
10225 (set (match_dup 1)
10226 (xor:QI (match_dup 3) (const_int -1)))])]
10227 "")
10228 \f
10229 ;; Arithmetic shift instructions
10230
10231 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10232 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10233 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10234 ;; from the assembler input.
10235 ;;
10236 ;; This instruction shifts the target reg/mem as usual, but instead of
10237 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10238 ;; is a left shift double, bits are taken from the high order bits of
10239 ;; reg, else if the insn is a shift right double, bits are taken from the
10240 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10241 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10242 ;;
10243 ;; Since sh[lr]d does not change the `reg' operand, that is done
10244 ;; separately, making all shifts emit pairs of shift double and normal
10245 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10246 ;; support a 63 bit shift, each shift where the count is in a reg expands
10247 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10248 ;;
10249 ;; If the shift count is a constant, we need never emit more than one
10250 ;; shift pair, instead using moves and sign extension for counts greater
10251 ;; than 31.
10252
10253 (define_expand "ashlti3"
10254 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10255 (ashift:TI (match_operand:TI 1 "register_operand" "")
10256 (match_operand:QI 2 "nonmemory_operand" "")))
10257 (clobber (reg:CC FLAGS_REG))])]
10258 "TARGET_64BIT"
10259 {
10260 if (! immediate_operand (operands[2], QImode))
10261 {
10262 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10263 DONE;
10264 }
10265 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10266 DONE;
10267 })
10268
10269 (define_insn "ashlti3_1"
10270 [(set (match_operand:TI 0 "register_operand" "=r")
10271 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10272 (match_operand:QI 2 "register_operand" "c")))
10273 (clobber (match_scratch:DI 3 "=&r"))
10274 (clobber (reg:CC FLAGS_REG))]
10275 "TARGET_64BIT"
10276 "#"
10277 [(set_attr "type" "multi")])
10278
10279 (define_insn "*ashlti3_2"
10280 [(set (match_operand:TI 0 "register_operand" "=r")
10281 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10282 (match_operand:QI 2 "immediate_operand" "O")))
10283 (clobber (reg:CC FLAGS_REG))]
10284 "TARGET_64BIT"
10285 "#"
10286 [(set_attr "type" "multi")])
10287
10288 (define_split
10289 [(set (match_operand:TI 0 "register_operand" "")
10290 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10291 (match_operand:QI 2 "register_operand" "")))
10292 (clobber (match_scratch:DI 3 ""))
10293 (clobber (reg:CC FLAGS_REG))]
10294 "TARGET_64BIT && reload_completed"
10295 [(const_int 0)]
10296 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10297
10298 (define_split
10299 [(set (match_operand:TI 0 "register_operand" "")
10300 (ashift:TI (match_operand:TI 1 "register_operand" "")
10301 (match_operand:QI 2 "immediate_operand" "")))
10302 (clobber (reg:CC FLAGS_REG))]
10303 "TARGET_64BIT && reload_completed"
10304 [(const_int 0)]
10305 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10306
10307 (define_insn "x86_64_shld"
10308 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10309 (ior:DI (ashift:DI (match_dup 0)
10310 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10311 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10312 (minus:QI (const_int 64) (match_dup 2)))))
10313 (clobber (reg:CC FLAGS_REG))]
10314 "TARGET_64BIT"
10315 "@
10316 shld{q}\t{%2, %1, %0|%0, %1, %2}
10317 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10318 [(set_attr "type" "ishift")
10319 (set_attr "prefix_0f" "1")
10320 (set_attr "mode" "DI")
10321 (set_attr "athlon_decode" "vector")])
10322
10323 (define_expand "x86_64_shift_adj"
10324 [(set (reg:CCZ FLAGS_REG)
10325 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10326 (const_int 64))
10327 (const_int 0)))
10328 (set (match_operand:DI 0 "register_operand" "")
10329 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10330 (match_operand:DI 1 "register_operand" "")
10331 (match_dup 0)))
10332 (set (match_dup 1)
10333 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10334 (match_operand:DI 3 "register_operand" "r")
10335 (match_dup 1)))]
10336 "TARGET_64BIT"
10337 "")
10338
10339 (define_expand "ashldi3"
10340 [(set (match_operand:DI 0 "shiftdi_operand" "")
10341 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10342 (match_operand:QI 2 "nonmemory_operand" "")))]
10343 ""
10344 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10345
10346 (define_insn "*ashldi3_1_rex64"
10347 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10348 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10349 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10350 (clobber (reg:CC FLAGS_REG))]
10351 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10352 {
10353 switch (get_attr_type (insn))
10354 {
10355 case TYPE_ALU:
10356 gcc_assert (operands[2] == const1_rtx);
10357 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10358 return "add{q}\t{%0, %0|%0, %0}";
10359
10360 case TYPE_LEA:
10361 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10362 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10363 operands[1] = gen_rtx_MULT (DImode, operands[1],
10364 GEN_INT (1 << INTVAL (operands[2])));
10365 return "lea{q}\t{%a1, %0|%0, %a1}";
10366
10367 default:
10368 if (REG_P (operands[2]))
10369 return "sal{q}\t{%b2, %0|%0, %b2}";
10370 else if (operands[2] == const1_rtx
10371 && (TARGET_SHIFT1 || optimize_size))
10372 return "sal{q}\t%0";
10373 else
10374 return "sal{q}\t{%2, %0|%0, %2}";
10375 }
10376 }
10377 [(set (attr "type")
10378 (cond [(eq_attr "alternative" "1")
10379 (const_string "lea")
10380 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10381 (const_int 0))
10382 (match_operand 0 "register_operand" ""))
10383 (match_operand 2 "const1_operand" ""))
10384 (const_string "alu")
10385 ]
10386 (const_string "ishift")))
10387 (set_attr "mode" "DI")])
10388
10389 ;; Convert lea to the lea pattern to avoid flags dependency.
10390 (define_split
10391 [(set (match_operand:DI 0 "register_operand" "")
10392 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10393 (match_operand:QI 2 "immediate_operand" "")))
10394 (clobber (reg:CC FLAGS_REG))]
10395 "TARGET_64BIT && reload_completed
10396 && true_regnum (operands[0]) != true_regnum (operands[1])"
10397 [(set (match_dup 0)
10398 (mult:DI (match_dup 1)
10399 (match_dup 2)))]
10400 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10401
10402 ;; This pattern can't accept a variable shift count, since shifts by
10403 ;; zero don't affect the flags. We assume that shifts by constant
10404 ;; zero are optimized away.
10405 (define_insn "*ashldi3_cmp_rex64"
10406 [(set (reg FLAGS_REG)
10407 (compare
10408 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10409 (match_operand:QI 2 "immediate_operand" "e"))
10410 (const_int 0)))
10411 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10412 (ashift:DI (match_dup 1) (match_dup 2)))]
10413 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10414 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10415 && (optimize_size
10416 || !TARGET_PARTIAL_FLAG_REG_STALL
10417 || (operands[2] == const1_rtx
10418 && (TARGET_SHIFT1
10419 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10420 {
10421 switch (get_attr_type (insn))
10422 {
10423 case TYPE_ALU:
10424 gcc_assert (operands[2] == const1_rtx);
10425 return "add{q}\t{%0, %0|%0, %0}";
10426
10427 default:
10428 if (REG_P (operands[2]))
10429 return "sal{q}\t{%b2, %0|%0, %b2}";
10430 else if (operands[2] == const1_rtx
10431 && (TARGET_SHIFT1 || optimize_size))
10432 return "sal{q}\t%0";
10433 else
10434 return "sal{q}\t{%2, %0|%0, %2}";
10435 }
10436 }
10437 [(set (attr "type")
10438 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10439 (const_int 0))
10440 (match_operand 0 "register_operand" ""))
10441 (match_operand 2 "const1_operand" ""))
10442 (const_string "alu")
10443 ]
10444 (const_string "ishift")))
10445 (set_attr "mode" "DI")])
10446
10447 (define_insn "*ashldi3_cconly_rex64"
10448 [(set (reg FLAGS_REG)
10449 (compare
10450 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10451 (match_operand:QI 2 "immediate_operand" "e"))
10452 (const_int 0)))
10453 (clobber (match_scratch:DI 0 "=r"))]
10454 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10455 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10456 && (optimize_size
10457 || !TARGET_PARTIAL_FLAG_REG_STALL
10458 || (operands[2] == const1_rtx
10459 && (TARGET_SHIFT1
10460 || TARGET_DOUBLE_WITH_ADD)))"
10461 {
10462 switch (get_attr_type (insn))
10463 {
10464 case TYPE_ALU:
10465 gcc_assert (operands[2] == const1_rtx);
10466 return "add{q}\t{%0, %0|%0, %0}";
10467
10468 default:
10469 if (REG_P (operands[2]))
10470 return "sal{q}\t{%b2, %0|%0, %b2}";
10471 else if (operands[2] == const1_rtx
10472 && (TARGET_SHIFT1 || optimize_size))
10473 return "sal{q}\t%0";
10474 else
10475 return "sal{q}\t{%2, %0|%0, %2}";
10476 }
10477 }
10478 [(set (attr "type")
10479 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10480 (const_int 0))
10481 (match_operand 0 "register_operand" ""))
10482 (match_operand 2 "const1_operand" ""))
10483 (const_string "alu")
10484 ]
10485 (const_string "ishift")))
10486 (set_attr "mode" "DI")])
10487
10488 (define_insn "*ashldi3_1"
10489 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10490 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10491 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10492 (clobber (reg:CC FLAGS_REG))]
10493 "!TARGET_64BIT"
10494 "#"
10495 [(set_attr "type" "multi")])
10496
10497 ;; By default we don't ask for a scratch register, because when DImode
10498 ;; values are manipulated, registers are already at a premium. But if
10499 ;; we have one handy, we won't turn it away.
10500 (define_peephole2
10501 [(match_scratch:SI 3 "r")
10502 (parallel [(set (match_operand:DI 0 "register_operand" "")
10503 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10504 (match_operand:QI 2 "nonmemory_operand" "")))
10505 (clobber (reg:CC FLAGS_REG))])
10506 (match_dup 3)]
10507 "!TARGET_64BIT && TARGET_CMOVE"
10508 [(const_int 0)]
10509 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10510
10511 (define_split
10512 [(set (match_operand:DI 0 "register_operand" "")
10513 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10514 (match_operand:QI 2 "nonmemory_operand" "")))
10515 (clobber (reg:CC FLAGS_REG))]
10516 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10517 ? flow2_completed : reload_completed)"
10518 [(const_int 0)]
10519 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10520
10521 (define_insn "x86_shld_1"
10522 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10523 (ior:SI (ashift:SI (match_dup 0)
10524 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10525 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10526 (minus:QI (const_int 32) (match_dup 2)))))
10527 (clobber (reg:CC FLAGS_REG))]
10528 ""
10529 "@
10530 shld{l}\t{%2, %1, %0|%0, %1, %2}
10531 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10532 [(set_attr "type" "ishift")
10533 (set_attr "prefix_0f" "1")
10534 (set_attr "mode" "SI")
10535 (set_attr "pent_pair" "np")
10536 (set_attr "athlon_decode" "vector")])
10537
10538 (define_expand "x86_shift_adj_1"
10539 [(set (reg:CCZ FLAGS_REG)
10540 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10541 (const_int 32))
10542 (const_int 0)))
10543 (set (match_operand:SI 0 "register_operand" "")
10544 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10545 (match_operand:SI 1 "register_operand" "")
10546 (match_dup 0)))
10547 (set (match_dup 1)
10548 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10549 (match_operand:SI 3 "register_operand" "r")
10550 (match_dup 1)))]
10551 "TARGET_CMOVE"
10552 "")
10553
10554 (define_expand "x86_shift_adj_2"
10555 [(use (match_operand:SI 0 "register_operand" ""))
10556 (use (match_operand:SI 1 "register_operand" ""))
10557 (use (match_operand:QI 2 "register_operand" ""))]
10558 ""
10559 {
10560 rtx label = gen_label_rtx ();
10561 rtx tmp;
10562
10563 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10564
10565 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10566 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10567 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10568 gen_rtx_LABEL_REF (VOIDmode, label),
10569 pc_rtx);
10570 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10571 JUMP_LABEL (tmp) = label;
10572
10573 emit_move_insn (operands[0], operands[1]);
10574 ix86_expand_clear (operands[1]);
10575
10576 emit_label (label);
10577 LABEL_NUSES (label) = 1;
10578
10579 DONE;
10580 })
10581
10582 (define_expand "ashlsi3"
10583 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10584 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10585 (match_operand:QI 2 "nonmemory_operand" "")))
10586 (clobber (reg:CC FLAGS_REG))]
10587 ""
10588 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10589
10590 (define_insn "*ashlsi3_1"
10591 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10592 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10593 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10594 (clobber (reg:CC FLAGS_REG))]
10595 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10596 {
10597 switch (get_attr_type (insn))
10598 {
10599 case TYPE_ALU:
10600 gcc_assert (operands[2] == const1_rtx);
10601 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10602 return "add{l}\t{%0, %0|%0, %0}";
10603
10604 case TYPE_LEA:
10605 return "#";
10606
10607 default:
10608 if (REG_P (operands[2]))
10609 return "sal{l}\t{%b2, %0|%0, %b2}";
10610 else if (operands[2] == const1_rtx
10611 && (TARGET_SHIFT1 || optimize_size))
10612 return "sal{l}\t%0";
10613 else
10614 return "sal{l}\t{%2, %0|%0, %2}";
10615 }
10616 }
10617 [(set (attr "type")
10618 (cond [(eq_attr "alternative" "1")
10619 (const_string "lea")
10620 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10621 (const_int 0))
10622 (match_operand 0 "register_operand" ""))
10623 (match_operand 2 "const1_operand" ""))
10624 (const_string "alu")
10625 ]
10626 (const_string "ishift")))
10627 (set_attr "mode" "SI")])
10628
10629 ;; Convert lea to the lea pattern to avoid flags dependency.
10630 (define_split
10631 [(set (match_operand 0 "register_operand" "")
10632 (ashift (match_operand 1 "index_register_operand" "")
10633 (match_operand:QI 2 "const_int_operand" "")))
10634 (clobber (reg:CC FLAGS_REG))]
10635 "reload_completed
10636 && true_regnum (operands[0]) != true_regnum (operands[1])
10637 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10638 [(const_int 0)]
10639 {
10640 rtx pat;
10641 enum machine_mode mode = GET_MODE (operands[0]);
10642
10643 if (GET_MODE_SIZE (mode) < 4)
10644 operands[0] = gen_lowpart (SImode, operands[0]);
10645 if (mode != Pmode)
10646 operands[1] = gen_lowpart (Pmode, operands[1]);
10647 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10648
10649 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10650 if (Pmode != SImode)
10651 pat = gen_rtx_SUBREG (SImode, pat, 0);
10652 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10653 DONE;
10654 })
10655
10656 ;; Rare case of shifting RSP is handled by generating move and shift
10657 (define_split
10658 [(set (match_operand 0 "register_operand" "")
10659 (ashift (match_operand 1 "register_operand" "")
10660 (match_operand:QI 2 "const_int_operand" "")))
10661 (clobber (reg:CC FLAGS_REG))]
10662 "reload_completed
10663 && true_regnum (operands[0]) != true_regnum (operands[1])"
10664 [(const_int 0)]
10665 {
10666 rtx pat, clob;
10667 emit_move_insn (operands[0], operands[1]);
10668 pat = gen_rtx_SET (VOIDmode, operands[0],
10669 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10670 operands[0], operands[2]));
10671 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10672 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10673 DONE;
10674 })
10675
10676 (define_insn "*ashlsi3_1_zext"
10677 [(set (match_operand:DI 0 "register_operand" "=r,r")
10678 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10679 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10680 (clobber (reg:CC FLAGS_REG))]
10681 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10682 {
10683 switch (get_attr_type (insn))
10684 {
10685 case TYPE_ALU:
10686 gcc_assert (operands[2] == const1_rtx);
10687 return "add{l}\t{%k0, %k0|%k0, %k0}";
10688
10689 case TYPE_LEA:
10690 return "#";
10691
10692 default:
10693 if (REG_P (operands[2]))
10694 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10695 else if (operands[2] == const1_rtx
10696 && (TARGET_SHIFT1 || optimize_size))
10697 return "sal{l}\t%k0";
10698 else
10699 return "sal{l}\t{%2, %k0|%k0, %2}";
10700 }
10701 }
10702 [(set (attr "type")
10703 (cond [(eq_attr "alternative" "1")
10704 (const_string "lea")
10705 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10706 (const_int 0))
10707 (match_operand 2 "const1_operand" ""))
10708 (const_string "alu")
10709 ]
10710 (const_string "ishift")))
10711 (set_attr "mode" "SI")])
10712
10713 ;; Convert lea to the lea pattern to avoid flags dependency.
10714 (define_split
10715 [(set (match_operand:DI 0 "register_operand" "")
10716 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10717 (match_operand:QI 2 "const_int_operand" ""))))
10718 (clobber (reg:CC FLAGS_REG))]
10719 "TARGET_64BIT && reload_completed
10720 && true_regnum (operands[0]) != true_regnum (operands[1])"
10721 [(set (match_dup 0) (zero_extend:DI
10722 (subreg:SI (mult:SI (match_dup 1)
10723 (match_dup 2)) 0)))]
10724 {
10725 operands[1] = gen_lowpart (Pmode, operands[1]);
10726 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10727 })
10728
10729 ;; This pattern can't accept a variable shift count, since shifts by
10730 ;; zero don't affect the flags. We assume that shifts by constant
10731 ;; zero are optimized away.
10732 (define_insn "*ashlsi3_cmp"
10733 [(set (reg FLAGS_REG)
10734 (compare
10735 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10736 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10737 (const_int 0)))
10738 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10739 (ashift:SI (match_dup 1) (match_dup 2)))]
10740 "ix86_match_ccmode (insn, CCGOCmode)
10741 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10742 && (optimize_size
10743 || !TARGET_PARTIAL_FLAG_REG_STALL
10744 || (operands[2] == const1_rtx
10745 && (TARGET_SHIFT1
10746 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10747 {
10748 switch (get_attr_type (insn))
10749 {
10750 case TYPE_ALU:
10751 gcc_assert (operands[2] == const1_rtx);
10752 return "add{l}\t{%0, %0|%0, %0}";
10753
10754 default:
10755 if (REG_P (operands[2]))
10756 return "sal{l}\t{%b2, %0|%0, %b2}";
10757 else if (operands[2] == const1_rtx
10758 && (TARGET_SHIFT1 || optimize_size))
10759 return "sal{l}\t%0";
10760 else
10761 return "sal{l}\t{%2, %0|%0, %2}";
10762 }
10763 }
10764 [(set (attr "type")
10765 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10766 (const_int 0))
10767 (match_operand 0 "register_operand" ""))
10768 (match_operand 2 "const1_operand" ""))
10769 (const_string "alu")
10770 ]
10771 (const_string "ishift")))
10772 (set_attr "mode" "SI")])
10773
10774 (define_insn "*ashlsi3_cconly"
10775 [(set (reg FLAGS_REG)
10776 (compare
10777 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10778 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10779 (const_int 0)))
10780 (clobber (match_scratch:SI 0 "=r"))]
10781 "ix86_match_ccmode (insn, CCGOCmode)
10782 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10783 && (optimize_size
10784 || !TARGET_PARTIAL_FLAG_REG_STALL
10785 || (operands[2] == const1_rtx
10786 && (TARGET_SHIFT1
10787 || TARGET_DOUBLE_WITH_ADD)))"
10788 {
10789 switch (get_attr_type (insn))
10790 {
10791 case TYPE_ALU:
10792 gcc_assert (operands[2] == const1_rtx);
10793 return "add{l}\t{%0, %0|%0, %0}";
10794
10795 default:
10796 if (REG_P (operands[2]))
10797 return "sal{l}\t{%b2, %0|%0, %b2}";
10798 else if (operands[2] == const1_rtx
10799 && (TARGET_SHIFT1 || optimize_size))
10800 return "sal{l}\t%0";
10801 else
10802 return "sal{l}\t{%2, %0|%0, %2}";
10803 }
10804 }
10805 [(set (attr "type")
10806 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10807 (const_int 0))
10808 (match_operand 0 "register_operand" ""))
10809 (match_operand 2 "const1_operand" ""))
10810 (const_string "alu")
10811 ]
10812 (const_string "ishift")))
10813 (set_attr "mode" "SI")])
10814
10815 (define_insn "*ashlsi3_cmp_zext"
10816 [(set (reg FLAGS_REG)
10817 (compare
10818 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10819 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10820 (const_int 0)))
10821 (set (match_operand:DI 0 "register_operand" "=r")
10822 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10823 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10824 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10825 && (optimize_size
10826 || !TARGET_PARTIAL_FLAG_REG_STALL
10827 || (operands[2] == const1_rtx
10828 && (TARGET_SHIFT1
10829 || TARGET_DOUBLE_WITH_ADD)))"
10830 {
10831 switch (get_attr_type (insn))
10832 {
10833 case TYPE_ALU:
10834 gcc_assert (operands[2] == const1_rtx);
10835 return "add{l}\t{%k0, %k0|%k0, %k0}";
10836
10837 default:
10838 if (REG_P (operands[2]))
10839 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10840 else if (operands[2] == const1_rtx
10841 && (TARGET_SHIFT1 || optimize_size))
10842 return "sal{l}\t%k0";
10843 else
10844 return "sal{l}\t{%2, %k0|%k0, %2}";
10845 }
10846 }
10847 [(set (attr "type")
10848 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10849 (const_int 0))
10850 (match_operand 2 "const1_operand" ""))
10851 (const_string "alu")
10852 ]
10853 (const_string "ishift")))
10854 (set_attr "mode" "SI")])
10855
10856 (define_expand "ashlhi3"
10857 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10858 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10859 (match_operand:QI 2 "nonmemory_operand" "")))
10860 (clobber (reg:CC FLAGS_REG))]
10861 "TARGET_HIMODE_MATH"
10862 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10863
10864 (define_insn "*ashlhi3_1_lea"
10865 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10866 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10867 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10868 (clobber (reg:CC FLAGS_REG))]
10869 "!TARGET_PARTIAL_REG_STALL
10870 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10871 {
10872 switch (get_attr_type (insn))
10873 {
10874 case TYPE_LEA:
10875 return "#";
10876 case TYPE_ALU:
10877 gcc_assert (operands[2] == const1_rtx);
10878 return "add{w}\t{%0, %0|%0, %0}";
10879
10880 default:
10881 if (REG_P (operands[2]))
10882 return "sal{w}\t{%b2, %0|%0, %b2}";
10883 else if (operands[2] == const1_rtx
10884 && (TARGET_SHIFT1 || optimize_size))
10885 return "sal{w}\t%0";
10886 else
10887 return "sal{w}\t{%2, %0|%0, %2}";
10888 }
10889 }
10890 [(set (attr "type")
10891 (cond [(eq_attr "alternative" "1")
10892 (const_string "lea")
10893 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10894 (const_int 0))
10895 (match_operand 0 "register_operand" ""))
10896 (match_operand 2 "const1_operand" ""))
10897 (const_string "alu")
10898 ]
10899 (const_string "ishift")))
10900 (set_attr "mode" "HI,SI")])
10901
10902 (define_insn "*ashlhi3_1"
10903 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10904 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10905 (match_operand:QI 2 "nonmemory_operand" "cI")))
10906 (clobber (reg:CC FLAGS_REG))]
10907 "TARGET_PARTIAL_REG_STALL
10908 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10909 {
10910 switch (get_attr_type (insn))
10911 {
10912 case TYPE_ALU:
10913 gcc_assert (operands[2] == const1_rtx);
10914 return "add{w}\t{%0, %0|%0, %0}";
10915
10916 default:
10917 if (REG_P (operands[2]))
10918 return "sal{w}\t{%b2, %0|%0, %b2}";
10919 else if (operands[2] == const1_rtx
10920 && (TARGET_SHIFT1 || optimize_size))
10921 return "sal{w}\t%0";
10922 else
10923 return "sal{w}\t{%2, %0|%0, %2}";
10924 }
10925 }
10926 [(set (attr "type")
10927 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10928 (const_int 0))
10929 (match_operand 0 "register_operand" ""))
10930 (match_operand 2 "const1_operand" ""))
10931 (const_string "alu")
10932 ]
10933 (const_string "ishift")))
10934 (set_attr "mode" "HI")])
10935
10936 ;; This pattern can't accept a variable shift count, since shifts by
10937 ;; zero don't affect the flags. We assume that shifts by constant
10938 ;; zero are optimized away.
10939 (define_insn "*ashlhi3_cmp"
10940 [(set (reg FLAGS_REG)
10941 (compare
10942 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10943 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10944 (const_int 0)))
10945 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10946 (ashift:HI (match_dup 1) (match_dup 2)))]
10947 "ix86_match_ccmode (insn, CCGOCmode)
10948 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10949 && (optimize_size
10950 || !TARGET_PARTIAL_FLAG_REG_STALL
10951 || (operands[2] == const1_rtx
10952 && (TARGET_SHIFT1
10953 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10954 {
10955 switch (get_attr_type (insn))
10956 {
10957 case TYPE_ALU:
10958 gcc_assert (operands[2] == const1_rtx);
10959 return "add{w}\t{%0, %0|%0, %0}";
10960
10961 default:
10962 if (REG_P (operands[2]))
10963 return "sal{w}\t{%b2, %0|%0, %b2}";
10964 else if (operands[2] == const1_rtx
10965 && (TARGET_SHIFT1 || optimize_size))
10966 return "sal{w}\t%0";
10967 else
10968 return "sal{w}\t{%2, %0|%0, %2}";
10969 }
10970 }
10971 [(set (attr "type")
10972 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10973 (const_int 0))
10974 (match_operand 0 "register_operand" ""))
10975 (match_operand 2 "const1_operand" ""))
10976 (const_string "alu")
10977 ]
10978 (const_string "ishift")))
10979 (set_attr "mode" "HI")])
10980
10981 (define_insn "*ashlhi3_cconly"
10982 [(set (reg FLAGS_REG)
10983 (compare
10984 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10985 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10986 (const_int 0)))
10987 (clobber (match_scratch:HI 0 "=r"))]
10988 "ix86_match_ccmode (insn, CCGOCmode)
10989 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10990 && (optimize_size
10991 || !TARGET_PARTIAL_FLAG_REG_STALL
10992 || (operands[2] == const1_rtx
10993 && (TARGET_SHIFT1
10994 || TARGET_DOUBLE_WITH_ADD)))"
10995 {
10996 switch (get_attr_type (insn))
10997 {
10998 case TYPE_ALU:
10999 gcc_assert (operands[2] == const1_rtx);
11000 return "add{w}\t{%0, %0|%0, %0}";
11001
11002 default:
11003 if (REG_P (operands[2]))
11004 return "sal{w}\t{%b2, %0|%0, %b2}";
11005 else if (operands[2] == const1_rtx
11006 && (TARGET_SHIFT1 || optimize_size))
11007 return "sal{w}\t%0";
11008 else
11009 return "sal{w}\t{%2, %0|%0, %2}";
11010 }
11011 }
11012 [(set (attr "type")
11013 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014 (const_int 0))
11015 (match_operand 0 "register_operand" ""))
11016 (match_operand 2 "const1_operand" ""))
11017 (const_string "alu")
11018 ]
11019 (const_string "ishift")))
11020 (set_attr "mode" "HI")])
11021
11022 (define_expand "ashlqi3"
11023 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11024 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11025 (match_operand:QI 2 "nonmemory_operand" "")))
11026 (clobber (reg:CC FLAGS_REG))]
11027 "TARGET_QIMODE_MATH"
11028 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11029
11030 ;; %%% Potential partial reg stall on alternative 2. What to do?
11031
11032 (define_insn "*ashlqi3_1_lea"
11033 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11034 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11035 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11036 (clobber (reg:CC FLAGS_REG))]
11037 "!TARGET_PARTIAL_REG_STALL
11038 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11039 {
11040 switch (get_attr_type (insn))
11041 {
11042 case TYPE_LEA:
11043 return "#";
11044 case TYPE_ALU:
11045 gcc_assert (operands[2] == const1_rtx);
11046 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11047 return "add{l}\t{%k0, %k0|%k0, %k0}";
11048 else
11049 return "add{b}\t{%0, %0|%0, %0}";
11050
11051 default:
11052 if (REG_P (operands[2]))
11053 {
11054 if (get_attr_mode (insn) == MODE_SI)
11055 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11056 else
11057 return "sal{b}\t{%b2, %0|%0, %b2}";
11058 }
11059 else if (operands[2] == const1_rtx
11060 && (TARGET_SHIFT1 || optimize_size))
11061 {
11062 if (get_attr_mode (insn) == MODE_SI)
11063 return "sal{l}\t%0";
11064 else
11065 return "sal{b}\t%0";
11066 }
11067 else
11068 {
11069 if (get_attr_mode (insn) == MODE_SI)
11070 return "sal{l}\t{%2, %k0|%k0, %2}";
11071 else
11072 return "sal{b}\t{%2, %0|%0, %2}";
11073 }
11074 }
11075 }
11076 [(set (attr "type")
11077 (cond [(eq_attr "alternative" "2")
11078 (const_string "lea")
11079 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11080 (const_int 0))
11081 (match_operand 0 "register_operand" ""))
11082 (match_operand 2 "const1_operand" ""))
11083 (const_string "alu")
11084 ]
11085 (const_string "ishift")))
11086 (set_attr "mode" "QI,SI,SI")])
11087
11088 (define_insn "*ashlqi3_1"
11089 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11090 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11091 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11092 (clobber (reg:CC FLAGS_REG))]
11093 "TARGET_PARTIAL_REG_STALL
11094 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11095 {
11096 switch (get_attr_type (insn))
11097 {
11098 case TYPE_ALU:
11099 gcc_assert (operands[2] == const1_rtx);
11100 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11101 return "add{l}\t{%k0, %k0|%k0, %k0}";
11102 else
11103 return "add{b}\t{%0, %0|%0, %0}";
11104
11105 default:
11106 if (REG_P (operands[2]))
11107 {
11108 if (get_attr_mode (insn) == MODE_SI)
11109 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11110 else
11111 return "sal{b}\t{%b2, %0|%0, %b2}";
11112 }
11113 else if (operands[2] == const1_rtx
11114 && (TARGET_SHIFT1 || optimize_size))
11115 {
11116 if (get_attr_mode (insn) == MODE_SI)
11117 return "sal{l}\t%0";
11118 else
11119 return "sal{b}\t%0";
11120 }
11121 else
11122 {
11123 if (get_attr_mode (insn) == MODE_SI)
11124 return "sal{l}\t{%2, %k0|%k0, %2}";
11125 else
11126 return "sal{b}\t{%2, %0|%0, %2}";
11127 }
11128 }
11129 }
11130 [(set (attr "type")
11131 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11132 (const_int 0))
11133 (match_operand 0 "register_operand" ""))
11134 (match_operand 2 "const1_operand" ""))
11135 (const_string "alu")
11136 ]
11137 (const_string "ishift")))
11138 (set_attr "mode" "QI,SI")])
11139
11140 ;; This pattern can't accept a variable shift count, since shifts by
11141 ;; zero don't affect the flags. We assume that shifts by constant
11142 ;; zero are optimized away.
11143 (define_insn "*ashlqi3_cmp"
11144 [(set (reg FLAGS_REG)
11145 (compare
11146 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11147 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11148 (const_int 0)))
11149 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11150 (ashift:QI (match_dup 1) (match_dup 2)))]
11151 "ix86_match_ccmode (insn, CCGOCmode)
11152 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11153 && (optimize_size
11154 || !TARGET_PARTIAL_FLAG_REG_STALL
11155 || (operands[2] == const1_rtx
11156 && (TARGET_SHIFT1
11157 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11158 {
11159 switch (get_attr_type (insn))
11160 {
11161 case TYPE_ALU:
11162 gcc_assert (operands[2] == const1_rtx);
11163 return "add{b}\t{%0, %0|%0, %0}";
11164
11165 default:
11166 if (REG_P (operands[2]))
11167 return "sal{b}\t{%b2, %0|%0, %b2}";
11168 else if (operands[2] == const1_rtx
11169 && (TARGET_SHIFT1 || optimize_size))
11170 return "sal{b}\t%0";
11171 else
11172 return "sal{b}\t{%2, %0|%0, %2}";
11173 }
11174 }
11175 [(set (attr "type")
11176 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11177 (const_int 0))
11178 (match_operand 0 "register_operand" ""))
11179 (match_operand 2 "const1_operand" ""))
11180 (const_string "alu")
11181 ]
11182 (const_string "ishift")))
11183 (set_attr "mode" "QI")])
11184
11185 (define_insn "*ashlqi3_cconly"
11186 [(set (reg FLAGS_REG)
11187 (compare
11188 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11189 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11190 (const_int 0)))
11191 (clobber (match_scratch:QI 0 "=q"))]
11192 "ix86_match_ccmode (insn, CCGOCmode)
11193 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11194 && (optimize_size
11195 || !TARGET_PARTIAL_FLAG_REG_STALL
11196 || (operands[2] == const1_rtx
11197 && (TARGET_SHIFT1
11198 || TARGET_DOUBLE_WITH_ADD)))"
11199 {
11200 switch (get_attr_type (insn))
11201 {
11202 case TYPE_ALU:
11203 gcc_assert (operands[2] == const1_rtx);
11204 return "add{b}\t{%0, %0|%0, %0}";
11205
11206 default:
11207 if (REG_P (operands[2]))
11208 return "sal{b}\t{%b2, %0|%0, %b2}";
11209 else if (operands[2] == const1_rtx
11210 && (TARGET_SHIFT1 || optimize_size))
11211 return "sal{b}\t%0";
11212 else
11213 return "sal{b}\t{%2, %0|%0, %2}";
11214 }
11215 }
11216 [(set (attr "type")
11217 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11218 (const_int 0))
11219 (match_operand 0 "register_operand" ""))
11220 (match_operand 2 "const1_operand" ""))
11221 (const_string "alu")
11222 ]
11223 (const_string "ishift")))
11224 (set_attr "mode" "QI")])
11225
11226 ;; See comment above `ashldi3' about how this works.
11227
11228 (define_expand "ashrti3"
11229 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11230 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11231 (match_operand:QI 2 "nonmemory_operand" "")))
11232 (clobber (reg:CC FLAGS_REG))])]
11233 "TARGET_64BIT"
11234 {
11235 if (! immediate_operand (operands[2], QImode))
11236 {
11237 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11238 DONE;
11239 }
11240 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11241 DONE;
11242 })
11243
11244 (define_insn "ashrti3_1"
11245 [(set (match_operand:TI 0 "register_operand" "=r")
11246 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11247 (match_operand:QI 2 "register_operand" "c")))
11248 (clobber (match_scratch:DI 3 "=&r"))
11249 (clobber (reg:CC FLAGS_REG))]
11250 "TARGET_64BIT"
11251 "#"
11252 [(set_attr "type" "multi")])
11253
11254 (define_insn "*ashrti3_2"
11255 [(set (match_operand:TI 0 "register_operand" "=r")
11256 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11257 (match_operand:QI 2 "immediate_operand" "O")))
11258 (clobber (reg:CC FLAGS_REG))]
11259 "TARGET_64BIT"
11260 "#"
11261 [(set_attr "type" "multi")])
11262
11263 (define_split
11264 [(set (match_operand:TI 0 "register_operand" "")
11265 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11266 (match_operand:QI 2 "register_operand" "")))
11267 (clobber (match_scratch:DI 3 ""))
11268 (clobber (reg:CC FLAGS_REG))]
11269 "TARGET_64BIT && reload_completed"
11270 [(const_int 0)]
11271 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11272
11273 (define_split
11274 [(set (match_operand:TI 0 "register_operand" "")
11275 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11276 (match_operand:QI 2 "immediate_operand" "")))
11277 (clobber (reg:CC FLAGS_REG))]
11278 "TARGET_64BIT && reload_completed"
11279 [(const_int 0)]
11280 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11281
11282 (define_insn "x86_64_shrd"
11283 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11284 (ior:DI (ashiftrt:DI (match_dup 0)
11285 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11286 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11287 (minus:QI (const_int 64) (match_dup 2)))))
11288 (clobber (reg:CC FLAGS_REG))]
11289 "TARGET_64BIT"
11290 "@
11291 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11292 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11293 [(set_attr "type" "ishift")
11294 (set_attr "prefix_0f" "1")
11295 (set_attr "mode" "DI")
11296 (set_attr "athlon_decode" "vector")])
11297
11298 (define_expand "ashrdi3"
11299 [(set (match_operand:DI 0 "shiftdi_operand" "")
11300 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11301 (match_operand:QI 2 "nonmemory_operand" "")))]
11302 ""
11303 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11304
11305 (define_insn "*ashrdi3_63_rex64"
11306 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11307 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11308 (match_operand:DI 2 "const_int_operand" "i,i")))
11309 (clobber (reg:CC FLAGS_REG))]
11310 "TARGET_64BIT && INTVAL (operands[2]) == 63
11311 && (TARGET_USE_CLTD || optimize_size)
11312 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11313 "@
11314 {cqto|cqo}
11315 sar{q}\t{%2, %0|%0, %2}"
11316 [(set_attr "type" "imovx,ishift")
11317 (set_attr "prefix_0f" "0,*")
11318 (set_attr "length_immediate" "0,*")
11319 (set_attr "modrm" "0,1")
11320 (set_attr "mode" "DI")])
11321
11322 (define_insn "*ashrdi3_1_one_bit_rex64"
11323 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11324 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11325 (match_operand:QI 2 "const1_operand" "")))
11326 (clobber (reg:CC FLAGS_REG))]
11327 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11328 && (TARGET_SHIFT1 || optimize_size)"
11329 "sar{q}\t%0"
11330 [(set_attr "type" "ishift")
11331 (set (attr "length")
11332 (if_then_else (match_operand:DI 0 "register_operand" "")
11333 (const_string "2")
11334 (const_string "*")))])
11335
11336 (define_insn "*ashrdi3_1_rex64"
11337 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11338 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11339 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11340 (clobber (reg:CC FLAGS_REG))]
11341 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11342 "@
11343 sar{q}\t{%2, %0|%0, %2}
11344 sar{q}\t{%b2, %0|%0, %b2}"
11345 [(set_attr "type" "ishift")
11346 (set_attr "mode" "DI")])
11347
11348 ;; This pattern can't accept a variable shift count, since shifts by
11349 ;; zero don't affect the flags. We assume that shifts by constant
11350 ;; zero are optimized away.
11351 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11352 [(set (reg FLAGS_REG)
11353 (compare
11354 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11355 (match_operand:QI 2 "const1_operand" ""))
11356 (const_int 0)))
11357 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11358 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11359 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11360 && (TARGET_SHIFT1 || optimize_size)
11361 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11362 "sar{q}\t%0"
11363 [(set_attr "type" "ishift")
11364 (set (attr "length")
11365 (if_then_else (match_operand:DI 0 "register_operand" "")
11366 (const_string "2")
11367 (const_string "*")))])
11368
11369 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11370 [(set (reg FLAGS_REG)
11371 (compare
11372 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11373 (match_operand:QI 2 "const1_operand" ""))
11374 (const_int 0)))
11375 (clobber (match_scratch:DI 0 "=r"))]
11376 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11377 && (TARGET_SHIFT1 || optimize_size)
11378 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11379 "sar{q}\t%0"
11380 [(set_attr "type" "ishift")
11381 (set_attr "length" "2")])
11382
11383 ;; This pattern can't accept a variable shift count, since shifts by
11384 ;; zero don't affect the flags. We assume that shifts by constant
11385 ;; zero are optimized away.
11386 (define_insn "*ashrdi3_cmp_rex64"
11387 [(set (reg FLAGS_REG)
11388 (compare
11389 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11390 (match_operand:QI 2 "const_int_operand" "n"))
11391 (const_int 0)))
11392 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11393 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11394 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11395 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11396 && (optimize_size
11397 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11398 "sar{q}\t{%2, %0|%0, %2}"
11399 [(set_attr "type" "ishift")
11400 (set_attr "mode" "DI")])
11401
11402 (define_insn "*ashrdi3_cconly_rex64"
11403 [(set (reg FLAGS_REG)
11404 (compare
11405 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11406 (match_operand:QI 2 "const_int_operand" "n"))
11407 (const_int 0)))
11408 (clobber (match_scratch:DI 0 "=r"))]
11409 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11410 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11411 && (optimize_size
11412 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11413 "sar{q}\t{%2, %0|%0, %2}"
11414 [(set_attr "type" "ishift")
11415 (set_attr "mode" "DI")])
11416
11417 (define_insn "*ashrdi3_1"
11418 [(set (match_operand:DI 0 "register_operand" "=r")
11419 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11420 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11421 (clobber (reg:CC FLAGS_REG))]
11422 "!TARGET_64BIT"
11423 "#"
11424 [(set_attr "type" "multi")])
11425
11426 ;; By default we don't ask for a scratch register, because when DImode
11427 ;; values are manipulated, registers are already at a premium. But if
11428 ;; we have one handy, we won't turn it away.
11429 (define_peephole2
11430 [(match_scratch:SI 3 "r")
11431 (parallel [(set (match_operand:DI 0 "register_operand" "")
11432 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11433 (match_operand:QI 2 "nonmemory_operand" "")))
11434 (clobber (reg:CC FLAGS_REG))])
11435 (match_dup 3)]
11436 "!TARGET_64BIT && TARGET_CMOVE"
11437 [(const_int 0)]
11438 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11439
11440 (define_split
11441 [(set (match_operand:DI 0 "register_operand" "")
11442 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11443 (match_operand:QI 2 "nonmemory_operand" "")))
11444 (clobber (reg:CC FLAGS_REG))]
11445 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11446 ? flow2_completed : reload_completed)"
11447 [(const_int 0)]
11448 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11449
11450 (define_insn "x86_shrd_1"
11451 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11452 (ior:SI (ashiftrt:SI (match_dup 0)
11453 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11454 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11455 (minus:QI (const_int 32) (match_dup 2)))))
11456 (clobber (reg:CC FLAGS_REG))]
11457 ""
11458 "@
11459 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11460 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11461 [(set_attr "type" "ishift")
11462 (set_attr "prefix_0f" "1")
11463 (set_attr "pent_pair" "np")
11464 (set_attr "mode" "SI")])
11465
11466 (define_expand "x86_shift_adj_3"
11467 [(use (match_operand:SI 0 "register_operand" ""))
11468 (use (match_operand:SI 1 "register_operand" ""))
11469 (use (match_operand:QI 2 "register_operand" ""))]
11470 ""
11471 {
11472 rtx label = gen_label_rtx ();
11473 rtx tmp;
11474
11475 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11476
11477 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11478 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11479 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11480 gen_rtx_LABEL_REF (VOIDmode, label),
11481 pc_rtx);
11482 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11483 JUMP_LABEL (tmp) = label;
11484
11485 emit_move_insn (operands[0], operands[1]);
11486 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11487
11488 emit_label (label);
11489 LABEL_NUSES (label) = 1;
11490
11491 DONE;
11492 })
11493
11494 (define_insn "ashrsi3_31"
11495 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11496 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11497 (match_operand:SI 2 "const_int_operand" "i,i")))
11498 (clobber (reg:CC FLAGS_REG))]
11499 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11500 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11501 "@
11502 {cltd|cdq}
11503 sar{l}\t{%2, %0|%0, %2}"
11504 [(set_attr "type" "imovx,ishift")
11505 (set_attr "prefix_0f" "0,*")
11506 (set_attr "length_immediate" "0,*")
11507 (set_attr "modrm" "0,1")
11508 (set_attr "mode" "SI")])
11509
11510 (define_insn "*ashrsi3_31_zext"
11511 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11512 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11513 (match_operand:SI 2 "const_int_operand" "i,i"))))
11514 (clobber (reg:CC FLAGS_REG))]
11515 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11516 && INTVAL (operands[2]) == 31
11517 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11518 "@
11519 {cltd|cdq}
11520 sar{l}\t{%2, %k0|%k0, %2}"
11521 [(set_attr "type" "imovx,ishift")
11522 (set_attr "prefix_0f" "0,*")
11523 (set_attr "length_immediate" "0,*")
11524 (set_attr "modrm" "0,1")
11525 (set_attr "mode" "SI")])
11526
11527 (define_expand "ashrsi3"
11528 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11529 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11530 (match_operand:QI 2 "nonmemory_operand" "")))
11531 (clobber (reg:CC FLAGS_REG))]
11532 ""
11533 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11534
11535 (define_insn "*ashrsi3_1_one_bit"
11536 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11537 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11538 (match_operand:QI 2 "const1_operand" "")))
11539 (clobber (reg:CC FLAGS_REG))]
11540 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11541 && (TARGET_SHIFT1 || optimize_size)"
11542 "sar{l}\t%0"
11543 [(set_attr "type" "ishift")
11544 (set (attr "length")
11545 (if_then_else (match_operand:SI 0 "register_operand" "")
11546 (const_string "2")
11547 (const_string "*")))])
11548
11549 (define_insn "*ashrsi3_1_one_bit_zext"
11550 [(set (match_operand:DI 0 "register_operand" "=r")
11551 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11552 (match_operand:QI 2 "const1_operand" ""))))
11553 (clobber (reg:CC FLAGS_REG))]
11554 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11555 && (TARGET_SHIFT1 || optimize_size)"
11556 "sar{l}\t%k0"
11557 [(set_attr "type" "ishift")
11558 (set_attr "length" "2")])
11559
11560 (define_insn "*ashrsi3_1"
11561 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11562 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11563 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11564 (clobber (reg:CC FLAGS_REG))]
11565 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11566 "@
11567 sar{l}\t{%2, %0|%0, %2}
11568 sar{l}\t{%b2, %0|%0, %b2}"
11569 [(set_attr "type" "ishift")
11570 (set_attr "mode" "SI")])
11571
11572 (define_insn "*ashrsi3_1_zext"
11573 [(set (match_operand:DI 0 "register_operand" "=r,r")
11574 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11575 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11576 (clobber (reg:CC FLAGS_REG))]
11577 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11578 "@
11579 sar{l}\t{%2, %k0|%k0, %2}
11580 sar{l}\t{%b2, %k0|%k0, %b2}"
11581 [(set_attr "type" "ishift")
11582 (set_attr "mode" "SI")])
11583
11584 ;; This pattern can't accept a variable shift count, since shifts by
11585 ;; zero don't affect the flags. We assume that shifts by constant
11586 ;; zero are optimized away.
11587 (define_insn "*ashrsi3_one_bit_cmp"
11588 [(set (reg FLAGS_REG)
11589 (compare
11590 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11591 (match_operand:QI 2 "const1_operand" ""))
11592 (const_int 0)))
11593 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11594 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11595 "ix86_match_ccmode (insn, CCGOCmode)
11596 && (TARGET_SHIFT1 || optimize_size)
11597 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11598 "sar{l}\t%0"
11599 [(set_attr "type" "ishift")
11600 (set (attr "length")
11601 (if_then_else (match_operand:SI 0 "register_operand" "")
11602 (const_string "2")
11603 (const_string "*")))])
11604
11605 (define_insn "*ashrsi3_one_bit_cconly"
11606 [(set (reg FLAGS_REG)
11607 (compare
11608 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11609 (match_operand:QI 2 "const1_operand" ""))
11610 (const_int 0)))
11611 (clobber (match_scratch:SI 0 "=r"))]
11612 "ix86_match_ccmode (insn, CCGOCmode)
11613 && (TARGET_SHIFT1 || optimize_size)
11614 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11615 "sar{l}\t%0"
11616 [(set_attr "type" "ishift")
11617 (set_attr "length" "2")])
11618
11619 (define_insn "*ashrsi3_one_bit_cmp_zext"
11620 [(set (reg FLAGS_REG)
11621 (compare
11622 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11623 (match_operand:QI 2 "const1_operand" ""))
11624 (const_int 0)))
11625 (set (match_operand:DI 0 "register_operand" "=r")
11626 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11627 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11628 && (TARGET_SHIFT1 || optimize_size)
11629 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11630 "sar{l}\t%k0"
11631 [(set_attr "type" "ishift")
11632 (set_attr "length" "2")])
11633
11634 ;; This pattern can't accept a variable shift count, since shifts by
11635 ;; zero don't affect the flags. We assume that shifts by constant
11636 ;; zero are optimized away.
11637 (define_insn "*ashrsi3_cmp"
11638 [(set (reg FLAGS_REG)
11639 (compare
11640 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11641 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11642 (const_int 0)))
11643 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11644 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11645 "ix86_match_ccmode (insn, CCGOCmode)
11646 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11647 && (optimize_size
11648 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11649 "sar{l}\t{%2, %0|%0, %2}"
11650 [(set_attr "type" "ishift")
11651 (set_attr "mode" "SI")])
11652
11653 (define_insn "*ashrsi3_cconly"
11654 [(set (reg FLAGS_REG)
11655 (compare
11656 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11657 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11658 (const_int 0)))
11659 (clobber (match_scratch:SI 0 "=r"))]
11660 "ix86_match_ccmode (insn, CCGOCmode)
11661 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11662 && (optimize_size
11663 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11664 "sar{l}\t{%2, %0|%0, %2}"
11665 [(set_attr "type" "ishift")
11666 (set_attr "mode" "SI")])
11667
11668 (define_insn "*ashrsi3_cmp_zext"
11669 [(set (reg FLAGS_REG)
11670 (compare
11671 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11672 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11673 (const_int 0)))
11674 (set (match_operand:DI 0 "register_operand" "=r")
11675 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11676 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11677 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11678 && (optimize_size
11679 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11680 "sar{l}\t{%2, %k0|%k0, %2}"
11681 [(set_attr "type" "ishift")
11682 (set_attr "mode" "SI")])
11683
11684 (define_expand "ashrhi3"
11685 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11686 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11687 (match_operand:QI 2 "nonmemory_operand" "")))
11688 (clobber (reg:CC FLAGS_REG))]
11689 "TARGET_HIMODE_MATH"
11690 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11691
11692 (define_insn "*ashrhi3_1_one_bit"
11693 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11694 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11695 (match_operand:QI 2 "const1_operand" "")))
11696 (clobber (reg:CC FLAGS_REG))]
11697 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11698 && (TARGET_SHIFT1 || optimize_size)"
11699 "sar{w}\t%0"
11700 [(set_attr "type" "ishift")
11701 (set (attr "length")
11702 (if_then_else (match_operand 0 "register_operand" "")
11703 (const_string "2")
11704 (const_string "*")))])
11705
11706 (define_insn "*ashrhi3_1"
11707 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11708 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11709 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11710 (clobber (reg:CC FLAGS_REG))]
11711 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11712 "@
11713 sar{w}\t{%2, %0|%0, %2}
11714 sar{w}\t{%b2, %0|%0, %b2}"
11715 [(set_attr "type" "ishift")
11716 (set_attr "mode" "HI")])
11717
11718 ;; This pattern can't accept a variable shift count, since shifts by
11719 ;; zero don't affect the flags. We assume that shifts by constant
11720 ;; zero are optimized away.
11721 (define_insn "*ashrhi3_one_bit_cmp"
11722 [(set (reg FLAGS_REG)
11723 (compare
11724 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11725 (match_operand:QI 2 "const1_operand" ""))
11726 (const_int 0)))
11727 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11728 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11729 "ix86_match_ccmode (insn, CCGOCmode)
11730 && (TARGET_SHIFT1 || optimize_size)
11731 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11732 "sar{w}\t%0"
11733 [(set_attr "type" "ishift")
11734 (set (attr "length")
11735 (if_then_else (match_operand 0 "register_operand" "")
11736 (const_string "2")
11737 (const_string "*")))])
11738
11739 (define_insn "*ashrhi3_one_bit_cconly"
11740 [(set (reg FLAGS_REG)
11741 (compare
11742 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11743 (match_operand:QI 2 "const1_operand" ""))
11744 (const_int 0)))
11745 (clobber (match_scratch:HI 0 "=r"))]
11746 "ix86_match_ccmode (insn, CCGOCmode)
11747 && (TARGET_SHIFT1 || optimize_size)
11748 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11749 "sar{w}\t%0"
11750 [(set_attr "type" "ishift")
11751 (set_attr "length" "2")])
11752
11753 ;; This pattern can't accept a variable shift count, since shifts by
11754 ;; zero don't affect the flags. We assume that shifts by constant
11755 ;; zero are optimized away.
11756 (define_insn "*ashrhi3_cmp"
11757 [(set (reg FLAGS_REG)
11758 (compare
11759 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11760 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11761 (const_int 0)))
11762 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11763 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11764 "ix86_match_ccmode (insn, CCGOCmode)
11765 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11766 && (optimize_size
11767 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11768 "sar{w}\t{%2, %0|%0, %2}"
11769 [(set_attr "type" "ishift")
11770 (set_attr "mode" "HI")])
11771
11772 (define_insn "*ashrhi3_cconly"
11773 [(set (reg FLAGS_REG)
11774 (compare
11775 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11776 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11777 (const_int 0)))
11778 (clobber (match_scratch:HI 0 "=r"))]
11779 "ix86_match_ccmode (insn, CCGOCmode)
11780 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11781 && (optimize_size
11782 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11783 "sar{w}\t{%2, %0|%0, %2}"
11784 [(set_attr "type" "ishift")
11785 (set_attr "mode" "HI")])
11786
11787 (define_expand "ashrqi3"
11788 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11789 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11790 (match_operand:QI 2 "nonmemory_operand" "")))
11791 (clobber (reg:CC FLAGS_REG))]
11792 "TARGET_QIMODE_MATH"
11793 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11794
11795 (define_insn "*ashrqi3_1_one_bit"
11796 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11797 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11798 (match_operand:QI 2 "const1_operand" "")))
11799 (clobber (reg:CC FLAGS_REG))]
11800 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11801 && (TARGET_SHIFT1 || optimize_size)"
11802 "sar{b}\t%0"
11803 [(set_attr "type" "ishift")
11804 (set (attr "length")
11805 (if_then_else (match_operand 0 "register_operand" "")
11806 (const_string "2")
11807 (const_string "*")))])
11808
11809 (define_insn "*ashrqi3_1_one_bit_slp"
11810 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11811 (ashiftrt:QI (match_dup 0)
11812 (match_operand:QI 1 "const1_operand" "")))
11813 (clobber (reg:CC FLAGS_REG))]
11814 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11815 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11816 && (TARGET_SHIFT1 || optimize_size)"
11817 "sar{b}\t%0"
11818 [(set_attr "type" "ishift1")
11819 (set (attr "length")
11820 (if_then_else (match_operand 0 "register_operand" "")
11821 (const_string "2")
11822 (const_string "*")))])
11823
11824 (define_insn "*ashrqi3_1"
11825 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11826 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11827 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11828 (clobber (reg:CC FLAGS_REG))]
11829 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11830 "@
11831 sar{b}\t{%2, %0|%0, %2}
11832 sar{b}\t{%b2, %0|%0, %b2}"
11833 [(set_attr "type" "ishift")
11834 (set_attr "mode" "QI")])
11835
11836 (define_insn "*ashrqi3_1_slp"
11837 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11838 (ashiftrt:QI (match_dup 0)
11839 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11840 (clobber (reg:CC FLAGS_REG))]
11841 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11842 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11843 "@
11844 sar{b}\t{%1, %0|%0, %1}
11845 sar{b}\t{%b1, %0|%0, %b1}"
11846 [(set_attr "type" "ishift1")
11847 (set_attr "mode" "QI")])
11848
11849 ;; This pattern can't accept a variable shift count, since shifts by
11850 ;; zero don't affect the flags. We assume that shifts by constant
11851 ;; zero are optimized away.
11852 (define_insn "*ashrqi3_one_bit_cmp"
11853 [(set (reg FLAGS_REG)
11854 (compare
11855 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11856 (match_operand:QI 2 "const1_operand" "I"))
11857 (const_int 0)))
11858 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11859 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11860 "ix86_match_ccmode (insn, CCGOCmode)
11861 && (TARGET_SHIFT1 || optimize_size)
11862 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11863 "sar{b}\t%0"
11864 [(set_attr "type" "ishift")
11865 (set (attr "length")
11866 (if_then_else (match_operand 0 "register_operand" "")
11867 (const_string "2")
11868 (const_string "*")))])
11869
11870 (define_insn "*ashrqi3_one_bit_cconly"
11871 [(set (reg FLAGS_REG)
11872 (compare
11873 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11874 (match_operand:QI 2 "const1_operand" "I"))
11875 (const_int 0)))
11876 (clobber (match_scratch:QI 0 "=q"))]
11877 "ix86_match_ccmode (insn, CCGOCmode)
11878 && (TARGET_SHIFT1 || optimize_size)
11879 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11880 "sar{b}\t%0"
11881 [(set_attr "type" "ishift")
11882 (set_attr "length" "2")])
11883
11884 ;; This pattern can't accept a variable shift count, since shifts by
11885 ;; zero don't affect the flags. We assume that shifts by constant
11886 ;; zero are optimized away.
11887 (define_insn "*ashrqi3_cmp"
11888 [(set (reg FLAGS_REG)
11889 (compare
11890 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11891 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11892 (const_int 0)))
11893 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11894 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11895 "ix86_match_ccmode (insn, CCGOCmode)
11896 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11897 && (optimize_size
11898 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11899 "sar{b}\t{%2, %0|%0, %2}"
11900 [(set_attr "type" "ishift")
11901 (set_attr "mode" "QI")])
11902
11903 (define_insn "*ashrqi3_cconly"
11904 [(set (reg FLAGS_REG)
11905 (compare
11906 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11907 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11908 (const_int 0)))
11909 (clobber (match_scratch:QI 0 "=q"))]
11910 "ix86_match_ccmode (insn, CCGOCmode)
11911 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11912 && (optimize_size
11913 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11914 "sar{b}\t{%2, %0|%0, %2}"
11915 [(set_attr "type" "ishift")
11916 (set_attr "mode" "QI")])
11917
11918 \f
11919 ;; Logical shift instructions
11920
11921 ;; See comment above `ashldi3' about how this works.
11922
11923 (define_expand "lshrti3"
11924 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11925 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11926 (match_operand:QI 2 "nonmemory_operand" "")))
11927 (clobber (reg:CC FLAGS_REG))])]
11928 "TARGET_64BIT"
11929 {
11930 if (! immediate_operand (operands[2], QImode))
11931 {
11932 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11933 DONE;
11934 }
11935 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11936 DONE;
11937 })
11938
11939 (define_insn "lshrti3_1"
11940 [(set (match_operand:TI 0 "register_operand" "=r")
11941 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11942 (match_operand:QI 2 "register_operand" "c")))
11943 (clobber (match_scratch:DI 3 "=&r"))
11944 (clobber (reg:CC FLAGS_REG))]
11945 "TARGET_64BIT"
11946 "#"
11947 [(set_attr "type" "multi")])
11948
11949 (define_insn "*lshrti3_2"
11950 [(set (match_operand:TI 0 "register_operand" "=r")
11951 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11952 (match_operand:QI 2 "immediate_operand" "O")))
11953 (clobber (reg:CC FLAGS_REG))]
11954 "TARGET_64BIT"
11955 "#"
11956 [(set_attr "type" "multi")])
11957
11958 (define_split
11959 [(set (match_operand:TI 0 "register_operand" "")
11960 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11961 (match_operand:QI 2 "register_operand" "")))
11962 (clobber (match_scratch:DI 3 ""))
11963 (clobber (reg:CC FLAGS_REG))]
11964 "TARGET_64BIT && reload_completed"
11965 [(const_int 0)]
11966 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11967
11968 (define_split
11969 [(set (match_operand:TI 0 "register_operand" "")
11970 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11971 (match_operand:QI 2 "immediate_operand" "")))
11972 (clobber (reg:CC FLAGS_REG))]
11973 "TARGET_64BIT && reload_completed"
11974 [(const_int 0)]
11975 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11976
11977 (define_expand "lshrdi3"
11978 [(set (match_operand:DI 0 "shiftdi_operand" "")
11979 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11980 (match_operand:QI 2 "nonmemory_operand" "")))]
11981 ""
11982 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11983
11984 (define_insn "*lshrdi3_1_one_bit_rex64"
11985 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11986 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11987 (match_operand:QI 2 "const1_operand" "")))
11988 (clobber (reg:CC FLAGS_REG))]
11989 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11990 && (TARGET_SHIFT1 || optimize_size)"
11991 "shr{q}\t%0"
11992 [(set_attr "type" "ishift")
11993 (set (attr "length")
11994 (if_then_else (match_operand:DI 0 "register_operand" "")
11995 (const_string "2")
11996 (const_string "*")))])
11997
11998 (define_insn "*lshrdi3_1_rex64"
11999 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12000 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12001 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12002 (clobber (reg:CC FLAGS_REG))]
12003 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12004 "@
12005 shr{q}\t{%2, %0|%0, %2}
12006 shr{q}\t{%b2, %0|%0, %b2}"
12007 [(set_attr "type" "ishift")
12008 (set_attr "mode" "DI")])
12009
12010 ;; This pattern can't accept a variable shift count, since shifts by
12011 ;; zero don't affect the flags. We assume that shifts by constant
12012 ;; zero are optimized away.
12013 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12014 [(set (reg FLAGS_REG)
12015 (compare
12016 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12017 (match_operand:QI 2 "const1_operand" ""))
12018 (const_int 0)))
12019 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12020 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12021 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12022 && (TARGET_SHIFT1 || optimize_size)
12023 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12024 "shr{q}\t%0"
12025 [(set_attr "type" "ishift")
12026 (set (attr "length")
12027 (if_then_else (match_operand:DI 0 "register_operand" "")
12028 (const_string "2")
12029 (const_string "*")))])
12030
12031 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12032 [(set (reg FLAGS_REG)
12033 (compare
12034 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12035 (match_operand:QI 2 "const1_operand" ""))
12036 (const_int 0)))
12037 (clobber (match_scratch:DI 0 "=r"))]
12038 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12039 && (TARGET_SHIFT1 || optimize_size)
12040 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12041 "shr{q}\t%0"
12042 [(set_attr "type" "ishift")
12043 (set_attr "length" "2")])
12044
12045 ;; This pattern can't accept a variable shift count, since shifts by
12046 ;; zero don't affect the flags. We assume that shifts by constant
12047 ;; zero are optimized away.
12048 (define_insn "*lshrdi3_cmp_rex64"
12049 [(set (reg FLAGS_REG)
12050 (compare
12051 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12052 (match_operand:QI 2 "const_int_operand" "e"))
12053 (const_int 0)))
12054 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12055 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12056 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12057 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12058 && (optimize_size
12059 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12060 "shr{q}\t{%2, %0|%0, %2}"
12061 [(set_attr "type" "ishift")
12062 (set_attr "mode" "DI")])
12063
12064 (define_insn "*lshrdi3_cconly_rex64"
12065 [(set (reg FLAGS_REG)
12066 (compare
12067 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12068 (match_operand:QI 2 "const_int_operand" "e"))
12069 (const_int 0)))
12070 (clobber (match_scratch:DI 0 "=r"))]
12071 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12072 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12073 && (optimize_size
12074 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12075 "shr{q}\t{%2, %0|%0, %2}"
12076 [(set_attr "type" "ishift")
12077 (set_attr "mode" "DI")])
12078
12079 (define_insn "*lshrdi3_1"
12080 [(set (match_operand:DI 0 "register_operand" "=r")
12081 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12082 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12083 (clobber (reg:CC FLAGS_REG))]
12084 "!TARGET_64BIT"
12085 "#"
12086 [(set_attr "type" "multi")])
12087
12088 ;; By default we don't ask for a scratch register, because when DImode
12089 ;; values are manipulated, registers are already at a premium. But if
12090 ;; we have one handy, we won't turn it away.
12091 (define_peephole2
12092 [(match_scratch:SI 3 "r")
12093 (parallel [(set (match_operand:DI 0 "register_operand" "")
12094 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12095 (match_operand:QI 2 "nonmemory_operand" "")))
12096 (clobber (reg:CC FLAGS_REG))])
12097 (match_dup 3)]
12098 "!TARGET_64BIT && TARGET_CMOVE"
12099 [(const_int 0)]
12100 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12101
12102 (define_split
12103 [(set (match_operand:DI 0 "register_operand" "")
12104 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12105 (match_operand:QI 2 "nonmemory_operand" "")))
12106 (clobber (reg:CC FLAGS_REG))]
12107 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12108 ? flow2_completed : reload_completed)"
12109 [(const_int 0)]
12110 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12111
12112 (define_expand "lshrsi3"
12113 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12114 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12115 (match_operand:QI 2 "nonmemory_operand" "")))
12116 (clobber (reg:CC FLAGS_REG))]
12117 ""
12118 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12119
12120 (define_insn "*lshrsi3_1_one_bit"
12121 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12122 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12123 (match_operand:QI 2 "const1_operand" "")))
12124 (clobber (reg:CC FLAGS_REG))]
12125 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12126 && (TARGET_SHIFT1 || optimize_size)"
12127 "shr{l}\t%0"
12128 [(set_attr "type" "ishift")
12129 (set (attr "length")
12130 (if_then_else (match_operand:SI 0 "register_operand" "")
12131 (const_string "2")
12132 (const_string "*")))])
12133
12134 (define_insn "*lshrsi3_1_one_bit_zext"
12135 [(set (match_operand:DI 0 "register_operand" "=r")
12136 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12137 (match_operand:QI 2 "const1_operand" "")))
12138 (clobber (reg:CC FLAGS_REG))]
12139 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12140 && (TARGET_SHIFT1 || optimize_size)"
12141 "shr{l}\t%k0"
12142 [(set_attr "type" "ishift")
12143 (set_attr "length" "2")])
12144
12145 (define_insn "*lshrsi3_1"
12146 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12147 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12148 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12149 (clobber (reg:CC FLAGS_REG))]
12150 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12151 "@
12152 shr{l}\t{%2, %0|%0, %2}
12153 shr{l}\t{%b2, %0|%0, %b2}"
12154 [(set_attr "type" "ishift")
12155 (set_attr "mode" "SI")])
12156
12157 (define_insn "*lshrsi3_1_zext"
12158 [(set (match_operand:DI 0 "register_operand" "=r,r")
12159 (zero_extend:DI
12160 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12161 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12162 (clobber (reg:CC FLAGS_REG))]
12163 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12164 "@
12165 shr{l}\t{%2, %k0|%k0, %2}
12166 shr{l}\t{%b2, %k0|%k0, %b2}"
12167 [(set_attr "type" "ishift")
12168 (set_attr "mode" "SI")])
12169
12170 ;; This pattern can't accept a variable shift count, since shifts by
12171 ;; zero don't affect the flags. We assume that shifts by constant
12172 ;; zero are optimized away.
12173 (define_insn "*lshrsi3_one_bit_cmp"
12174 [(set (reg FLAGS_REG)
12175 (compare
12176 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12177 (match_operand:QI 2 "const1_operand" ""))
12178 (const_int 0)))
12179 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12180 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12181 "ix86_match_ccmode (insn, CCGOCmode)
12182 && (TARGET_SHIFT1 || optimize_size)
12183 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12184 "shr{l}\t%0"
12185 [(set_attr "type" "ishift")
12186 (set (attr "length")
12187 (if_then_else (match_operand:SI 0 "register_operand" "")
12188 (const_string "2")
12189 (const_string "*")))])
12190
12191 (define_insn "*lshrsi3_one_bit_cconly"
12192 [(set (reg FLAGS_REG)
12193 (compare
12194 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12195 (match_operand:QI 2 "const1_operand" ""))
12196 (const_int 0)))
12197 (clobber (match_scratch:SI 0 "=r"))]
12198 "ix86_match_ccmode (insn, CCGOCmode)
12199 && (TARGET_SHIFT1 || optimize_size)
12200 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12201 "shr{l}\t%0"
12202 [(set_attr "type" "ishift")
12203 (set_attr "length" "2")])
12204
12205 (define_insn "*lshrsi3_cmp_one_bit_zext"
12206 [(set (reg FLAGS_REG)
12207 (compare
12208 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12209 (match_operand:QI 2 "const1_operand" ""))
12210 (const_int 0)))
12211 (set (match_operand:DI 0 "register_operand" "=r")
12212 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12213 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12214 && (TARGET_SHIFT1 || optimize_size)
12215 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12216 "shr{l}\t%k0"
12217 [(set_attr "type" "ishift")
12218 (set_attr "length" "2")])
12219
12220 ;; This pattern can't accept a variable shift count, since shifts by
12221 ;; zero don't affect the flags. We assume that shifts by constant
12222 ;; zero are optimized away.
12223 (define_insn "*lshrsi3_cmp"
12224 [(set (reg FLAGS_REG)
12225 (compare
12226 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12227 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12228 (const_int 0)))
12229 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12230 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12231 "ix86_match_ccmode (insn, CCGOCmode)
12232 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12233 && (optimize_size
12234 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12235 "shr{l}\t{%2, %0|%0, %2}"
12236 [(set_attr "type" "ishift")
12237 (set_attr "mode" "SI")])
12238
12239 (define_insn "*lshrsi3_cconly"
12240 [(set (reg FLAGS_REG)
12241 (compare
12242 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12243 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12244 (const_int 0)))
12245 (clobber (match_scratch:SI 0 "=r"))]
12246 "ix86_match_ccmode (insn, CCGOCmode)
12247 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12248 && (optimize_size
12249 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12250 "shr{l}\t{%2, %0|%0, %2}"
12251 [(set_attr "type" "ishift")
12252 (set_attr "mode" "SI")])
12253
12254 (define_insn "*lshrsi3_cmp_zext"
12255 [(set (reg FLAGS_REG)
12256 (compare
12257 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12258 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12259 (const_int 0)))
12260 (set (match_operand:DI 0 "register_operand" "=r")
12261 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12262 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12263 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12264 && (optimize_size
12265 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12266 "shr{l}\t{%2, %k0|%k0, %2}"
12267 [(set_attr "type" "ishift")
12268 (set_attr "mode" "SI")])
12269
12270 (define_expand "lshrhi3"
12271 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12272 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12273 (match_operand:QI 2 "nonmemory_operand" "")))
12274 (clobber (reg:CC FLAGS_REG))]
12275 "TARGET_HIMODE_MATH"
12276 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12277
12278 (define_insn "*lshrhi3_1_one_bit"
12279 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12280 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12281 (match_operand:QI 2 "const1_operand" "")))
12282 (clobber (reg:CC FLAGS_REG))]
12283 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12284 && (TARGET_SHIFT1 || optimize_size)"
12285 "shr{w}\t%0"
12286 [(set_attr "type" "ishift")
12287 (set (attr "length")
12288 (if_then_else (match_operand 0 "register_operand" "")
12289 (const_string "2")
12290 (const_string "*")))])
12291
12292 (define_insn "*lshrhi3_1"
12293 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12294 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12295 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12296 (clobber (reg:CC FLAGS_REG))]
12297 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12298 "@
12299 shr{w}\t{%2, %0|%0, %2}
12300 shr{w}\t{%b2, %0|%0, %b2}"
12301 [(set_attr "type" "ishift")
12302 (set_attr "mode" "HI")])
12303
12304 ;; This pattern can't accept a variable shift count, since shifts by
12305 ;; zero don't affect the flags. We assume that shifts by constant
12306 ;; zero are optimized away.
12307 (define_insn "*lshrhi3_one_bit_cmp"
12308 [(set (reg FLAGS_REG)
12309 (compare
12310 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12311 (match_operand:QI 2 "const1_operand" ""))
12312 (const_int 0)))
12313 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12314 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12315 "ix86_match_ccmode (insn, CCGOCmode)
12316 && (TARGET_SHIFT1 || optimize_size)
12317 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12318 "shr{w}\t%0"
12319 [(set_attr "type" "ishift")
12320 (set (attr "length")
12321 (if_then_else (match_operand:SI 0 "register_operand" "")
12322 (const_string "2")
12323 (const_string "*")))])
12324
12325 (define_insn "*lshrhi3_one_bit_cconly"
12326 [(set (reg FLAGS_REG)
12327 (compare
12328 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12329 (match_operand:QI 2 "const1_operand" ""))
12330 (const_int 0)))
12331 (clobber (match_scratch:HI 0 "=r"))]
12332 "ix86_match_ccmode (insn, CCGOCmode)
12333 && (TARGET_SHIFT1 || optimize_size)
12334 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12335 "shr{w}\t%0"
12336 [(set_attr "type" "ishift")
12337 (set_attr "length" "2")])
12338
12339 ;; This pattern can't accept a variable shift count, since shifts by
12340 ;; zero don't affect the flags. We assume that shifts by constant
12341 ;; zero are optimized away.
12342 (define_insn "*lshrhi3_cmp"
12343 [(set (reg FLAGS_REG)
12344 (compare
12345 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12346 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12347 (const_int 0)))
12348 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12349 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12350 "ix86_match_ccmode (insn, CCGOCmode)
12351 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12352 && (optimize_size
12353 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12354 "shr{w}\t{%2, %0|%0, %2}"
12355 [(set_attr "type" "ishift")
12356 (set_attr "mode" "HI")])
12357
12358 (define_insn "*lshrhi3_cconly"
12359 [(set (reg FLAGS_REG)
12360 (compare
12361 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12362 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12363 (const_int 0)))
12364 (clobber (match_scratch:HI 0 "=r"))]
12365 "ix86_match_ccmode (insn, CCGOCmode)
12366 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12367 && (optimize_size
12368 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12369 "shr{w}\t{%2, %0|%0, %2}"
12370 [(set_attr "type" "ishift")
12371 (set_attr "mode" "HI")])
12372
12373 (define_expand "lshrqi3"
12374 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12375 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12376 (match_operand:QI 2 "nonmemory_operand" "")))
12377 (clobber (reg:CC FLAGS_REG))]
12378 "TARGET_QIMODE_MATH"
12379 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12380
12381 (define_insn "*lshrqi3_1_one_bit"
12382 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12383 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12384 (match_operand:QI 2 "const1_operand" "")))
12385 (clobber (reg:CC FLAGS_REG))]
12386 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12387 && (TARGET_SHIFT1 || optimize_size)"
12388 "shr{b}\t%0"
12389 [(set_attr "type" "ishift")
12390 (set (attr "length")
12391 (if_then_else (match_operand 0 "register_operand" "")
12392 (const_string "2")
12393 (const_string "*")))])
12394
12395 (define_insn "*lshrqi3_1_one_bit_slp"
12396 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12397 (lshiftrt:QI (match_dup 0)
12398 (match_operand:QI 1 "const1_operand" "")))
12399 (clobber (reg:CC FLAGS_REG))]
12400 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12401 && (TARGET_SHIFT1 || optimize_size)"
12402 "shr{b}\t%0"
12403 [(set_attr "type" "ishift1")
12404 (set (attr "length")
12405 (if_then_else (match_operand 0 "register_operand" "")
12406 (const_string "2")
12407 (const_string "*")))])
12408
12409 (define_insn "*lshrqi3_1"
12410 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12411 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12412 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12413 (clobber (reg:CC FLAGS_REG))]
12414 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12415 "@
12416 shr{b}\t{%2, %0|%0, %2}
12417 shr{b}\t{%b2, %0|%0, %b2}"
12418 [(set_attr "type" "ishift")
12419 (set_attr "mode" "QI")])
12420
12421 (define_insn "*lshrqi3_1_slp"
12422 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12423 (lshiftrt:QI (match_dup 0)
12424 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12425 (clobber (reg:CC FLAGS_REG))]
12426 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12427 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12428 "@
12429 shr{b}\t{%1, %0|%0, %1}
12430 shr{b}\t{%b1, %0|%0, %b1}"
12431 [(set_attr "type" "ishift1")
12432 (set_attr "mode" "QI")])
12433
12434 ;; This pattern can't accept a variable shift count, since shifts by
12435 ;; zero don't affect the flags. We assume that shifts by constant
12436 ;; zero are optimized away.
12437 (define_insn "*lshrqi2_one_bit_cmp"
12438 [(set (reg FLAGS_REG)
12439 (compare
12440 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12441 (match_operand:QI 2 "const1_operand" ""))
12442 (const_int 0)))
12443 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12444 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12445 "ix86_match_ccmode (insn, CCGOCmode)
12446 && (TARGET_SHIFT1 || optimize_size)
12447 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12448 "shr{b}\t%0"
12449 [(set_attr "type" "ishift")
12450 (set (attr "length")
12451 (if_then_else (match_operand:SI 0 "register_operand" "")
12452 (const_string "2")
12453 (const_string "*")))])
12454
12455 (define_insn "*lshrqi2_one_bit_cconly"
12456 [(set (reg FLAGS_REG)
12457 (compare
12458 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12459 (match_operand:QI 2 "const1_operand" ""))
12460 (const_int 0)))
12461 (clobber (match_scratch:QI 0 "=q"))]
12462 "ix86_match_ccmode (insn, CCGOCmode)
12463 && (TARGET_SHIFT1 || optimize_size)
12464 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12465 "shr{b}\t%0"
12466 [(set_attr "type" "ishift")
12467 (set_attr "length" "2")])
12468
12469 ;; This pattern can't accept a variable shift count, since shifts by
12470 ;; zero don't affect the flags. We assume that shifts by constant
12471 ;; zero are optimized away.
12472 (define_insn "*lshrqi2_cmp"
12473 [(set (reg FLAGS_REG)
12474 (compare
12475 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12476 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12477 (const_int 0)))
12478 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12479 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12480 "ix86_match_ccmode (insn, CCGOCmode)
12481 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12482 && (optimize_size
12483 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12484 "shr{b}\t{%2, %0|%0, %2}"
12485 [(set_attr "type" "ishift")
12486 (set_attr "mode" "QI")])
12487
12488 (define_insn "*lshrqi2_cconly"
12489 [(set (reg FLAGS_REG)
12490 (compare
12491 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12492 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12493 (const_int 0)))
12494 (clobber (match_scratch:QI 0 "=q"))]
12495 "ix86_match_ccmode (insn, CCGOCmode)
12496 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12497 && (optimize_size
12498 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12499 "shr{b}\t{%2, %0|%0, %2}"
12500 [(set_attr "type" "ishift")
12501 (set_attr "mode" "QI")])
12502 \f
12503 ;; Rotate instructions
12504
12505 (define_expand "rotldi3"
12506 [(set (match_operand:DI 0 "shiftdi_operand" "")
12507 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12508 (match_operand:QI 2 "nonmemory_operand" "")))
12509 (clobber (reg:CC FLAGS_REG))]
12510 ""
12511 {
12512 if (TARGET_64BIT)
12513 {
12514 ix86_expand_binary_operator (ROTATE, DImode, operands);
12515 DONE;
12516 }
12517 if (!const_1_to_31_operand (operands[2], VOIDmode))
12518 FAIL;
12519 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12520 DONE;
12521 })
12522
12523 ;; Implement rotation using two double-precision shift instructions
12524 ;; and a scratch register.
12525 (define_insn_and_split "ix86_rotldi3"
12526 [(set (match_operand:DI 0 "register_operand" "=r")
12527 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12528 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12529 (clobber (reg:CC FLAGS_REG))
12530 (clobber (match_scratch:SI 3 "=&r"))]
12531 "!TARGET_64BIT"
12532 ""
12533 "&& reload_completed"
12534 [(set (match_dup 3) (match_dup 4))
12535 (parallel
12536 [(set (match_dup 4)
12537 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12538 (lshiftrt:SI (match_dup 5)
12539 (minus:QI (const_int 32) (match_dup 2)))))
12540 (clobber (reg:CC FLAGS_REG))])
12541 (parallel
12542 [(set (match_dup 5)
12543 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12544 (lshiftrt:SI (match_dup 3)
12545 (minus:QI (const_int 32) (match_dup 2)))))
12546 (clobber (reg:CC FLAGS_REG))])]
12547 "split_di (operands, 1, operands + 4, operands + 5);")
12548
12549 (define_insn "*rotlsi3_1_one_bit_rex64"
12550 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12551 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12552 (match_operand:QI 2 "const1_operand" "")))
12553 (clobber (reg:CC FLAGS_REG))]
12554 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12555 && (TARGET_SHIFT1 || optimize_size)"
12556 "rol{q}\t%0"
12557 [(set_attr "type" "rotate")
12558 (set (attr "length")
12559 (if_then_else (match_operand:DI 0 "register_operand" "")
12560 (const_string "2")
12561 (const_string "*")))])
12562
12563 (define_insn "*rotldi3_1_rex64"
12564 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12565 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12566 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12567 (clobber (reg:CC FLAGS_REG))]
12568 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12569 "@
12570 rol{q}\t{%2, %0|%0, %2}
12571 rol{q}\t{%b2, %0|%0, %b2}"
12572 [(set_attr "type" "rotate")
12573 (set_attr "mode" "DI")])
12574
12575 (define_expand "rotlsi3"
12576 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12577 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12578 (match_operand:QI 2 "nonmemory_operand" "")))
12579 (clobber (reg:CC FLAGS_REG))]
12580 ""
12581 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12582
12583 (define_insn "*rotlsi3_1_one_bit"
12584 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12585 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12586 (match_operand:QI 2 "const1_operand" "")))
12587 (clobber (reg:CC FLAGS_REG))]
12588 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12589 && (TARGET_SHIFT1 || optimize_size)"
12590 "rol{l}\t%0"
12591 [(set_attr "type" "rotate")
12592 (set (attr "length")
12593 (if_then_else (match_operand:SI 0 "register_operand" "")
12594 (const_string "2")
12595 (const_string "*")))])
12596
12597 (define_insn "*rotlsi3_1_one_bit_zext"
12598 [(set (match_operand:DI 0 "register_operand" "=r")
12599 (zero_extend:DI
12600 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12601 (match_operand:QI 2 "const1_operand" ""))))
12602 (clobber (reg:CC FLAGS_REG))]
12603 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12604 && (TARGET_SHIFT1 || optimize_size)"
12605 "rol{l}\t%k0"
12606 [(set_attr "type" "rotate")
12607 (set_attr "length" "2")])
12608
12609 (define_insn "*rotlsi3_1"
12610 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12611 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12612 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12613 (clobber (reg:CC FLAGS_REG))]
12614 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12615 "@
12616 rol{l}\t{%2, %0|%0, %2}
12617 rol{l}\t{%b2, %0|%0, %b2}"
12618 [(set_attr "type" "rotate")
12619 (set_attr "mode" "SI")])
12620
12621 (define_insn "*rotlsi3_1_zext"
12622 [(set (match_operand:DI 0 "register_operand" "=r,r")
12623 (zero_extend:DI
12624 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12625 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12626 (clobber (reg:CC FLAGS_REG))]
12627 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12628 "@
12629 rol{l}\t{%2, %k0|%k0, %2}
12630 rol{l}\t{%b2, %k0|%k0, %b2}"
12631 [(set_attr "type" "rotate")
12632 (set_attr "mode" "SI")])
12633
12634 (define_expand "rotlhi3"
12635 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12636 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12637 (match_operand:QI 2 "nonmemory_operand" "")))
12638 (clobber (reg:CC FLAGS_REG))]
12639 "TARGET_HIMODE_MATH"
12640 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12641
12642 (define_insn "*rotlhi3_1_one_bit"
12643 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12644 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12645 (match_operand:QI 2 "const1_operand" "")))
12646 (clobber (reg:CC FLAGS_REG))]
12647 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12648 && (TARGET_SHIFT1 || optimize_size)"
12649 "rol{w}\t%0"
12650 [(set_attr "type" "rotate")
12651 (set (attr "length")
12652 (if_then_else (match_operand 0 "register_operand" "")
12653 (const_string "2")
12654 (const_string "*")))])
12655
12656 (define_insn "*rotlhi3_1"
12657 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12658 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12659 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12660 (clobber (reg:CC FLAGS_REG))]
12661 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12662 "@
12663 rol{w}\t{%2, %0|%0, %2}
12664 rol{w}\t{%b2, %0|%0, %b2}"
12665 [(set_attr "type" "rotate")
12666 (set_attr "mode" "HI")])
12667
12668 (define_expand "rotlqi3"
12669 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12670 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12671 (match_operand:QI 2 "nonmemory_operand" "")))
12672 (clobber (reg:CC FLAGS_REG))]
12673 "TARGET_QIMODE_MATH"
12674 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12675
12676 (define_insn "*rotlqi3_1_one_bit_slp"
12677 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12678 (rotate:QI (match_dup 0)
12679 (match_operand:QI 1 "const1_operand" "")))
12680 (clobber (reg:CC FLAGS_REG))]
12681 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12682 && (TARGET_SHIFT1 || optimize_size)"
12683 "rol{b}\t%0"
12684 [(set_attr "type" "rotate1")
12685 (set (attr "length")
12686 (if_then_else (match_operand 0 "register_operand" "")
12687 (const_string "2")
12688 (const_string "*")))])
12689
12690 (define_insn "*rotlqi3_1_one_bit"
12691 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12692 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12693 (match_operand:QI 2 "const1_operand" "")))
12694 (clobber (reg:CC FLAGS_REG))]
12695 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12696 && (TARGET_SHIFT1 || optimize_size)"
12697 "rol{b}\t%0"
12698 [(set_attr "type" "rotate")
12699 (set (attr "length")
12700 (if_then_else (match_operand 0 "register_operand" "")
12701 (const_string "2")
12702 (const_string "*")))])
12703
12704 (define_insn "*rotlqi3_1_slp"
12705 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12706 (rotate:QI (match_dup 0)
12707 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12708 (clobber (reg:CC FLAGS_REG))]
12709 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12710 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12711 "@
12712 rol{b}\t{%1, %0|%0, %1}
12713 rol{b}\t{%b1, %0|%0, %b1}"
12714 [(set_attr "type" "rotate1")
12715 (set_attr "mode" "QI")])
12716
12717 (define_insn "*rotlqi3_1"
12718 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12719 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12720 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12721 (clobber (reg:CC FLAGS_REG))]
12722 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12723 "@
12724 rol{b}\t{%2, %0|%0, %2}
12725 rol{b}\t{%b2, %0|%0, %b2}"
12726 [(set_attr "type" "rotate")
12727 (set_attr "mode" "QI")])
12728
12729 (define_expand "rotrdi3"
12730 [(set (match_operand:DI 0 "shiftdi_operand" "")
12731 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12732 (match_operand:QI 2 "nonmemory_operand" "")))
12733 (clobber (reg:CC FLAGS_REG))]
12734 ""
12735 {
12736 if (TARGET_64BIT)
12737 {
12738 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12739 DONE;
12740 }
12741 if (!const_1_to_31_operand (operands[2], VOIDmode))
12742 FAIL;
12743 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12744 DONE;
12745 })
12746
12747 ;; Implement rotation using two double-precision shift instructions
12748 ;; and a scratch register.
12749 (define_insn_and_split "ix86_rotrdi3"
12750 [(set (match_operand:DI 0 "register_operand" "=r")
12751 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12752 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12753 (clobber (reg:CC FLAGS_REG))
12754 (clobber (match_scratch:SI 3 "=&r"))]
12755 "!TARGET_64BIT"
12756 ""
12757 "&& reload_completed"
12758 [(set (match_dup 3) (match_dup 4))
12759 (parallel
12760 [(set (match_dup 4)
12761 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12762 (ashift:SI (match_dup 5)
12763 (minus:QI (const_int 32) (match_dup 2)))))
12764 (clobber (reg:CC FLAGS_REG))])
12765 (parallel
12766 [(set (match_dup 5)
12767 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12768 (ashift:SI (match_dup 3)
12769 (minus:QI (const_int 32) (match_dup 2)))))
12770 (clobber (reg:CC FLAGS_REG))])]
12771 "split_di (operands, 1, operands + 4, operands + 5);")
12772
12773 (define_insn "*rotrdi3_1_one_bit_rex64"
12774 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12775 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12776 (match_operand:QI 2 "const1_operand" "")))
12777 (clobber (reg:CC FLAGS_REG))]
12778 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12779 && (TARGET_SHIFT1 || optimize_size)"
12780 "ror{q}\t%0"
12781 [(set_attr "type" "rotate")
12782 (set (attr "length")
12783 (if_then_else (match_operand:DI 0 "register_operand" "")
12784 (const_string "2")
12785 (const_string "*")))])
12786
12787 (define_insn "*rotrdi3_1_rex64"
12788 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12789 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12790 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12791 (clobber (reg:CC FLAGS_REG))]
12792 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12793 "@
12794 ror{q}\t{%2, %0|%0, %2}
12795 ror{q}\t{%b2, %0|%0, %b2}"
12796 [(set_attr "type" "rotate")
12797 (set_attr "mode" "DI")])
12798
12799 (define_expand "rotrsi3"
12800 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12801 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12802 (match_operand:QI 2 "nonmemory_operand" "")))
12803 (clobber (reg:CC FLAGS_REG))]
12804 ""
12805 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12806
12807 (define_insn "*rotrsi3_1_one_bit"
12808 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12809 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12810 (match_operand:QI 2 "const1_operand" "")))
12811 (clobber (reg:CC FLAGS_REG))]
12812 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12813 && (TARGET_SHIFT1 || optimize_size)"
12814 "ror{l}\t%0"
12815 [(set_attr "type" "rotate")
12816 (set (attr "length")
12817 (if_then_else (match_operand:SI 0 "register_operand" "")
12818 (const_string "2")
12819 (const_string "*")))])
12820
12821 (define_insn "*rotrsi3_1_one_bit_zext"
12822 [(set (match_operand:DI 0 "register_operand" "=r")
12823 (zero_extend:DI
12824 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12825 (match_operand:QI 2 "const1_operand" ""))))
12826 (clobber (reg:CC FLAGS_REG))]
12827 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12828 && (TARGET_SHIFT1 || optimize_size)"
12829 "ror{l}\t%k0"
12830 [(set_attr "type" "rotate")
12831 (set (attr "length")
12832 (if_then_else (match_operand:SI 0 "register_operand" "")
12833 (const_string "2")
12834 (const_string "*")))])
12835
12836 (define_insn "*rotrsi3_1"
12837 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12838 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12839 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12840 (clobber (reg:CC FLAGS_REG))]
12841 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12842 "@
12843 ror{l}\t{%2, %0|%0, %2}
12844 ror{l}\t{%b2, %0|%0, %b2}"
12845 [(set_attr "type" "rotate")
12846 (set_attr "mode" "SI")])
12847
12848 (define_insn "*rotrsi3_1_zext"
12849 [(set (match_operand:DI 0 "register_operand" "=r,r")
12850 (zero_extend:DI
12851 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12852 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12853 (clobber (reg:CC FLAGS_REG))]
12854 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12855 "@
12856 ror{l}\t{%2, %k0|%k0, %2}
12857 ror{l}\t{%b2, %k0|%k0, %b2}"
12858 [(set_attr "type" "rotate")
12859 (set_attr "mode" "SI")])
12860
12861 (define_expand "rotrhi3"
12862 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12863 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12864 (match_operand:QI 2 "nonmemory_operand" "")))
12865 (clobber (reg:CC FLAGS_REG))]
12866 "TARGET_HIMODE_MATH"
12867 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12868
12869 (define_insn "*rotrhi3_one_bit"
12870 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12871 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12872 (match_operand:QI 2 "const1_operand" "")))
12873 (clobber (reg:CC FLAGS_REG))]
12874 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12875 && (TARGET_SHIFT1 || optimize_size)"
12876 "ror{w}\t%0"
12877 [(set_attr "type" "rotate")
12878 (set (attr "length")
12879 (if_then_else (match_operand 0 "register_operand" "")
12880 (const_string "2")
12881 (const_string "*")))])
12882
12883 (define_insn "*rotrhi3"
12884 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12885 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12886 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12887 (clobber (reg:CC FLAGS_REG))]
12888 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12889 "@
12890 ror{w}\t{%2, %0|%0, %2}
12891 ror{w}\t{%b2, %0|%0, %b2}"
12892 [(set_attr "type" "rotate")
12893 (set_attr "mode" "HI")])
12894
12895 (define_expand "rotrqi3"
12896 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12897 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12898 (match_operand:QI 2 "nonmemory_operand" "")))
12899 (clobber (reg:CC FLAGS_REG))]
12900 "TARGET_QIMODE_MATH"
12901 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12902
12903 (define_insn "*rotrqi3_1_one_bit"
12904 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12905 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12906 (match_operand:QI 2 "const1_operand" "")))
12907 (clobber (reg:CC FLAGS_REG))]
12908 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12909 && (TARGET_SHIFT1 || optimize_size)"
12910 "ror{b}\t%0"
12911 [(set_attr "type" "rotate")
12912 (set (attr "length")
12913 (if_then_else (match_operand 0 "register_operand" "")
12914 (const_string "2")
12915 (const_string "*")))])
12916
12917 (define_insn "*rotrqi3_1_one_bit_slp"
12918 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12919 (rotatert:QI (match_dup 0)
12920 (match_operand:QI 1 "const1_operand" "")))
12921 (clobber (reg:CC FLAGS_REG))]
12922 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12923 && (TARGET_SHIFT1 || optimize_size)"
12924 "ror{b}\t%0"
12925 [(set_attr "type" "rotate1")
12926 (set (attr "length")
12927 (if_then_else (match_operand 0 "register_operand" "")
12928 (const_string "2")
12929 (const_string "*")))])
12930
12931 (define_insn "*rotrqi3_1"
12932 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12933 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12934 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12935 (clobber (reg:CC FLAGS_REG))]
12936 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12937 "@
12938 ror{b}\t{%2, %0|%0, %2}
12939 ror{b}\t{%b2, %0|%0, %b2}"
12940 [(set_attr "type" "rotate")
12941 (set_attr "mode" "QI")])
12942
12943 (define_insn "*rotrqi3_1_slp"
12944 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12945 (rotatert:QI (match_dup 0)
12946 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12947 (clobber (reg:CC FLAGS_REG))]
12948 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12949 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12950 "@
12951 ror{b}\t{%1, %0|%0, %1}
12952 ror{b}\t{%b1, %0|%0, %b1}"
12953 [(set_attr "type" "rotate1")
12954 (set_attr "mode" "QI")])
12955 \f
12956 ;; Bit set / bit test instructions
12957
12958 (define_expand "extv"
12959 [(set (match_operand:SI 0 "register_operand" "")
12960 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12961 (match_operand:SI 2 "const8_operand" "")
12962 (match_operand:SI 3 "const8_operand" "")))]
12963 ""
12964 {
12965 /* Handle extractions from %ah et al. */
12966 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12967 FAIL;
12968
12969 /* From mips.md: extract_bit_field doesn't verify that our source
12970 matches the predicate, so check it again here. */
12971 if (! ext_register_operand (operands[1], VOIDmode))
12972 FAIL;
12973 })
12974
12975 (define_expand "extzv"
12976 [(set (match_operand:SI 0 "register_operand" "")
12977 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12978 (match_operand:SI 2 "const8_operand" "")
12979 (match_operand:SI 3 "const8_operand" "")))]
12980 ""
12981 {
12982 /* Handle extractions from %ah et al. */
12983 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12984 FAIL;
12985
12986 /* From mips.md: extract_bit_field doesn't verify that our source
12987 matches the predicate, so check it again here. */
12988 if (! ext_register_operand (operands[1], VOIDmode))
12989 FAIL;
12990 })
12991
12992 (define_expand "insv"
12993 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12994 (match_operand 1 "const8_operand" "")
12995 (match_operand 2 "const8_operand" ""))
12996 (match_operand 3 "register_operand" ""))]
12997 ""
12998 {
12999 /* Handle insertions to %ah et al. */
13000 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13001 FAIL;
13002
13003 /* From mips.md: insert_bit_field doesn't verify that our source
13004 matches the predicate, so check it again here. */
13005 if (! ext_register_operand (operands[0], VOIDmode))
13006 FAIL;
13007
13008 if (TARGET_64BIT)
13009 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13010 else
13011 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13012
13013 DONE;
13014 })
13015
13016 ;; %%% bts, btr, btc, bt.
13017 ;; In general these instructions are *slow* when applied to memory,
13018 ;; since they enforce atomic operation. When applied to registers,
13019 ;; it depends on the cpu implementation. They're never faster than
13020 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13021 ;; no point. But in 64-bit, we can't hold the relevant immediates
13022 ;; within the instruction itself, so operating on bits in the high
13023 ;; 32-bits of a register becomes easier.
13024 ;;
13025 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13026 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13027 ;; negdf respectively, so they can never be disabled entirely.
13028
13029 (define_insn "*btsq"
13030 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13031 (const_int 1)
13032 (match_operand:DI 1 "const_0_to_63_operand" ""))
13033 (const_int 1))
13034 (clobber (reg:CC FLAGS_REG))]
13035 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13036 "bts{q} %1,%0"
13037 [(set_attr "type" "alu1")])
13038
13039 (define_insn "*btrq"
13040 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13041 (const_int 1)
13042 (match_operand:DI 1 "const_0_to_63_operand" ""))
13043 (const_int 0))
13044 (clobber (reg:CC FLAGS_REG))]
13045 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13046 "btr{q} %1,%0"
13047 [(set_attr "type" "alu1")])
13048
13049 (define_insn "*btcq"
13050 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13051 (const_int 1)
13052 (match_operand:DI 1 "const_0_to_63_operand" ""))
13053 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13054 (clobber (reg:CC FLAGS_REG))]
13055 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13056 "btc{q} %1,%0"
13057 [(set_attr "type" "alu1")])
13058
13059 ;; Allow Nocona to avoid these instructions if a register is available.
13060
13061 (define_peephole2
13062 [(match_scratch:DI 2 "r")
13063 (parallel [(set (zero_extract:DI
13064 (match_operand:DI 0 "register_operand" "")
13065 (const_int 1)
13066 (match_operand:DI 1 "const_0_to_63_operand" ""))
13067 (const_int 1))
13068 (clobber (reg:CC FLAGS_REG))])]
13069 "TARGET_64BIT && !TARGET_USE_BT"
13070 [(const_int 0)]
13071 {
13072 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13073 rtx op1;
13074
13075 if (HOST_BITS_PER_WIDE_INT >= 64)
13076 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13077 else if (i < HOST_BITS_PER_WIDE_INT)
13078 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13079 else
13080 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13081
13082 op1 = immed_double_const (lo, hi, DImode);
13083 if (i >= 31)
13084 {
13085 emit_move_insn (operands[2], op1);
13086 op1 = operands[2];
13087 }
13088
13089 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13090 DONE;
13091 })
13092
13093 (define_peephole2
13094 [(match_scratch:DI 2 "r")
13095 (parallel [(set (zero_extract:DI
13096 (match_operand:DI 0 "register_operand" "")
13097 (const_int 1)
13098 (match_operand:DI 1 "const_0_to_63_operand" ""))
13099 (const_int 0))
13100 (clobber (reg:CC FLAGS_REG))])]
13101 "TARGET_64BIT && !TARGET_USE_BT"
13102 [(const_int 0)]
13103 {
13104 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13105 rtx op1;
13106
13107 if (HOST_BITS_PER_WIDE_INT >= 64)
13108 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13109 else if (i < HOST_BITS_PER_WIDE_INT)
13110 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13111 else
13112 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13113
13114 op1 = immed_double_const (~lo, ~hi, DImode);
13115 if (i >= 32)
13116 {
13117 emit_move_insn (operands[2], op1);
13118 op1 = operands[2];
13119 }
13120
13121 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13122 DONE;
13123 })
13124
13125 (define_peephole2
13126 [(match_scratch:DI 2 "r")
13127 (parallel [(set (zero_extract:DI
13128 (match_operand:DI 0 "register_operand" "")
13129 (const_int 1)
13130 (match_operand:DI 1 "const_0_to_63_operand" ""))
13131 (not:DI (zero_extract:DI
13132 (match_dup 0) (const_int 1) (match_dup 1))))
13133 (clobber (reg:CC FLAGS_REG))])]
13134 "TARGET_64BIT && !TARGET_USE_BT"
13135 [(const_int 0)]
13136 {
13137 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13138 rtx op1;
13139
13140 if (HOST_BITS_PER_WIDE_INT >= 64)
13141 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13142 else if (i < HOST_BITS_PER_WIDE_INT)
13143 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13144 else
13145 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13146
13147 op1 = immed_double_const (lo, hi, DImode);
13148 if (i >= 31)
13149 {
13150 emit_move_insn (operands[2], op1);
13151 op1 = operands[2];
13152 }
13153
13154 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13155 DONE;
13156 })
13157 \f
13158 ;; Store-flag instructions.
13159
13160 ;; For all sCOND expanders, also expand the compare or test insn that
13161 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13162
13163 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13164 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13165 ;; way, which can later delete the movzx if only QImode is needed.
13166
13167 (define_expand "seq"
13168 [(set (match_operand:QI 0 "register_operand" "")
13169 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13170 ""
13171 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13172
13173 (define_expand "sne"
13174 [(set (match_operand:QI 0 "register_operand" "")
13175 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13176 ""
13177 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13178
13179 (define_expand "sgt"
13180 [(set (match_operand:QI 0 "register_operand" "")
13181 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13182 ""
13183 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13184
13185 (define_expand "sgtu"
13186 [(set (match_operand:QI 0 "register_operand" "")
13187 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13188 ""
13189 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13190
13191 (define_expand "slt"
13192 [(set (match_operand:QI 0 "register_operand" "")
13193 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13194 ""
13195 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13196
13197 (define_expand "sltu"
13198 [(set (match_operand:QI 0 "register_operand" "")
13199 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13200 ""
13201 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13202
13203 (define_expand "sge"
13204 [(set (match_operand:QI 0 "register_operand" "")
13205 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13206 ""
13207 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13208
13209 (define_expand "sgeu"
13210 [(set (match_operand:QI 0 "register_operand" "")
13211 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13212 ""
13213 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13214
13215 (define_expand "sle"
13216 [(set (match_operand:QI 0 "register_operand" "")
13217 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13218 ""
13219 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13220
13221 (define_expand "sleu"
13222 [(set (match_operand:QI 0 "register_operand" "")
13223 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13224 ""
13225 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13226
13227 (define_expand "sunordered"
13228 [(set (match_operand:QI 0 "register_operand" "")
13229 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13230 "TARGET_80387 || TARGET_SSE"
13231 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13232
13233 (define_expand "sordered"
13234 [(set (match_operand:QI 0 "register_operand" "")
13235 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13236 "TARGET_80387"
13237 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13238
13239 (define_expand "suneq"
13240 [(set (match_operand:QI 0 "register_operand" "")
13241 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13242 "TARGET_80387 || TARGET_SSE"
13243 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13244
13245 (define_expand "sunge"
13246 [(set (match_operand:QI 0 "register_operand" "")
13247 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13248 "TARGET_80387 || TARGET_SSE"
13249 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13250
13251 (define_expand "sungt"
13252 [(set (match_operand:QI 0 "register_operand" "")
13253 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13254 "TARGET_80387 || TARGET_SSE"
13255 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13256
13257 (define_expand "sunle"
13258 [(set (match_operand:QI 0 "register_operand" "")
13259 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13260 "TARGET_80387 || TARGET_SSE"
13261 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13262
13263 (define_expand "sunlt"
13264 [(set (match_operand:QI 0 "register_operand" "")
13265 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13266 "TARGET_80387 || TARGET_SSE"
13267 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13268
13269 (define_expand "sltgt"
13270 [(set (match_operand:QI 0 "register_operand" "")
13271 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13272 "TARGET_80387 || TARGET_SSE"
13273 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13274
13275 (define_insn "*setcc_1"
13276 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13277 (match_operator:QI 1 "ix86_comparison_operator"
13278 [(reg FLAGS_REG) (const_int 0)]))]
13279 ""
13280 "set%C1\t%0"
13281 [(set_attr "type" "setcc")
13282 (set_attr "mode" "QI")])
13283
13284 (define_insn "*setcc_2"
13285 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13286 (match_operator:QI 1 "ix86_comparison_operator"
13287 [(reg FLAGS_REG) (const_int 0)]))]
13288 ""
13289 "set%C1\t%0"
13290 [(set_attr "type" "setcc")
13291 (set_attr "mode" "QI")])
13292
13293 ;; In general it is not safe to assume too much about CCmode registers,
13294 ;; so simplify-rtx stops when it sees a second one. Under certain
13295 ;; conditions this is safe on x86, so help combine not create
13296 ;;
13297 ;; seta %al
13298 ;; testb %al, %al
13299 ;; sete %al
13300
13301 (define_split
13302 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13303 (ne:QI (match_operator 1 "ix86_comparison_operator"
13304 [(reg FLAGS_REG) (const_int 0)])
13305 (const_int 0)))]
13306 ""
13307 [(set (match_dup 0) (match_dup 1))]
13308 {
13309 PUT_MODE (operands[1], QImode);
13310 })
13311
13312 (define_split
13313 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13314 (ne:QI (match_operator 1 "ix86_comparison_operator"
13315 [(reg FLAGS_REG) (const_int 0)])
13316 (const_int 0)))]
13317 ""
13318 [(set (match_dup 0) (match_dup 1))]
13319 {
13320 PUT_MODE (operands[1], QImode);
13321 })
13322
13323 (define_split
13324 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13325 (eq:QI (match_operator 1 "ix86_comparison_operator"
13326 [(reg FLAGS_REG) (const_int 0)])
13327 (const_int 0)))]
13328 ""
13329 [(set (match_dup 0) (match_dup 1))]
13330 {
13331 rtx new_op1 = copy_rtx (operands[1]);
13332 operands[1] = new_op1;
13333 PUT_MODE (new_op1, QImode);
13334 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13335 GET_MODE (XEXP (new_op1, 0))));
13336
13337 /* Make sure that (a) the CCmode we have for the flags is strong
13338 enough for the reversed compare or (b) we have a valid FP compare. */
13339 if (! ix86_comparison_operator (new_op1, VOIDmode))
13340 FAIL;
13341 })
13342
13343 (define_split
13344 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13345 (eq:QI (match_operator 1 "ix86_comparison_operator"
13346 [(reg FLAGS_REG) (const_int 0)])
13347 (const_int 0)))]
13348 ""
13349 [(set (match_dup 0) (match_dup 1))]
13350 {
13351 rtx new_op1 = copy_rtx (operands[1]);
13352 operands[1] = new_op1;
13353 PUT_MODE (new_op1, QImode);
13354 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13355 GET_MODE (XEXP (new_op1, 0))));
13356
13357 /* Make sure that (a) the CCmode we have for the flags is strong
13358 enough for the reversed compare or (b) we have a valid FP compare. */
13359 if (! ix86_comparison_operator (new_op1, VOIDmode))
13360 FAIL;
13361 })
13362
13363 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13364 ;; subsequent logical operations are used to imitate conditional moves.
13365 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13366 ;; it directly.
13367
13368 (define_insn "*sse_setccsf"
13369 [(set (match_operand:SF 0 "register_operand" "=x")
13370 (match_operator:SF 1 "sse_comparison_operator"
13371 [(match_operand:SF 2 "register_operand" "0")
13372 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13373 "TARGET_SSE"
13374 "cmp%D1ss\t{%3, %0|%0, %3}"
13375 [(set_attr "type" "ssecmp")
13376 (set_attr "mode" "SF")])
13377
13378 (define_insn "*sse_setccdf"
13379 [(set (match_operand:DF 0 "register_operand" "=Y")
13380 (match_operator:DF 1 "sse_comparison_operator"
13381 [(match_operand:DF 2 "register_operand" "0")
13382 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13383 "TARGET_SSE2"
13384 "cmp%D1sd\t{%3, %0|%0, %3}"
13385 [(set_attr "type" "ssecmp")
13386 (set_attr "mode" "DF")])
13387 \f
13388 ;; Basic conditional jump instructions.
13389 ;; We ignore the overflow flag for signed branch instructions.
13390
13391 ;; For all bCOND expanders, also expand the compare or test insn that
13392 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13393
13394 (define_expand "beq"
13395 [(set (pc)
13396 (if_then_else (match_dup 1)
13397 (label_ref (match_operand 0 "" ""))
13398 (pc)))]
13399 ""
13400 "ix86_expand_branch (EQ, operands[0]); DONE;")
13401
13402 (define_expand "bne"
13403 [(set (pc)
13404 (if_then_else (match_dup 1)
13405 (label_ref (match_operand 0 "" ""))
13406 (pc)))]
13407 ""
13408 "ix86_expand_branch (NE, operands[0]); DONE;")
13409
13410 (define_expand "bgt"
13411 [(set (pc)
13412 (if_then_else (match_dup 1)
13413 (label_ref (match_operand 0 "" ""))
13414 (pc)))]
13415 ""
13416 "ix86_expand_branch (GT, operands[0]); DONE;")
13417
13418 (define_expand "bgtu"
13419 [(set (pc)
13420 (if_then_else (match_dup 1)
13421 (label_ref (match_operand 0 "" ""))
13422 (pc)))]
13423 ""
13424 "ix86_expand_branch (GTU, operands[0]); DONE;")
13425
13426 (define_expand "blt"
13427 [(set (pc)
13428 (if_then_else (match_dup 1)
13429 (label_ref (match_operand 0 "" ""))
13430 (pc)))]
13431 ""
13432 "ix86_expand_branch (LT, operands[0]); DONE;")
13433
13434 (define_expand "bltu"
13435 [(set (pc)
13436 (if_then_else (match_dup 1)
13437 (label_ref (match_operand 0 "" ""))
13438 (pc)))]
13439 ""
13440 "ix86_expand_branch (LTU, operands[0]); DONE;")
13441
13442 (define_expand "bge"
13443 [(set (pc)
13444 (if_then_else (match_dup 1)
13445 (label_ref (match_operand 0 "" ""))
13446 (pc)))]
13447 ""
13448 "ix86_expand_branch (GE, operands[0]); DONE;")
13449
13450 (define_expand "bgeu"
13451 [(set (pc)
13452 (if_then_else (match_dup 1)
13453 (label_ref (match_operand 0 "" ""))
13454 (pc)))]
13455 ""
13456 "ix86_expand_branch (GEU, operands[0]); DONE;")
13457
13458 (define_expand "ble"
13459 [(set (pc)
13460 (if_then_else (match_dup 1)
13461 (label_ref (match_operand 0 "" ""))
13462 (pc)))]
13463 ""
13464 "ix86_expand_branch (LE, operands[0]); DONE;")
13465
13466 (define_expand "bleu"
13467 [(set (pc)
13468 (if_then_else (match_dup 1)
13469 (label_ref (match_operand 0 "" ""))
13470 (pc)))]
13471 ""
13472 "ix86_expand_branch (LEU, operands[0]); DONE;")
13473
13474 (define_expand "bunordered"
13475 [(set (pc)
13476 (if_then_else (match_dup 1)
13477 (label_ref (match_operand 0 "" ""))
13478 (pc)))]
13479 "TARGET_80387 || TARGET_SSE_MATH"
13480 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13481
13482 (define_expand "bordered"
13483 [(set (pc)
13484 (if_then_else (match_dup 1)
13485 (label_ref (match_operand 0 "" ""))
13486 (pc)))]
13487 "TARGET_80387 || TARGET_SSE_MATH"
13488 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13489
13490 (define_expand "buneq"
13491 [(set (pc)
13492 (if_then_else (match_dup 1)
13493 (label_ref (match_operand 0 "" ""))
13494 (pc)))]
13495 "TARGET_80387 || TARGET_SSE_MATH"
13496 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13497
13498 (define_expand "bunge"
13499 [(set (pc)
13500 (if_then_else (match_dup 1)
13501 (label_ref (match_operand 0 "" ""))
13502 (pc)))]
13503 "TARGET_80387 || TARGET_SSE_MATH"
13504 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13505
13506 (define_expand "bungt"
13507 [(set (pc)
13508 (if_then_else (match_dup 1)
13509 (label_ref (match_operand 0 "" ""))
13510 (pc)))]
13511 "TARGET_80387 || TARGET_SSE_MATH"
13512 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13513
13514 (define_expand "bunle"
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 (UNLE, operands[0]); DONE;")
13521
13522 (define_expand "bunlt"
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 (UNLT, operands[0]); DONE;")
13529
13530 (define_expand "bltgt"
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 (LTGT, operands[0]); DONE;")
13537
13538 (define_insn "*jcc_1"
13539 [(set (pc)
13540 (if_then_else (match_operator 1 "ix86_comparison_operator"
13541 [(reg FLAGS_REG) (const_int 0)])
13542 (label_ref (match_operand 0 "" ""))
13543 (pc)))]
13544 ""
13545 "%+j%C1\t%l0"
13546 [(set_attr "type" "ibr")
13547 (set_attr "modrm" "0")
13548 (set (attr "length")
13549 (if_then_else (and (ge (minus (match_dup 0) (pc))
13550 (const_int -126))
13551 (lt (minus (match_dup 0) (pc))
13552 (const_int 128)))
13553 (const_int 2)
13554 (const_int 6)))])
13555
13556 (define_insn "*jcc_2"
13557 [(set (pc)
13558 (if_then_else (match_operator 1 "ix86_comparison_operator"
13559 [(reg FLAGS_REG) (const_int 0)])
13560 (pc)
13561 (label_ref (match_operand 0 "" ""))))]
13562 ""
13563 "%+j%c1\t%l0"
13564 [(set_attr "type" "ibr")
13565 (set_attr "modrm" "0")
13566 (set (attr "length")
13567 (if_then_else (and (ge (minus (match_dup 0) (pc))
13568 (const_int -126))
13569 (lt (minus (match_dup 0) (pc))
13570 (const_int 128)))
13571 (const_int 2)
13572 (const_int 6)))])
13573
13574 ;; In general it is not safe to assume too much about CCmode registers,
13575 ;; so simplify-rtx stops when it sees a second one. Under certain
13576 ;; conditions this is safe on x86, so help combine not create
13577 ;;
13578 ;; seta %al
13579 ;; testb %al, %al
13580 ;; je Lfoo
13581
13582 (define_split
13583 [(set (pc)
13584 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13585 [(reg FLAGS_REG) (const_int 0)])
13586 (const_int 0))
13587 (label_ref (match_operand 1 "" ""))
13588 (pc)))]
13589 ""
13590 [(set (pc)
13591 (if_then_else (match_dup 0)
13592 (label_ref (match_dup 1))
13593 (pc)))]
13594 {
13595 PUT_MODE (operands[0], VOIDmode);
13596 })
13597
13598 (define_split
13599 [(set (pc)
13600 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13601 [(reg FLAGS_REG) (const_int 0)])
13602 (const_int 0))
13603 (label_ref (match_operand 1 "" ""))
13604 (pc)))]
13605 ""
13606 [(set (pc)
13607 (if_then_else (match_dup 0)
13608 (label_ref (match_dup 1))
13609 (pc)))]
13610 {
13611 rtx new_op0 = copy_rtx (operands[0]);
13612 operands[0] = new_op0;
13613 PUT_MODE (new_op0, VOIDmode);
13614 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13615 GET_MODE (XEXP (new_op0, 0))));
13616
13617 /* Make sure that (a) the CCmode we have for the flags is strong
13618 enough for the reversed compare or (b) we have a valid FP compare. */
13619 if (! ix86_comparison_operator (new_op0, VOIDmode))
13620 FAIL;
13621 })
13622
13623 ;; Define combination compare-and-branch fp compare instructions to use
13624 ;; during early optimization. Splitting the operation apart early makes
13625 ;; for bad code when we want to reverse the operation.
13626
13627 (define_insn "*fp_jcc_1_mixed"
13628 [(set (pc)
13629 (if_then_else (match_operator 0 "comparison_operator"
13630 [(match_operand 1 "register_operand" "f,x")
13631 (match_operand 2 "nonimmediate_operand" "f,xm")])
13632 (label_ref (match_operand 3 "" ""))
13633 (pc)))
13634 (clobber (reg:CCFP FPSR_REG))
13635 (clobber (reg:CCFP FLAGS_REG))]
13636 "TARGET_MIX_SSE_I387
13637 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13638 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13639 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13640 "#")
13641
13642 (define_insn "*fp_jcc_1_sse"
13643 [(set (pc)
13644 (if_then_else (match_operator 0 "comparison_operator"
13645 [(match_operand 1 "register_operand" "x")
13646 (match_operand 2 "nonimmediate_operand" "xm")])
13647 (label_ref (match_operand 3 "" ""))
13648 (pc)))
13649 (clobber (reg:CCFP FPSR_REG))
13650 (clobber (reg:CCFP FLAGS_REG))]
13651 "TARGET_SSE_MATH
13652 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13653 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13654 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13655 "#")
13656
13657 (define_insn "*fp_jcc_1_387"
13658 [(set (pc)
13659 (if_then_else (match_operator 0 "comparison_operator"
13660 [(match_operand 1 "register_operand" "f")
13661 (match_operand 2 "register_operand" "f")])
13662 (label_ref (match_operand 3 "" ""))
13663 (pc)))
13664 (clobber (reg:CCFP FPSR_REG))
13665 (clobber (reg:CCFP FLAGS_REG))]
13666 "TARGET_CMOVE && TARGET_80387
13667 && FLOAT_MODE_P (GET_MODE (operands[1]))
13668 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13669 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13670 "#")
13671
13672 (define_insn "*fp_jcc_2_mixed"
13673 [(set (pc)
13674 (if_then_else (match_operator 0 "comparison_operator"
13675 [(match_operand 1 "register_operand" "f,x")
13676 (match_operand 2 "nonimmediate_operand" "f,xm")])
13677 (pc)
13678 (label_ref (match_operand 3 "" ""))))
13679 (clobber (reg:CCFP FPSR_REG))
13680 (clobber (reg:CCFP FLAGS_REG))]
13681 "TARGET_MIX_SSE_I387
13682 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13683 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13684 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13685 "#")
13686
13687 (define_insn "*fp_jcc_2_sse"
13688 [(set (pc)
13689 (if_then_else (match_operator 0 "comparison_operator"
13690 [(match_operand 1 "register_operand" "x")
13691 (match_operand 2 "nonimmediate_operand" "xm")])
13692 (pc)
13693 (label_ref (match_operand 3 "" ""))))
13694 (clobber (reg:CCFP FPSR_REG))
13695 (clobber (reg:CCFP FLAGS_REG))]
13696 "TARGET_SSE_MATH
13697 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13698 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13699 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13700 "#")
13701
13702 (define_insn "*fp_jcc_2_387"
13703 [(set (pc)
13704 (if_then_else (match_operator 0 "comparison_operator"
13705 [(match_operand 1 "register_operand" "f")
13706 (match_operand 2 "register_operand" "f")])
13707 (pc)
13708 (label_ref (match_operand 3 "" ""))))
13709 (clobber (reg:CCFP FPSR_REG))
13710 (clobber (reg:CCFP FLAGS_REG))]
13711 "TARGET_CMOVE && TARGET_80387
13712 && FLOAT_MODE_P (GET_MODE (operands[1]))
13713 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13714 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13715 "#")
13716
13717 (define_insn "*fp_jcc_3_387"
13718 [(set (pc)
13719 (if_then_else (match_operator 0 "comparison_operator"
13720 [(match_operand 1 "register_operand" "f")
13721 (match_operand 2 "nonimmediate_operand" "fm")])
13722 (label_ref (match_operand 3 "" ""))
13723 (pc)))
13724 (clobber (reg:CCFP FPSR_REG))
13725 (clobber (reg:CCFP FLAGS_REG))
13726 (clobber (match_scratch:HI 4 "=a"))]
13727 "TARGET_80387
13728 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13729 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13730 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13731 && SELECT_CC_MODE (GET_CODE (operands[0]),
13732 operands[1], operands[2]) == CCFPmode
13733 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13734 "#")
13735
13736 (define_insn "*fp_jcc_4_387"
13737 [(set (pc)
13738 (if_then_else (match_operator 0 "comparison_operator"
13739 [(match_operand 1 "register_operand" "f")
13740 (match_operand 2 "nonimmediate_operand" "fm")])
13741 (pc)
13742 (label_ref (match_operand 3 "" ""))))
13743 (clobber (reg:CCFP FPSR_REG))
13744 (clobber (reg:CCFP FLAGS_REG))
13745 (clobber (match_scratch:HI 4 "=a"))]
13746 "TARGET_80387
13747 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13748 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13749 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13750 && SELECT_CC_MODE (GET_CODE (operands[0]),
13751 operands[1], operands[2]) == CCFPmode
13752 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13753 "#")
13754
13755 (define_insn "*fp_jcc_5_387"
13756 [(set (pc)
13757 (if_then_else (match_operator 0 "comparison_operator"
13758 [(match_operand 1 "register_operand" "f")
13759 (match_operand 2 "register_operand" "f")])
13760 (label_ref (match_operand 3 "" ""))
13761 (pc)))
13762 (clobber (reg:CCFP FPSR_REG))
13763 (clobber (reg:CCFP FLAGS_REG))
13764 (clobber (match_scratch:HI 4 "=a"))]
13765 "TARGET_80387
13766 && FLOAT_MODE_P (GET_MODE (operands[1]))
13767 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13768 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13769 "#")
13770
13771 (define_insn "*fp_jcc_6_387"
13772 [(set (pc)
13773 (if_then_else (match_operator 0 "comparison_operator"
13774 [(match_operand 1 "register_operand" "f")
13775 (match_operand 2 "register_operand" "f")])
13776 (pc)
13777 (label_ref (match_operand 3 "" ""))))
13778 (clobber (reg:CCFP FPSR_REG))
13779 (clobber (reg:CCFP FLAGS_REG))
13780 (clobber (match_scratch:HI 4 "=a"))]
13781 "TARGET_80387
13782 && FLOAT_MODE_P (GET_MODE (operands[1]))
13783 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13784 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13785 "#")
13786
13787 (define_insn "*fp_jcc_7_387"
13788 [(set (pc)
13789 (if_then_else (match_operator 0 "comparison_operator"
13790 [(match_operand 1 "register_operand" "f")
13791 (match_operand 2 "const0_operand" "X")])
13792 (label_ref (match_operand 3 "" ""))
13793 (pc)))
13794 (clobber (reg:CCFP FPSR_REG))
13795 (clobber (reg:CCFP FLAGS_REG))
13796 (clobber (match_scratch:HI 4 "=a"))]
13797 "TARGET_80387
13798 && FLOAT_MODE_P (GET_MODE (operands[1]))
13799 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13800 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13801 && SELECT_CC_MODE (GET_CODE (operands[0]),
13802 operands[1], operands[2]) == CCFPmode
13803 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13804 "#")
13805
13806 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13807 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13808 ;; with a precedence over other operators and is always put in the first
13809 ;; place. Swap condition and operands to match ficom instruction.
13810
13811 (define_insn "*fp_jcc_8<mode>_387"
13812 [(set (pc)
13813 (if_then_else (match_operator 0 "comparison_operator"
13814 [(match_operator 1 "float_operator"
13815 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13816 (match_operand 3 "register_operand" "f,f")])
13817 (label_ref (match_operand 4 "" ""))
13818 (pc)))
13819 (clobber (reg:CCFP FPSR_REG))
13820 (clobber (reg:CCFP FLAGS_REG))
13821 (clobber (match_scratch:HI 5 "=a,a"))]
13822 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13823 && FLOAT_MODE_P (GET_MODE (operands[3]))
13824 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13825 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13826 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13827 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13828 "#")
13829
13830 (define_split
13831 [(set (pc)
13832 (if_then_else (match_operator 0 "comparison_operator"
13833 [(match_operand 1 "register_operand" "")
13834 (match_operand 2 "nonimmediate_operand" "")])
13835 (match_operand 3 "" "")
13836 (match_operand 4 "" "")))
13837 (clobber (reg:CCFP FPSR_REG))
13838 (clobber (reg:CCFP FLAGS_REG))]
13839 "reload_completed"
13840 [(const_int 0)]
13841 {
13842 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13843 operands[3], operands[4], NULL_RTX, NULL_RTX);
13844 DONE;
13845 })
13846
13847 (define_split
13848 [(set (pc)
13849 (if_then_else (match_operator 0 "comparison_operator"
13850 [(match_operand 1 "register_operand" "")
13851 (match_operand 2 "general_operand" "")])
13852 (match_operand 3 "" "")
13853 (match_operand 4 "" "")))
13854 (clobber (reg:CCFP FPSR_REG))
13855 (clobber (reg:CCFP FLAGS_REG))
13856 (clobber (match_scratch:HI 5 "=a"))]
13857 "reload_completed"
13858 [(const_int 0)]
13859 {
13860 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13861 operands[3], operands[4], operands[5], NULL_RTX);
13862 DONE;
13863 })
13864
13865 (define_split
13866 [(set (pc)
13867 (if_then_else (match_operator 0 "comparison_operator"
13868 [(match_operator 1 "float_operator"
13869 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13870 (match_operand 3 "register_operand" "")])
13871 (match_operand 4 "" "")
13872 (match_operand 5 "" "")))
13873 (clobber (reg:CCFP FPSR_REG))
13874 (clobber (reg:CCFP FLAGS_REG))
13875 (clobber (match_scratch:HI 6 "=a"))]
13876 "reload_completed"
13877 [(const_int 0)]
13878 {
13879 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13880 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13881 operands[3], operands[7],
13882 operands[4], operands[5], operands[6], NULL_RTX);
13883 DONE;
13884 })
13885
13886 ;; %%% Kill this when reload knows how to do it.
13887 (define_split
13888 [(set (pc)
13889 (if_then_else (match_operator 0 "comparison_operator"
13890 [(match_operator 1 "float_operator"
13891 [(match_operand:X87MODEI12 2 "register_operand" "")])
13892 (match_operand 3 "register_operand" "")])
13893 (match_operand 4 "" "")
13894 (match_operand 5 "" "")))
13895 (clobber (reg:CCFP FPSR_REG))
13896 (clobber (reg:CCFP FLAGS_REG))
13897 (clobber (match_scratch:HI 6 "=a"))]
13898 "reload_completed"
13899 [(const_int 0)]
13900 {
13901 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13902 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13903 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13904 operands[3], operands[7],
13905 operands[4], operands[5], operands[6], operands[2]);
13906 DONE;
13907 })
13908 \f
13909 ;; Unconditional and other jump instructions
13910
13911 (define_insn "jump"
13912 [(set (pc)
13913 (label_ref (match_operand 0 "" "")))]
13914 ""
13915 "jmp\t%l0"
13916 [(set_attr "type" "ibr")
13917 (set (attr "length")
13918 (if_then_else (and (ge (minus (match_dup 0) (pc))
13919 (const_int -126))
13920 (lt (minus (match_dup 0) (pc))
13921 (const_int 128)))
13922 (const_int 2)
13923 (const_int 5)))
13924 (set_attr "modrm" "0")])
13925
13926 (define_expand "indirect_jump"
13927 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13928 ""
13929 "")
13930
13931 (define_insn "*indirect_jump"
13932 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13933 "!TARGET_64BIT"
13934 "jmp\t%A0"
13935 [(set_attr "type" "ibr")
13936 (set_attr "length_immediate" "0")])
13937
13938 (define_insn "*indirect_jump_rtx64"
13939 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13940 "TARGET_64BIT"
13941 "jmp\t%A0"
13942 [(set_attr "type" "ibr")
13943 (set_attr "length_immediate" "0")])
13944
13945 (define_expand "tablejump"
13946 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13947 (use (label_ref (match_operand 1 "" "")))])]
13948 ""
13949 {
13950 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13951 relative. Convert the relative address to an absolute address. */
13952 if (flag_pic)
13953 {
13954 rtx op0, op1;
13955 enum rtx_code code;
13956
13957 if (TARGET_64BIT)
13958 {
13959 code = PLUS;
13960 op0 = operands[0];
13961 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13962 }
13963 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13964 {
13965 code = PLUS;
13966 op0 = operands[0];
13967 op1 = pic_offset_table_rtx;
13968 }
13969 else
13970 {
13971 code = MINUS;
13972 op0 = pic_offset_table_rtx;
13973 op1 = operands[0];
13974 }
13975
13976 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13977 OPTAB_DIRECT);
13978 }
13979 })
13980
13981 (define_insn "*tablejump_1"
13982 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13983 (use (label_ref (match_operand 1 "" "")))]
13984 "!TARGET_64BIT"
13985 "jmp\t%A0"
13986 [(set_attr "type" "ibr")
13987 (set_attr "length_immediate" "0")])
13988
13989 (define_insn "*tablejump_1_rtx64"
13990 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13991 (use (label_ref (match_operand 1 "" "")))]
13992 "TARGET_64BIT"
13993 "jmp\t%A0"
13994 [(set_attr "type" "ibr")
13995 (set_attr "length_immediate" "0")])
13996 \f
13997 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13998
13999 (define_peephole2
14000 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14001 (set (match_operand:QI 1 "register_operand" "")
14002 (match_operator:QI 2 "ix86_comparison_operator"
14003 [(reg FLAGS_REG) (const_int 0)]))
14004 (set (match_operand 3 "q_regs_operand" "")
14005 (zero_extend (match_dup 1)))]
14006 "(peep2_reg_dead_p (3, operands[1])
14007 || operands_match_p (operands[1], operands[3]))
14008 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14009 [(set (match_dup 4) (match_dup 0))
14010 (set (strict_low_part (match_dup 5))
14011 (match_dup 2))]
14012 {
14013 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14014 operands[5] = gen_lowpart (QImode, operands[3]);
14015 ix86_expand_clear (operands[3]);
14016 })
14017
14018 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14019
14020 (define_peephole2
14021 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14022 (set (match_operand:QI 1 "register_operand" "")
14023 (match_operator:QI 2 "ix86_comparison_operator"
14024 [(reg FLAGS_REG) (const_int 0)]))
14025 (parallel [(set (match_operand 3 "q_regs_operand" "")
14026 (zero_extend (match_dup 1)))
14027 (clobber (reg:CC FLAGS_REG))])]
14028 "(peep2_reg_dead_p (3, operands[1])
14029 || operands_match_p (operands[1], operands[3]))
14030 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14031 [(set (match_dup 4) (match_dup 0))
14032 (set (strict_low_part (match_dup 5))
14033 (match_dup 2))]
14034 {
14035 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14036 operands[5] = gen_lowpart (QImode, operands[3]);
14037 ix86_expand_clear (operands[3]);
14038 })
14039 \f
14040 ;; Call instructions.
14041
14042 ;; The predicates normally associated with named expanders are not properly
14043 ;; checked for calls. This is a bug in the generic code, but it isn't that
14044 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14045
14046 ;; Call subroutine returning no value.
14047
14048 (define_expand "call_pop"
14049 [(parallel [(call (match_operand:QI 0 "" "")
14050 (match_operand:SI 1 "" ""))
14051 (set (reg:SI SP_REG)
14052 (plus:SI (reg:SI SP_REG)
14053 (match_operand:SI 3 "" "")))])]
14054 "!TARGET_64BIT"
14055 {
14056 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14057 DONE;
14058 })
14059
14060 (define_insn "*call_pop_0"
14061 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14062 (match_operand:SI 1 "" ""))
14063 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14064 (match_operand:SI 2 "immediate_operand" "")))]
14065 "!TARGET_64BIT"
14066 {
14067 if (SIBLING_CALL_P (insn))
14068 return "jmp\t%P0";
14069 else
14070 return "call\t%P0";
14071 }
14072 [(set_attr "type" "call")])
14073
14074 (define_insn "*call_pop_1"
14075 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14076 (match_operand:SI 1 "" ""))
14077 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14078 (match_operand:SI 2 "immediate_operand" "i")))]
14079 "!TARGET_64BIT"
14080 {
14081 if (constant_call_address_operand (operands[0], Pmode))
14082 {
14083 if (SIBLING_CALL_P (insn))
14084 return "jmp\t%P0";
14085 else
14086 return "call\t%P0";
14087 }
14088 if (SIBLING_CALL_P (insn))
14089 return "jmp\t%A0";
14090 else
14091 return "call\t%A0";
14092 }
14093 [(set_attr "type" "call")])
14094
14095 (define_expand "call"
14096 [(call (match_operand:QI 0 "" "")
14097 (match_operand 1 "" ""))
14098 (use (match_operand 2 "" ""))]
14099 ""
14100 {
14101 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14102 DONE;
14103 })
14104
14105 (define_expand "sibcall"
14106 [(call (match_operand:QI 0 "" "")
14107 (match_operand 1 "" ""))
14108 (use (match_operand 2 "" ""))]
14109 ""
14110 {
14111 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14112 DONE;
14113 })
14114
14115 (define_insn "*call_0"
14116 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14117 (match_operand 1 "" ""))]
14118 ""
14119 {
14120 if (SIBLING_CALL_P (insn))
14121 return "jmp\t%P0";
14122 else
14123 return "call\t%P0";
14124 }
14125 [(set_attr "type" "call")])
14126
14127 (define_insn "*call_1"
14128 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14129 (match_operand 1 "" ""))]
14130 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14131 {
14132 if (constant_call_address_operand (operands[0], Pmode))
14133 return "call\t%P0";
14134 return "call\t%A0";
14135 }
14136 [(set_attr "type" "call")])
14137
14138 (define_insn "*sibcall_1"
14139 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14140 (match_operand 1 "" ""))]
14141 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14142 {
14143 if (constant_call_address_operand (operands[0], Pmode))
14144 return "jmp\t%P0";
14145 return "jmp\t%A0";
14146 }
14147 [(set_attr "type" "call")])
14148
14149 (define_insn "*call_1_rex64"
14150 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14151 (match_operand 1 "" ""))]
14152 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14153 {
14154 if (constant_call_address_operand (operands[0], Pmode))
14155 return "call\t%P0";
14156 return "call\t%A0";
14157 }
14158 [(set_attr "type" "call")])
14159
14160 (define_insn "*sibcall_1_rex64"
14161 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14162 (match_operand 1 "" ""))]
14163 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14164 "jmp\t%P0"
14165 [(set_attr "type" "call")])
14166
14167 (define_insn "*sibcall_1_rex64_v"
14168 [(call (mem:QI (reg:DI R11_REG))
14169 (match_operand 0 "" ""))]
14170 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14171 "jmp\t*%%r11"
14172 [(set_attr "type" "call")])
14173
14174
14175 ;; Call subroutine, returning value in operand 0
14176
14177 (define_expand "call_value_pop"
14178 [(parallel [(set (match_operand 0 "" "")
14179 (call (match_operand:QI 1 "" "")
14180 (match_operand:SI 2 "" "")))
14181 (set (reg:SI SP_REG)
14182 (plus:SI (reg:SI SP_REG)
14183 (match_operand:SI 4 "" "")))])]
14184 "!TARGET_64BIT"
14185 {
14186 ix86_expand_call (operands[0], operands[1], operands[2],
14187 operands[3], operands[4], 0);
14188 DONE;
14189 })
14190
14191 (define_expand "call_value"
14192 [(set (match_operand 0 "" "")
14193 (call (match_operand:QI 1 "" "")
14194 (match_operand:SI 2 "" "")))
14195 (use (match_operand:SI 3 "" ""))]
14196 ;; Operand 2 not used on the i386.
14197 ""
14198 {
14199 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14200 DONE;
14201 })
14202
14203 (define_expand "sibcall_value"
14204 [(set (match_operand 0 "" "")
14205 (call (match_operand:QI 1 "" "")
14206 (match_operand:SI 2 "" "")))
14207 (use (match_operand:SI 3 "" ""))]
14208 ;; Operand 2 not used on the i386.
14209 ""
14210 {
14211 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14212 DONE;
14213 })
14214
14215 ;; Call subroutine returning any type.
14216
14217 (define_expand "untyped_call"
14218 [(parallel [(call (match_operand 0 "" "")
14219 (const_int 0))
14220 (match_operand 1 "" "")
14221 (match_operand 2 "" "")])]
14222 ""
14223 {
14224 int i;
14225
14226 /* In order to give reg-stack an easier job in validating two
14227 coprocessor registers as containing a possible return value,
14228 simply pretend the untyped call returns a complex long double
14229 value. */
14230
14231 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14232 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14233 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14234 NULL, 0);
14235
14236 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14237 {
14238 rtx set = XVECEXP (operands[2], 0, i);
14239 emit_move_insn (SET_DEST (set), SET_SRC (set));
14240 }
14241
14242 /* The optimizer does not know that the call sets the function value
14243 registers we stored in the result block. We avoid problems by
14244 claiming that all hard registers are used and clobbered at this
14245 point. */
14246 emit_insn (gen_blockage (const0_rtx));
14247
14248 DONE;
14249 })
14250 \f
14251 ;; Prologue and epilogue instructions
14252
14253 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14254 ;; all of memory. This blocks insns from being moved across this point.
14255
14256 (define_insn "blockage"
14257 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14258 ""
14259 ""
14260 [(set_attr "length" "0")])
14261
14262 ;; Insn emitted into the body of a function to return from a function.
14263 ;; This is only done if the function's epilogue is known to be simple.
14264 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14265
14266 (define_expand "return"
14267 [(return)]
14268 "ix86_can_use_return_insn_p ()"
14269 {
14270 if (current_function_pops_args)
14271 {
14272 rtx popc = GEN_INT (current_function_pops_args);
14273 emit_jump_insn (gen_return_pop_internal (popc));
14274 DONE;
14275 }
14276 })
14277
14278 (define_insn "return_internal"
14279 [(return)]
14280 "reload_completed"
14281 "ret"
14282 [(set_attr "length" "1")
14283 (set_attr "length_immediate" "0")
14284 (set_attr "modrm" "0")])
14285
14286 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14287 ;; instruction Athlon and K8 have.
14288
14289 (define_insn "return_internal_long"
14290 [(return)
14291 (unspec [(const_int 0)] UNSPEC_REP)]
14292 "reload_completed"
14293 "rep {;} ret"
14294 [(set_attr "length" "1")
14295 (set_attr "length_immediate" "0")
14296 (set_attr "prefix_rep" "1")
14297 (set_attr "modrm" "0")])
14298
14299 (define_insn "return_pop_internal"
14300 [(return)
14301 (use (match_operand:SI 0 "const_int_operand" ""))]
14302 "reload_completed"
14303 "ret\t%0"
14304 [(set_attr "length" "3")
14305 (set_attr "length_immediate" "2")
14306 (set_attr "modrm" "0")])
14307
14308 (define_insn "return_indirect_internal"
14309 [(return)
14310 (use (match_operand:SI 0 "register_operand" "r"))]
14311 "reload_completed"
14312 "jmp\t%A0"
14313 [(set_attr "type" "ibr")
14314 (set_attr "length_immediate" "0")])
14315
14316 (define_insn "nop"
14317 [(const_int 0)]
14318 ""
14319 "nop"
14320 [(set_attr "length" "1")
14321 (set_attr "length_immediate" "0")
14322 (set_attr "modrm" "0")])
14323
14324 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14325 ;; branch prediction penalty for the third jump in a 16-byte
14326 ;; block on K8.
14327
14328 (define_insn "align"
14329 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14330 ""
14331 {
14332 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14333 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14334 #else
14335 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14336 The align insn is used to avoid 3 jump instructions in the row to improve
14337 branch prediction and the benefits hardly outweigh the cost of extra 8
14338 nops on the average inserted by full alignment pseudo operation. */
14339 #endif
14340 return "";
14341 }
14342 [(set_attr "length" "16")])
14343
14344 (define_expand "prologue"
14345 [(const_int 1)]
14346 ""
14347 "ix86_expand_prologue (); DONE;")
14348
14349 (define_insn "set_got"
14350 [(set (match_operand:SI 0 "register_operand" "=r")
14351 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14352 (clobber (reg:CC FLAGS_REG))]
14353 "!TARGET_64BIT"
14354 { return output_set_got (operands[0], NULL_RTX); }
14355 [(set_attr "type" "multi")
14356 (set_attr "length" "12")])
14357
14358 (define_insn "set_got_labelled"
14359 [(set (match_operand:SI 0 "register_operand" "=r")
14360 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14361 UNSPEC_SET_GOT))
14362 (clobber (reg:CC FLAGS_REG))]
14363 "!TARGET_64BIT"
14364 { return output_set_got (operands[0], operands[1]); }
14365 [(set_attr "type" "multi")
14366 (set_attr "length" "12")])
14367
14368 (define_insn "set_got_rex64"
14369 [(set (match_operand:DI 0 "register_operand" "=r")
14370 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14371 "TARGET_64BIT"
14372 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14373 [(set_attr "type" "lea")
14374 (set_attr "length" "6")])
14375
14376 (define_expand "epilogue"
14377 [(const_int 1)]
14378 ""
14379 "ix86_expand_epilogue (1); DONE;")
14380
14381 (define_expand "sibcall_epilogue"
14382 [(const_int 1)]
14383 ""
14384 "ix86_expand_epilogue (0); DONE;")
14385
14386 (define_expand "eh_return"
14387 [(use (match_operand 0 "register_operand" ""))]
14388 ""
14389 {
14390 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14391
14392 /* Tricky bit: we write the address of the handler to which we will
14393 be returning into someone else's stack frame, one word below the
14394 stack address we wish to restore. */
14395 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14396 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14397 tmp = gen_rtx_MEM (Pmode, tmp);
14398 emit_move_insn (tmp, ra);
14399
14400 if (Pmode == SImode)
14401 emit_jump_insn (gen_eh_return_si (sa));
14402 else
14403 emit_jump_insn (gen_eh_return_di (sa));
14404 emit_barrier ();
14405 DONE;
14406 })
14407
14408 (define_insn_and_split "eh_return_si"
14409 [(set (pc)
14410 (unspec [(match_operand:SI 0 "register_operand" "c")]
14411 UNSPEC_EH_RETURN))]
14412 "!TARGET_64BIT"
14413 "#"
14414 "reload_completed"
14415 [(const_int 1)]
14416 "ix86_expand_epilogue (2); DONE;")
14417
14418 (define_insn_and_split "eh_return_di"
14419 [(set (pc)
14420 (unspec [(match_operand:DI 0 "register_operand" "c")]
14421 UNSPEC_EH_RETURN))]
14422 "TARGET_64BIT"
14423 "#"
14424 "reload_completed"
14425 [(const_int 1)]
14426 "ix86_expand_epilogue (2); DONE;")
14427
14428 (define_insn "leave"
14429 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14430 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14431 (clobber (mem:BLK (scratch)))]
14432 "!TARGET_64BIT"
14433 "leave"
14434 [(set_attr "type" "leave")])
14435
14436 (define_insn "leave_rex64"
14437 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14438 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14439 (clobber (mem:BLK (scratch)))]
14440 "TARGET_64BIT"
14441 "leave"
14442 [(set_attr "type" "leave")])
14443 \f
14444 (define_expand "ffssi2"
14445 [(parallel
14446 [(set (match_operand:SI 0 "register_operand" "")
14447 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14448 (clobber (match_scratch:SI 2 ""))
14449 (clobber (reg:CC FLAGS_REG))])]
14450 ""
14451 "")
14452
14453 (define_insn_and_split "*ffs_cmove"
14454 [(set (match_operand:SI 0 "register_operand" "=r")
14455 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14456 (clobber (match_scratch:SI 2 "=&r"))
14457 (clobber (reg:CC FLAGS_REG))]
14458 "TARGET_CMOVE"
14459 "#"
14460 "&& reload_completed"
14461 [(set (match_dup 2) (const_int -1))
14462 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14463 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14464 (set (match_dup 0) (if_then_else:SI
14465 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14466 (match_dup 2)
14467 (match_dup 0)))
14468 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14469 (clobber (reg:CC FLAGS_REG))])]
14470 "")
14471
14472 (define_insn_and_split "*ffs_no_cmove"
14473 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14474 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14475 (clobber (match_scratch:SI 2 "=&q"))
14476 (clobber (reg:CC FLAGS_REG))]
14477 ""
14478 "#"
14479 "reload_completed"
14480 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14481 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14482 (set (strict_low_part (match_dup 3))
14483 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14484 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14485 (clobber (reg:CC FLAGS_REG))])
14486 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14487 (clobber (reg:CC FLAGS_REG))])
14488 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14489 (clobber (reg:CC FLAGS_REG))])]
14490 {
14491 operands[3] = gen_lowpart (QImode, operands[2]);
14492 ix86_expand_clear (operands[2]);
14493 })
14494
14495 (define_insn "*ffssi_1"
14496 [(set (reg:CCZ FLAGS_REG)
14497 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14498 (const_int 0)))
14499 (set (match_operand:SI 0 "register_operand" "=r")
14500 (ctz:SI (match_dup 1)))]
14501 ""
14502 "bsf{l}\t{%1, %0|%0, %1}"
14503 [(set_attr "prefix_0f" "1")])
14504
14505 (define_expand "ffsdi2"
14506 [(parallel
14507 [(set (match_operand:DI 0 "register_operand" "")
14508 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14509 (clobber (match_scratch:DI 2 ""))
14510 (clobber (reg:CC FLAGS_REG))])]
14511 "TARGET_64BIT && TARGET_CMOVE"
14512 "")
14513
14514 (define_insn_and_split "*ffs_rex64"
14515 [(set (match_operand:DI 0 "register_operand" "=r")
14516 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14517 (clobber (match_scratch:DI 2 "=&r"))
14518 (clobber (reg:CC FLAGS_REG))]
14519 "TARGET_64BIT && TARGET_CMOVE"
14520 "#"
14521 "&& reload_completed"
14522 [(set (match_dup 2) (const_int -1))
14523 (parallel [(set (reg:CCZ FLAGS_REG)
14524 (compare:CCZ (match_dup 1) (const_int 0)))
14525 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14526 (set (match_dup 0) (if_then_else:DI
14527 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14528 (match_dup 2)
14529 (match_dup 0)))
14530 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14531 (clobber (reg:CC FLAGS_REG))])]
14532 "")
14533
14534 (define_insn "*ffsdi_1"
14535 [(set (reg:CCZ FLAGS_REG)
14536 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14537 (const_int 0)))
14538 (set (match_operand:DI 0 "register_operand" "=r")
14539 (ctz:DI (match_dup 1)))]
14540 "TARGET_64BIT"
14541 "bsf{q}\t{%1, %0|%0, %1}"
14542 [(set_attr "prefix_0f" "1")])
14543
14544 (define_insn "ctzsi2"
14545 [(set (match_operand:SI 0 "register_operand" "=r")
14546 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14547 (clobber (reg:CC FLAGS_REG))]
14548 ""
14549 "bsf{l}\t{%1, %0|%0, %1}"
14550 [(set_attr "prefix_0f" "1")])
14551
14552 (define_insn "ctzdi2"
14553 [(set (match_operand:DI 0 "register_operand" "=r")
14554 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14555 (clobber (reg:CC FLAGS_REG))]
14556 "TARGET_64BIT"
14557 "bsf{q}\t{%1, %0|%0, %1}"
14558 [(set_attr "prefix_0f" "1")])
14559
14560 (define_expand "clzsi2"
14561 [(parallel
14562 [(set (match_operand:SI 0 "register_operand" "")
14563 (minus:SI (const_int 31)
14564 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14565 (clobber (reg:CC FLAGS_REG))])
14566 (parallel
14567 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14568 (clobber (reg:CC FLAGS_REG))])]
14569 ""
14570 "")
14571
14572 (define_insn "*bsr"
14573 [(set (match_operand:SI 0 "register_operand" "=r")
14574 (minus:SI (const_int 31)
14575 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14576 (clobber (reg:CC FLAGS_REG))]
14577 ""
14578 "bsr{l}\t{%1, %0|%0, %1}"
14579 [(set_attr "prefix_0f" "1")])
14580
14581 (define_expand "clzdi2"
14582 [(parallel
14583 [(set (match_operand:DI 0 "register_operand" "")
14584 (minus:DI (const_int 63)
14585 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14586 (clobber (reg:CC FLAGS_REG))])
14587 (parallel
14588 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14589 (clobber (reg:CC FLAGS_REG))])]
14590 "TARGET_64BIT"
14591 "")
14592
14593 (define_insn "*bsr_rex64"
14594 [(set (match_operand:DI 0 "register_operand" "=r")
14595 (minus:DI (const_int 63)
14596 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14597 (clobber (reg:CC FLAGS_REG))]
14598 "TARGET_64BIT"
14599 "bsr{q}\t{%1, %0|%0, %1}"
14600 [(set_attr "prefix_0f" "1")])
14601 \f
14602 ;; Thread-local storage patterns for ELF.
14603 ;;
14604 ;; Note that these code sequences must appear exactly as shown
14605 ;; in order to allow linker relaxation.
14606
14607 (define_insn "*tls_global_dynamic_32_gnu"
14608 [(set (match_operand:SI 0 "register_operand" "=a")
14609 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14610 (match_operand:SI 2 "tls_symbolic_operand" "")
14611 (match_operand:SI 3 "call_insn_operand" "")]
14612 UNSPEC_TLS_GD))
14613 (clobber (match_scratch:SI 4 "=d"))
14614 (clobber (match_scratch:SI 5 "=c"))
14615 (clobber (reg:CC FLAGS_REG))]
14616 "!TARGET_64BIT && TARGET_GNU_TLS"
14617 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14618 [(set_attr "type" "multi")
14619 (set_attr "length" "12")])
14620
14621 (define_insn "*tls_global_dynamic_32_sun"
14622 [(set (match_operand:SI 0 "register_operand" "=a")
14623 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14624 (match_operand:SI 2 "tls_symbolic_operand" "")
14625 (match_operand:SI 3 "call_insn_operand" "")]
14626 UNSPEC_TLS_GD))
14627 (clobber (match_scratch:SI 4 "=d"))
14628 (clobber (match_scratch:SI 5 "=c"))
14629 (clobber (reg:CC FLAGS_REG))]
14630 "!TARGET_64BIT && TARGET_SUN_TLS"
14631 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14632 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14633 [(set_attr "type" "multi")
14634 (set_attr "length" "14")])
14635
14636 (define_expand "tls_global_dynamic_32"
14637 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14638 (unspec:SI
14639 [(match_dup 2)
14640 (match_operand:SI 1 "tls_symbolic_operand" "")
14641 (match_dup 3)]
14642 UNSPEC_TLS_GD))
14643 (clobber (match_scratch:SI 4 ""))
14644 (clobber (match_scratch:SI 5 ""))
14645 (clobber (reg:CC FLAGS_REG))])]
14646 ""
14647 {
14648 if (flag_pic)
14649 operands[2] = pic_offset_table_rtx;
14650 else
14651 {
14652 operands[2] = gen_reg_rtx (Pmode);
14653 emit_insn (gen_set_got (operands[2]));
14654 }
14655 if (TARGET_GNU2_TLS)
14656 {
14657 emit_insn (gen_tls_dynamic_gnu2_32
14658 (operands[0], operands[1], operands[2]));
14659 DONE;
14660 }
14661 operands[3] = ix86_tls_get_addr ();
14662 })
14663
14664 (define_insn "*tls_global_dynamic_64"
14665 [(set (match_operand:DI 0 "register_operand" "=a")
14666 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14667 (match_operand:DI 3 "" "")))
14668 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14669 UNSPEC_TLS_GD)]
14670 "TARGET_64BIT"
14671 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14672 [(set_attr "type" "multi")
14673 (set_attr "length" "16")])
14674
14675 (define_expand "tls_global_dynamic_64"
14676 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14677 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14678 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14679 UNSPEC_TLS_GD)])]
14680 ""
14681 {
14682 if (TARGET_GNU2_TLS)
14683 {
14684 emit_insn (gen_tls_dynamic_gnu2_64
14685 (operands[0], operands[1]));
14686 DONE;
14687 }
14688 operands[2] = ix86_tls_get_addr ();
14689 })
14690
14691 (define_insn "*tls_local_dynamic_base_32_gnu"
14692 [(set (match_operand:SI 0 "register_operand" "=a")
14693 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14694 (match_operand:SI 2 "call_insn_operand" "")]
14695 UNSPEC_TLS_LD_BASE))
14696 (clobber (match_scratch:SI 3 "=d"))
14697 (clobber (match_scratch:SI 4 "=c"))
14698 (clobber (reg:CC FLAGS_REG))]
14699 "!TARGET_64BIT && TARGET_GNU_TLS"
14700 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14701 [(set_attr "type" "multi")
14702 (set_attr "length" "11")])
14703
14704 (define_insn "*tls_local_dynamic_base_32_sun"
14705 [(set (match_operand:SI 0 "register_operand" "=a")
14706 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14707 (match_operand:SI 2 "call_insn_operand" "")]
14708 UNSPEC_TLS_LD_BASE))
14709 (clobber (match_scratch:SI 3 "=d"))
14710 (clobber (match_scratch:SI 4 "=c"))
14711 (clobber (reg:CC FLAGS_REG))]
14712 "!TARGET_64BIT && TARGET_SUN_TLS"
14713 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14714 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14715 [(set_attr "type" "multi")
14716 (set_attr "length" "13")])
14717
14718 (define_expand "tls_local_dynamic_base_32"
14719 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14720 (unspec:SI [(match_dup 1) (match_dup 2)]
14721 UNSPEC_TLS_LD_BASE))
14722 (clobber (match_scratch:SI 3 ""))
14723 (clobber (match_scratch:SI 4 ""))
14724 (clobber (reg:CC FLAGS_REG))])]
14725 ""
14726 {
14727 if (flag_pic)
14728 operands[1] = pic_offset_table_rtx;
14729 else
14730 {
14731 operands[1] = gen_reg_rtx (Pmode);
14732 emit_insn (gen_set_got (operands[1]));
14733 }
14734 if (TARGET_GNU2_TLS)
14735 {
14736 emit_insn (gen_tls_dynamic_gnu2_32
14737 (operands[0], ix86_tls_module_base (), operands[1]));
14738 DONE;
14739 }
14740 operands[2] = ix86_tls_get_addr ();
14741 })
14742
14743 (define_insn "*tls_local_dynamic_base_64"
14744 [(set (match_operand:DI 0 "register_operand" "=a")
14745 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14746 (match_operand:DI 2 "" "")))
14747 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14748 "TARGET_64BIT"
14749 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14750 [(set_attr "type" "multi")
14751 (set_attr "length" "12")])
14752
14753 (define_expand "tls_local_dynamic_base_64"
14754 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14755 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14756 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14757 ""
14758 {
14759 if (TARGET_GNU2_TLS)
14760 {
14761 emit_insn (gen_tls_dynamic_gnu2_64
14762 (operands[0], ix86_tls_module_base ()));
14763 DONE;
14764 }
14765 operands[1] = ix86_tls_get_addr ();
14766 })
14767
14768 ;; Local dynamic of a single variable is a lose. Show combine how
14769 ;; to convert that back to global dynamic.
14770
14771 (define_insn_and_split "*tls_local_dynamic_32_once"
14772 [(set (match_operand:SI 0 "register_operand" "=a")
14773 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14774 (match_operand:SI 2 "call_insn_operand" "")]
14775 UNSPEC_TLS_LD_BASE)
14776 (const:SI (unspec:SI
14777 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14778 UNSPEC_DTPOFF))))
14779 (clobber (match_scratch:SI 4 "=d"))
14780 (clobber (match_scratch:SI 5 "=c"))
14781 (clobber (reg:CC FLAGS_REG))]
14782 ""
14783 "#"
14784 ""
14785 [(parallel [(set (match_dup 0)
14786 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14787 UNSPEC_TLS_GD))
14788 (clobber (match_dup 4))
14789 (clobber (match_dup 5))
14790 (clobber (reg:CC FLAGS_REG))])]
14791 "")
14792
14793 ;; Load and add the thread base pointer from %gs:0.
14794
14795 (define_insn "*load_tp_si"
14796 [(set (match_operand:SI 0 "register_operand" "=r")
14797 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14798 "!TARGET_64BIT"
14799 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14800 [(set_attr "type" "imov")
14801 (set_attr "modrm" "0")
14802 (set_attr "length" "7")
14803 (set_attr "memory" "load")
14804 (set_attr "imm_disp" "false")])
14805
14806 (define_insn "*add_tp_si"
14807 [(set (match_operand:SI 0 "register_operand" "=r")
14808 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14809 (match_operand:SI 1 "register_operand" "0")))
14810 (clobber (reg:CC FLAGS_REG))]
14811 "!TARGET_64BIT"
14812 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14813 [(set_attr "type" "alu")
14814 (set_attr "modrm" "0")
14815 (set_attr "length" "7")
14816 (set_attr "memory" "load")
14817 (set_attr "imm_disp" "false")])
14818
14819 (define_insn "*load_tp_di"
14820 [(set (match_operand:DI 0 "register_operand" "=r")
14821 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14822 "TARGET_64BIT"
14823 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14824 [(set_attr "type" "imov")
14825 (set_attr "modrm" "0")
14826 (set_attr "length" "7")
14827 (set_attr "memory" "load")
14828 (set_attr "imm_disp" "false")])
14829
14830 (define_insn "*add_tp_di"
14831 [(set (match_operand:DI 0 "register_operand" "=r")
14832 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14833 (match_operand:DI 1 "register_operand" "0")))
14834 (clobber (reg:CC FLAGS_REG))]
14835 "TARGET_64BIT"
14836 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14837 [(set_attr "type" "alu")
14838 (set_attr "modrm" "0")
14839 (set_attr "length" "7")
14840 (set_attr "memory" "load")
14841 (set_attr "imm_disp" "false")])
14842
14843 ;; GNU2 TLS patterns can be split.
14844
14845 (define_expand "tls_dynamic_gnu2_32"
14846 [(set (match_dup 3)
14847 (plus:SI (match_operand:SI 2 "register_operand" "")
14848 (const:SI
14849 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14850 UNSPEC_TLSDESC))))
14851 (parallel
14852 [(set (match_operand:SI 0 "register_operand" "")
14853 (unspec:SI [(match_dup 1) (match_dup 3)
14854 (match_dup 2) (reg:SI SP_REG)]
14855 UNSPEC_TLSDESC))
14856 (clobber (reg:CC FLAGS_REG))])]
14857 "!TARGET_64BIT && TARGET_GNU2_TLS"
14858 {
14859 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14860 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14861 })
14862
14863 (define_insn "*tls_dynamic_lea_32"
14864 [(set (match_operand:SI 0 "register_operand" "=r")
14865 (plus:SI (match_operand:SI 1 "register_operand" "b")
14866 (const:SI
14867 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14868 UNSPEC_TLSDESC))))]
14869 "!TARGET_64BIT && TARGET_GNU2_TLS"
14870 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14871 [(set_attr "type" "lea")
14872 (set_attr "mode" "SI")
14873 (set_attr "length" "6")
14874 (set_attr "length_address" "4")])
14875
14876 (define_insn "*tls_dynamic_call_32"
14877 [(set (match_operand:SI 0 "register_operand" "=a")
14878 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14879 (match_operand:SI 2 "register_operand" "0")
14880 ;; we have to make sure %ebx still points to the GOT
14881 (match_operand:SI 3 "register_operand" "b")
14882 (reg:SI SP_REG)]
14883 UNSPEC_TLSDESC))
14884 (clobber (reg:CC FLAGS_REG))]
14885 "!TARGET_64BIT && TARGET_GNU2_TLS"
14886 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14887 [(set_attr "type" "call")
14888 (set_attr "length" "2")
14889 (set_attr "length_address" "0")])
14890
14891 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14892 [(set (match_operand:SI 0 "register_operand" "=&a")
14893 (plus:SI
14894 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14895 (match_operand:SI 4 "" "")
14896 (match_operand:SI 2 "register_operand" "b")
14897 (reg:SI SP_REG)]
14898 UNSPEC_TLSDESC)
14899 (const:SI (unspec:SI
14900 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14901 UNSPEC_DTPOFF))))
14902 (clobber (reg:CC FLAGS_REG))]
14903 "!TARGET_64BIT && TARGET_GNU2_TLS"
14904 "#"
14905 ""
14906 [(set (match_dup 0) (match_dup 5))]
14907 {
14908 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14909 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14910 })
14911
14912 (define_expand "tls_dynamic_gnu2_64"
14913 [(set (match_dup 2)
14914 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14915 UNSPEC_TLSDESC))
14916 (parallel
14917 [(set (match_operand:DI 0 "register_operand" "")
14918 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14919 UNSPEC_TLSDESC))
14920 (clobber (reg:CC FLAGS_REG))])]
14921 "TARGET_64BIT && TARGET_GNU2_TLS"
14922 {
14923 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14924 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14925 })
14926
14927 (define_insn "*tls_dynamic_lea_64"
14928 [(set (match_operand:DI 0 "register_operand" "=r")
14929 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14930 UNSPEC_TLSDESC))]
14931 "TARGET_64BIT && TARGET_GNU2_TLS"
14932 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14933 [(set_attr "type" "lea")
14934 (set_attr "mode" "DI")
14935 (set_attr "length" "7")
14936 (set_attr "length_address" "4")])
14937
14938 (define_insn "*tls_dynamic_call_64"
14939 [(set (match_operand:DI 0 "register_operand" "=a")
14940 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14941 (match_operand:DI 2 "register_operand" "0")
14942 (reg:DI SP_REG)]
14943 UNSPEC_TLSDESC))
14944 (clobber (reg:CC FLAGS_REG))]
14945 "TARGET_64BIT && TARGET_GNU2_TLS"
14946 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14947 [(set_attr "type" "call")
14948 (set_attr "length" "2")
14949 (set_attr "length_address" "0")])
14950
14951 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14952 [(set (match_operand:DI 0 "register_operand" "=&a")
14953 (plus:DI
14954 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14955 (match_operand:DI 3 "" "")
14956 (reg:DI SP_REG)]
14957 UNSPEC_TLSDESC)
14958 (const:DI (unspec:DI
14959 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14960 UNSPEC_DTPOFF))))
14961 (clobber (reg:CC FLAGS_REG))]
14962 "TARGET_64BIT && TARGET_GNU2_TLS"
14963 "#"
14964 ""
14965 [(set (match_dup 0) (match_dup 4))]
14966 {
14967 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14968 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14969 })
14970
14971 ;;
14972 \f
14973 ;; These patterns match the binary 387 instructions for addM3, subM3,
14974 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14975 ;; SFmode. The first is the normal insn, the second the same insn but
14976 ;; with one operand a conversion, and the third the same insn but with
14977 ;; the other operand a conversion. The conversion may be SFmode or
14978 ;; SImode if the target mode DFmode, but only SImode if the target mode
14979 ;; is SFmode.
14980
14981 ;; Gcc is slightly more smart about handling normal two address instructions
14982 ;; so use special patterns for add and mull.
14983
14984 (define_insn "*fop_sf_comm_mixed"
14985 [(set (match_operand:SF 0 "register_operand" "=f,x")
14986 (match_operator:SF 3 "binary_fp_operator"
14987 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14988 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14989 "TARGET_MIX_SSE_I387
14990 && COMMUTATIVE_ARITH_P (operands[3])
14991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14992 "* return output_387_binary_op (insn, operands);"
14993 [(set (attr "type")
14994 (if_then_else (eq_attr "alternative" "1")
14995 (if_then_else (match_operand:SF 3 "mult_operator" "")
14996 (const_string "ssemul")
14997 (const_string "sseadd"))
14998 (if_then_else (match_operand:SF 3 "mult_operator" "")
14999 (const_string "fmul")
15000 (const_string "fop"))))
15001 (set_attr "mode" "SF")])
15002
15003 (define_insn "*fop_sf_comm_sse"
15004 [(set (match_operand:SF 0 "register_operand" "=x")
15005 (match_operator:SF 3 "binary_fp_operator"
15006 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15007 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15008 "TARGET_SSE_MATH
15009 && COMMUTATIVE_ARITH_P (operands[3])
15010 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15011 "* return output_387_binary_op (insn, operands);"
15012 [(set (attr "type")
15013 (if_then_else (match_operand:SF 3 "mult_operator" "")
15014 (const_string "ssemul")
15015 (const_string "sseadd")))
15016 (set_attr "mode" "SF")])
15017
15018 (define_insn "*fop_sf_comm_i387"
15019 [(set (match_operand:SF 0 "register_operand" "=f")
15020 (match_operator:SF 3 "binary_fp_operator"
15021 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15022 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15023 "TARGET_80387
15024 && COMMUTATIVE_ARITH_P (operands[3])
15025 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15026 "* return output_387_binary_op (insn, operands);"
15027 [(set (attr "type")
15028 (if_then_else (match_operand:SF 3 "mult_operator" "")
15029 (const_string "fmul")
15030 (const_string "fop")))
15031 (set_attr "mode" "SF")])
15032
15033 (define_insn "*fop_sf_1_mixed"
15034 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15035 (match_operator:SF 3 "binary_fp_operator"
15036 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15037 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15038 "TARGET_MIX_SSE_I387
15039 && !COMMUTATIVE_ARITH_P (operands[3])
15040 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15041 "* return output_387_binary_op (insn, operands);"
15042 [(set (attr "type")
15043 (cond [(and (eq_attr "alternative" "2")
15044 (match_operand:SF 3 "mult_operator" ""))
15045 (const_string "ssemul")
15046 (and (eq_attr "alternative" "2")
15047 (match_operand:SF 3 "div_operator" ""))
15048 (const_string "ssediv")
15049 (eq_attr "alternative" "2")
15050 (const_string "sseadd")
15051 (match_operand:SF 3 "mult_operator" "")
15052 (const_string "fmul")
15053 (match_operand:SF 3 "div_operator" "")
15054 (const_string "fdiv")
15055 ]
15056 (const_string "fop")))
15057 (set_attr "mode" "SF")])
15058
15059 (define_insn "*fop_sf_1_sse"
15060 [(set (match_operand:SF 0 "register_operand" "=x")
15061 (match_operator:SF 3 "binary_fp_operator"
15062 [(match_operand:SF 1 "register_operand" "0")
15063 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15064 "TARGET_SSE_MATH
15065 && !COMMUTATIVE_ARITH_P (operands[3])"
15066 "* return output_387_binary_op (insn, operands);"
15067 [(set (attr "type")
15068 (cond [(match_operand:SF 3 "mult_operator" "")
15069 (const_string "ssemul")
15070 (match_operand:SF 3 "div_operator" "")
15071 (const_string "ssediv")
15072 ]
15073 (const_string "sseadd")))
15074 (set_attr "mode" "SF")])
15075
15076 ;; This pattern is not fully shadowed by the pattern above.
15077 (define_insn "*fop_sf_1_i387"
15078 [(set (match_operand:SF 0 "register_operand" "=f,f")
15079 (match_operator:SF 3 "binary_fp_operator"
15080 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15081 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15082 "TARGET_80387 && !TARGET_SSE_MATH
15083 && !COMMUTATIVE_ARITH_P (operands[3])
15084 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15085 "* return output_387_binary_op (insn, operands);"
15086 [(set (attr "type")
15087 (cond [(match_operand:SF 3 "mult_operator" "")
15088 (const_string "fmul")
15089 (match_operand:SF 3 "div_operator" "")
15090 (const_string "fdiv")
15091 ]
15092 (const_string "fop")))
15093 (set_attr "mode" "SF")])
15094
15095 ;; ??? Add SSE splitters for these!
15096 (define_insn "*fop_sf_2<mode>_i387"
15097 [(set (match_operand:SF 0 "register_operand" "=f,f")
15098 (match_operator:SF 3 "binary_fp_operator"
15099 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15100 (match_operand:SF 2 "register_operand" "0,0")]))]
15101 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15102 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15103 [(set (attr "type")
15104 (cond [(match_operand:SF 3 "mult_operator" "")
15105 (const_string "fmul")
15106 (match_operand:SF 3 "div_operator" "")
15107 (const_string "fdiv")
15108 ]
15109 (const_string "fop")))
15110 (set_attr "fp_int_src" "true")
15111 (set_attr "mode" "<MODE>")])
15112
15113 (define_insn "*fop_sf_3<mode>_i387"
15114 [(set (match_operand:SF 0 "register_operand" "=f,f")
15115 (match_operator:SF 3 "binary_fp_operator"
15116 [(match_operand:SF 1 "register_operand" "0,0")
15117 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15118 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15119 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15120 [(set (attr "type")
15121 (cond [(match_operand:SF 3 "mult_operator" "")
15122 (const_string "fmul")
15123 (match_operand:SF 3 "div_operator" "")
15124 (const_string "fdiv")
15125 ]
15126 (const_string "fop")))
15127 (set_attr "fp_int_src" "true")
15128 (set_attr "mode" "<MODE>")])
15129
15130 (define_insn "*fop_df_comm_mixed"
15131 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15132 (match_operator:DF 3 "binary_fp_operator"
15133 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15134 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15135 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15136 && COMMUTATIVE_ARITH_P (operands[3])
15137 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15138 "* return output_387_binary_op (insn, operands);"
15139 [(set (attr "type")
15140 (if_then_else (eq_attr "alternative" "1")
15141 (if_then_else (match_operand:DF 3 "mult_operator" "")
15142 (const_string "ssemul")
15143 (const_string "sseadd"))
15144 (if_then_else (match_operand:DF 3 "mult_operator" "")
15145 (const_string "fmul")
15146 (const_string "fop"))))
15147 (set_attr "mode" "DF")])
15148
15149 (define_insn "*fop_df_comm_sse"
15150 [(set (match_operand:DF 0 "register_operand" "=Y")
15151 (match_operator:DF 3 "binary_fp_operator"
15152 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15153 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15154 "TARGET_SSE2 && TARGET_SSE_MATH
15155 && COMMUTATIVE_ARITH_P (operands[3])
15156 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15157 "* return output_387_binary_op (insn, operands);"
15158 [(set (attr "type")
15159 (if_then_else (match_operand:DF 3 "mult_operator" "")
15160 (const_string "ssemul")
15161 (const_string "sseadd")))
15162 (set_attr "mode" "DF")])
15163
15164 (define_insn "*fop_df_comm_i387"
15165 [(set (match_operand:DF 0 "register_operand" "=f")
15166 (match_operator:DF 3 "binary_fp_operator"
15167 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15168 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15169 "TARGET_80387
15170 && COMMUTATIVE_ARITH_P (operands[3])
15171 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15172 "* return output_387_binary_op (insn, operands);"
15173 [(set (attr "type")
15174 (if_then_else (match_operand:DF 3 "mult_operator" "")
15175 (const_string "fmul")
15176 (const_string "fop")))
15177 (set_attr "mode" "DF")])
15178
15179 (define_insn "*fop_df_1_mixed"
15180 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15181 (match_operator:DF 3 "binary_fp_operator"
15182 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15183 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15184 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15185 && !COMMUTATIVE_ARITH_P (operands[3])
15186 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15187 "* return output_387_binary_op (insn, operands);"
15188 [(set (attr "type")
15189 (cond [(and (eq_attr "alternative" "2")
15190 (match_operand:DF 3 "mult_operator" ""))
15191 (const_string "ssemul")
15192 (and (eq_attr "alternative" "2")
15193 (match_operand:DF 3 "div_operator" ""))
15194 (const_string "ssediv")
15195 (eq_attr "alternative" "2")
15196 (const_string "sseadd")
15197 (match_operand:DF 3 "mult_operator" "")
15198 (const_string "fmul")
15199 (match_operand:DF 3 "div_operator" "")
15200 (const_string "fdiv")
15201 ]
15202 (const_string "fop")))
15203 (set_attr "mode" "DF")])
15204
15205 (define_insn "*fop_df_1_sse"
15206 [(set (match_operand:DF 0 "register_operand" "=Y")
15207 (match_operator:DF 3 "binary_fp_operator"
15208 [(match_operand:DF 1 "register_operand" "0")
15209 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15210 "TARGET_SSE2 && TARGET_SSE_MATH
15211 && !COMMUTATIVE_ARITH_P (operands[3])"
15212 "* return output_387_binary_op (insn, operands);"
15213 [(set_attr "mode" "DF")
15214 (set (attr "type")
15215 (cond [(match_operand:DF 3 "mult_operator" "")
15216 (const_string "ssemul")
15217 (match_operand:DF 3 "div_operator" "")
15218 (const_string "ssediv")
15219 ]
15220 (const_string "sseadd")))])
15221
15222 ;; This pattern is not fully shadowed by the pattern above.
15223 (define_insn "*fop_df_1_i387"
15224 [(set (match_operand:DF 0 "register_operand" "=f,f")
15225 (match_operator:DF 3 "binary_fp_operator"
15226 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15227 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15228 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15229 && !COMMUTATIVE_ARITH_P (operands[3])
15230 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15231 "* return output_387_binary_op (insn, operands);"
15232 [(set (attr "type")
15233 (cond [(match_operand:DF 3 "mult_operator" "")
15234 (const_string "fmul")
15235 (match_operand:DF 3 "div_operator" "")
15236 (const_string "fdiv")
15237 ]
15238 (const_string "fop")))
15239 (set_attr "mode" "DF")])
15240
15241 ;; ??? Add SSE splitters for these!
15242 (define_insn "*fop_df_2<mode>_i387"
15243 [(set (match_operand:DF 0 "register_operand" "=f,f")
15244 (match_operator:DF 3 "binary_fp_operator"
15245 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15246 (match_operand:DF 2 "register_operand" "0,0")]))]
15247 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15248 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15249 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15250 [(set (attr "type")
15251 (cond [(match_operand:DF 3 "mult_operator" "")
15252 (const_string "fmul")
15253 (match_operand:DF 3 "div_operator" "")
15254 (const_string "fdiv")
15255 ]
15256 (const_string "fop")))
15257 (set_attr "fp_int_src" "true")
15258 (set_attr "mode" "<MODE>")])
15259
15260 (define_insn "*fop_df_3<mode>_i387"
15261 [(set (match_operand:DF 0 "register_operand" "=f,f")
15262 (match_operator:DF 3 "binary_fp_operator"
15263 [(match_operand:DF 1 "register_operand" "0,0")
15264 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15265 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15266 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15267 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15268 [(set (attr "type")
15269 (cond [(match_operand:DF 3 "mult_operator" "")
15270 (const_string "fmul")
15271 (match_operand:DF 3 "div_operator" "")
15272 (const_string "fdiv")
15273 ]
15274 (const_string "fop")))
15275 (set_attr "fp_int_src" "true")
15276 (set_attr "mode" "<MODE>")])
15277
15278 (define_insn "*fop_df_4_i387"
15279 [(set (match_operand:DF 0 "register_operand" "=f,f")
15280 (match_operator:DF 3 "binary_fp_operator"
15281 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15282 (match_operand:DF 2 "register_operand" "0,f")]))]
15283 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15284 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15285 "* return output_387_binary_op (insn, operands);"
15286 [(set (attr "type")
15287 (cond [(match_operand:DF 3 "mult_operator" "")
15288 (const_string "fmul")
15289 (match_operand:DF 3 "div_operator" "")
15290 (const_string "fdiv")
15291 ]
15292 (const_string "fop")))
15293 (set_attr "mode" "SF")])
15294
15295 (define_insn "*fop_df_5_i387"
15296 [(set (match_operand:DF 0 "register_operand" "=f,f")
15297 (match_operator:DF 3 "binary_fp_operator"
15298 [(match_operand:DF 1 "register_operand" "0,f")
15299 (float_extend:DF
15300 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15301 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15302 "* return output_387_binary_op (insn, operands);"
15303 [(set (attr "type")
15304 (cond [(match_operand:DF 3 "mult_operator" "")
15305 (const_string "fmul")
15306 (match_operand:DF 3 "div_operator" "")
15307 (const_string "fdiv")
15308 ]
15309 (const_string "fop")))
15310 (set_attr "mode" "SF")])
15311
15312 (define_insn "*fop_df_6_i387"
15313 [(set (match_operand:DF 0 "register_operand" "=f,f")
15314 (match_operator:DF 3 "binary_fp_operator"
15315 [(float_extend:DF
15316 (match_operand:SF 1 "register_operand" "0,f"))
15317 (float_extend:DF
15318 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15319 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15320 "* return output_387_binary_op (insn, operands);"
15321 [(set (attr "type")
15322 (cond [(match_operand:DF 3 "mult_operator" "")
15323 (const_string "fmul")
15324 (match_operand:DF 3 "div_operator" "")
15325 (const_string "fdiv")
15326 ]
15327 (const_string "fop")))
15328 (set_attr "mode" "SF")])
15329
15330 (define_insn "*fop_xf_comm_i387"
15331 [(set (match_operand:XF 0 "register_operand" "=f")
15332 (match_operator:XF 3 "binary_fp_operator"
15333 [(match_operand:XF 1 "register_operand" "%0")
15334 (match_operand:XF 2 "register_operand" "f")]))]
15335 "TARGET_80387
15336 && COMMUTATIVE_ARITH_P (operands[3])"
15337 "* return output_387_binary_op (insn, operands);"
15338 [(set (attr "type")
15339 (if_then_else (match_operand:XF 3 "mult_operator" "")
15340 (const_string "fmul")
15341 (const_string "fop")))
15342 (set_attr "mode" "XF")])
15343
15344 (define_insn "*fop_xf_1_i387"
15345 [(set (match_operand:XF 0 "register_operand" "=f,f")
15346 (match_operator:XF 3 "binary_fp_operator"
15347 [(match_operand:XF 1 "register_operand" "0,f")
15348 (match_operand:XF 2 "register_operand" "f,0")]))]
15349 "TARGET_80387
15350 && !COMMUTATIVE_ARITH_P (operands[3])"
15351 "* return output_387_binary_op (insn, operands);"
15352 [(set (attr "type")
15353 (cond [(match_operand:XF 3 "mult_operator" "")
15354 (const_string "fmul")
15355 (match_operand:XF 3 "div_operator" "")
15356 (const_string "fdiv")
15357 ]
15358 (const_string "fop")))
15359 (set_attr "mode" "XF")])
15360
15361 (define_insn "*fop_xf_2<mode>_i387"
15362 [(set (match_operand:XF 0 "register_operand" "=f,f")
15363 (match_operator:XF 3 "binary_fp_operator"
15364 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15365 (match_operand:XF 2 "register_operand" "0,0")]))]
15366 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15367 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15368 [(set (attr "type")
15369 (cond [(match_operand:XF 3 "mult_operator" "")
15370 (const_string "fmul")
15371 (match_operand:XF 3 "div_operator" "")
15372 (const_string "fdiv")
15373 ]
15374 (const_string "fop")))
15375 (set_attr "fp_int_src" "true")
15376 (set_attr "mode" "<MODE>")])
15377
15378 (define_insn "*fop_xf_3<mode>_i387"
15379 [(set (match_operand:XF 0 "register_operand" "=f,f")
15380 (match_operator:XF 3 "binary_fp_operator"
15381 [(match_operand:XF 1 "register_operand" "0,0")
15382 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15383 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15384 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15385 [(set (attr "type")
15386 (cond [(match_operand:XF 3 "mult_operator" "")
15387 (const_string "fmul")
15388 (match_operand:XF 3 "div_operator" "")
15389 (const_string "fdiv")
15390 ]
15391 (const_string "fop")))
15392 (set_attr "fp_int_src" "true")
15393 (set_attr "mode" "<MODE>")])
15394
15395 (define_insn "*fop_xf_4_i387"
15396 [(set (match_operand:XF 0 "register_operand" "=f,f")
15397 (match_operator:XF 3 "binary_fp_operator"
15398 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15399 (match_operand:XF 2 "register_operand" "0,f")]))]
15400 "TARGET_80387"
15401 "* return output_387_binary_op (insn, operands);"
15402 [(set (attr "type")
15403 (cond [(match_operand:XF 3 "mult_operator" "")
15404 (const_string "fmul")
15405 (match_operand:XF 3 "div_operator" "")
15406 (const_string "fdiv")
15407 ]
15408 (const_string "fop")))
15409 (set_attr "mode" "SF")])
15410
15411 (define_insn "*fop_xf_5_i387"
15412 [(set (match_operand:XF 0 "register_operand" "=f,f")
15413 (match_operator:XF 3 "binary_fp_operator"
15414 [(match_operand:XF 1 "register_operand" "0,f")
15415 (float_extend:XF
15416 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15417 "TARGET_80387"
15418 "* return output_387_binary_op (insn, operands);"
15419 [(set (attr "type")
15420 (cond [(match_operand:XF 3 "mult_operator" "")
15421 (const_string "fmul")
15422 (match_operand:XF 3 "div_operator" "")
15423 (const_string "fdiv")
15424 ]
15425 (const_string "fop")))
15426 (set_attr "mode" "SF")])
15427
15428 (define_insn "*fop_xf_6_i387"
15429 [(set (match_operand:XF 0 "register_operand" "=f,f")
15430 (match_operator:XF 3 "binary_fp_operator"
15431 [(float_extend:XF
15432 (match_operand 1 "register_operand" "0,f"))
15433 (float_extend:XF
15434 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15435 "TARGET_80387"
15436 "* return output_387_binary_op (insn, operands);"
15437 [(set (attr "type")
15438 (cond [(match_operand:XF 3 "mult_operator" "")
15439 (const_string "fmul")
15440 (match_operand:XF 3 "div_operator" "")
15441 (const_string "fdiv")
15442 ]
15443 (const_string "fop")))
15444 (set_attr "mode" "SF")])
15445
15446 (define_split
15447 [(set (match_operand 0 "register_operand" "")
15448 (match_operator 3 "binary_fp_operator"
15449 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15450 (match_operand 2 "register_operand" "")]))]
15451 "TARGET_80387 && reload_completed
15452 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15453 [(const_int 0)]
15454 {
15455 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15456 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15457 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15458 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15459 GET_MODE (operands[3]),
15460 operands[4],
15461 operands[2])));
15462 ix86_free_from_memory (GET_MODE (operands[1]));
15463 DONE;
15464 })
15465
15466 (define_split
15467 [(set (match_operand 0 "register_operand" "")
15468 (match_operator 3 "binary_fp_operator"
15469 [(match_operand 1 "register_operand" "")
15470 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15471 "TARGET_80387 && reload_completed
15472 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15473 [(const_int 0)]
15474 {
15475 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15476 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15477 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15478 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15479 GET_MODE (operands[3]),
15480 operands[1],
15481 operands[4])));
15482 ix86_free_from_memory (GET_MODE (operands[2]));
15483 DONE;
15484 })
15485 \f
15486 ;; FPU special functions.
15487
15488 (define_expand "sqrtsf2"
15489 [(set (match_operand:SF 0 "register_operand" "")
15490 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15491 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15492 {
15493 if (!TARGET_SSE_MATH)
15494 operands[1] = force_reg (SFmode, operands[1]);
15495 })
15496
15497 (define_insn "*sqrtsf2_mixed"
15498 [(set (match_operand:SF 0 "register_operand" "=f,x")
15499 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15500 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15501 "@
15502 fsqrt
15503 sqrtss\t{%1, %0|%0, %1}"
15504 [(set_attr "type" "fpspc,sse")
15505 (set_attr "mode" "SF,SF")
15506 (set_attr "athlon_decode" "direct,*")])
15507
15508 (define_insn "*sqrtsf2_sse"
15509 [(set (match_operand:SF 0 "register_operand" "=x")
15510 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15511 "TARGET_SSE_MATH"
15512 "sqrtss\t{%1, %0|%0, %1}"
15513 [(set_attr "type" "sse")
15514 (set_attr "mode" "SF")
15515 (set_attr "athlon_decode" "*")])
15516
15517 (define_insn "*sqrtsf2_i387"
15518 [(set (match_operand:SF 0 "register_operand" "=f")
15519 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15520 "TARGET_USE_FANCY_MATH_387"
15521 "fsqrt"
15522 [(set_attr "type" "fpspc")
15523 (set_attr "mode" "SF")
15524 (set_attr "athlon_decode" "direct")])
15525
15526 (define_expand "sqrtdf2"
15527 [(set (match_operand:DF 0 "register_operand" "")
15528 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15529 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15530 {
15531 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15532 operands[1] = force_reg (DFmode, operands[1]);
15533 })
15534
15535 (define_insn "*sqrtdf2_mixed"
15536 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15537 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15538 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15539 "@
15540 fsqrt
15541 sqrtsd\t{%1, %0|%0, %1}"
15542 [(set_attr "type" "fpspc,sse")
15543 (set_attr "mode" "DF,DF")
15544 (set_attr "athlon_decode" "direct,*")])
15545
15546 (define_insn "*sqrtdf2_sse"
15547 [(set (match_operand:DF 0 "register_operand" "=Y")
15548 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15549 "TARGET_SSE2 && TARGET_SSE_MATH"
15550 "sqrtsd\t{%1, %0|%0, %1}"
15551 [(set_attr "type" "sse")
15552 (set_attr "mode" "DF")
15553 (set_attr "athlon_decode" "*")])
15554
15555 (define_insn "*sqrtdf2_i387"
15556 [(set (match_operand:DF 0 "register_operand" "=f")
15557 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15558 "TARGET_USE_FANCY_MATH_387"
15559 "fsqrt"
15560 [(set_attr "type" "fpspc")
15561 (set_attr "mode" "DF")
15562 (set_attr "athlon_decode" "direct")])
15563
15564 (define_insn "*sqrtextendsfdf2_i387"
15565 [(set (match_operand:DF 0 "register_operand" "=f")
15566 (sqrt:DF (float_extend:DF
15567 (match_operand:SF 1 "register_operand" "0"))))]
15568 "TARGET_USE_FANCY_MATH_387
15569 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15570 "fsqrt"
15571 [(set_attr "type" "fpspc")
15572 (set_attr "mode" "DF")
15573 (set_attr "athlon_decode" "direct")])
15574
15575 (define_insn "sqrtxf2"
15576 [(set (match_operand:XF 0 "register_operand" "=f")
15577 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15578 "TARGET_USE_FANCY_MATH_387"
15579 "fsqrt"
15580 [(set_attr "type" "fpspc")
15581 (set_attr "mode" "XF")
15582 (set_attr "athlon_decode" "direct")])
15583
15584 (define_insn "*sqrtextendsfxf2_i387"
15585 [(set (match_operand:XF 0 "register_operand" "=f")
15586 (sqrt:XF (float_extend:XF
15587 (match_operand:SF 1 "register_operand" "0"))))]
15588 "TARGET_USE_FANCY_MATH_387"
15589 "fsqrt"
15590 [(set_attr "type" "fpspc")
15591 (set_attr "mode" "XF")
15592 (set_attr "athlon_decode" "direct")])
15593
15594 (define_insn "*sqrtextenddfxf2_i387"
15595 [(set (match_operand:XF 0 "register_operand" "=f")
15596 (sqrt:XF (float_extend:XF
15597 (match_operand:DF 1 "register_operand" "0"))))]
15598 "TARGET_USE_FANCY_MATH_387"
15599 "fsqrt"
15600 [(set_attr "type" "fpspc")
15601 (set_attr "mode" "XF")
15602 (set_attr "athlon_decode" "direct")])
15603
15604 (define_insn "fpremxf4"
15605 [(set (match_operand:XF 0 "register_operand" "=f")
15606 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15607 (match_operand:XF 3 "register_operand" "1")]
15608 UNSPEC_FPREM_F))
15609 (set (match_operand:XF 1 "register_operand" "=u")
15610 (unspec:XF [(match_dup 2) (match_dup 3)]
15611 UNSPEC_FPREM_U))
15612 (set (reg:CCFP FPSR_REG)
15613 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15614 "TARGET_USE_FANCY_MATH_387"
15615 "fprem"
15616 [(set_attr "type" "fpspc")
15617 (set_attr "mode" "XF")])
15618
15619 (define_expand "fmodsf3"
15620 [(use (match_operand:SF 0 "register_operand" ""))
15621 (use (match_operand:SF 1 "register_operand" ""))
15622 (use (match_operand:SF 2 "register_operand" ""))]
15623 "TARGET_USE_FANCY_MATH_387
15624 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15625 {
15626 rtx label = gen_label_rtx ();
15627
15628 rtx op1 = gen_reg_rtx (XFmode);
15629 rtx op2 = gen_reg_rtx (XFmode);
15630
15631 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15632 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15633
15634 emit_label (label);
15635
15636 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15637 ix86_emit_fp_unordered_jump (label);
15638
15639 emit_insn (gen_truncxfsf2 (operands[0], op1));
15640 DONE;
15641 })
15642
15643 (define_expand "fmoddf3"
15644 [(use (match_operand:DF 0 "register_operand" ""))
15645 (use (match_operand:DF 1 "register_operand" ""))
15646 (use (match_operand:DF 2 "register_operand" ""))]
15647 "TARGET_USE_FANCY_MATH_387
15648 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15649 {
15650 rtx label = gen_label_rtx ();
15651
15652 rtx op1 = gen_reg_rtx (XFmode);
15653 rtx op2 = gen_reg_rtx (XFmode);
15654
15655 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15656 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15657
15658 emit_label (label);
15659
15660 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15661 ix86_emit_fp_unordered_jump (label);
15662
15663 emit_insn (gen_truncxfdf2 (operands[0], op1));
15664 DONE;
15665 })
15666
15667 (define_expand "fmodxf3"
15668 [(use (match_operand:XF 0 "register_operand" ""))
15669 (use (match_operand:XF 1 "register_operand" ""))
15670 (use (match_operand:XF 2 "register_operand" ""))]
15671 "TARGET_USE_FANCY_MATH_387"
15672 {
15673 rtx label = gen_label_rtx ();
15674
15675 emit_label (label);
15676
15677 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15678 operands[1], operands[2]));
15679 ix86_emit_fp_unordered_jump (label);
15680
15681 emit_move_insn (operands[0], operands[1]);
15682 DONE;
15683 })
15684
15685 (define_insn "fprem1xf4"
15686 [(set (match_operand:XF 0 "register_operand" "=f")
15687 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15688 (match_operand:XF 3 "register_operand" "1")]
15689 UNSPEC_FPREM1_F))
15690 (set (match_operand:XF 1 "register_operand" "=u")
15691 (unspec:XF [(match_dup 2) (match_dup 3)]
15692 UNSPEC_FPREM1_U))
15693 (set (reg:CCFP FPSR_REG)
15694 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15695 "TARGET_USE_FANCY_MATH_387"
15696 "fprem1"
15697 [(set_attr "type" "fpspc")
15698 (set_attr "mode" "XF")])
15699
15700 (define_expand "remaindersf3"
15701 [(use (match_operand:SF 0 "register_operand" ""))
15702 (use (match_operand:SF 1 "register_operand" ""))
15703 (use (match_operand:SF 2 "register_operand" ""))]
15704 "TARGET_USE_FANCY_MATH_387
15705 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
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_extendsfxf2 (op1, operands[1]));
15713 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15714
15715 emit_label (label);
15716
15717 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15718 ix86_emit_fp_unordered_jump (label);
15719
15720 emit_insn (gen_truncxfsf2 (operands[0], op1));
15721 DONE;
15722 })
15723
15724 (define_expand "remainderdf3"
15725 [(use (match_operand:DF 0 "register_operand" ""))
15726 (use (match_operand:DF 1 "register_operand" ""))
15727 (use (match_operand:DF 2 "register_operand" ""))]
15728 "TARGET_USE_FANCY_MATH_387
15729 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15730 {
15731 rtx label = gen_label_rtx ();
15732
15733 rtx op1 = gen_reg_rtx (XFmode);
15734 rtx op2 = gen_reg_rtx (XFmode);
15735
15736 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15737 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15738
15739 emit_label (label);
15740
15741 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15742 ix86_emit_fp_unordered_jump (label);
15743
15744 emit_insn (gen_truncxfdf2 (operands[0], op1));
15745 DONE;
15746 })
15747
15748 (define_expand "remainderxf3"
15749 [(use (match_operand:XF 0 "register_operand" ""))
15750 (use (match_operand:XF 1 "register_operand" ""))
15751 (use (match_operand:XF 2 "register_operand" ""))]
15752 "TARGET_USE_FANCY_MATH_387"
15753 {
15754 rtx label = gen_label_rtx ();
15755
15756 emit_label (label);
15757
15758 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15759 operands[1], operands[2]));
15760 ix86_emit_fp_unordered_jump (label);
15761
15762 emit_move_insn (operands[0], operands[1]);
15763 DONE;
15764 })
15765
15766 (define_insn "*sindf2"
15767 [(set (match_operand:DF 0 "register_operand" "=f")
15768 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15769 "TARGET_USE_FANCY_MATH_387
15770 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15771 && flag_unsafe_math_optimizations"
15772 "fsin"
15773 [(set_attr "type" "fpspc")
15774 (set_attr "mode" "DF")])
15775
15776 (define_insn "*sinsf2"
15777 [(set (match_operand:SF 0 "register_operand" "=f")
15778 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15779 "TARGET_USE_FANCY_MATH_387
15780 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15781 && flag_unsafe_math_optimizations"
15782 "fsin"
15783 [(set_attr "type" "fpspc")
15784 (set_attr "mode" "SF")])
15785
15786 (define_insn "*sinextendsfdf2"
15787 [(set (match_operand:DF 0 "register_operand" "=f")
15788 (unspec:DF [(float_extend:DF
15789 (match_operand:SF 1 "register_operand" "0"))]
15790 UNSPEC_SIN))]
15791 "TARGET_USE_FANCY_MATH_387
15792 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15793 && flag_unsafe_math_optimizations"
15794 "fsin"
15795 [(set_attr "type" "fpspc")
15796 (set_attr "mode" "DF")])
15797
15798 (define_insn "*sinxf2"
15799 [(set (match_operand:XF 0 "register_operand" "=f")
15800 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15801 "TARGET_USE_FANCY_MATH_387
15802 && flag_unsafe_math_optimizations"
15803 "fsin"
15804 [(set_attr "type" "fpspc")
15805 (set_attr "mode" "XF")])
15806
15807 (define_insn "*cosdf2"
15808 [(set (match_operand:DF 0 "register_operand" "=f")
15809 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15810 "TARGET_USE_FANCY_MATH_387
15811 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15812 && flag_unsafe_math_optimizations"
15813 "fcos"
15814 [(set_attr "type" "fpspc")
15815 (set_attr "mode" "DF")])
15816
15817 (define_insn "*cossf2"
15818 [(set (match_operand:SF 0 "register_operand" "=f")
15819 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15820 "TARGET_USE_FANCY_MATH_387
15821 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15822 && flag_unsafe_math_optimizations"
15823 "fcos"
15824 [(set_attr "type" "fpspc")
15825 (set_attr "mode" "SF")])
15826
15827 (define_insn "*cosextendsfdf2"
15828 [(set (match_operand:DF 0 "register_operand" "=f")
15829 (unspec:DF [(float_extend:DF
15830 (match_operand:SF 1 "register_operand" "0"))]
15831 UNSPEC_COS))]
15832 "TARGET_USE_FANCY_MATH_387
15833 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15834 && flag_unsafe_math_optimizations"
15835 "fcos"
15836 [(set_attr "type" "fpspc")
15837 (set_attr "mode" "DF")])
15838
15839 (define_insn "*cosxf2"
15840 [(set (match_operand:XF 0 "register_operand" "=f")
15841 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15842 "TARGET_USE_FANCY_MATH_387
15843 && flag_unsafe_math_optimizations"
15844 "fcos"
15845 [(set_attr "type" "fpspc")
15846 (set_attr "mode" "XF")])
15847
15848 ;; With sincos pattern defined, sin and cos builtin function will be
15849 ;; expanded to sincos pattern with one of its outputs left unused.
15850 ;; Cse pass will detected, if two sincos patterns can be combined,
15851 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15852 ;; depending on the unused output.
15853
15854 (define_insn "sincosdf3"
15855 [(set (match_operand:DF 0 "register_operand" "=f")
15856 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15857 UNSPEC_SINCOS_COS))
15858 (set (match_operand:DF 1 "register_operand" "=u")
15859 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15860 "TARGET_USE_FANCY_MATH_387
15861 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15862 && flag_unsafe_math_optimizations"
15863 "fsincos"
15864 [(set_attr "type" "fpspc")
15865 (set_attr "mode" "DF")])
15866
15867 (define_split
15868 [(set (match_operand:DF 0 "register_operand" "")
15869 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15870 UNSPEC_SINCOS_COS))
15871 (set (match_operand:DF 1 "register_operand" "")
15872 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15873 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15874 && !reload_completed && !reload_in_progress"
15875 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15876 "")
15877
15878 (define_split
15879 [(set (match_operand:DF 0 "register_operand" "")
15880 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15881 UNSPEC_SINCOS_COS))
15882 (set (match_operand:DF 1 "register_operand" "")
15883 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15884 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15885 && !reload_completed && !reload_in_progress"
15886 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15887 "")
15888
15889 (define_insn "sincossf3"
15890 [(set (match_operand:SF 0 "register_operand" "=f")
15891 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15892 UNSPEC_SINCOS_COS))
15893 (set (match_operand:SF 1 "register_operand" "=u")
15894 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15895 "TARGET_USE_FANCY_MATH_387
15896 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15897 && flag_unsafe_math_optimizations"
15898 "fsincos"
15899 [(set_attr "type" "fpspc")
15900 (set_attr "mode" "SF")])
15901
15902 (define_split
15903 [(set (match_operand:SF 0 "register_operand" "")
15904 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15905 UNSPEC_SINCOS_COS))
15906 (set (match_operand:SF 1 "register_operand" "")
15907 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15908 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15909 && !reload_completed && !reload_in_progress"
15910 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15911 "")
15912
15913 (define_split
15914 [(set (match_operand:SF 0 "register_operand" "")
15915 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15916 UNSPEC_SINCOS_COS))
15917 (set (match_operand:SF 1 "register_operand" "")
15918 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15919 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15920 && !reload_completed && !reload_in_progress"
15921 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15922 "")
15923
15924 (define_insn "*sincosextendsfdf3"
15925 [(set (match_operand:DF 0 "register_operand" "=f")
15926 (unspec:DF [(float_extend:DF
15927 (match_operand:SF 2 "register_operand" "0"))]
15928 UNSPEC_SINCOS_COS))
15929 (set (match_operand:DF 1 "register_operand" "=u")
15930 (unspec:DF [(float_extend:DF
15931 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15932 "TARGET_USE_FANCY_MATH_387
15933 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15934 && flag_unsafe_math_optimizations"
15935 "fsincos"
15936 [(set_attr "type" "fpspc")
15937 (set_attr "mode" "DF")])
15938
15939 (define_split
15940 [(set (match_operand:DF 0 "register_operand" "")
15941 (unspec:DF [(float_extend:DF
15942 (match_operand:SF 2 "register_operand" ""))]
15943 UNSPEC_SINCOS_COS))
15944 (set (match_operand:DF 1 "register_operand" "")
15945 (unspec:DF [(float_extend:DF
15946 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15947 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15948 && !reload_completed && !reload_in_progress"
15949 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15950 (match_dup 2))] UNSPEC_SIN))]
15951 "")
15952
15953 (define_split
15954 [(set (match_operand:DF 0 "register_operand" "")
15955 (unspec:DF [(float_extend:DF
15956 (match_operand:SF 2 "register_operand" ""))]
15957 UNSPEC_SINCOS_COS))
15958 (set (match_operand:DF 1 "register_operand" "")
15959 (unspec:DF [(float_extend:DF
15960 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15961 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15962 && !reload_completed && !reload_in_progress"
15963 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15964 (match_dup 2))] UNSPEC_COS))]
15965 "")
15966
15967 (define_insn "sincosxf3"
15968 [(set (match_operand:XF 0 "register_operand" "=f")
15969 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15970 UNSPEC_SINCOS_COS))
15971 (set (match_operand:XF 1 "register_operand" "=u")
15972 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15973 "TARGET_USE_FANCY_MATH_387
15974 && flag_unsafe_math_optimizations"
15975 "fsincos"
15976 [(set_attr "type" "fpspc")
15977 (set_attr "mode" "XF")])
15978
15979 (define_split
15980 [(set (match_operand:XF 0 "register_operand" "")
15981 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15982 UNSPEC_SINCOS_COS))
15983 (set (match_operand:XF 1 "register_operand" "")
15984 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15985 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15986 && !reload_completed && !reload_in_progress"
15987 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15988 "")
15989
15990 (define_split
15991 [(set (match_operand:XF 0 "register_operand" "")
15992 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15993 UNSPEC_SINCOS_COS))
15994 (set (match_operand:XF 1 "register_operand" "")
15995 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15996 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15997 && !reload_completed && !reload_in_progress"
15998 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15999 "")
16000
16001 (define_insn "*tandf3_1"
16002 [(set (match_operand:DF 0 "register_operand" "=f")
16003 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16004 UNSPEC_TAN_ONE))
16005 (set (match_operand:DF 1 "register_operand" "=u")
16006 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16007 "TARGET_USE_FANCY_MATH_387
16008 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16009 && flag_unsafe_math_optimizations"
16010 "fptan"
16011 [(set_attr "type" "fpspc")
16012 (set_attr "mode" "DF")])
16013
16014 ;; optimize sequence: fptan
16015 ;; fstp %st(0)
16016 ;; fld1
16017 ;; into fptan insn.
16018
16019 (define_peephole2
16020 [(parallel[(set (match_operand:DF 0 "register_operand" "")
16021 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16022 UNSPEC_TAN_ONE))
16023 (set (match_operand:DF 1 "register_operand" "")
16024 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16025 (set (match_dup 0)
16026 (match_operand:DF 3 "immediate_operand" ""))]
16027 "standard_80387_constant_p (operands[3]) == 2"
16028 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16029 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16030 "")
16031
16032 (define_expand "tandf2"
16033 [(parallel [(set (match_dup 2)
16034 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16035 UNSPEC_TAN_ONE))
16036 (set (match_operand:DF 0 "register_operand" "")
16037 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16038 "TARGET_USE_FANCY_MATH_387
16039 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16040 && flag_unsafe_math_optimizations"
16041 {
16042 operands[2] = gen_reg_rtx (DFmode);
16043 })
16044
16045 (define_insn "*tansf3_1"
16046 [(set (match_operand:SF 0 "register_operand" "=f")
16047 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16048 UNSPEC_TAN_ONE))
16049 (set (match_operand:SF 1 "register_operand" "=u")
16050 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16051 "TARGET_USE_FANCY_MATH_387
16052 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16053 && flag_unsafe_math_optimizations"
16054 "fptan"
16055 [(set_attr "type" "fpspc")
16056 (set_attr "mode" "SF")])
16057
16058 ;; optimize sequence: fptan
16059 ;; fstp %st(0)
16060 ;; fld1
16061 ;; into fptan insn.
16062
16063 (define_peephole2
16064 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16065 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16066 UNSPEC_TAN_ONE))
16067 (set (match_operand:SF 1 "register_operand" "")
16068 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16069 (set (match_dup 0)
16070 (match_operand:SF 3 "immediate_operand" ""))]
16071 "standard_80387_constant_p (operands[3]) == 2"
16072 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16073 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16074 "")
16075
16076 (define_expand "tansf2"
16077 [(parallel [(set (match_dup 2)
16078 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16079 UNSPEC_TAN_ONE))
16080 (set (match_operand:SF 0 "register_operand" "")
16081 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16082 "TARGET_USE_FANCY_MATH_387
16083 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16084 && flag_unsafe_math_optimizations"
16085 {
16086 operands[2] = gen_reg_rtx (SFmode);
16087 })
16088
16089 (define_insn "*tanxf3_1"
16090 [(set (match_operand:XF 0 "register_operand" "=f")
16091 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16092 UNSPEC_TAN_ONE))
16093 (set (match_operand:XF 1 "register_operand" "=u")
16094 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16095 "TARGET_USE_FANCY_MATH_387
16096 && flag_unsafe_math_optimizations"
16097 "fptan"
16098 [(set_attr "type" "fpspc")
16099 (set_attr "mode" "XF")])
16100
16101 ;; optimize sequence: fptan
16102 ;; fstp %st(0)
16103 ;; fld1
16104 ;; into fptan insn.
16105
16106 (define_peephole2
16107 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16108 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16109 UNSPEC_TAN_ONE))
16110 (set (match_operand:XF 1 "register_operand" "")
16111 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16112 (set (match_dup 0)
16113 (match_operand:XF 3 "immediate_operand" ""))]
16114 "standard_80387_constant_p (operands[3]) == 2"
16115 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16116 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16117 "")
16118
16119 (define_expand "tanxf2"
16120 [(parallel [(set (match_dup 2)
16121 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16122 UNSPEC_TAN_ONE))
16123 (set (match_operand:XF 0 "register_operand" "")
16124 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16125 "TARGET_USE_FANCY_MATH_387
16126 && flag_unsafe_math_optimizations"
16127 {
16128 operands[2] = gen_reg_rtx (XFmode);
16129 })
16130
16131 (define_insn "atan2df3_1"
16132 [(set (match_operand:DF 0 "register_operand" "=f")
16133 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16134 (match_operand:DF 1 "register_operand" "u")]
16135 UNSPEC_FPATAN))
16136 (clobber (match_scratch:DF 3 "=1"))]
16137 "TARGET_USE_FANCY_MATH_387
16138 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16139 && flag_unsafe_math_optimizations"
16140 "fpatan"
16141 [(set_attr "type" "fpspc")
16142 (set_attr "mode" "DF")])
16143
16144 (define_expand "atan2df3"
16145 [(use (match_operand:DF 0 "register_operand" ""))
16146 (use (match_operand:DF 2 "register_operand" ""))
16147 (use (match_operand:DF 1 "register_operand" ""))]
16148 "TARGET_USE_FANCY_MATH_387
16149 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16150 && flag_unsafe_math_optimizations"
16151 {
16152 rtx copy = gen_reg_rtx (DFmode);
16153 emit_move_insn (copy, operands[1]);
16154 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16155 DONE;
16156 })
16157
16158 (define_expand "atandf2"
16159 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16160 (unspec:DF [(match_dup 2)
16161 (match_operand:DF 1 "register_operand" "")]
16162 UNSPEC_FPATAN))
16163 (clobber (match_scratch:DF 3 ""))])]
16164 "TARGET_USE_FANCY_MATH_387
16165 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16166 && flag_unsafe_math_optimizations"
16167 {
16168 operands[2] = gen_reg_rtx (DFmode);
16169 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16170 })
16171
16172 (define_insn "atan2sf3_1"
16173 [(set (match_operand:SF 0 "register_operand" "=f")
16174 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16175 (match_operand:SF 1 "register_operand" "u")]
16176 UNSPEC_FPATAN))
16177 (clobber (match_scratch:SF 3 "=1"))]
16178 "TARGET_USE_FANCY_MATH_387
16179 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16180 && flag_unsafe_math_optimizations"
16181 "fpatan"
16182 [(set_attr "type" "fpspc")
16183 (set_attr "mode" "SF")])
16184
16185 (define_expand "atan2sf3"
16186 [(use (match_operand:SF 0 "register_operand" ""))
16187 (use (match_operand:SF 2 "register_operand" ""))
16188 (use (match_operand:SF 1 "register_operand" ""))]
16189 "TARGET_USE_FANCY_MATH_387
16190 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16191 && flag_unsafe_math_optimizations"
16192 {
16193 rtx copy = gen_reg_rtx (SFmode);
16194 emit_move_insn (copy, operands[1]);
16195 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16196 DONE;
16197 })
16198
16199 (define_expand "atansf2"
16200 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16201 (unspec:SF [(match_dup 2)
16202 (match_operand:SF 1 "register_operand" "")]
16203 UNSPEC_FPATAN))
16204 (clobber (match_scratch:SF 3 ""))])]
16205 "TARGET_USE_FANCY_MATH_387
16206 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16207 && flag_unsafe_math_optimizations"
16208 {
16209 operands[2] = gen_reg_rtx (SFmode);
16210 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16211 })
16212
16213 (define_insn "atan2xf3_1"
16214 [(set (match_operand:XF 0 "register_operand" "=f")
16215 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16216 (match_operand:XF 1 "register_operand" "u")]
16217 UNSPEC_FPATAN))
16218 (clobber (match_scratch:XF 3 "=1"))]
16219 "TARGET_USE_FANCY_MATH_387
16220 && flag_unsafe_math_optimizations"
16221 "fpatan"
16222 [(set_attr "type" "fpspc")
16223 (set_attr "mode" "XF")])
16224
16225 (define_expand "atan2xf3"
16226 [(use (match_operand:XF 0 "register_operand" ""))
16227 (use (match_operand:XF 2 "register_operand" ""))
16228 (use (match_operand:XF 1 "register_operand" ""))]
16229 "TARGET_USE_FANCY_MATH_387
16230 && flag_unsafe_math_optimizations"
16231 {
16232 rtx copy = gen_reg_rtx (XFmode);
16233 emit_move_insn (copy, operands[1]);
16234 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16235 DONE;
16236 })
16237
16238 (define_expand "atanxf2"
16239 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16240 (unspec:XF [(match_dup 2)
16241 (match_operand:XF 1 "register_operand" "")]
16242 UNSPEC_FPATAN))
16243 (clobber (match_scratch:XF 3 ""))])]
16244 "TARGET_USE_FANCY_MATH_387
16245 && flag_unsafe_math_optimizations"
16246 {
16247 operands[2] = gen_reg_rtx (XFmode);
16248 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16249 })
16250
16251 (define_expand "asindf2"
16252 [(set (match_dup 2)
16253 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16254 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16255 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16256 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16257 (parallel [(set (match_dup 7)
16258 (unspec:XF [(match_dup 6) (match_dup 2)]
16259 UNSPEC_FPATAN))
16260 (clobber (match_scratch:XF 8 ""))])
16261 (set (match_operand:DF 0 "register_operand" "")
16262 (float_truncate:DF (match_dup 7)))]
16263 "TARGET_USE_FANCY_MATH_387
16264 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16265 && flag_unsafe_math_optimizations"
16266 {
16267 int i;
16268
16269 for (i=2; i<8; i++)
16270 operands[i] = gen_reg_rtx (XFmode);
16271
16272 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16273 })
16274
16275 (define_expand "asinsf2"
16276 [(set (match_dup 2)
16277 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16278 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16279 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16280 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16281 (parallel [(set (match_dup 7)
16282 (unspec:XF [(match_dup 6) (match_dup 2)]
16283 UNSPEC_FPATAN))
16284 (clobber (match_scratch:XF 8 ""))])
16285 (set (match_operand:SF 0 "register_operand" "")
16286 (float_truncate:SF (match_dup 7)))]
16287 "TARGET_USE_FANCY_MATH_387
16288 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16289 && flag_unsafe_math_optimizations"
16290 {
16291 int i;
16292
16293 for (i=2; i<8; i++)
16294 operands[i] = gen_reg_rtx (XFmode);
16295
16296 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16297 })
16298
16299 (define_expand "asinxf2"
16300 [(set (match_dup 2)
16301 (mult:XF (match_operand:XF 1 "register_operand" "")
16302 (match_dup 1)))
16303 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16304 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16305 (parallel [(set (match_operand:XF 0 "register_operand" "")
16306 (unspec:XF [(match_dup 5) (match_dup 1)]
16307 UNSPEC_FPATAN))
16308 (clobber (match_scratch:XF 6 ""))])]
16309 "TARGET_USE_FANCY_MATH_387
16310 && flag_unsafe_math_optimizations"
16311 {
16312 int i;
16313
16314 for (i=2; i<6; i++)
16315 operands[i] = gen_reg_rtx (XFmode);
16316
16317 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16318 })
16319
16320 (define_expand "acosdf2"
16321 [(set (match_dup 2)
16322 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16323 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16324 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16325 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16326 (parallel [(set (match_dup 7)
16327 (unspec:XF [(match_dup 2) (match_dup 6)]
16328 UNSPEC_FPATAN))
16329 (clobber (match_scratch:XF 8 ""))])
16330 (set (match_operand:DF 0 "register_operand" "")
16331 (float_truncate:DF (match_dup 7)))]
16332 "TARGET_USE_FANCY_MATH_387
16333 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16334 && flag_unsafe_math_optimizations"
16335 {
16336 int i;
16337
16338 for (i=2; i<8; i++)
16339 operands[i] = gen_reg_rtx (XFmode);
16340
16341 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16342 })
16343
16344 (define_expand "acossf2"
16345 [(set (match_dup 2)
16346 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16347 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16348 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16349 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16350 (parallel [(set (match_dup 7)
16351 (unspec:XF [(match_dup 2) (match_dup 6)]
16352 UNSPEC_FPATAN))
16353 (clobber (match_scratch:XF 8 ""))])
16354 (set (match_operand:SF 0 "register_operand" "")
16355 (float_truncate:SF (match_dup 7)))]
16356 "TARGET_USE_FANCY_MATH_387
16357 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16358 && flag_unsafe_math_optimizations"
16359 {
16360 int i;
16361
16362 for (i=2; i<8; i++)
16363 operands[i] = gen_reg_rtx (XFmode);
16364
16365 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16366 })
16367
16368 (define_expand "acosxf2"
16369 [(set (match_dup 2)
16370 (mult:XF (match_operand:XF 1 "register_operand" "")
16371 (match_dup 1)))
16372 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16373 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16374 (parallel [(set (match_operand:XF 0 "register_operand" "")
16375 (unspec:XF [(match_dup 1) (match_dup 5)]
16376 UNSPEC_FPATAN))
16377 (clobber (match_scratch:XF 6 ""))])]
16378 "TARGET_USE_FANCY_MATH_387
16379 && flag_unsafe_math_optimizations"
16380 {
16381 int i;
16382
16383 for (i=2; i<6; i++)
16384 operands[i] = gen_reg_rtx (XFmode);
16385
16386 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16387 })
16388
16389 (define_insn "fyl2x_xf3"
16390 [(set (match_operand:XF 0 "register_operand" "=f")
16391 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16392 (match_operand:XF 1 "register_operand" "u")]
16393 UNSPEC_FYL2X))
16394 (clobber (match_scratch:XF 3 "=1"))]
16395 "TARGET_USE_FANCY_MATH_387
16396 && flag_unsafe_math_optimizations"
16397 "fyl2x"
16398 [(set_attr "type" "fpspc")
16399 (set_attr "mode" "XF")])
16400
16401 (define_expand "logsf2"
16402 [(set (match_dup 2)
16403 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16404 (parallel [(set (match_dup 4)
16405 (unspec:XF [(match_dup 2)
16406 (match_dup 3)] UNSPEC_FYL2X))
16407 (clobber (match_scratch:XF 5 ""))])
16408 (set (match_operand:SF 0 "register_operand" "")
16409 (float_truncate:SF (match_dup 4)))]
16410 "TARGET_USE_FANCY_MATH_387
16411 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16412 && flag_unsafe_math_optimizations"
16413 {
16414 rtx temp;
16415
16416 operands[2] = gen_reg_rtx (XFmode);
16417 operands[3] = gen_reg_rtx (XFmode);
16418 operands[4] = gen_reg_rtx (XFmode);
16419
16420 temp = standard_80387_constant_rtx (4); /* fldln2 */
16421 emit_move_insn (operands[3], temp);
16422 })
16423
16424 (define_expand "logdf2"
16425 [(set (match_dup 2)
16426 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16427 (parallel [(set (match_dup 4)
16428 (unspec:XF [(match_dup 2)
16429 (match_dup 3)] UNSPEC_FYL2X))
16430 (clobber (match_scratch:XF 5 ""))])
16431 (set (match_operand:DF 0 "register_operand" "")
16432 (float_truncate:DF (match_dup 4)))]
16433 "TARGET_USE_FANCY_MATH_387
16434 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16435 && flag_unsafe_math_optimizations"
16436 {
16437 rtx temp;
16438
16439 operands[2] = gen_reg_rtx (XFmode);
16440 operands[3] = gen_reg_rtx (XFmode);
16441 operands[4] = gen_reg_rtx (XFmode);
16442
16443 temp = standard_80387_constant_rtx (4); /* fldln2 */
16444 emit_move_insn (operands[3], temp);
16445 })
16446
16447 (define_expand "logxf2"
16448 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16449 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16450 (match_dup 2)] UNSPEC_FYL2X))
16451 (clobber (match_scratch:XF 3 ""))])]
16452 "TARGET_USE_FANCY_MATH_387
16453 && flag_unsafe_math_optimizations"
16454 {
16455 rtx temp;
16456
16457 operands[2] = gen_reg_rtx (XFmode);
16458 temp = standard_80387_constant_rtx (4); /* fldln2 */
16459 emit_move_insn (operands[2], temp);
16460 })
16461
16462 (define_expand "log10sf2"
16463 [(set (match_dup 2)
16464 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16465 (parallel [(set (match_dup 4)
16466 (unspec:XF [(match_dup 2)
16467 (match_dup 3)] UNSPEC_FYL2X))
16468 (clobber (match_scratch:XF 5 ""))])
16469 (set (match_operand:SF 0 "register_operand" "")
16470 (float_truncate:SF (match_dup 4)))]
16471 "TARGET_USE_FANCY_MATH_387
16472 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16473 && flag_unsafe_math_optimizations"
16474 {
16475 rtx temp;
16476
16477 operands[2] = gen_reg_rtx (XFmode);
16478 operands[3] = gen_reg_rtx (XFmode);
16479 operands[4] = gen_reg_rtx (XFmode);
16480
16481 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16482 emit_move_insn (operands[3], temp);
16483 })
16484
16485 (define_expand "log10df2"
16486 [(set (match_dup 2)
16487 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16488 (parallel [(set (match_dup 4)
16489 (unspec:XF [(match_dup 2)
16490 (match_dup 3)] UNSPEC_FYL2X))
16491 (clobber (match_scratch:XF 5 ""))])
16492 (set (match_operand:DF 0 "register_operand" "")
16493 (float_truncate:DF (match_dup 4)))]
16494 "TARGET_USE_FANCY_MATH_387
16495 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16496 && flag_unsafe_math_optimizations"
16497 {
16498 rtx temp;
16499
16500 operands[2] = gen_reg_rtx (XFmode);
16501 operands[3] = gen_reg_rtx (XFmode);
16502 operands[4] = gen_reg_rtx (XFmode);
16503
16504 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16505 emit_move_insn (operands[3], temp);
16506 })
16507
16508 (define_expand "log10xf2"
16509 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16510 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16511 (match_dup 2)] UNSPEC_FYL2X))
16512 (clobber (match_scratch:XF 3 ""))])]
16513 "TARGET_USE_FANCY_MATH_387
16514 && flag_unsafe_math_optimizations"
16515 {
16516 rtx temp;
16517
16518 operands[2] = gen_reg_rtx (XFmode);
16519 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16520 emit_move_insn (operands[2], temp);
16521 })
16522
16523 (define_expand "log2sf2"
16524 [(set (match_dup 2)
16525 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16526 (parallel [(set (match_dup 4)
16527 (unspec:XF [(match_dup 2)
16528 (match_dup 3)] UNSPEC_FYL2X))
16529 (clobber (match_scratch:XF 5 ""))])
16530 (set (match_operand:SF 0 "register_operand" "")
16531 (float_truncate:SF (match_dup 4)))]
16532 "TARGET_USE_FANCY_MATH_387
16533 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16534 && flag_unsafe_math_optimizations"
16535 {
16536 operands[2] = gen_reg_rtx (XFmode);
16537 operands[3] = gen_reg_rtx (XFmode);
16538 operands[4] = gen_reg_rtx (XFmode);
16539
16540 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16541 })
16542
16543 (define_expand "log2df2"
16544 [(set (match_dup 2)
16545 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16546 (parallel [(set (match_dup 4)
16547 (unspec:XF [(match_dup 2)
16548 (match_dup 3)] UNSPEC_FYL2X))
16549 (clobber (match_scratch:XF 5 ""))])
16550 (set (match_operand:DF 0 "register_operand" "")
16551 (float_truncate:DF (match_dup 4)))]
16552 "TARGET_USE_FANCY_MATH_387
16553 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16554 && flag_unsafe_math_optimizations"
16555 {
16556 operands[2] = gen_reg_rtx (XFmode);
16557 operands[3] = gen_reg_rtx (XFmode);
16558 operands[4] = gen_reg_rtx (XFmode);
16559
16560 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16561 })
16562
16563 (define_expand "log2xf2"
16564 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16565 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16566 (match_dup 2)] UNSPEC_FYL2X))
16567 (clobber (match_scratch:XF 3 ""))])]
16568 "TARGET_USE_FANCY_MATH_387
16569 && flag_unsafe_math_optimizations"
16570 {
16571 operands[2] = gen_reg_rtx (XFmode);
16572 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16573 })
16574
16575 (define_insn "fyl2xp1_xf3"
16576 [(set (match_operand:XF 0 "register_operand" "=f")
16577 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16578 (match_operand:XF 1 "register_operand" "u")]
16579 UNSPEC_FYL2XP1))
16580 (clobber (match_scratch:XF 3 "=1"))]
16581 "TARGET_USE_FANCY_MATH_387
16582 && flag_unsafe_math_optimizations"
16583 "fyl2xp1"
16584 [(set_attr "type" "fpspc")
16585 (set_attr "mode" "XF")])
16586
16587 (define_expand "log1psf2"
16588 [(use (match_operand:SF 0 "register_operand" ""))
16589 (use (match_operand:SF 1 "register_operand" ""))]
16590 "TARGET_USE_FANCY_MATH_387
16591 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16592 && flag_unsafe_math_optimizations"
16593 {
16594 rtx op0 = gen_reg_rtx (XFmode);
16595 rtx op1 = gen_reg_rtx (XFmode);
16596
16597 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16598 ix86_emit_i387_log1p (op0, op1);
16599 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16600 DONE;
16601 })
16602
16603 (define_expand "log1pdf2"
16604 [(use (match_operand:DF 0 "register_operand" ""))
16605 (use (match_operand:DF 1 "register_operand" ""))]
16606 "TARGET_USE_FANCY_MATH_387
16607 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16608 && flag_unsafe_math_optimizations"
16609 {
16610 rtx op0 = gen_reg_rtx (XFmode);
16611 rtx op1 = gen_reg_rtx (XFmode);
16612
16613 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16614 ix86_emit_i387_log1p (op0, op1);
16615 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16616 DONE;
16617 })
16618
16619 (define_expand "log1pxf2"
16620 [(use (match_operand:XF 0 "register_operand" ""))
16621 (use (match_operand:XF 1 "register_operand" ""))]
16622 "TARGET_USE_FANCY_MATH_387
16623 && flag_unsafe_math_optimizations"
16624 {
16625 ix86_emit_i387_log1p (operands[0], operands[1]);
16626 DONE;
16627 })
16628
16629 (define_insn "*fxtractxf3"
16630 [(set (match_operand:XF 0 "register_operand" "=f")
16631 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16632 UNSPEC_XTRACT_FRACT))
16633 (set (match_operand:XF 1 "register_operand" "=u")
16634 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16635 "TARGET_USE_FANCY_MATH_387
16636 && flag_unsafe_math_optimizations"
16637 "fxtract"
16638 [(set_attr "type" "fpspc")
16639 (set_attr "mode" "XF")])
16640
16641 (define_expand "logbsf2"
16642 [(set (match_dup 2)
16643 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16644 (parallel [(set (match_dup 3)
16645 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16646 (set (match_dup 4)
16647 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16648 (set (match_operand:SF 0 "register_operand" "")
16649 (float_truncate:SF (match_dup 4)))]
16650 "TARGET_USE_FANCY_MATH_387
16651 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16652 && flag_unsafe_math_optimizations"
16653 {
16654 operands[2] = gen_reg_rtx (XFmode);
16655 operands[3] = gen_reg_rtx (XFmode);
16656 operands[4] = gen_reg_rtx (XFmode);
16657 })
16658
16659 (define_expand "logbdf2"
16660 [(set (match_dup 2)
16661 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16662 (parallel [(set (match_dup 3)
16663 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16664 (set (match_dup 4)
16665 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16666 (set (match_operand:DF 0 "register_operand" "")
16667 (float_truncate:DF (match_dup 4)))]
16668 "TARGET_USE_FANCY_MATH_387
16669 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16670 && flag_unsafe_math_optimizations"
16671 {
16672 operands[2] = gen_reg_rtx (XFmode);
16673 operands[3] = gen_reg_rtx (XFmode);
16674 operands[4] = gen_reg_rtx (XFmode);
16675 })
16676
16677 (define_expand "logbxf2"
16678 [(parallel [(set (match_dup 2)
16679 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16680 UNSPEC_XTRACT_FRACT))
16681 (set (match_operand:XF 0 "register_operand" "")
16682 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16683 "TARGET_USE_FANCY_MATH_387
16684 && flag_unsafe_math_optimizations"
16685 {
16686 operands[2] = gen_reg_rtx (XFmode);
16687 })
16688
16689 (define_expand "ilogbsi2"
16690 [(parallel [(set (match_dup 2)
16691 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16692 UNSPEC_XTRACT_FRACT))
16693 (set (match_operand:XF 3 "register_operand" "")
16694 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16695 (parallel [(set (match_operand:SI 0 "register_operand" "")
16696 (fix:SI (match_dup 3)))
16697 (clobber (reg:CC FLAGS_REG))])]
16698 "TARGET_USE_FANCY_MATH_387
16699 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16700 && flag_unsafe_math_optimizations"
16701 {
16702 operands[2] = gen_reg_rtx (XFmode);
16703 operands[3] = gen_reg_rtx (XFmode);
16704 })
16705
16706 (define_insn "*f2xm1xf2"
16707 [(set (match_operand:XF 0 "register_operand" "=f")
16708 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16709 UNSPEC_F2XM1))]
16710 "TARGET_USE_FANCY_MATH_387
16711 && flag_unsafe_math_optimizations"
16712 "f2xm1"
16713 [(set_attr "type" "fpspc")
16714 (set_attr "mode" "XF")])
16715
16716 (define_insn "*fscalexf4"
16717 [(set (match_operand:XF 0 "register_operand" "=f")
16718 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16719 (match_operand:XF 3 "register_operand" "1")]
16720 UNSPEC_FSCALE_FRACT))
16721 (set (match_operand:XF 1 "register_operand" "=u")
16722 (unspec:XF [(match_dup 2) (match_dup 3)]
16723 UNSPEC_FSCALE_EXP))]
16724 "TARGET_USE_FANCY_MATH_387
16725 && flag_unsafe_math_optimizations"
16726 "fscale"
16727 [(set_attr "type" "fpspc")
16728 (set_attr "mode" "XF")])
16729
16730 (define_expand "expsf2"
16731 [(set (match_dup 2)
16732 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16733 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16734 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16735 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16736 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16737 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16738 (parallel [(set (match_dup 10)
16739 (unspec:XF [(match_dup 9) (match_dup 5)]
16740 UNSPEC_FSCALE_FRACT))
16741 (set (match_dup 11)
16742 (unspec:XF [(match_dup 9) (match_dup 5)]
16743 UNSPEC_FSCALE_EXP))])
16744 (set (match_operand:SF 0 "register_operand" "")
16745 (float_truncate:SF (match_dup 10)))]
16746 "TARGET_USE_FANCY_MATH_387
16747 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16748 && flag_unsafe_math_optimizations"
16749 {
16750 rtx temp;
16751 int i;
16752
16753 for (i=2; i<12; i++)
16754 operands[i] = gen_reg_rtx (XFmode);
16755 temp = standard_80387_constant_rtx (5); /* fldl2e */
16756 emit_move_insn (operands[3], temp);
16757 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16758 })
16759
16760 (define_expand "expdf2"
16761 [(set (match_dup 2)
16762 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16763 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16764 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16765 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16766 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16767 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16768 (parallel [(set (match_dup 10)
16769 (unspec:XF [(match_dup 9) (match_dup 5)]
16770 UNSPEC_FSCALE_FRACT))
16771 (set (match_dup 11)
16772 (unspec:XF [(match_dup 9) (match_dup 5)]
16773 UNSPEC_FSCALE_EXP))])
16774 (set (match_operand:DF 0 "register_operand" "")
16775 (float_truncate:DF (match_dup 10)))]
16776 "TARGET_USE_FANCY_MATH_387
16777 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16778 && flag_unsafe_math_optimizations"
16779 {
16780 rtx temp;
16781 int i;
16782
16783 for (i=2; i<12; i++)
16784 operands[i] = gen_reg_rtx (XFmode);
16785 temp = standard_80387_constant_rtx (5); /* fldl2e */
16786 emit_move_insn (operands[3], temp);
16787 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16788 })
16789
16790 (define_expand "expxf2"
16791 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16792 (match_dup 2)))
16793 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16794 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16795 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16796 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16797 (parallel [(set (match_operand:XF 0 "register_operand" "")
16798 (unspec:XF [(match_dup 8) (match_dup 4)]
16799 UNSPEC_FSCALE_FRACT))
16800 (set (match_dup 9)
16801 (unspec:XF [(match_dup 8) (match_dup 4)]
16802 UNSPEC_FSCALE_EXP))])]
16803 "TARGET_USE_FANCY_MATH_387
16804 && flag_unsafe_math_optimizations"
16805 {
16806 rtx temp;
16807 int i;
16808
16809 for (i=2; i<10; i++)
16810 operands[i] = gen_reg_rtx (XFmode);
16811 temp = standard_80387_constant_rtx (5); /* fldl2e */
16812 emit_move_insn (operands[2], temp);
16813 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16814 })
16815
16816 (define_expand "exp10sf2"
16817 [(set (match_dup 2)
16818 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16819 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16820 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16821 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16822 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16823 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16824 (parallel [(set (match_dup 10)
16825 (unspec:XF [(match_dup 9) (match_dup 5)]
16826 UNSPEC_FSCALE_FRACT))
16827 (set (match_dup 11)
16828 (unspec:XF [(match_dup 9) (match_dup 5)]
16829 UNSPEC_FSCALE_EXP))])
16830 (set (match_operand:SF 0 "register_operand" "")
16831 (float_truncate:SF (match_dup 10)))]
16832 "TARGET_USE_FANCY_MATH_387
16833 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16834 && flag_unsafe_math_optimizations"
16835 {
16836 rtx temp;
16837 int i;
16838
16839 for (i=2; i<12; i++)
16840 operands[i] = gen_reg_rtx (XFmode);
16841 temp = standard_80387_constant_rtx (6); /* fldl2t */
16842 emit_move_insn (operands[3], temp);
16843 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16844 })
16845
16846 (define_expand "exp10df2"
16847 [(set (match_dup 2)
16848 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16849 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16850 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16851 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16852 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16853 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16854 (parallel [(set (match_dup 10)
16855 (unspec:XF [(match_dup 9) (match_dup 5)]
16856 UNSPEC_FSCALE_FRACT))
16857 (set (match_dup 11)
16858 (unspec:XF [(match_dup 9) (match_dup 5)]
16859 UNSPEC_FSCALE_EXP))])
16860 (set (match_operand:DF 0 "register_operand" "")
16861 (float_truncate:DF (match_dup 10)))]
16862 "TARGET_USE_FANCY_MATH_387
16863 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16864 && flag_unsafe_math_optimizations"
16865 {
16866 rtx temp;
16867 int i;
16868
16869 for (i=2; i<12; i++)
16870 operands[i] = gen_reg_rtx (XFmode);
16871 temp = standard_80387_constant_rtx (6); /* fldl2t */
16872 emit_move_insn (operands[3], temp);
16873 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16874 })
16875
16876 (define_expand "exp10xf2"
16877 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16878 (match_dup 2)))
16879 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16880 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16881 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16882 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16883 (parallel [(set (match_operand:XF 0 "register_operand" "")
16884 (unspec:XF [(match_dup 8) (match_dup 4)]
16885 UNSPEC_FSCALE_FRACT))
16886 (set (match_dup 9)
16887 (unspec:XF [(match_dup 8) (match_dup 4)]
16888 UNSPEC_FSCALE_EXP))])]
16889 "TARGET_USE_FANCY_MATH_387
16890 && flag_unsafe_math_optimizations"
16891 {
16892 rtx temp;
16893 int i;
16894
16895 for (i=2; i<10; i++)
16896 operands[i] = gen_reg_rtx (XFmode);
16897 temp = standard_80387_constant_rtx (6); /* fldl2t */
16898 emit_move_insn (operands[2], temp);
16899 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16900 })
16901
16902 (define_expand "exp2sf2"
16903 [(set (match_dup 2)
16904 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16905 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16906 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16907 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16908 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16909 (parallel [(set (match_dup 8)
16910 (unspec:XF [(match_dup 7) (match_dup 3)]
16911 UNSPEC_FSCALE_FRACT))
16912 (set (match_dup 9)
16913 (unspec:XF [(match_dup 7) (match_dup 3)]
16914 UNSPEC_FSCALE_EXP))])
16915 (set (match_operand:SF 0 "register_operand" "")
16916 (float_truncate:SF (match_dup 8)))]
16917 "TARGET_USE_FANCY_MATH_387
16918 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16919 && flag_unsafe_math_optimizations"
16920 {
16921 int i;
16922
16923 for (i=2; i<10; i++)
16924 operands[i] = gen_reg_rtx (XFmode);
16925 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16926 })
16927
16928 (define_expand "exp2df2"
16929 [(set (match_dup 2)
16930 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16931 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16932 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16933 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16934 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16935 (parallel [(set (match_dup 8)
16936 (unspec:XF [(match_dup 7) (match_dup 3)]
16937 UNSPEC_FSCALE_FRACT))
16938 (set (match_dup 9)
16939 (unspec:XF [(match_dup 7) (match_dup 3)]
16940 UNSPEC_FSCALE_EXP))])
16941 (set (match_operand:DF 0 "register_operand" "")
16942 (float_truncate:DF (match_dup 8)))]
16943 "TARGET_USE_FANCY_MATH_387
16944 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16945 && flag_unsafe_math_optimizations"
16946 {
16947 int i;
16948
16949 for (i=2; i<10; i++)
16950 operands[i] = gen_reg_rtx (XFmode);
16951 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16952 })
16953
16954 (define_expand "exp2xf2"
16955 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16956 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16957 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16958 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16959 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16960 (parallel [(set (match_operand:XF 0 "register_operand" "")
16961 (unspec:XF [(match_dup 7) (match_dup 3)]
16962 UNSPEC_FSCALE_FRACT))
16963 (set (match_dup 8)
16964 (unspec:XF [(match_dup 7) (match_dup 3)]
16965 UNSPEC_FSCALE_EXP))])]
16966 "TARGET_USE_FANCY_MATH_387
16967 && flag_unsafe_math_optimizations"
16968 {
16969 int i;
16970
16971 for (i=2; i<9; i++)
16972 operands[i] = gen_reg_rtx (XFmode);
16973 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16974 })
16975
16976 (define_expand "expm1df2"
16977 [(set (match_dup 2)
16978 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16979 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16980 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16981 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16982 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16983 (parallel [(set (match_dup 8)
16984 (unspec:XF [(match_dup 7) (match_dup 5)]
16985 UNSPEC_FSCALE_FRACT))
16986 (set (match_dup 9)
16987 (unspec:XF [(match_dup 7) (match_dup 5)]
16988 UNSPEC_FSCALE_EXP))])
16989 (parallel [(set (match_dup 11)
16990 (unspec:XF [(match_dup 10) (match_dup 9)]
16991 UNSPEC_FSCALE_FRACT))
16992 (set (match_dup 12)
16993 (unspec:XF [(match_dup 10) (match_dup 9)]
16994 UNSPEC_FSCALE_EXP))])
16995 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16996 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16997 (set (match_operand:DF 0 "register_operand" "")
16998 (float_truncate:DF (match_dup 14)))]
16999 "TARGET_USE_FANCY_MATH_387
17000 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17001 && flag_unsafe_math_optimizations"
17002 {
17003 rtx temp;
17004 int i;
17005
17006 for (i=2; i<15; i++)
17007 operands[i] = gen_reg_rtx (XFmode);
17008 temp = standard_80387_constant_rtx (5); /* fldl2e */
17009 emit_move_insn (operands[3], temp);
17010 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17011 })
17012
17013 (define_expand "expm1sf2"
17014 [(set (match_dup 2)
17015 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17016 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17017 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17018 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17019 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17020 (parallel [(set (match_dup 8)
17021 (unspec:XF [(match_dup 7) (match_dup 5)]
17022 UNSPEC_FSCALE_FRACT))
17023 (set (match_dup 9)
17024 (unspec:XF [(match_dup 7) (match_dup 5)]
17025 UNSPEC_FSCALE_EXP))])
17026 (parallel [(set (match_dup 11)
17027 (unspec:XF [(match_dup 10) (match_dup 9)]
17028 UNSPEC_FSCALE_FRACT))
17029 (set (match_dup 12)
17030 (unspec:XF [(match_dup 10) (match_dup 9)]
17031 UNSPEC_FSCALE_EXP))])
17032 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17033 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17034 (set (match_operand:SF 0 "register_operand" "")
17035 (float_truncate:SF (match_dup 14)))]
17036 "TARGET_USE_FANCY_MATH_387
17037 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17038 && flag_unsafe_math_optimizations"
17039 {
17040 rtx temp;
17041 int i;
17042
17043 for (i=2; i<15; i++)
17044 operands[i] = gen_reg_rtx (XFmode);
17045 temp = standard_80387_constant_rtx (5); /* fldl2e */
17046 emit_move_insn (operands[3], temp);
17047 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17048 })
17049
17050 (define_expand "expm1xf2"
17051 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17052 (match_dup 2)))
17053 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17054 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17055 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17056 (parallel [(set (match_dup 7)
17057 (unspec:XF [(match_dup 6) (match_dup 4)]
17058 UNSPEC_FSCALE_FRACT))
17059 (set (match_dup 8)
17060 (unspec:XF [(match_dup 6) (match_dup 4)]
17061 UNSPEC_FSCALE_EXP))])
17062 (parallel [(set (match_dup 10)
17063 (unspec:XF [(match_dup 9) (match_dup 8)]
17064 UNSPEC_FSCALE_FRACT))
17065 (set (match_dup 11)
17066 (unspec:XF [(match_dup 9) (match_dup 8)]
17067 UNSPEC_FSCALE_EXP))])
17068 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17069 (set (match_operand:XF 0 "register_operand" "")
17070 (plus:XF (match_dup 12) (match_dup 7)))]
17071 "TARGET_USE_FANCY_MATH_387
17072 && flag_unsafe_math_optimizations"
17073 {
17074 rtx temp;
17075 int i;
17076
17077 for (i=2; i<13; i++)
17078 operands[i] = gen_reg_rtx (XFmode);
17079 temp = standard_80387_constant_rtx (5); /* fldl2e */
17080 emit_move_insn (operands[2], temp);
17081 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17082 })
17083
17084 (define_expand "ldexpdf3"
17085 [(set (match_dup 3)
17086 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17087 (set (match_dup 4)
17088 (float:XF (match_operand:SI 2 "register_operand" "")))
17089 (parallel [(set (match_dup 5)
17090 (unspec:XF [(match_dup 3) (match_dup 4)]
17091 UNSPEC_FSCALE_FRACT))
17092 (set (match_dup 6)
17093 (unspec:XF [(match_dup 3) (match_dup 4)]
17094 UNSPEC_FSCALE_EXP))])
17095 (set (match_operand:DF 0 "register_operand" "")
17096 (float_truncate:DF (match_dup 5)))]
17097 "TARGET_USE_FANCY_MATH_387
17098 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17099 && flag_unsafe_math_optimizations"
17100 {
17101 int i;
17102
17103 for (i=3; i<7; i++)
17104 operands[i] = gen_reg_rtx (XFmode);
17105 })
17106
17107 (define_expand "ldexpsf3"
17108 [(set (match_dup 3)
17109 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17110 (set (match_dup 4)
17111 (float:XF (match_operand:SI 2 "register_operand" "")))
17112 (parallel [(set (match_dup 5)
17113 (unspec:XF [(match_dup 3) (match_dup 4)]
17114 UNSPEC_FSCALE_FRACT))
17115 (set (match_dup 6)
17116 (unspec:XF [(match_dup 3) (match_dup 4)]
17117 UNSPEC_FSCALE_EXP))])
17118 (set (match_operand:SF 0 "register_operand" "")
17119 (float_truncate:SF (match_dup 5)))]
17120 "TARGET_USE_FANCY_MATH_387
17121 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17122 && flag_unsafe_math_optimizations"
17123 {
17124 int i;
17125
17126 for (i=3; i<7; i++)
17127 operands[i] = gen_reg_rtx (XFmode);
17128 })
17129
17130 (define_expand "ldexpxf3"
17131 [(set (match_dup 3)
17132 (float:XF (match_operand:SI 2 "register_operand" "")))
17133 (parallel [(set (match_operand:XF 0 " register_operand" "")
17134 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17135 (match_dup 3)]
17136 UNSPEC_FSCALE_FRACT))
17137 (set (match_dup 4)
17138 (unspec:XF [(match_dup 1) (match_dup 3)]
17139 UNSPEC_FSCALE_EXP))])]
17140 "TARGET_USE_FANCY_MATH_387
17141 && flag_unsafe_math_optimizations"
17142 {
17143 int i;
17144
17145 for (i=3; i<5; i++)
17146 operands[i] = gen_reg_rtx (XFmode);
17147 })
17148 \f
17149
17150 (define_insn "frndintxf2"
17151 [(set (match_operand:XF 0 "register_operand" "=f")
17152 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17153 UNSPEC_FRNDINT))]
17154 "TARGET_USE_FANCY_MATH_387
17155 && flag_unsafe_math_optimizations"
17156 "frndint"
17157 [(set_attr "type" "fpspc")
17158 (set_attr "mode" "XF")])
17159
17160 (define_expand "rintdf2"
17161 [(use (match_operand:DF 0 "register_operand" ""))
17162 (use (match_operand:DF 1 "register_operand" ""))]
17163 "TARGET_USE_FANCY_MATH_387
17164 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17165 && flag_unsafe_math_optimizations"
17166 {
17167 rtx op0 = gen_reg_rtx (XFmode);
17168 rtx op1 = gen_reg_rtx (XFmode);
17169
17170 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17171 emit_insn (gen_frndintxf2 (op0, op1));
17172
17173 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17174 DONE;
17175 })
17176
17177 (define_expand "rintsf2"
17178 [(use (match_operand:SF 0 "register_operand" ""))
17179 (use (match_operand:SF 1 "register_operand" ""))]
17180 "TARGET_USE_FANCY_MATH_387
17181 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17182 && flag_unsafe_math_optimizations"
17183 {
17184 rtx op0 = gen_reg_rtx (XFmode);
17185 rtx op1 = gen_reg_rtx (XFmode);
17186
17187 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17188 emit_insn (gen_frndintxf2 (op0, op1));
17189
17190 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17191 DONE;
17192 })
17193
17194 (define_expand "rintxf2"
17195 [(use (match_operand:XF 0 "register_operand" ""))
17196 (use (match_operand:XF 1 "register_operand" ""))]
17197 "TARGET_USE_FANCY_MATH_387
17198 && flag_unsafe_math_optimizations"
17199 {
17200 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17201 DONE;
17202 })
17203
17204 (define_insn_and_split "*fistdi2_1"
17205 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17206 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17207 UNSPEC_FIST))]
17208 "TARGET_USE_FANCY_MATH_387
17209 && !(reload_completed || reload_in_progress)"
17210 "#"
17211 "&& 1"
17212 [(const_int 0)]
17213 {
17214 if (memory_operand (operands[0], VOIDmode))
17215 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17216 else
17217 {
17218 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17219 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17220 operands[2]));
17221 }
17222 DONE;
17223 }
17224 [(set_attr "type" "fpspc")
17225 (set_attr "mode" "DI")])
17226
17227 (define_insn "fistdi2"
17228 [(set (match_operand:DI 0 "memory_operand" "=m")
17229 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17230 UNSPEC_FIST))
17231 (clobber (match_scratch:XF 2 "=&1f"))]
17232 "TARGET_USE_FANCY_MATH_387"
17233 "* return output_fix_trunc (insn, operands, 0);"
17234 [(set_attr "type" "fpspc")
17235 (set_attr "mode" "DI")])
17236
17237 (define_insn "fistdi2_with_temp"
17238 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17239 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17240 UNSPEC_FIST))
17241 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17242 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17243 "TARGET_USE_FANCY_MATH_387"
17244 "#"
17245 [(set_attr "type" "fpspc")
17246 (set_attr "mode" "DI")])
17247
17248 (define_split
17249 [(set (match_operand:DI 0 "register_operand" "")
17250 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17251 UNSPEC_FIST))
17252 (clobber (match_operand:DI 2 "memory_operand" ""))
17253 (clobber (match_scratch 3 ""))]
17254 "reload_completed"
17255 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17256 (clobber (match_dup 3))])
17257 (set (match_dup 0) (match_dup 2))]
17258 "")
17259
17260 (define_split
17261 [(set (match_operand:DI 0 "memory_operand" "")
17262 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17263 UNSPEC_FIST))
17264 (clobber (match_operand:DI 2 "memory_operand" ""))
17265 (clobber (match_scratch 3 ""))]
17266 "reload_completed"
17267 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17268 (clobber (match_dup 3))])]
17269 "")
17270
17271 (define_insn_and_split "*fist<mode>2_1"
17272 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17273 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17274 UNSPEC_FIST))]
17275 "TARGET_USE_FANCY_MATH_387
17276 && !(reload_completed || reload_in_progress)"
17277 "#"
17278 "&& 1"
17279 [(const_int 0)]
17280 {
17281 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17282 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17283 operands[2]));
17284 DONE;
17285 }
17286 [(set_attr "type" "fpspc")
17287 (set_attr "mode" "<MODE>")])
17288
17289 (define_insn "fist<mode>2"
17290 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17291 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17292 UNSPEC_FIST))]
17293 "TARGET_USE_FANCY_MATH_387"
17294 "* return output_fix_trunc (insn, operands, 0);"
17295 [(set_attr "type" "fpspc")
17296 (set_attr "mode" "<MODE>")])
17297
17298 (define_insn "fist<mode>2_with_temp"
17299 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17300 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17301 UNSPEC_FIST))
17302 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17303 "TARGET_USE_FANCY_MATH_387"
17304 "#"
17305 [(set_attr "type" "fpspc")
17306 (set_attr "mode" "<MODE>")])
17307
17308 (define_split
17309 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17310 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17311 UNSPEC_FIST))
17312 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17313 "reload_completed"
17314 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17315 UNSPEC_FIST))
17316 (set (match_dup 0) (match_dup 2))]
17317 "")
17318
17319 (define_split
17320 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17321 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17322 UNSPEC_FIST))
17323 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17324 "reload_completed"
17325 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17326 UNSPEC_FIST))]
17327 "")
17328
17329 (define_expand "lrintxf<mode>2"
17330 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17331 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17332 UNSPEC_FIST))]
17333 "TARGET_USE_FANCY_MATH_387"
17334 "")
17335
17336 (define_expand "lrint<mode>di2"
17337 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17338 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17339 UNSPEC_FIX_NOTRUNC))]
17340 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17341 "")
17342
17343 (define_expand "lrint<mode>si2"
17344 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17345 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17346 UNSPEC_FIX_NOTRUNC))]
17347 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17348 "")
17349
17350 (define_expand "lround<mode>di2"
17351 [(match_operand:DI 0 "nonimmediate_operand" "")
17352 (match_operand:SSEMODEF 1 "register_operand" "")]
17353 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17354 && !flag_trapping_math && !flag_rounding_math"
17355 {
17356 ix86_expand_lround (operand0, operand1);
17357 DONE;
17358 })
17359
17360 (define_expand "lround<mode>si2"
17361 [(match_operand:SI 0 "nonimmediate_operand" "")
17362 (match_operand:SSEMODEF 1 "register_operand" "")]
17363 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17364 && !flag_trapping_math && !flag_rounding_math"
17365 {
17366 ix86_expand_lround (operand0, operand1);
17367 DONE;
17368 })
17369
17370 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17371 (define_insn_and_split "frndintxf2_floor"
17372 [(set (match_operand:XF 0 "register_operand" "=f")
17373 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17374 UNSPEC_FRNDINT_FLOOR))
17375 (clobber (reg:CC FLAGS_REG))]
17376 "TARGET_USE_FANCY_MATH_387
17377 && flag_unsafe_math_optimizations
17378 && !(reload_completed || reload_in_progress)"
17379 "#"
17380 "&& 1"
17381 [(const_int 0)]
17382 {
17383 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17384
17385 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17386 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17387
17388 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17389 operands[2], operands[3]));
17390 DONE;
17391 }
17392 [(set_attr "type" "frndint")
17393 (set_attr "i387_cw" "floor")
17394 (set_attr "mode" "XF")])
17395
17396 (define_insn "frndintxf2_floor_i387"
17397 [(set (match_operand:XF 0 "register_operand" "=f")
17398 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17399 UNSPEC_FRNDINT_FLOOR))
17400 (use (match_operand:HI 2 "memory_operand" "m"))
17401 (use (match_operand:HI 3 "memory_operand" "m"))]
17402 "TARGET_USE_FANCY_MATH_387
17403 && flag_unsafe_math_optimizations"
17404 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17405 [(set_attr "type" "frndint")
17406 (set_attr "i387_cw" "floor")
17407 (set_attr "mode" "XF")])
17408
17409 (define_expand "floorxf2"
17410 [(use (match_operand:XF 0 "register_operand" ""))
17411 (use (match_operand:XF 1 "register_operand" ""))]
17412 "TARGET_USE_FANCY_MATH_387
17413 && flag_unsafe_math_optimizations"
17414 {
17415 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17416 DONE;
17417 })
17418
17419 (define_expand "floordf2"
17420 [(use (match_operand:DF 0 "register_operand" ""))
17421 (use (match_operand:DF 1 "register_operand" ""))]
17422 "TARGET_USE_FANCY_MATH_387
17423 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17424 && flag_unsafe_math_optimizations"
17425 {
17426 rtx op0 = gen_reg_rtx (XFmode);
17427 rtx op1 = gen_reg_rtx (XFmode);
17428
17429 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17430 emit_insn (gen_frndintxf2_floor (op0, op1));
17431
17432 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17433 DONE;
17434 })
17435
17436 (define_expand "floorsf2"
17437 [(use (match_operand:SF 0 "register_operand" ""))
17438 (use (match_operand:SF 1 "register_operand" ""))]
17439 "TARGET_USE_FANCY_MATH_387
17440 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17441 && flag_unsafe_math_optimizations"
17442 {
17443 rtx op0 = gen_reg_rtx (XFmode);
17444 rtx op1 = gen_reg_rtx (XFmode);
17445
17446 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17447 emit_insn (gen_frndintxf2_floor (op0, op1));
17448
17449 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17450 DONE;
17451 })
17452
17453 (define_insn_and_split "*fist<mode>2_floor_1"
17454 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17455 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17456 UNSPEC_FIST_FLOOR))
17457 (clobber (reg:CC FLAGS_REG))]
17458 "TARGET_USE_FANCY_MATH_387
17459 && flag_unsafe_math_optimizations
17460 && !(reload_completed || reload_in_progress)"
17461 "#"
17462 "&& 1"
17463 [(const_int 0)]
17464 {
17465 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17466
17467 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17468 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17469 if (memory_operand (operands[0], VOIDmode))
17470 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17471 operands[2], operands[3]));
17472 else
17473 {
17474 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17475 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17476 operands[2], operands[3],
17477 operands[4]));
17478 }
17479 DONE;
17480 }
17481 [(set_attr "type" "fistp")
17482 (set_attr "i387_cw" "floor")
17483 (set_attr "mode" "<MODE>")])
17484
17485 (define_insn "fistdi2_floor"
17486 [(set (match_operand:DI 0 "memory_operand" "=m")
17487 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17488 UNSPEC_FIST_FLOOR))
17489 (use (match_operand:HI 2 "memory_operand" "m"))
17490 (use (match_operand:HI 3 "memory_operand" "m"))
17491 (clobber (match_scratch:XF 4 "=&1f"))]
17492 "TARGET_USE_FANCY_MATH_387
17493 && flag_unsafe_math_optimizations"
17494 "* return output_fix_trunc (insn, operands, 0);"
17495 [(set_attr "type" "fistp")
17496 (set_attr "i387_cw" "floor")
17497 (set_attr "mode" "DI")])
17498
17499 (define_insn "fistdi2_floor_with_temp"
17500 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17501 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17502 UNSPEC_FIST_FLOOR))
17503 (use (match_operand:HI 2 "memory_operand" "m,m"))
17504 (use (match_operand:HI 3 "memory_operand" "m,m"))
17505 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17506 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17507 "TARGET_USE_FANCY_MATH_387
17508 && flag_unsafe_math_optimizations"
17509 "#"
17510 [(set_attr "type" "fistp")
17511 (set_attr "i387_cw" "floor")
17512 (set_attr "mode" "DI")])
17513
17514 (define_split
17515 [(set (match_operand:DI 0 "register_operand" "")
17516 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17517 UNSPEC_FIST_FLOOR))
17518 (use (match_operand:HI 2 "memory_operand" ""))
17519 (use (match_operand:HI 3 "memory_operand" ""))
17520 (clobber (match_operand:DI 4 "memory_operand" ""))
17521 (clobber (match_scratch 5 ""))]
17522 "reload_completed"
17523 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17524 (use (match_dup 2))
17525 (use (match_dup 3))
17526 (clobber (match_dup 5))])
17527 (set (match_dup 0) (match_dup 4))]
17528 "")
17529
17530 (define_split
17531 [(set (match_operand:DI 0 "memory_operand" "")
17532 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17533 UNSPEC_FIST_FLOOR))
17534 (use (match_operand:HI 2 "memory_operand" ""))
17535 (use (match_operand:HI 3 "memory_operand" ""))
17536 (clobber (match_operand:DI 4 "memory_operand" ""))
17537 (clobber (match_scratch 5 ""))]
17538 "reload_completed"
17539 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17540 (use (match_dup 2))
17541 (use (match_dup 3))
17542 (clobber (match_dup 5))])]
17543 "")
17544
17545 (define_insn "fist<mode>2_floor"
17546 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17547 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17548 UNSPEC_FIST_FLOOR))
17549 (use (match_operand:HI 2 "memory_operand" "m"))
17550 (use (match_operand:HI 3 "memory_operand" "m"))]
17551 "TARGET_USE_FANCY_MATH_387
17552 && flag_unsafe_math_optimizations"
17553 "* return output_fix_trunc (insn, operands, 0);"
17554 [(set_attr "type" "fistp")
17555 (set_attr "i387_cw" "floor")
17556 (set_attr "mode" "<MODE>")])
17557
17558 (define_insn "fist<mode>2_floor_with_temp"
17559 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17560 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17561 UNSPEC_FIST_FLOOR))
17562 (use (match_operand:HI 2 "memory_operand" "m,m"))
17563 (use (match_operand:HI 3 "memory_operand" "m,m"))
17564 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17565 "TARGET_USE_FANCY_MATH_387
17566 && flag_unsafe_math_optimizations"
17567 "#"
17568 [(set_attr "type" "fistp")
17569 (set_attr "i387_cw" "floor")
17570 (set_attr "mode" "<MODE>")])
17571
17572 (define_split
17573 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17574 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17575 UNSPEC_FIST_FLOOR))
17576 (use (match_operand:HI 2 "memory_operand" ""))
17577 (use (match_operand:HI 3 "memory_operand" ""))
17578 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17579 "reload_completed"
17580 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17581 UNSPEC_FIST_FLOOR))
17582 (use (match_dup 2))
17583 (use (match_dup 3))])
17584 (set (match_dup 0) (match_dup 4))]
17585 "")
17586
17587 (define_split
17588 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17589 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17590 UNSPEC_FIST_FLOOR))
17591 (use (match_operand:HI 2 "memory_operand" ""))
17592 (use (match_operand:HI 3 "memory_operand" ""))
17593 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17594 "reload_completed"
17595 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17596 UNSPEC_FIST_FLOOR))
17597 (use (match_dup 2))
17598 (use (match_dup 3))])]
17599 "")
17600
17601 (define_expand "lfloorxf<mode>2"
17602 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17603 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17604 UNSPEC_FIST_FLOOR))
17605 (clobber (reg:CC FLAGS_REG))])]
17606 "TARGET_USE_FANCY_MATH_387
17607 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17608 && flag_unsafe_math_optimizations"
17609 "")
17610
17611 (define_expand "lfloor<mode>di2"
17612 [(match_operand:DI 0 "nonimmediate_operand" "")
17613 (match_operand:SSEMODEF 1 "register_operand" "")]
17614 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17615 && !flag_trapping_math"
17616 {
17617 ix86_expand_lfloorceil (operand0, operand1, true);
17618 DONE;
17619 })
17620
17621 (define_expand "lfloor<mode>si2"
17622 [(match_operand:SI 0 "nonimmediate_operand" "")
17623 (match_operand:SSEMODEF 1 "register_operand" "")]
17624 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17625 && !flag_trapping_math"
17626 {
17627 ix86_expand_lfloorceil (operand0, operand1, true);
17628 DONE;
17629 })
17630
17631 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17632 (define_insn_and_split "frndintxf2_ceil"
17633 [(set (match_operand:XF 0 "register_operand" "=f")
17634 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17635 UNSPEC_FRNDINT_CEIL))
17636 (clobber (reg:CC FLAGS_REG))]
17637 "TARGET_USE_FANCY_MATH_387
17638 && flag_unsafe_math_optimizations
17639 && !(reload_completed || reload_in_progress)"
17640 "#"
17641 "&& 1"
17642 [(const_int 0)]
17643 {
17644 ix86_optimize_mode_switching[I387_CEIL] = 1;
17645
17646 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17647 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17648
17649 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17650 operands[2], operands[3]));
17651 DONE;
17652 }
17653 [(set_attr "type" "frndint")
17654 (set_attr "i387_cw" "ceil")
17655 (set_attr "mode" "XF")])
17656
17657 (define_insn "frndintxf2_ceil_i387"
17658 [(set (match_operand:XF 0 "register_operand" "=f")
17659 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17660 UNSPEC_FRNDINT_CEIL))
17661 (use (match_operand:HI 2 "memory_operand" "m"))
17662 (use (match_operand:HI 3 "memory_operand" "m"))]
17663 "TARGET_USE_FANCY_MATH_387
17664 && flag_unsafe_math_optimizations"
17665 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17666 [(set_attr "type" "frndint")
17667 (set_attr "i387_cw" "ceil")
17668 (set_attr "mode" "XF")])
17669
17670 (define_expand "ceilxf2"
17671 [(use (match_operand:XF 0 "register_operand" ""))
17672 (use (match_operand:XF 1 "register_operand" ""))]
17673 "TARGET_USE_FANCY_MATH_387
17674 && flag_unsafe_math_optimizations"
17675 {
17676 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17677 DONE;
17678 })
17679
17680 (define_expand "ceildf2"
17681 [(use (match_operand:DF 0 "register_operand" ""))
17682 (use (match_operand:DF 1 "register_operand" ""))]
17683 "TARGET_USE_FANCY_MATH_387
17684 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17685 && flag_unsafe_math_optimizations"
17686 {
17687 rtx op0 = gen_reg_rtx (XFmode);
17688 rtx op1 = gen_reg_rtx (XFmode);
17689
17690 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17691 emit_insn (gen_frndintxf2_ceil (op0, op1));
17692
17693 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17694 DONE;
17695 })
17696
17697 (define_expand "ceilsf2"
17698 [(use (match_operand:SF 0 "register_operand" ""))
17699 (use (match_operand:SF 1 "register_operand" ""))]
17700 "TARGET_USE_FANCY_MATH_387
17701 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17702 && flag_unsafe_math_optimizations"
17703 {
17704 rtx op0 = gen_reg_rtx (XFmode);
17705 rtx op1 = gen_reg_rtx (XFmode);
17706
17707 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17708 emit_insn (gen_frndintxf2_ceil (op0, op1));
17709
17710 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17711 DONE;
17712 })
17713
17714 (define_insn_and_split "*fist<mode>2_ceil_1"
17715 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17716 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17717 UNSPEC_FIST_CEIL))
17718 (clobber (reg:CC FLAGS_REG))]
17719 "TARGET_USE_FANCY_MATH_387
17720 && flag_unsafe_math_optimizations
17721 && !(reload_completed || reload_in_progress)"
17722 "#"
17723 "&& 1"
17724 [(const_int 0)]
17725 {
17726 ix86_optimize_mode_switching[I387_CEIL] = 1;
17727
17728 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17729 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17730 if (memory_operand (operands[0], VOIDmode))
17731 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17732 operands[2], operands[3]));
17733 else
17734 {
17735 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17736 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17737 operands[2], operands[3],
17738 operands[4]));
17739 }
17740 DONE;
17741 }
17742 [(set_attr "type" "fistp")
17743 (set_attr "i387_cw" "ceil")
17744 (set_attr "mode" "<MODE>")])
17745
17746 (define_insn "fistdi2_ceil"
17747 [(set (match_operand:DI 0 "memory_operand" "=m")
17748 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17749 UNSPEC_FIST_CEIL))
17750 (use (match_operand:HI 2 "memory_operand" "m"))
17751 (use (match_operand:HI 3 "memory_operand" "m"))
17752 (clobber (match_scratch:XF 4 "=&1f"))]
17753 "TARGET_USE_FANCY_MATH_387
17754 && flag_unsafe_math_optimizations"
17755 "* return output_fix_trunc (insn, operands, 0);"
17756 [(set_attr "type" "fistp")
17757 (set_attr "i387_cw" "ceil")
17758 (set_attr "mode" "DI")])
17759
17760 (define_insn "fistdi2_ceil_with_temp"
17761 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17762 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17763 UNSPEC_FIST_CEIL))
17764 (use (match_operand:HI 2 "memory_operand" "m,m"))
17765 (use (match_operand:HI 3 "memory_operand" "m,m"))
17766 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17767 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17768 "TARGET_USE_FANCY_MATH_387
17769 && flag_unsafe_math_optimizations"
17770 "#"
17771 [(set_attr "type" "fistp")
17772 (set_attr "i387_cw" "ceil")
17773 (set_attr "mode" "DI")])
17774
17775 (define_split
17776 [(set (match_operand:DI 0 "register_operand" "")
17777 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17778 UNSPEC_FIST_CEIL))
17779 (use (match_operand:HI 2 "memory_operand" ""))
17780 (use (match_operand:HI 3 "memory_operand" ""))
17781 (clobber (match_operand:DI 4 "memory_operand" ""))
17782 (clobber (match_scratch 5 ""))]
17783 "reload_completed"
17784 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17785 (use (match_dup 2))
17786 (use (match_dup 3))
17787 (clobber (match_dup 5))])
17788 (set (match_dup 0) (match_dup 4))]
17789 "")
17790
17791 (define_split
17792 [(set (match_operand:DI 0 "memory_operand" "")
17793 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17794 UNSPEC_FIST_CEIL))
17795 (use (match_operand:HI 2 "memory_operand" ""))
17796 (use (match_operand:HI 3 "memory_operand" ""))
17797 (clobber (match_operand:DI 4 "memory_operand" ""))
17798 (clobber (match_scratch 5 ""))]
17799 "reload_completed"
17800 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17801 (use (match_dup 2))
17802 (use (match_dup 3))
17803 (clobber (match_dup 5))])]
17804 "")
17805
17806 (define_insn "fist<mode>2_ceil"
17807 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17808 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17809 UNSPEC_FIST_CEIL))
17810 (use (match_operand:HI 2 "memory_operand" "m"))
17811 (use (match_operand:HI 3 "memory_operand" "m"))]
17812 "TARGET_USE_FANCY_MATH_387
17813 && flag_unsafe_math_optimizations"
17814 "* return output_fix_trunc (insn, operands, 0);"
17815 [(set_attr "type" "fistp")
17816 (set_attr "i387_cw" "ceil")
17817 (set_attr "mode" "<MODE>")])
17818
17819 (define_insn "fist<mode>2_ceil_with_temp"
17820 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17821 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17822 UNSPEC_FIST_CEIL))
17823 (use (match_operand:HI 2 "memory_operand" "m,m"))
17824 (use (match_operand:HI 3 "memory_operand" "m,m"))
17825 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17826 "TARGET_USE_FANCY_MATH_387
17827 && flag_unsafe_math_optimizations"
17828 "#"
17829 [(set_attr "type" "fistp")
17830 (set_attr "i387_cw" "ceil")
17831 (set_attr "mode" "<MODE>")])
17832
17833 (define_split
17834 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17835 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17836 UNSPEC_FIST_CEIL))
17837 (use (match_operand:HI 2 "memory_operand" ""))
17838 (use (match_operand:HI 3 "memory_operand" ""))
17839 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17840 "reload_completed"
17841 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17842 UNSPEC_FIST_CEIL))
17843 (use (match_dup 2))
17844 (use (match_dup 3))])
17845 (set (match_dup 0) (match_dup 4))]
17846 "")
17847
17848 (define_split
17849 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17850 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17851 UNSPEC_FIST_CEIL))
17852 (use (match_operand:HI 2 "memory_operand" ""))
17853 (use (match_operand:HI 3 "memory_operand" ""))
17854 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17855 "reload_completed"
17856 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17857 UNSPEC_FIST_CEIL))
17858 (use (match_dup 2))
17859 (use (match_dup 3))])]
17860 "")
17861
17862 (define_expand "lceilxf<mode>2"
17863 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17864 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17865 UNSPEC_FIST_CEIL))
17866 (clobber (reg:CC FLAGS_REG))])]
17867 "TARGET_USE_FANCY_MATH_387
17868 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17869 && flag_unsafe_math_optimizations"
17870 "")
17871
17872 (define_expand "lceil<mode>di2"
17873 [(match_operand:DI 0 "nonimmediate_operand" "")
17874 (match_operand:SSEMODEF 1 "register_operand" "")]
17875 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17876 && !flag_trapping_math"
17877 {
17878 ix86_expand_lfloorceil (operand0, operand1, false);
17879 DONE;
17880 })
17881
17882 (define_expand "lceil<mode>si2"
17883 [(match_operand:SI 0 "nonimmediate_operand" "")
17884 (match_operand:SSEMODEF 1 "register_operand" "")]
17885 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17886 && !flag_trapping_math"
17887 {
17888 ix86_expand_lfloorceil (operand0, operand1, false);
17889 DONE;
17890 })
17891
17892 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17893 (define_insn_and_split "frndintxf2_trunc"
17894 [(set (match_operand:XF 0 "register_operand" "=f")
17895 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17896 UNSPEC_FRNDINT_TRUNC))
17897 (clobber (reg:CC FLAGS_REG))]
17898 "TARGET_USE_FANCY_MATH_387
17899 && flag_unsafe_math_optimizations
17900 && !(reload_completed || reload_in_progress)"
17901 "#"
17902 "&& 1"
17903 [(const_int 0)]
17904 {
17905 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17906
17907 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17908 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17909
17910 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17911 operands[2], operands[3]));
17912 DONE;
17913 }
17914 [(set_attr "type" "frndint")
17915 (set_attr "i387_cw" "trunc")
17916 (set_attr "mode" "XF")])
17917
17918 (define_insn "frndintxf2_trunc_i387"
17919 [(set (match_operand:XF 0 "register_operand" "=f")
17920 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17921 UNSPEC_FRNDINT_TRUNC))
17922 (use (match_operand:HI 2 "memory_operand" "m"))
17923 (use (match_operand:HI 3 "memory_operand" "m"))]
17924 "TARGET_USE_FANCY_MATH_387
17925 && flag_unsafe_math_optimizations"
17926 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17927 [(set_attr "type" "frndint")
17928 (set_attr "i387_cw" "trunc")
17929 (set_attr "mode" "XF")])
17930
17931 (define_expand "btruncxf2"
17932 [(use (match_operand:XF 0 "register_operand" ""))
17933 (use (match_operand:XF 1 "register_operand" ""))]
17934 "TARGET_USE_FANCY_MATH_387
17935 && flag_unsafe_math_optimizations"
17936 {
17937 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17938 DONE;
17939 })
17940
17941 (define_expand "btruncdf2"
17942 [(use (match_operand:DF 0 "register_operand" ""))
17943 (use (match_operand:DF 1 "register_operand" ""))]
17944 "TARGET_USE_FANCY_MATH_387
17945 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17946 && flag_unsafe_math_optimizations"
17947 {
17948 rtx op0 = gen_reg_rtx (XFmode);
17949 rtx op1 = gen_reg_rtx (XFmode);
17950
17951 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17952 emit_insn (gen_frndintxf2_trunc (op0, op1));
17953
17954 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17955 DONE;
17956 })
17957
17958 (define_expand "btruncsf2"
17959 [(use (match_operand:SF 0 "register_operand" ""))
17960 (use (match_operand:SF 1 "register_operand" ""))]
17961 "TARGET_USE_FANCY_MATH_387
17962 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17963 && flag_unsafe_math_optimizations"
17964 {
17965 rtx op0 = gen_reg_rtx (XFmode);
17966 rtx op1 = gen_reg_rtx (XFmode);
17967
17968 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17969 emit_insn (gen_frndintxf2_trunc (op0, op1));
17970
17971 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17972 DONE;
17973 })
17974
17975 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17976 (define_insn_and_split "frndintxf2_mask_pm"
17977 [(set (match_operand:XF 0 "register_operand" "=f")
17978 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17979 UNSPEC_FRNDINT_MASK_PM))
17980 (clobber (reg:CC FLAGS_REG))]
17981 "TARGET_USE_FANCY_MATH_387
17982 && flag_unsafe_math_optimizations
17983 && !(reload_completed || reload_in_progress)"
17984 "#"
17985 "&& 1"
17986 [(const_int 0)]
17987 {
17988 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17989
17990 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17991 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17992
17993 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17994 operands[2], operands[3]));
17995 DONE;
17996 }
17997 [(set_attr "type" "frndint")
17998 (set_attr "i387_cw" "mask_pm")
17999 (set_attr "mode" "XF")])
18000
18001 (define_insn "frndintxf2_mask_pm_i387"
18002 [(set (match_operand:XF 0 "register_operand" "=f")
18003 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18004 UNSPEC_FRNDINT_MASK_PM))
18005 (use (match_operand:HI 2 "memory_operand" "m"))
18006 (use (match_operand:HI 3 "memory_operand" "m"))]
18007 "TARGET_USE_FANCY_MATH_387
18008 && flag_unsafe_math_optimizations"
18009 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18010 [(set_attr "type" "frndint")
18011 (set_attr "i387_cw" "mask_pm")
18012 (set_attr "mode" "XF")])
18013
18014 (define_expand "nearbyintxf2"
18015 [(use (match_operand:XF 0 "register_operand" ""))
18016 (use (match_operand:XF 1 "register_operand" ""))]
18017 "TARGET_USE_FANCY_MATH_387
18018 && flag_unsafe_math_optimizations"
18019 {
18020 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18021
18022 DONE;
18023 })
18024
18025 (define_expand "nearbyintdf2"
18026 [(use (match_operand:DF 0 "register_operand" ""))
18027 (use (match_operand:DF 1 "register_operand" ""))]
18028 "TARGET_USE_FANCY_MATH_387
18029 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18030 && flag_unsafe_math_optimizations"
18031 {
18032 rtx op0 = gen_reg_rtx (XFmode);
18033 rtx op1 = gen_reg_rtx (XFmode);
18034
18035 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18036 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18037
18038 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18039 DONE;
18040 })
18041
18042 (define_expand "nearbyintsf2"
18043 [(use (match_operand:SF 0 "register_operand" ""))
18044 (use (match_operand:SF 1 "register_operand" ""))]
18045 "TARGET_USE_FANCY_MATH_387
18046 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18047 && flag_unsafe_math_optimizations"
18048 {
18049 rtx op0 = gen_reg_rtx (XFmode);
18050 rtx op1 = gen_reg_rtx (XFmode);
18051
18052 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18053 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18054
18055 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18056 DONE;
18057 })
18058
18059 \f
18060 ;; Block operation instructions
18061
18062 (define_insn "cld"
18063 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18064 ""
18065 "cld"
18066 [(set_attr "type" "cld")])
18067
18068 (define_expand "movmemsi"
18069 [(use (match_operand:BLK 0 "memory_operand" ""))
18070 (use (match_operand:BLK 1 "memory_operand" ""))
18071 (use (match_operand:SI 2 "nonmemory_operand" ""))
18072 (use (match_operand:SI 3 "const_int_operand" ""))]
18073 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18074 {
18075 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18076 DONE;
18077 else
18078 FAIL;
18079 })
18080
18081 (define_expand "movmemdi"
18082 [(use (match_operand:BLK 0 "memory_operand" ""))
18083 (use (match_operand:BLK 1 "memory_operand" ""))
18084 (use (match_operand:DI 2 "nonmemory_operand" ""))
18085 (use (match_operand:DI 3 "const_int_operand" ""))]
18086 "TARGET_64BIT"
18087 {
18088 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18089 DONE;
18090 else
18091 FAIL;
18092 })
18093
18094 ;; Most CPUs don't like single string operations
18095 ;; Handle this case here to simplify previous expander.
18096
18097 (define_expand "strmov"
18098 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18099 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18100 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18101 (clobber (reg:CC FLAGS_REG))])
18102 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18103 (clobber (reg:CC FLAGS_REG))])]
18104 ""
18105 {
18106 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18107
18108 /* If .md ever supports :P for Pmode, these can be directly
18109 in the pattern above. */
18110 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18111 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18112
18113 if (TARGET_SINGLE_STRINGOP || optimize_size)
18114 {
18115 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18116 operands[2], operands[3],
18117 operands[5], operands[6]));
18118 DONE;
18119 }
18120
18121 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18122 })
18123
18124 (define_expand "strmov_singleop"
18125 [(parallel [(set (match_operand 1 "memory_operand" "")
18126 (match_operand 3 "memory_operand" ""))
18127 (set (match_operand 0 "register_operand" "")
18128 (match_operand 4 "" ""))
18129 (set (match_operand 2 "register_operand" "")
18130 (match_operand 5 "" ""))
18131 (use (reg:SI DIRFLAG_REG))])]
18132 "TARGET_SINGLE_STRINGOP || optimize_size"
18133 "")
18134
18135 (define_insn "*strmovdi_rex_1"
18136 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18137 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18138 (set (match_operand:DI 0 "register_operand" "=D")
18139 (plus:DI (match_dup 2)
18140 (const_int 8)))
18141 (set (match_operand:DI 1 "register_operand" "=S")
18142 (plus:DI (match_dup 3)
18143 (const_int 8)))
18144 (use (reg:SI DIRFLAG_REG))]
18145 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18146 "movsq"
18147 [(set_attr "type" "str")
18148 (set_attr "mode" "DI")
18149 (set_attr "memory" "both")])
18150
18151 (define_insn "*strmovsi_1"
18152 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18153 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18154 (set (match_operand:SI 0 "register_operand" "=D")
18155 (plus:SI (match_dup 2)
18156 (const_int 4)))
18157 (set (match_operand:SI 1 "register_operand" "=S")
18158 (plus:SI (match_dup 3)
18159 (const_int 4)))
18160 (use (reg:SI DIRFLAG_REG))]
18161 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18162 "{movsl|movsd}"
18163 [(set_attr "type" "str")
18164 (set_attr "mode" "SI")
18165 (set_attr "memory" "both")])
18166
18167 (define_insn "*strmovsi_rex_1"
18168 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18169 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18170 (set (match_operand:DI 0 "register_operand" "=D")
18171 (plus:DI (match_dup 2)
18172 (const_int 4)))
18173 (set (match_operand:DI 1 "register_operand" "=S")
18174 (plus:DI (match_dup 3)
18175 (const_int 4)))
18176 (use (reg:SI DIRFLAG_REG))]
18177 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18178 "{movsl|movsd}"
18179 [(set_attr "type" "str")
18180 (set_attr "mode" "SI")
18181 (set_attr "memory" "both")])
18182
18183 (define_insn "*strmovhi_1"
18184 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18185 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18186 (set (match_operand:SI 0 "register_operand" "=D")
18187 (plus:SI (match_dup 2)
18188 (const_int 2)))
18189 (set (match_operand:SI 1 "register_operand" "=S")
18190 (plus:SI (match_dup 3)
18191 (const_int 2)))
18192 (use (reg:SI DIRFLAG_REG))]
18193 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18194 "movsw"
18195 [(set_attr "type" "str")
18196 (set_attr "memory" "both")
18197 (set_attr "mode" "HI")])
18198
18199 (define_insn "*strmovhi_rex_1"
18200 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18201 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18202 (set (match_operand:DI 0 "register_operand" "=D")
18203 (plus:DI (match_dup 2)
18204 (const_int 2)))
18205 (set (match_operand:DI 1 "register_operand" "=S")
18206 (plus:DI (match_dup 3)
18207 (const_int 2)))
18208 (use (reg:SI DIRFLAG_REG))]
18209 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18210 "movsw"
18211 [(set_attr "type" "str")
18212 (set_attr "memory" "both")
18213 (set_attr "mode" "HI")])
18214
18215 (define_insn "*strmovqi_1"
18216 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18217 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18218 (set (match_operand:SI 0 "register_operand" "=D")
18219 (plus:SI (match_dup 2)
18220 (const_int 1)))
18221 (set (match_operand:SI 1 "register_operand" "=S")
18222 (plus:SI (match_dup 3)
18223 (const_int 1)))
18224 (use (reg:SI DIRFLAG_REG))]
18225 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18226 "movsb"
18227 [(set_attr "type" "str")
18228 (set_attr "memory" "both")
18229 (set_attr "mode" "QI")])
18230
18231 (define_insn "*strmovqi_rex_1"
18232 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18233 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18234 (set (match_operand:DI 0 "register_operand" "=D")
18235 (plus:DI (match_dup 2)
18236 (const_int 1)))
18237 (set (match_operand:DI 1 "register_operand" "=S")
18238 (plus:DI (match_dup 3)
18239 (const_int 1)))
18240 (use (reg:SI DIRFLAG_REG))]
18241 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18242 "movsb"
18243 [(set_attr "type" "str")
18244 (set_attr "memory" "both")
18245 (set_attr "mode" "QI")])
18246
18247 (define_expand "rep_mov"
18248 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18249 (set (match_operand 0 "register_operand" "")
18250 (match_operand 5 "" ""))
18251 (set (match_operand 2 "register_operand" "")
18252 (match_operand 6 "" ""))
18253 (set (match_operand 1 "memory_operand" "")
18254 (match_operand 3 "memory_operand" ""))
18255 (use (match_dup 4))
18256 (use (reg:SI DIRFLAG_REG))])]
18257 ""
18258 "")
18259
18260 (define_insn "*rep_movdi_rex64"
18261 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18262 (set (match_operand:DI 0 "register_operand" "=D")
18263 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18264 (const_int 3))
18265 (match_operand:DI 3 "register_operand" "0")))
18266 (set (match_operand:DI 1 "register_operand" "=S")
18267 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18268 (match_operand:DI 4 "register_operand" "1")))
18269 (set (mem:BLK (match_dup 3))
18270 (mem:BLK (match_dup 4)))
18271 (use (match_dup 5))
18272 (use (reg:SI DIRFLAG_REG))]
18273 "TARGET_64BIT"
18274 "{rep\;movsq|rep movsq}"
18275 [(set_attr "type" "str")
18276 (set_attr "prefix_rep" "1")
18277 (set_attr "memory" "both")
18278 (set_attr "mode" "DI")])
18279
18280 (define_insn "*rep_movsi"
18281 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18282 (set (match_operand:SI 0 "register_operand" "=D")
18283 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18284 (const_int 2))
18285 (match_operand:SI 3 "register_operand" "0")))
18286 (set (match_operand:SI 1 "register_operand" "=S")
18287 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18288 (match_operand:SI 4 "register_operand" "1")))
18289 (set (mem:BLK (match_dup 3))
18290 (mem:BLK (match_dup 4)))
18291 (use (match_dup 5))
18292 (use (reg:SI DIRFLAG_REG))]
18293 "!TARGET_64BIT"
18294 "{rep\;movsl|rep movsd}"
18295 [(set_attr "type" "str")
18296 (set_attr "prefix_rep" "1")
18297 (set_attr "memory" "both")
18298 (set_attr "mode" "SI")])
18299
18300 (define_insn "*rep_movsi_rex64"
18301 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18302 (set (match_operand:DI 0 "register_operand" "=D")
18303 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18304 (const_int 2))
18305 (match_operand:DI 3 "register_operand" "0")))
18306 (set (match_operand:DI 1 "register_operand" "=S")
18307 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18308 (match_operand:DI 4 "register_operand" "1")))
18309 (set (mem:BLK (match_dup 3))
18310 (mem:BLK (match_dup 4)))
18311 (use (match_dup 5))
18312 (use (reg:SI DIRFLAG_REG))]
18313 "TARGET_64BIT"
18314 "{rep\;movsl|rep movsd}"
18315 [(set_attr "type" "str")
18316 (set_attr "prefix_rep" "1")
18317 (set_attr "memory" "both")
18318 (set_attr "mode" "SI")])
18319
18320 (define_insn "*rep_movqi"
18321 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18322 (set (match_operand:SI 0 "register_operand" "=D")
18323 (plus:SI (match_operand:SI 3 "register_operand" "0")
18324 (match_operand:SI 5 "register_operand" "2")))
18325 (set (match_operand:SI 1 "register_operand" "=S")
18326 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18327 (set (mem:BLK (match_dup 3))
18328 (mem:BLK (match_dup 4)))
18329 (use (match_dup 5))
18330 (use (reg:SI DIRFLAG_REG))]
18331 "!TARGET_64BIT"
18332 "{rep\;movsb|rep movsb}"
18333 [(set_attr "type" "str")
18334 (set_attr "prefix_rep" "1")
18335 (set_attr "memory" "both")
18336 (set_attr "mode" "SI")])
18337
18338 (define_insn "*rep_movqi_rex64"
18339 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18340 (set (match_operand:DI 0 "register_operand" "=D")
18341 (plus:DI (match_operand:DI 3 "register_operand" "0")
18342 (match_operand:DI 5 "register_operand" "2")))
18343 (set (match_operand:DI 1 "register_operand" "=S")
18344 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18345 (set (mem:BLK (match_dup 3))
18346 (mem:BLK (match_dup 4)))
18347 (use (match_dup 5))
18348 (use (reg:SI DIRFLAG_REG))]
18349 "TARGET_64BIT"
18350 "{rep\;movsb|rep movsb}"
18351 [(set_attr "type" "str")
18352 (set_attr "prefix_rep" "1")
18353 (set_attr "memory" "both")
18354 (set_attr "mode" "SI")])
18355
18356 (define_expand "setmemsi"
18357 [(use (match_operand:BLK 0 "memory_operand" ""))
18358 (use (match_operand:SI 1 "nonmemory_operand" ""))
18359 (use (match_operand 2 "const_int_operand" ""))
18360 (use (match_operand 3 "const_int_operand" ""))]
18361 ""
18362 {
18363 /* If value to set is not zero, use the library routine. */
18364 if (operands[2] != const0_rtx)
18365 FAIL;
18366
18367 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18368 DONE;
18369 else
18370 FAIL;
18371 })
18372
18373 (define_expand "setmemdi"
18374 [(use (match_operand:BLK 0 "memory_operand" ""))
18375 (use (match_operand:DI 1 "nonmemory_operand" ""))
18376 (use (match_operand 2 "const_int_operand" ""))
18377 (use (match_operand 3 "const_int_operand" ""))]
18378 "TARGET_64BIT"
18379 {
18380 /* If value to set is not zero, use the library routine. */
18381 if (operands[2] != const0_rtx)
18382 FAIL;
18383
18384 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18385 DONE;
18386 else
18387 FAIL;
18388 })
18389
18390 ;; Most CPUs don't like single string operations
18391 ;; Handle this case here to simplify previous expander.
18392
18393 (define_expand "strset"
18394 [(set (match_operand 1 "memory_operand" "")
18395 (match_operand 2 "register_operand" ""))
18396 (parallel [(set (match_operand 0 "register_operand" "")
18397 (match_dup 3))
18398 (clobber (reg:CC FLAGS_REG))])]
18399 ""
18400 {
18401 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18402 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18403
18404 /* If .md ever supports :P for Pmode, this can be directly
18405 in the pattern above. */
18406 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18407 GEN_INT (GET_MODE_SIZE (GET_MODE
18408 (operands[2]))));
18409 if (TARGET_SINGLE_STRINGOP || optimize_size)
18410 {
18411 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18412 operands[3]));
18413 DONE;
18414 }
18415 })
18416
18417 (define_expand "strset_singleop"
18418 [(parallel [(set (match_operand 1 "memory_operand" "")
18419 (match_operand 2 "register_operand" ""))
18420 (set (match_operand 0 "register_operand" "")
18421 (match_operand 3 "" ""))
18422 (use (reg:SI DIRFLAG_REG))])]
18423 "TARGET_SINGLE_STRINGOP || optimize_size"
18424 "")
18425
18426 (define_insn "*strsetdi_rex_1"
18427 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18428 (match_operand:DI 2 "register_operand" "a"))
18429 (set (match_operand:DI 0 "register_operand" "=D")
18430 (plus:DI (match_dup 1)
18431 (const_int 8)))
18432 (use (reg:SI DIRFLAG_REG))]
18433 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18434 "stosq"
18435 [(set_attr "type" "str")
18436 (set_attr "memory" "store")
18437 (set_attr "mode" "DI")])
18438
18439 (define_insn "*strsetsi_1"
18440 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18441 (match_operand:SI 2 "register_operand" "a"))
18442 (set (match_operand:SI 0 "register_operand" "=D")
18443 (plus:SI (match_dup 1)
18444 (const_int 4)))
18445 (use (reg:SI DIRFLAG_REG))]
18446 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18447 "{stosl|stosd}"
18448 [(set_attr "type" "str")
18449 (set_attr "memory" "store")
18450 (set_attr "mode" "SI")])
18451
18452 (define_insn "*strsetsi_rex_1"
18453 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18454 (match_operand:SI 2 "register_operand" "a"))
18455 (set (match_operand:DI 0 "register_operand" "=D")
18456 (plus:DI (match_dup 1)
18457 (const_int 4)))
18458 (use (reg:SI DIRFLAG_REG))]
18459 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18460 "{stosl|stosd}"
18461 [(set_attr "type" "str")
18462 (set_attr "memory" "store")
18463 (set_attr "mode" "SI")])
18464
18465 (define_insn "*strsethi_1"
18466 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18467 (match_operand:HI 2 "register_operand" "a"))
18468 (set (match_operand:SI 0 "register_operand" "=D")
18469 (plus:SI (match_dup 1)
18470 (const_int 2)))
18471 (use (reg:SI DIRFLAG_REG))]
18472 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18473 "stosw"
18474 [(set_attr "type" "str")
18475 (set_attr "memory" "store")
18476 (set_attr "mode" "HI")])
18477
18478 (define_insn "*strsethi_rex_1"
18479 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18480 (match_operand:HI 2 "register_operand" "a"))
18481 (set (match_operand:DI 0 "register_operand" "=D")
18482 (plus:DI (match_dup 1)
18483 (const_int 2)))
18484 (use (reg:SI DIRFLAG_REG))]
18485 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18486 "stosw"
18487 [(set_attr "type" "str")
18488 (set_attr "memory" "store")
18489 (set_attr "mode" "HI")])
18490
18491 (define_insn "*strsetqi_1"
18492 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18493 (match_operand:QI 2 "register_operand" "a"))
18494 (set (match_operand:SI 0 "register_operand" "=D")
18495 (plus:SI (match_dup 1)
18496 (const_int 1)))
18497 (use (reg:SI DIRFLAG_REG))]
18498 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18499 "stosb"
18500 [(set_attr "type" "str")
18501 (set_attr "memory" "store")
18502 (set_attr "mode" "QI")])
18503
18504 (define_insn "*strsetqi_rex_1"
18505 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18506 (match_operand:QI 2 "register_operand" "a"))
18507 (set (match_operand:DI 0 "register_operand" "=D")
18508 (plus:DI (match_dup 1)
18509 (const_int 1)))
18510 (use (reg:SI DIRFLAG_REG))]
18511 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18512 "stosb"
18513 [(set_attr "type" "str")
18514 (set_attr "memory" "store")
18515 (set_attr "mode" "QI")])
18516
18517 (define_expand "rep_stos"
18518 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18519 (set (match_operand 0 "register_operand" "")
18520 (match_operand 4 "" ""))
18521 (set (match_operand 2 "memory_operand" "") (const_int 0))
18522 (use (match_operand 3 "register_operand" ""))
18523 (use (match_dup 1))
18524 (use (reg:SI DIRFLAG_REG))])]
18525 ""
18526 "")
18527
18528 (define_insn "*rep_stosdi_rex64"
18529 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18530 (set (match_operand:DI 0 "register_operand" "=D")
18531 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18532 (const_int 3))
18533 (match_operand:DI 3 "register_operand" "0")))
18534 (set (mem:BLK (match_dup 3))
18535 (const_int 0))
18536 (use (match_operand:DI 2 "register_operand" "a"))
18537 (use (match_dup 4))
18538 (use (reg:SI DIRFLAG_REG))]
18539 "TARGET_64BIT"
18540 "{rep\;stosq|rep stosq}"
18541 [(set_attr "type" "str")
18542 (set_attr "prefix_rep" "1")
18543 (set_attr "memory" "store")
18544 (set_attr "mode" "DI")])
18545
18546 (define_insn "*rep_stossi"
18547 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18548 (set (match_operand:SI 0 "register_operand" "=D")
18549 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18550 (const_int 2))
18551 (match_operand:SI 3 "register_operand" "0")))
18552 (set (mem:BLK (match_dup 3))
18553 (const_int 0))
18554 (use (match_operand:SI 2 "register_operand" "a"))
18555 (use (match_dup 4))
18556 (use (reg:SI DIRFLAG_REG))]
18557 "!TARGET_64BIT"
18558 "{rep\;stosl|rep stosd}"
18559 [(set_attr "type" "str")
18560 (set_attr "prefix_rep" "1")
18561 (set_attr "memory" "store")
18562 (set_attr "mode" "SI")])
18563
18564 (define_insn "*rep_stossi_rex64"
18565 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18566 (set (match_operand:DI 0 "register_operand" "=D")
18567 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18568 (const_int 2))
18569 (match_operand:DI 3 "register_operand" "0")))
18570 (set (mem:BLK (match_dup 3))
18571 (const_int 0))
18572 (use (match_operand:SI 2 "register_operand" "a"))
18573 (use (match_dup 4))
18574 (use (reg:SI DIRFLAG_REG))]
18575 "TARGET_64BIT"
18576 "{rep\;stosl|rep stosd}"
18577 [(set_attr "type" "str")
18578 (set_attr "prefix_rep" "1")
18579 (set_attr "memory" "store")
18580 (set_attr "mode" "SI")])
18581
18582 (define_insn "*rep_stosqi"
18583 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18584 (set (match_operand:SI 0 "register_operand" "=D")
18585 (plus:SI (match_operand:SI 3 "register_operand" "0")
18586 (match_operand:SI 4 "register_operand" "1")))
18587 (set (mem:BLK (match_dup 3))
18588 (const_int 0))
18589 (use (match_operand:QI 2 "register_operand" "a"))
18590 (use (match_dup 4))
18591 (use (reg:SI DIRFLAG_REG))]
18592 "!TARGET_64BIT"
18593 "{rep\;stosb|rep stosb}"
18594 [(set_attr "type" "str")
18595 (set_attr "prefix_rep" "1")
18596 (set_attr "memory" "store")
18597 (set_attr "mode" "QI")])
18598
18599 (define_insn "*rep_stosqi_rex64"
18600 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18601 (set (match_operand:DI 0 "register_operand" "=D")
18602 (plus:DI (match_operand:DI 3 "register_operand" "0")
18603 (match_operand:DI 4 "register_operand" "1")))
18604 (set (mem:BLK (match_dup 3))
18605 (const_int 0))
18606 (use (match_operand:QI 2 "register_operand" "a"))
18607 (use (match_dup 4))
18608 (use (reg:SI DIRFLAG_REG))]
18609 "TARGET_64BIT"
18610 "{rep\;stosb|rep stosb}"
18611 [(set_attr "type" "str")
18612 (set_attr "prefix_rep" "1")
18613 (set_attr "memory" "store")
18614 (set_attr "mode" "QI")])
18615
18616 (define_expand "cmpstrnsi"
18617 [(set (match_operand:SI 0 "register_operand" "")
18618 (compare:SI (match_operand:BLK 1 "general_operand" "")
18619 (match_operand:BLK 2 "general_operand" "")))
18620 (use (match_operand 3 "general_operand" ""))
18621 (use (match_operand 4 "immediate_operand" ""))]
18622 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18623 {
18624 rtx addr1, addr2, out, outlow, count, countreg, align;
18625
18626 /* Can't use this if the user has appropriated esi or edi. */
18627 if (global_regs[4] || global_regs[5])
18628 FAIL;
18629
18630 out = operands[0];
18631 if (GET_CODE (out) != REG)
18632 out = gen_reg_rtx (SImode);
18633
18634 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18635 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18636 if (addr1 != XEXP (operands[1], 0))
18637 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18638 if (addr2 != XEXP (operands[2], 0))
18639 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18640
18641 count = operands[3];
18642 countreg = ix86_zero_extend_to_Pmode (count);
18643
18644 /* %%% Iff we are testing strict equality, we can use known alignment
18645 to good advantage. This may be possible with combine, particularly
18646 once cc0 is dead. */
18647 align = operands[4];
18648
18649 emit_insn (gen_cld ());
18650 if (GET_CODE (count) == CONST_INT)
18651 {
18652 if (INTVAL (count) == 0)
18653 {
18654 emit_move_insn (operands[0], const0_rtx);
18655 DONE;
18656 }
18657 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18658 operands[1], operands[2]));
18659 }
18660 else
18661 {
18662 if (TARGET_64BIT)
18663 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18664 else
18665 emit_insn (gen_cmpsi_1 (countreg, countreg));
18666 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18667 operands[1], operands[2]));
18668 }
18669
18670 outlow = gen_lowpart (QImode, out);
18671 emit_insn (gen_cmpintqi (outlow));
18672 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18673
18674 if (operands[0] != out)
18675 emit_move_insn (operands[0], out);
18676
18677 DONE;
18678 })
18679
18680 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18681
18682 (define_expand "cmpintqi"
18683 [(set (match_dup 1)
18684 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18685 (set (match_dup 2)
18686 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18687 (parallel [(set (match_operand:QI 0 "register_operand" "")
18688 (minus:QI (match_dup 1)
18689 (match_dup 2)))
18690 (clobber (reg:CC FLAGS_REG))])]
18691 ""
18692 "operands[1] = gen_reg_rtx (QImode);
18693 operands[2] = gen_reg_rtx (QImode);")
18694
18695 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18696 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18697
18698 (define_expand "cmpstrnqi_nz_1"
18699 [(parallel [(set (reg:CC FLAGS_REG)
18700 (compare:CC (match_operand 4 "memory_operand" "")
18701 (match_operand 5 "memory_operand" "")))
18702 (use (match_operand 2 "register_operand" ""))
18703 (use (match_operand:SI 3 "immediate_operand" ""))
18704 (use (reg:SI DIRFLAG_REG))
18705 (clobber (match_operand 0 "register_operand" ""))
18706 (clobber (match_operand 1 "register_operand" ""))
18707 (clobber (match_dup 2))])]
18708 ""
18709 "")
18710
18711 (define_insn "*cmpstrnqi_nz_1"
18712 [(set (reg:CC FLAGS_REG)
18713 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18714 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18715 (use (match_operand:SI 6 "register_operand" "2"))
18716 (use (match_operand:SI 3 "immediate_operand" "i"))
18717 (use (reg:SI DIRFLAG_REG))
18718 (clobber (match_operand:SI 0 "register_operand" "=S"))
18719 (clobber (match_operand:SI 1 "register_operand" "=D"))
18720 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18721 "!TARGET_64BIT"
18722 "repz{\;| }cmpsb"
18723 [(set_attr "type" "str")
18724 (set_attr "mode" "QI")
18725 (set_attr "prefix_rep" "1")])
18726
18727 (define_insn "*cmpstrnqi_nz_rex_1"
18728 [(set (reg:CC FLAGS_REG)
18729 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18730 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18731 (use (match_operand:DI 6 "register_operand" "2"))
18732 (use (match_operand:SI 3 "immediate_operand" "i"))
18733 (use (reg:SI DIRFLAG_REG))
18734 (clobber (match_operand:DI 0 "register_operand" "=S"))
18735 (clobber (match_operand:DI 1 "register_operand" "=D"))
18736 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18737 "TARGET_64BIT"
18738 "repz{\;| }cmpsb"
18739 [(set_attr "type" "str")
18740 (set_attr "mode" "QI")
18741 (set_attr "prefix_rep" "1")])
18742
18743 ;; The same, but the count is not known to not be zero.
18744
18745 (define_expand "cmpstrnqi_1"
18746 [(parallel [(set (reg:CC FLAGS_REG)
18747 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18748 (const_int 0))
18749 (compare:CC (match_operand 4 "memory_operand" "")
18750 (match_operand 5 "memory_operand" ""))
18751 (const_int 0)))
18752 (use (match_operand:SI 3 "immediate_operand" ""))
18753 (use (reg:CC FLAGS_REG))
18754 (use (reg:SI DIRFLAG_REG))
18755 (clobber (match_operand 0 "register_operand" ""))
18756 (clobber (match_operand 1 "register_operand" ""))
18757 (clobber (match_dup 2))])]
18758 ""
18759 "")
18760
18761 (define_insn "*cmpstrnqi_1"
18762 [(set (reg:CC FLAGS_REG)
18763 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18764 (const_int 0))
18765 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18766 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18767 (const_int 0)))
18768 (use (match_operand:SI 3 "immediate_operand" "i"))
18769 (use (reg:CC FLAGS_REG))
18770 (use (reg:SI DIRFLAG_REG))
18771 (clobber (match_operand:SI 0 "register_operand" "=S"))
18772 (clobber (match_operand:SI 1 "register_operand" "=D"))
18773 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18774 "!TARGET_64BIT"
18775 "repz{\;| }cmpsb"
18776 [(set_attr "type" "str")
18777 (set_attr "mode" "QI")
18778 (set_attr "prefix_rep" "1")])
18779
18780 (define_insn "*cmpstrnqi_rex_1"
18781 [(set (reg:CC FLAGS_REG)
18782 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18783 (const_int 0))
18784 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18785 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18786 (const_int 0)))
18787 (use (match_operand:SI 3 "immediate_operand" "i"))
18788 (use (reg:CC FLAGS_REG))
18789 (use (reg:SI DIRFLAG_REG))
18790 (clobber (match_operand:DI 0 "register_operand" "=S"))
18791 (clobber (match_operand:DI 1 "register_operand" "=D"))
18792 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18793 "TARGET_64BIT"
18794 "repz{\;| }cmpsb"
18795 [(set_attr "type" "str")
18796 (set_attr "mode" "QI")
18797 (set_attr "prefix_rep" "1")])
18798
18799 (define_expand "strlensi"
18800 [(set (match_operand:SI 0 "register_operand" "")
18801 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18802 (match_operand:QI 2 "immediate_operand" "")
18803 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18804 ""
18805 {
18806 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18807 DONE;
18808 else
18809 FAIL;
18810 })
18811
18812 (define_expand "strlendi"
18813 [(set (match_operand:DI 0 "register_operand" "")
18814 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18815 (match_operand:QI 2 "immediate_operand" "")
18816 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18817 ""
18818 {
18819 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18820 DONE;
18821 else
18822 FAIL;
18823 })
18824
18825 (define_expand "strlenqi_1"
18826 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18827 (use (reg:SI DIRFLAG_REG))
18828 (clobber (match_operand 1 "register_operand" ""))
18829 (clobber (reg:CC FLAGS_REG))])]
18830 ""
18831 "")
18832
18833 (define_insn "*strlenqi_1"
18834 [(set (match_operand:SI 0 "register_operand" "=&c")
18835 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18836 (match_operand:QI 2 "register_operand" "a")
18837 (match_operand:SI 3 "immediate_operand" "i")
18838 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18839 (use (reg:SI DIRFLAG_REG))
18840 (clobber (match_operand:SI 1 "register_operand" "=D"))
18841 (clobber (reg:CC FLAGS_REG))]
18842 "!TARGET_64BIT"
18843 "repnz{\;| }scasb"
18844 [(set_attr "type" "str")
18845 (set_attr "mode" "QI")
18846 (set_attr "prefix_rep" "1")])
18847
18848 (define_insn "*strlenqi_rex_1"
18849 [(set (match_operand:DI 0 "register_operand" "=&c")
18850 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18851 (match_operand:QI 2 "register_operand" "a")
18852 (match_operand:DI 3 "immediate_operand" "i")
18853 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18854 (use (reg:SI DIRFLAG_REG))
18855 (clobber (match_operand:DI 1 "register_operand" "=D"))
18856 (clobber (reg:CC FLAGS_REG))]
18857 "TARGET_64BIT"
18858 "repnz{\;| }scasb"
18859 [(set_attr "type" "str")
18860 (set_attr "mode" "QI")
18861 (set_attr "prefix_rep" "1")])
18862
18863 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18864 ;; handled in combine, but it is not currently up to the task.
18865 ;; When used for their truth value, the cmpstrn* expanders generate
18866 ;; code like this:
18867 ;;
18868 ;; repz cmpsb
18869 ;; seta %al
18870 ;; setb %dl
18871 ;; cmpb %al, %dl
18872 ;; jcc label
18873 ;;
18874 ;; The intermediate three instructions are unnecessary.
18875
18876 ;; This one handles cmpstrn*_nz_1...
18877 (define_peephole2
18878 [(parallel[
18879 (set (reg:CC FLAGS_REG)
18880 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18881 (mem:BLK (match_operand 5 "register_operand" ""))))
18882 (use (match_operand 6 "register_operand" ""))
18883 (use (match_operand:SI 3 "immediate_operand" ""))
18884 (use (reg:SI DIRFLAG_REG))
18885 (clobber (match_operand 0 "register_operand" ""))
18886 (clobber (match_operand 1 "register_operand" ""))
18887 (clobber (match_operand 2 "register_operand" ""))])
18888 (set (match_operand:QI 7 "register_operand" "")
18889 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18890 (set (match_operand:QI 8 "register_operand" "")
18891 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18892 (set (reg FLAGS_REG)
18893 (compare (match_dup 7) (match_dup 8)))
18894 ]
18895 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18896 [(parallel[
18897 (set (reg:CC FLAGS_REG)
18898 (compare:CC (mem:BLK (match_dup 4))
18899 (mem:BLK (match_dup 5))))
18900 (use (match_dup 6))
18901 (use (match_dup 3))
18902 (use (reg:SI DIRFLAG_REG))
18903 (clobber (match_dup 0))
18904 (clobber (match_dup 1))
18905 (clobber (match_dup 2))])]
18906 "")
18907
18908 ;; ...and this one handles cmpstrn*_1.
18909 (define_peephole2
18910 [(parallel[
18911 (set (reg:CC FLAGS_REG)
18912 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18913 (const_int 0))
18914 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18915 (mem:BLK (match_operand 5 "register_operand" "")))
18916 (const_int 0)))
18917 (use (match_operand:SI 3 "immediate_operand" ""))
18918 (use (reg:CC FLAGS_REG))
18919 (use (reg:SI DIRFLAG_REG))
18920 (clobber (match_operand 0 "register_operand" ""))
18921 (clobber (match_operand 1 "register_operand" ""))
18922 (clobber (match_operand 2 "register_operand" ""))])
18923 (set (match_operand:QI 7 "register_operand" "")
18924 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18925 (set (match_operand:QI 8 "register_operand" "")
18926 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18927 (set (reg FLAGS_REG)
18928 (compare (match_dup 7) (match_dup 8)))
18929 ]
18930 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18931 [(parallel[
18932 (set (reg:CC FLAGS_REG)
18933 (if_then_else:CC (ne (match_dup 6)
18934 (const_int 0))
18935 (compare:CC (mem:BLK (match_dup 4))
18936 (mem:BLK (match_dup 5)))
18937 (const_int 0)))
18938 (use (match_dup 3))
18939 (use (reg:CC FLAGS_REG))
18940 (use (reg:SI DIRFLAG_REG))
18941 (clobber (match_dup 0))
18942 (clobber (match_dup 1))
18943 (clobber (match_dup 2))])]
18944 "")
18945
18946
18947 \f
18948 ;; Conditional move instructions.
18949
18950 (define_expand "movdicc"
18951 [(set (match_operand:DI 0 "register_operand" "")
18952 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18953 (match_operand:DI 2 "general_operand" "")
18954 (match_operand:DI 3 "general_operand" "")))]
18955 "TARGET_64BIT"
18956 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18957
18958 (define_insn "x86_movdicc_0_m1_rex64"
18959 [(set (match_operand:DI 0 "register_operand" "=r")
18960 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18961 (const_int -1)
18962 (const_int 0)))
18963 (clobber (reg:CC FLAGS_REG))]
18964 "TARGET_64BIT"
18965 "sbb{q}\t%0, %0"
18966 ; Since we don't have the proper number of operands for an alu insn,
18967 ; fill in all the blanks.
18968 [(set_attr "type" "alu")
18969 (set_attr "pent_pair" "pu")
18970 (set_attr "memory" "none")
18971 (set_attr "imm_disp" "false")
18972 (set_attr "mode" "DI")
18973 (set_attr "length_immediate" "0")])
18974
18975 (define_insn "*movdicc_c_rex64"
18976 [(set (match_operand:DI 0 "register_operand" "=r,r")
18977 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18978 [(reg FLAGS_REG) (const_int 0)])
18979 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18980 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18981 "TARGET_64BIT && TARGET_CMOVE
18982 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18983 "@
18984 cmov%O2%C1\t{%2, %0|%0, %2}
18985 cmov%O2%c1\t{%3, %0|%0, %3}"
18986 [(set_attr "type" "icmov")
18987 (set_attr "mode" "DI")])
18988
18989 (define_expand "movsicc"
18990 [(set (match_operand:SI 0 "register_operand" "")
18991 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18992 (match_operand:SI 2 "general_operand" "")
18993 (match_operand:SI 3 "general_operand" "")))]
18994 ""
18995 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18996
18997 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18998 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18999 ;; So just document what we're doing explicitly.
19000
19001 (define_insn "x86_movsicc_0_m1"
19002 [(set (match_operand:SI 0 "register_operand" "=r")
19003 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19004 (const_int -1)
19005 (const_int 0)))
19006 (clobber (reg:CC FLAGS_REG))]
19007 ""
19008 "sbb{l}\t%0, %0"
19009 ; Since we don't have the proper number of operands for an alu insn,
19010 ; fill in all the blanks.
19011 [(set_attr "type" "alu")
19012 (set_attr "pent_pair" "pu")
19013 (set_attr "memory" "none")
19014 (set_attr "imm_disp" "false")
19015 (set_attr "mode" "SI")
19016 (set_attr "length_immediate" "0")])
19017
19018 (define_insn "*movsicc_noc"
19019 [(set (match_operand:SI 0 "register_operand" "=r,r")
19020 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19021 [(reg FLAGS_REG) (const_int 0)])
19022 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19023 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19024 "TARGET_CMOVE
19025 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19026 "@
19027 cmov%O2%C1\t{%2, %0|%0, %2}
19028 cmov%O2%c1\t{%3, %0|%0, %3}"
19029 [(set_attr "type" "icmov")
19030 (set_attr "mode" "SI")])
19031
19032 (define_expand "movhicc"
19033 [(set (match_operand:HI 0 "register_operand" "")
19034 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19035 (match_operand:HI 2 "general_operand" "")
19036 (match_operand:HI 3 "general_operand" "")))]
19037 "TARGET_HIMODE_MATH"
19038 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19039
19040 (define_insn "*movhicc_noc"
19041 [(set (match_operand:HI 0 "register_operand" "=r,r")
19042 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19043 [(reg FLAGS_REG) (const_int 0)])
19044 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19045 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19046 "TARGET_CMOVE
19047 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19048 "@
19049 cmov%O2%C1\t{%2, %0|%0, %2}
19050 cmov%O2%c1\t{%3, %0|%0, %3}"
19051 [(set_attr "type" "icmov")
19052 (set_attr "mode" "HI")])
19053
19054 (define_expand "movqicc"
19055 [(set (match_operand:QI 0 "register_operand" "")
19056 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19057 (match_operand:QI 2 "general_operand" "")
19058 (match_operand:QI 3 "general_operand" "")))]
19059 "TARGET_QIMODE_MATH"
19060 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19061
19062 (define_insn_and_split "*movqicc_noc"
19063 [(set (match_operand:QI 0 "register_operand" "=r,r")
19064 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19065 [(match_operand 4 "flags_reg_operand" "")
19066 (const_int 0)])
19067 (match_operand:QI 2 "register_operand" "r,0")
19068 (match_operand:QI 3 "register_operand" "0,r")))]
19069 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19070 "#"
19071 "&& reload_completed"
19072 [(set (match_dup 0)
19073 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19074 (match_dup 2)
19075 (match_dup 3)))]
19076 "operands[0] = gen_lowpart (SImode, operands[0]);
19077 operands[2] = gen_lowpart (SImode, operands[2]);
19078 operands[3] = gen_lowpart (SImode, operands[3]);"
19079 [(set_attr "type" "icmov")
19080 (set_attr "mode" "SI")])
19081
19082 (define_expand "movsfcc"
19083 [(set (match_operand:SF 0 "register_operand" "")
19084 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19085 (match_operand:SF 2 "register_operand" "")
19086 (match_operand:SF 3 "register_operand" "")))]
19087 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19088 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19089
19090 (define_insn "*movsfcc_1_387"
19091 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19092 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19093 [(reg FLAGS_REG) (const_int 0)])
19094 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19095 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19096 "TARGET_80387 && TARGET_CMOVE
19097 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19098 "@
19099 fcmov%F1\t{%2, %0|%0, %2}
19100 fcmov%f1\t{%3, %0|%0, %3}
19101 cmov%O2%C1\t{%2, %0|%0, %2}
19102 cmov%O2%c1\t{%3, %0|%0, %3}"
19103 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19104 (set_attr "mode" "SF,SF,SI,SI")])
19105
19106 (define_expand "movdfcc"
19107 [(set (match_operand:DF 0 "register_operand" "")
19108 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19109 (match_operand:DF 2 "register_operand" "")
19110 (match_operand:DF 3 "register_operand" "")))]
19111 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19112 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19113
19114 (define_insn "*movdfcc_1"
19115 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19116 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19117 [(reg FLAGS_REG) (const_int 0)])
19118 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19119 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19120 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19121 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19122 "@
19123 fcmov%F1\t{%2, %0|%0, %2}
19124 fcmov%f1\t{%3, %0|%0, %3}
19125 #
19126 #"
19127 [(set_attr "type" "fcmov,fcmov,multi,multi")
19128 (set_attr "mode" "DF")])
19129
19130 (define_insn "*movdfcc_1_rex64"
19131 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19132 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19133 [(reg FLAGS_REG) (const_int 0)])
19134 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19135 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19136 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19137 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19138 "@
19139 fcmov%F1\t{%2, %0|%0, %2}
19140 fcmov%f1\t{%3, %0|%0, %3}
19141 cmov%O2%C1\t{%2, %0|%0, %2}
19142 cmov%O2%c1\t{%3, %0|%0, %3}"
19143 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19144 (set_attr "mode" "DF")])
19145
19146 (define_split
19147 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19148 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19149 [(match_operand 4 "flags_reg_operand" "")
19150 (const_int 0)])
19151 (match_operand:DF 2 "nonimmediate_operand" "")
19152 (match_operand:DF 3 "nonimmediate_operand" "")))]
19153 "!TARGET_64BIT && reload_completed"
19154 [(set (match_dup 2)
19155 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19156 (match_dup 5)
19157 (match_dup 7)))
19158 (set (match_dup 3)
19159 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19160 (match_dup 6)
19161 (match_dup 8)))]
19162 "split_di (operands+2, 1, operands+5, operands+6);
19163 split_di (operands+3, 1, operands+7, operands+8);
19164 split_di (operands, 1, operands+2, operands+3);")
19165
19166 (define_expand "movxfcc"
19167 [(set (match_operand:XF 0 "register_operand" "")
19168 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19169 (match_operand:XF 2 "register_operand" "")
19170 (match_operand:XF 3 "register_operand" "")))]
19171 "TARGET_80387 && TARGET_CMOVE"
19172 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19173
19174 (define_insn "*movxfcc_1"
19175 [(set (match_operand:XF 0 "register_operand" "=f,f")
19176 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19177 [(reg FLAGS_REG) (const_int 0)])
19178 (match_operand:XF 2 "register_operand" "f,0")
19179 (match_operand:XF 3 "register_operand" "0,f")))]
19180 "TARGET_80387 && TARGET_CMOVE"
19181 "@
19182 fcmov%F1\t{%2, %0|%0, %2}
19183 fcmov%f1\t{%3, %0|%0, %3}"
19184 [(set_attr "type" "fcmov")
19185 (set_attr "mode" "XF")])
19186
19187 ;; These versions of the min/max patterns are intentionally ignorant of
19188 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19189 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19190 ;; are undefined in this condition, we're certain this is correct.
19191
19192 (define_insn "sminsf3"
19193 [(set (match_operand:SF 0 "register_operand" "=x")
19194 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19195 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19196 "TARGET_SSE_MATH"
19197 "minss\t{%2, %0|%0, %2}"
19198 [(set_attr "type" "sseadd")
19199 (set_attr "mode" "SF")])
19200
19201 (define_insn "smaxsf3"
19202 [(set (match_operand:SF 0 "register_operand" "=x")
19203 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19204 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19205 "TARGET_SSE_MATH"
19206 "maxss\t{%2, %0|%0, %2}"
19207 [(set_attr "type" "sseadd")
19208 (set_attr "mode" "SF")])
19209
19210 (define_insn "smindf3"
19211 [(set (match_operand:DF 0 "register_operand" "=x")
19212 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19213 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19214 "TARGET_SSE2 && TARGET_SSE_MATH"
19215 "minsd\t{%2, %0|%0, %2}"
19216 [(set_attr "type" "sseadd")
19217 (set_attr "mode" "DF")])
19218
19219 (define_insn "smaxdf3"
19220 [(set (match_operand:DF 0 "register_operand" "=x")
19221 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19222 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19223 "TARGET_SSE2 && TARGET_SSE_MATH"
19224 "maxsd\t{%2, %0|%0, %2}"
19225 [(set_attr "type" "sseadd")
19226 (set_attr "mode" "DF")])
19227
19228 ;; These versions of the min/max patterns implement exactly the operations
19229 ;; min = (op1 < op2 ? op1 : op2)
19230 ;; max = (!(op1 < op2) ? op1 : op2)
19231 ;; Their operands are not commutative, and thus they may be used in the
19232 ;; presence of -0.0 and NaN.
19233
19234 (define_insn "*ieee_sminsf3"
19235 [(set (match_operand:SF 0 "register_operand" "=x")
19236 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19237 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19238 UNSPEC_IEEE_MIN))]
19239 "TARGET_SSE_MATH"
19240 "minss\t{%2, %0|%0, %2}"
19241 [(set_attr "type" "sseadd")
19242 (set_attr "mode" "SF")])
19243
19244 (define_insn "*ieee_smaxsf3"
19245 [(set (match_operand:SF 0 "register_operand" "=x")
19246 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19247 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19248 UNSPEC_IEEE_MAX))]
19249 "TARGET_SSE_MATH"
19250 "maxss\t{%2, %0|%0, %2}"
19251 [(set_attr "type" "sseadd")
19252 (set_attr "mode" "SF")])
19253
19254 (define_insn "*ieee_smindf3"
19255 [(set (match_operand:DF 0 "register_operand" "=x")
19256 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19257 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19258 UNSPEC_IEEE_MIN))]
19259 "TARGET_SSE2 && TARGET_SSE_MATH"
19260 "minsd\t{%2, %0|%0, %2}"
19261 [(set_attr "type" "sseadd")
19262 (set_attr "mode" "DF")])
19263
19264 (define_insn "*ieee_smaxdf3"
19265 [(set (match_operand:DF 0 "register_operand" "=x")
19266 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19267 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19268 UNSPEC_IEEE_MAX))]
19269 "TARGET_SSE2 && TARGET_SSE_MATH"
19270 "maxsd\t{%2, %0|%0, %2}"
19271 [(set_attr "type" "sseadd")
19272 (set_attr "mode" "DF")])
19273
19274 ;; Make two stack loads independent:
19275 ;; fld aa fld aa
19276 ;; fld %st(0) -> fld bb
19277 ;; fmul bb fmul %st(1), %st
19278 ;;
19279 ;; Actually we only match the last two instructions for simplicity.
19280 (define_peephole2
19281 [(set (match_operand 0 "fp_register_operand" "")
19282 (match_operand 1 "fp_register_operand" ""))
19283 (set (match_dup 0)
19284 (match_operator 2 "binary_fp_operator"
19285 [(match_dup 0)
19286 (match_operand 3 "memory_operand" "")]))]
19287 "REGNO (operands[0]) != REGNO (operands[1])"
19288 [(set (match_dup 0) (match_dup 3))
19289 (set (match_dup 0) (match_dup 4))]
19290
19291 ;; The % modifier is not operational anymore in peephole2's, so we have to
19292 ;; swap the operands manually in the case of addition and multiplication.
19293 "if (COMMUTATIVE_ARITH_P (operands[2]))
19294 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19295 operands[0], operands[1]);
19296 else
19297 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19298 operands[1], operands[0]);")
19299
19300 ;; Conditional addition patterns
19301 (define_expand "addqicc"
19302 [(match_operand:QI 0 "register_operand" "")
19303 (match_operand 1 "comparison_operator" "")
19304 (match_operand:QI 2 "register_operand" "")
19305 (match_operand:QI 3 "const_int_operand" "")]
19306 ""
19307 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19308
19309 (define_expand "addhicc"
19310 [(match_operand:HI 0 "register_operand" "")
19311 (match_operand 1 "comparison_operator" "")
19312 (match_operand:HI 2 "register_operand" "")
19313 (match_operand:HI 3 "const_int_operand" "")]
19314 ""
19315 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19316
19317 (define_expand "addsicc"
19318 [(match_operand:SI 0 "register_operand" "")
19319 (match_operand 1 "comparison_operator" "")
19320 (match_operand:SI 2 "register_operand" "")
19321 (match_operand:SI 3 "const_int_operand" "")]
19322 ""
19323 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19324
19325 (define_expand "adddicc"
19326 [(match_operand:DI 0 "register_operand" "")
19327 (match_operand 1 "comparison_operator" "")
19328 (match_operand:DI 2 "register_operand" "")
19329 (match_operand:DI 3 "const_int_operand" "")]
19330 "TARGET_64BIT"
19331 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19332
19333 \f
19334 ;; Misc patterns (?)
19335
19336 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19337 ;; Otherwise there will be nothing to keep
19338 ;;
19339 ;; [(set (reg ebp) (reg esp))]
19340 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19341 ;; (clobber (eflags)]
19342 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19343 ;;
19344 ;; in proper program order.
19345 (define_insn "pro_epilogue_adjust_stack_1"
19346 [(set (match_operand:SI 0 "register_operand" "=r,r")
19347 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19348 (match_operand:SI 2 "immediate_operand" "i,i")))
19349 (clobber (reg:CC FLAGS_REG))
19350 (clobber (mem:BLK (scratch)))]
19351 "!TARGET_64BIT"
19352 {
19353 switch (get_attr_type (insn))
19354 {
19355 case TYPE_IMOV:
19356 return "mov{l}\t{%1, %0|%0, %1}";
19357
19358 case TYPE_ALU:
19359 if (GET_CODE (operands[2]) == CONST_INT
19360 && (INTVAL (operands[2]) == 128
19361 || (INTVAL (operands[2]) < 0
19362 && INTVAL (operands[2]) != -128)))
19363 {
19364 operands[2] = GEN_INT (-INTVAL (operands[2]));
19365 return "sub{l}\t{%2, %0|%0, %2}";
19366 }
19367 return "add{l}\t{%2, %0|%0, %2}";
19368
19369 case TYPE_LEA:
19370 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19371 return "lea{l}\t{%a2, %0|%0, %a2}";
19372
19373 default:
19374 gcc_unreachable ();
19375 }
19376 }
19377 [(set (attr "type")
19378 (cond [(eq_attr "alternative" "0")
19379 (const_string "alu")
19380 (match_operand:SI 2 "const0_operand" "")
19381 (const_string "imov")
19382 ]
19383 (const_string "lea")))
19384 (set_attr "mode" "SI")])
19385
19386 (define_insn "pro_epilogue_adjust_stack_rex64"
19387 [(set (match_operand:DI 0 "register_operand" "=r,r")
19388 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19389 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19390 (clobber (reg:CC FLAGS_REG))
19391 (clobber (mem:BLK (scratch)))]
19392 "TARGET_64BIT"
19393 {
19394 switch (get_attr_type (insn))
19395 {
19396 case TYPE_IMOV:
19397 return "mov{q}\t{%1, %0|%0, %1}";
19398
19399 case TYPE_ALU:
19400 if (GET_CODE (operands[2]) == CONST_INT
19401 /* Avoid overflows. */
19402 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19403 && (INTVAL (operands[2]) == 128
19404 || (INTVAL (operands[2]) < 0
19405 && INTVAL (operands[2]) != -128)))
19406 {
19407 operands[2] = GEN_INT (-INTVAL (operands[2]));
19408 return "sub{q}\t{%2, %0|%0, %2}";
19409 }
19410 return "add{q}\t{%2, %0|%0, %2}";
19411
19412 case TYPE_LEA:
19413 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19414 return "lea{q}\t{%a2, %0|%0, %a2}";
19415
19416 default:
19417 gcc_unreachable ();
19418 }
19419 }
19420 [(set (attr "type")
19421 (cond [(eq_attr "alternative" "0")
19422 (const_string "alu")
19423 (match_operand:DI 2 "const0_operand" "")
19424 (const_string "imov")
19425 ]
19426 (const_string "lea")))
19427 (set_attr "mode" "DI")])
19428
19429 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19430 [(set (match_operand:DI 0 "register_operand" "=r,r")
19431 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19432 (match_operand:DI 3 "immediate_operand" "i,i")))
19433 (use (match_operand:DI 2 "register_operand" "r,r"))
19434 (clobber (reg:CC FLAGS_REG))
19435 (clobber (mem:BLK (scratch)))]
19436 "TARGET_64BIT"
19437 {
19438 switch (get_attr_type (insn))
19439 {
19440 case TYPE_ALU:
19441 return "add{q}\t{%2, %0|%0, %2}";
19442
19443 case TYPE_LEA:
19444 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19445 return "lea{q}\t{%a2, %0|%0, %a2}";
19446
19447 default:
19448 gcc_unreachable ();
19449 }
19450 }
19451 [(set_attr "type" "alu,lea")
19452 (set_attr "mode" "DI")])
19453
19454 (define_expand "allocate_stack_worker"
19455 [(match_operand:SI 0 "register_operand" "")]
19456 "TARGET_STACK_PROBE"
19457 {
19458 if (reload_completed)
19459 {
19460 if (TARGET_64BIT)
19461 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19462 else
19463 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19464 }
19465 else
19466 {
19467 if (TARGET_64BIT)
19468 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19469 else
19470 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19471 }
19472 DONE;
19473 })
19474
19475 (define_insn "allocate_stack_worker_1"
19476 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19477 UNSPECV_STACK_PROBE)
19478 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19479 (clobber (match_scratch:SI 1 "=0"))
19480 (clobber (reg:CC FLAGS_REG))]
19481 "!TARGET_64BIT && TARGET_STACK_PROBE"
19482 "call\t__alloca"
19483 [(set_attr "type" "multi")
19484 (set_attr "length" "5")])
19485
19486 (define_expand "allocate_stack_worker_postreload"
19487 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19488 UNSPECV_STACK_PROBE)
19489 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19490 (clobber (match_dup 0))
19491 (clobber (reg:CC FLAGS_REG))])]
19492 ""
19493 "")
19494
19495 (define_insn "allocate_stack_worker_rex64"
19496 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19497 UNSPECV_STACK_PROBE)
19498 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19499 (clobber (match_scratch:DI 1 "=0"))
19500 (clobber (reg:CC FLAGS_REG))]
19501 "TARGET_64BIT && TARGET_STACK_PROBE"
19502 "call\t__alloca"
19503 [(set_attr "type" "multi")
19504 (set_attr "length" "5")])
19505
19506 (define_expand "allocate_stack_worker_rex64_postreload"
19507 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19508 UNSPECV_STACK_PROBE)
19509 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19510 (clobber (match_dup 0))
19511 (clobber (reg:CC FLAGS_REG))])]
19512 ""
19513 "")
19514
19515 (define_expand "allocate_stack"
19516 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19517 (minus:SI (reg:SI SP_REG)
19518 (match_operand:SI 1 "general_operand" "")))
19519 (clobber (reg:CC FLAGS_REG))])
19520 (parallel [(set (reg:SI SP_REG)
19521 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19522 (clobber (reg:CC FLAGS_REG))])]
19523 "TARGET_STACK_PROBE"
19524 {
19525 #ifdef CHECK_STACK_LIMIT
19526 if (GET_CODE (operands[1]) == CONST_INT
19527 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19528 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19529 operands[1]));
19530 else
19531 #endif
19532 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19533 operands[1])));
19534
19535 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19536 DONE;
19537 })
19538
19539 (define_expand "builtin_setjmp_receiver"
19540 [(label_ref (match_operand 0 "" ""))]
19541 "!TARGET_64BIT && flag_pic"
19542 {
19543 if (TARGET_MACHO)
19544 {
19545 rtx xops[3];
19546 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19547 rtx label_rtx = gen_label_rtx ();
19548 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19549 xops[0] = xops[1] = picreg;
19550 xops[2] = gen_rtx_CONST (SImode,
19551 gen_rtx_MINUS (SImode,
19552 gen_rtx_LABEL_REF (SImode, label_rtx),
19553 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19554 ix86_expand_binary_operator (MINUS, SImode, xops);
19555 }
19556 else
19557 emit_insn (gen_set_got (pic_offset_table_rtx));
19558 DONE;
19559 })
19560 \f
19561 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19562
19563 (define_split
19564 [(set (match_operand 0 "register_operand" "")
19565 (match_operator 3 "promotable_binary_operator"
19566 [(match_operand 1 "register_operand" "")
19567 (match_operand 2 "aligned_operand" "")]))
19568 (clobber (reg:CC FLAGS_REG))]
19569 "! TARGET_PARTIAL_REG_STALL && reload_completed
19570 && ((GET_MODE (operands[0]) == HImode
19571 && ((!optimize_size && !TARGET_FAST_PREFIX)
19572 /* ??? next two lines just !satisfies_constraint_K (...) */
19573 || GET_CODE (operands[2]) != CONST_INT
19574 || satisfies_constraint_K (operands[2])))
19575 || (GET_MODE (operands[0]) == QImode
19576 && (TARGET_PROMOTE_QImode || optimize_size)))"
19577 [(parallel [(set (match_dup 0)
19578 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19579 (clobber (reg:CC FLAGS_REG))])]
19580 "operands[0] = gen_lowpart (SImode, operands[0]);
19581 operands[1] = gen_lowpart (SImode, operands[1]);
19582 if (GET_CODE (operands[3]) != ASHIFT)
19583 operands[2] = gen_lowpart (SImode, operands[2]);
19584 PUT_MODE (operands[3], SImode);")
19585
19586 ; Promote the QImode tests, as i386 has encoding of the AND
19587 ; instruction with 32-bit sign-extended immediate and thus the
19588 ; instruction size is unchanged, except in the %eax case for
19589 ; which it is increased by one byte, hence the ! optimize_size.
19590 (define_split
19591 [(set (match_operand 0 "flags_reg_operand" "")
19592 (match_operator 2 "compare_operator"
19593 [(and (match_operand 3 "aligned_operand" "")
19594 (match_operand 4 "const_int_operand" ""))
19595 (const_int 0)]))
19596 (set (match_operand 1 "register_operand" "")
19597 (and (match_dup 3) (match_dup 4)))]
19598 "! TARGET_PARTIAL_REG_STALL && reload_completed
19599 /* Ensure that the operand will remain sign-extended immediate. */
19600 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19601 && ! optimize_size
19602 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19603 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19604 [(parallel [(set (match_dup 0)
19605 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19606 (const_int 0)]))
19607 (set (match_dup 1)
19608 (and:SI (match_dup 3) (match_dup 4)))])]
19609 {
19610 operands[4]
19611 = gen_int_mode (INTVAL (operands[4])
19612 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19613 operands[1] = gen_lowpart (SImode, operands[1]);
19614 operands[3] = gen_lowpart (SImode, operands[3]);
19615 })
19616
19617 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19618 ; the TEST instruction with 32-bit sign-extended immediate and thus
19619 ; the instruction size would at least double, which is not what we
19620 ; want even with ! optimize_size.
19621 (define_split
19622 [(set (match_operand 0 "flags_reg_operand" "")
19623 (match_operator 1 "compare_operator"
19624 [(and (match_operand:HI 2 "aligned_operand" "")
19625 (match_operand:HI 3 "const_int_operand" ""))
19626 (const_int 0)]))]
19627 "! TARGET_PARTIAL_REG_STALL && reload_completed
19628 /* Ensure that the operand will remain sign-extended immediate. */
19629 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19630 && ! TARGET_FAST_PREFIX
19631 && ! optimize_size"
19632 [(set (match_dup 0)
19633 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19634 (const_int 0)]))]
19635 {
19636 operands[3]
19637 = gen_int_mode (INTVAL (operands[3])
19638 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19639 operands[2] = gen_lowpart (SImode, operands[2]);
19640 })
19641
19642 (define_split
19643 [(set (match_operand 0 "register_operand" "")
19644 (neg (match_operand 1 "register_operand" "")))
19645 (clobber (reg:CC FLAGS_REG))]
19646 "! TARGET_PARTIAL_REG_STALL && reload_completed
19647 && (GET_MODE (operands[0]) == HImode
19648 || (GET_MODE (operands[0]) == QImode
19649 && (TARGET_PROMOTE_QImode || optimize_size)))"
19650 [(parallel [(set (match_dup 0)
19651 (neg:SI (match_dup 1)))
19652 (clobber (reg:CC FLAGS_REG))])]
19653 "operands[0] = gen_lowpart (SImode, operands[0]);
19654 operands[1] = gen_lowpart (SImode, operands[1]);")
19655
19656 (define_split
19657 [(set (match_operand 0 "register_operand" "")
19658 (not (match_operand 1 "register_operand" "")))]
19659 "! TARGET_PARTIAL_REG_STALL && reload_completed
19660 && (GET_MODE (operands[0]) == HImode
19661 || (GET_MODE (operands[0]) == QImode
19662 && (TARGET_PROMOTE_QImode || optimize_size)))"
19663 [(set (match_dup 0)
19664 (not:SI (match_dup 1)))]
19665 "operands[0] = gen_lowpart (SImode, operands[0]);
19666 operands[1] = gen_lowpart (SImode, operands[1]);")
19667
19668 (define_split
19669 [(set (match_operand 0 "register_operand" "")
19670 (if_then_else (match_operator 1 "comparison_operator"
19671 [(reg FLAGS_REG) (const_int 0)])
19672 (match_operand 2 "register_operand" "")
19673 (match_operand 3 "register_operand" "")))]
19674 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19675 && (GET_MODE (operands[0]) == HImode
19676 || (GET_MODE (operands[0]) == QImode
19677 && (TARGET_PROMOTE_QImode || optimize_size)))"
19678 [(set (match_dup 0)
19679 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19680 "operands[0] = gen_lowpart (SImode, operands[0]);
19681 operands[2] = gen_lowpart (SImode, operands[2]);
19682 operands[3] = gen_lowpart (SImode, operands[3]);")
19683
19684 \f
19685 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19686 ;; transform a complex memory operation into two memory to register operations.
19687
19688 ;; Don't push memory operands
19689 (define_peephole2
19690 [(set (match_operand:SI 0 "push_operand" "")
19691 (match_operand:SI 1 "memory_operand" ""))
19692 (match_scratch:SI 2 "r")]
19693 "!optimize_size && !TARGET_PUSH_MEMORY
19694 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19695 [(set (match_dup 2) (match_dup 1))
19696 (set (match_dup 0) (match_dup 2))]
19697 "")
19698
19699 (define_peephole2
19700 [(set (match_operand:DI 0 "push_operand" "")
19701 (match_operand:DI 1 "memory_operand" ""))
19702 (match_scratch:DI 2 "r")]
19703 "!optimize_size && !TARGET_PUSH_MEMORY
19704 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19705 [(set (match_dup 2) (match_dup 1))
19706 (set (match_dup 0) (match_dup 2))]
19707 "")
19708
19709 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19710 ;; SImode pushes.
19711 (define_peephole2
19712 [(set (match_operand:SF 0 "push_operand" "")
19713 (match_operand:SF 1 "memory_operand" ""))
19714 (match_scratch:SF 2 "r")]
19715 "!optimize_size && !TARGET_PUSH_MEMORY
19716 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19717 [(set (match_dup 2) (match_dup 1))
19718 (set (match_dup 0) (match_dup 2))]
19719 "")
19720
19721 (define_peephole2
19722 [(set (match_operand:HI 0 "push_operand" "")
19723 (match_operand:HI 1 "memory_operand" ""))
19724 (match_scratch:HI 2 "r")]
19725 "!optimize_size && !TARGET_PUSH_MEMORY
19726 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19727 [(set (match_dup 2) (match_dup 1))
19728 (set (match_dup 0) (match_dup 2))]
19729 "")
19730
19731 (define_peephole2
19732 [(set (match_operand:QI 0 "push_operand" "")
19733 (match_operand:QI 1 "memory_operand" ""))
19734 (match_scratch:QI 2 "q")]
19735 "!optimize_size && !TARGET_PUSH_MEMORY
19736 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19737 [(set (match_dup 2) (match_dup 1))
19738 (set (match_dup 0) (match_dup 2))]
19739 "")
19740
19741 ;; Don't move an immediate directly to memory when the instruction
19742 ;; gets too big.
19743 (define_peephole2
19744 [(match_scratch:SI 1 "r")
19745 (set (match_operand:SI 0 "memory_operand" "")
19746 (const_int 0))]
19747 "! optimize_size
19748 && ! TARGET_USE_MOV0
19749 && TARGET_SPLIT_LONG_MOVES
19750 && get_attr_length (insn) >= ix86_cost->large_insn
19751 && peep2_regno_dead_p (0, FLAGS_REG)"
19752 [(parallel [(set (match_dup 1) (const_int 0))
19753 (clobber (reg:CC FLAGS_REG))])
19754 (set (match_dup 0) (match_dup 1))]
19755 "")
19756
19757 (define_peephole2
19758 [(match_scratch:HI 1 "r")
19759 (set (match_operand:HI 0 "memory_operand" "")
19760 (const_int 0))]
19761 "! optimize_size
19762 && ! TARGET_USE_MOV0
19763 && TARGET_SPLIT_LONG_MOVES
19764 && get_attr_length (insn) >= ix86_cost->large_insn
19765 && peep2_regno_dead_p (0, FLAGS_REG)"
19766 [(parallel [(set (match_dup 2) (const_int 0))
19767 (clobber (reg:CC FLAGS_REG))])
19768 (set (match_dup 0) (match_dup 1))]
19769 "operands[2] = gen_lowpart (SImode, operands[1]);")
19770
19771 (define_peephole2
19772 [(match_scratch:QI 1 "q")
19773 (set (match_operand:QI 0 "memory_operand" "")
19774 (const_int 0))]
19775 "! optimize_size
19776 && ! TARGET_USE_MOV0
19777 && TARGET_SPLIT_LONG_MOVES
19778 && get_attr_length (insn) >= ix86_cost->large_insn
19779 && peep2_regno_dead_p (0, FLAGS_REG)"
19780 [(parallel [(set (match_dup 2) (const_int 0))
19781 (clobber (reg:CC FLAGS_REG))])
19782 (set (match_dup 0) (match_dup 1))]
19783 "operands[2] = gen_lowpart (SImode, operands[1]);")
19784
19785 (define_peephole2
19786 [(match_scratch:SI 2 "r")
19787 (set (match_operand:SI 0 "memory_operand" "")
19788 (match_operand:SI 1 "immediate_operand" ""))]
19789 "! optimize_size
19790 && get_attr_length (insn) >= ix86_cost->large_insn
19791 && TARGET_SPLIT_LONG_MOVES"
19792 [(set (match_dup 2) (match_dup 1))
19793 (set (match_dup 0) (match_dup 2))]
19794 "")
19795
19796 (define_peephole2
19797 [(match_scratch:HI 2 "r")
19798 (set (match_operand:HI 0 "memory_operand" "")
19799 (match_operand:HI 1 "immediate_operand" ""))]
19800 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19801 && TARGET_SPLIT_LONG_MOVES"
19802 [(set (match_dup 2) (match_dup 1))
19803 (set (match_dup 0) (match_dup 2))]
19804 "")
19805
19806 (define_peephole2
19807 [(match_scratch:QI 2 "q")
19808 (set (match_operand:QI 0 "memory_operand" "")
19809 (match_operand:QI 1 "immediate_operand" ""))]
19810 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19811 && TARGET_SPLIT_LONG_MOVES"
19812 [(set (match_dup 2) (match_dup 1))
19813 (set (match_dup 0) (match_dup 2))]
19814 "")
19815
19816 ;; Don't compare memory with zero, load and use a test instead.
19817 (define_peephole2
19818 [(set (match_operand 0 "flags_reg_operand" "")
19819 (match_operator 1 "compare_operator"
19820 [(match_operand:SI 2 "memory_operand" "")
19821 (const_int 0)]))
19822 (match_scratch:SI 3 "r")]
19823 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19824 [(set (match_dup 3) (match_dup 2))
19825 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19826 "")
19827
19828 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19829 ;; Don't split NOTs with a displacement operand, because resulting XOR
19830 ;; will not be pairable anyway.
19831 ;;
19832 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19833 ;; represented using a modRM byte. The XOR replacement is long decoded,
19834 ;; so this split helps here as well.
19835 ;;
19836 ;; Note: Can't do this as a regular split because we can't get proper
19837 ;; lifetime information then.
19838
19839 (define_peephole2
19840 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19841 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19842 "!optimize_size
19843 && peep2_regno_dead_p (0, FLAGS_REG)
19844 && ((TARGET_PENTIUM
19845 && (GET_CODE (operands[0]) != MEM
19846 || !memory_displacement_operand (operands[0], SImode)))
19847 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19848 [(parallel [(set (match_dup 0)
19849 (xor:SI (match_dup 1) (const_int -1)))
19850 (clobber (reg:CC FLAGS_REG))])]
19851 "")
19852
19853 (define_peephole2
19854 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19855 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19856 "!optimize_size
19857 && peep2_regno_dead_p (0, FLAGS_REG)
19858 && ((TARGET_PENTIUM
19859 && (GET_CODE (operands[0]) != MEM
19860 || !memory_displacement_operand (operands[0], HImode)))
19861 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19862 [(parallel [(set (match_dup 0)
19863 (xor:HI (match_dup 1) (const_int -1)))
19864 (clobber (reg:CC FLAGS_REG))])]
19865 "")
19866
19867 (define_peephole2
19868 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19869 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19870 "!optimize_size
19871 && peep2_regno_dead_p (0, FLAGS_REG)
19872 && ((TARGET_PENTIUM
19873 && (GET_CODE (operands[0]) != MEM
19874 || !memory_displacement_operand (operands[0], QImode)))
19875 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19876 [(parallel [(set (match_dup 0)
19877 (xor:QI (match_dup 1) (const_int -1)))
19878 (clobber (reg:CC FLAGS_REG))])]
19879 "")
19880
19881 ;; Non pairable "test imm, reg" instructions can be translated to
19882 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19883 ;; byte opcode instead of two, have a short form for byte operands),
19884 ;; so do it for other CPUs as well. Given that the value was dead,
19885 ;; this should not create any new dependencies. Pass on the sub-word
19886 ;; versions if we're concerned about partial register stalls.
19887
19888 (define_peephole2
19889 [(set (match_operand 0 "flags_reg_operand" "")
19890 (match_operator 1 "compare_operator"
19891 [(and:SI (match_operand:SI 2 "register_operand" "")
19892 (match_operand:SI 3 "immediate_operand" ""))
19893 (const_int 0)]))]
19894 "ix86_match_ccmode (insn, CCNOmode)
19895 && (true_regnum (operands[2]) != 0
19896 || satisfies_constraint_K (operands[3]))
19897 && peep2_reg_dead_p (1, operands[2])"
19898 [(parallel
19899 [(set (match_dup 0)
19900 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19901 (const_int 0)]))
19902 (set (match_dup 2)
19903 (and:SI (match_dup 2) (match_dup 3)))])]
19904 "")
19905
19906 ;; We don't need to handle HImode case, because it will be promoted to SImode
19907 ;; on ! TARGET_PARTIAL_REG_STALL
19908
19909 (define_peephole2
19910 [(set (match_operand 0 "flags_reg_operand" "")
19911 (match_operator 1 "compare_operator"
19912 [(and:QI (match_operand:QI 2 "register_operand" "")
19913 (match_operand:QI 3 "immediate_operand" ""))
19914 (const_int 0)]))]
19915 "! TARGET_PARTIAL_REG_STALL
19916 && ix86_match_ccmode (insn, CCNOmode)
19917 && true_regnum (operands[2]) != 0
19918 && peep2_reg_dead_p (1, operands[2])"
19919 [(parallel
19920 [(set (match_dup 0)
19921 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19922 (const_int 0)]))
19923 (set (match_dup 2)
19924 (and:QI (match_dup 2) (match_dup 3)))])]
19925 "")
19926
19927 (define_peephole2
19928 [(set (match_operand 0 "flags_reg_operand" "")
19929 (match_operator 1 "compare_operator"
19930 [(and:SI
19931 (zero_extract:SI
19932 (match_operand 2 "ext_register_operand" "")
19933 (const_int 8)
19934 (const_int 8))
19935 (match_operand 3 "const_int_operand" ""))
19936 (const_int 0)]))]
19937 "! TARGET_PARTIAL_REG_STALL
19938 && ix86_match_ccmode (insn, CCNOmode)
19939 && true_regnum (operands[2]) != 0
19940 && peep2_reg_dead_p (1, operands[2])"
19941 [(parallel [(set (match_dup 0)
19942 (match_op_dup 1
19943 [(and:SI
19944 (zero_extract:SI
19945 (match_dup 2)
19946 (const_int 8)
19947 (const_int 8))
19948 (match_dup 3))
19949 (const_int 0)]))
19950 (set (zero_extract:SI (match_dup 2)
19951 (const_int 8)
19952 (const_int 8))
19953 (and:SI
19954 (zero_extract:SI
19955 (match_dup 2)
19956 (const_int 8)
19957 (const_int 8))
19958 (match_dup 3)))])]
19959 "")
19960
19961 ;; Don't do logical operations with memory inputs.
19962 (define_peephole2
19963 [(match_scratch:SI 2 "r")
19964 (parallel [(set (match_operand:SI 0 "register_operand" "")
19965 (match_operator:SI 3 "arith_or_logical_operator"
19966 [(match_dup 0)
19967 (match_operand:SI 1 "memory_operand" "")]))
19968 (clobber (reg:CC FLAGS_REG))])]
19969 "! optimize_size && ! TARGET_READ_MODIFY"
19970 [(set (match_dup 2) (match_dup 1))
19971 (parallel [(set (match_dup 0)
19972 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19973 (clobber (reg:CC FLAGS_REG))])]
19974 "")
19975
19976 (define_peephole2
19977 [(match_scratch:SI 2 "r")
19978 (parallel [(set (match_operand:SI 0 "register_operand" "")
19979 (match_operator:SI 3 "arith_or_logical_operator"
19980 [(match_operand:SI 1 "memory_operand" "")
19981 (match_dup 0)]))
19982 (clobber (reg:CC FLAGS_REG))])]
19983 "! optimize_size && ! TARGET_READ_MODIFY"
19984 [(set (match_dup 2) (match_dup 1))
19985 (parallel [(set (match_dup 0)
19986 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19987 (clobber (reg:CC FLAGS_REG))])]
19988 "")
19989
19990 ; Don't do logical operations with memory outputs
19991 ;
19992 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19993 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19994 ; the same decoder scheduling characteristics as the original.
19995
19996 (define_peephole2
19997 [(match_scratch:SI 2 "r")
19998 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19999 (match_operator:SI 3 "arith_or_logical_operator"
20000 [(match_dup 0)
20001 (match_operand:SI 1 "nonmemory_operand" "")]))
20002 (clobber (reg:CC FLAGS_REG))])]
20003 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20004 [(set (match_dup 2) (match_dup 0))
20005 (parallel [(set (match_dup 2)
20006 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20007 (clobber (reg:CC FLAGS_REG))])
20008 (set (match_dup 0) (match_dup 2))]
20009 "")
20010
20011 (define_peephole2
20012 [(match_scratch:SI 2 "r")
20013 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20014 (match_operator:SI 3 "arith_or_logical_operator"
20015 [(match_operand:SI 1 "nonmemory_operand" "")
20016 (match_dup 0)]))
20017 (clobber (reg:CC FLAGS_REG))])]
20018 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20019 [(set (match_dup 2) (match_dup 0))
20020 (parallel [(set (match_dup 2)
20021 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20022 (clobber (reg:CC FLAGS_REG))])
20023 (set (match_dup 0) (match_dup 2))]
20024 "")
20025
20026 ;; Attempt to always use XOR for zeroing registers.
20027 (define_peephole2
20028 [(set (match_operand 0 "register_operand" "")
20029 (match_operand 1 "const0_operand" ""))]
20030 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20031 && (! TARGET_USE_MOV0 || optimize_size)
20032 && GENERAL_REG_P (operands[0])
20033 && peep2_regno_dead_p (0, FLAGS_REG)"
20034 [(parallel [(set (match_dup 0) (const_int 0))
20035 (clobber (reg:CC FLAGS_REG))])]
20036 {
20037 operands[0] = gen_lowpart (word_mode, operands[0]);
20038 })
20039
20040 (define_peephole2
20041 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20042 (const_int 0))]
20043 "(GET_MODE (operands[0]) == QImode
20044 || GET_MODE (operands[0]) == HImode)
20045 && (! TARGET_USE_MOV0 || optimize_size)
20046 && peep2_regno_dead_p (0, FLAGS_REG)"
20047 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20048 (clobber (reg:CC FLAGS_REG))])])
20049
20050 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20051 (define_peephole2
20052 [(set (match_operand 0 "register_operand" "")
20053 (const_int -1))]
20054 "(GET_MODE (operands[0]) == HImode
20055 || GET_MODE (operands[0]) == SImode
20056 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20057 && (optimize_size || TARGET_PENTIUM)
20058 && peep2_regno_dead_p (0, FLAGS_REG)"
20059 [(parallel [(set (match_dup 0) (const_int -1))
20060 (clobber (reg:CC FLAGS_REG))])]
20061 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20062 operands[0]);")
20063
20064 ;; Attempt to convert simple leas to adds. These can be created by
20065 ;; move expanders.
20066 (define_peephole2
20067 [(set (match_operand:SI 0 "register_operand" "")
20068 (plus:SI (match_dup 0)
20069 (match_operand:SI 1 "nonmemory_operand" "")))]
20070 "peep2_regno_dead_p (0, FLAGS_REG)"
20071 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20072 (clobber (reg:CC FLAGS_REG))])]
20073 "")
20074
20075 (define_peephole2
20076 [(set (match_operand:SI 0 "register_operand" "")
20077 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20078 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20079 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20080 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20081 (clobber (reg:CC FLAGS_REG))])]
20082 "operands[2] = gen_lowpart (SImode, operands[2]);")
20083
20084 (define_peephole2
20085 [(set (match_operand:DI 0 "register_operand" "")
20086 (plus:DI (match_dup 0)
20087 (match_operand:DI 1 "x86_64_general_operand" "")))]
20088 "peep2_regno_dead_p (0, FLAGS_REG)"
20089 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20090 (clobber (reg:CC FLAGS_REG))])]
20091 "")
20092
20093 (define_peephole2
20094 [(set (match_operand:SI 0 "register_operand" "")
20095 (mult:SI (match_dup 0)
20096 (match_operand:SI 1 "const_int_operand" "")))]
20097 "exact_log2 (INTVAL (operands[1])) >= 0
20098 && peep2_regno_dead_p (0, FLAGS_REG)"
20099 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20100 (clobber (reg:CC FLAGS_REG))])]
20101 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20102
20103 (define_peephole2
20104 [(set (match_operand:DI 0 "register_operand" "")
20105 (mult:DI (match_dup 0)
20106 (match_operand:DI 1 "const_int_operand" "")))]
20107 "exact_log2 (INTVAL (operands[1])) >= 0
20108 && peep2_regno_dead_p (0, FLAGS_REG)"
20109 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20110 (clobber (reg:CC FLAGS_REG))])]
20111 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20112
20113 (define_peephole2
20114 [(set (match_operand:SI 0 "register_operand" "")
20115 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20116 (match_operand:DI 2 "const_int_operand" "")) 0))]
20117 "exact_log2 (INTVAL (operands[2])) >= 0
20118 && REGNO (operands[0]) == REGNO (operands[1])
20119 && peep2_regno_dead_p (0, FLAGS_REG)"
20120 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20121 (clobber (reg:CC FLAGS_REG))])]
20122 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20123
20124 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20125 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20126 ;; many CPUs it is also faster, since special hardware to avoid esp
20127 ;; dependencies is present.
20128
20129 ;; While some of these conversions may be done using splitters, we use peepholes
20130 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20131
20132 ;; Convert prologue esp subtractions to push.
20133 ;; We need register to push. In order to keep verify_flow_info happy we have
20134 ;; two choices
20135 ;; - use scratch and clobber it in order to avoid dependencies
20136 ;; - use already live register
20137 ;; We can't use the second way right now, since there is no reliable way how to
20138 ;; verify that given register is live. First choice will also most likely in
20139 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20140 ;; call clobbered registers are dead. We may want to use base pointer as an
20141 ;; alternative when no register is available later.
20142
20143 (define_peephole2
20144 [(match_scratch:SI 0 "r")
20145 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20146 (clobber (reg:CC FLAGS_REG))
20147 (clobber (mem:BLK (scratch)))])]
20148 "optimize_size || !TARGET_SUB_ESP_4"
20149 [(clobber (match_dup 0))
20150 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20151 (clobber (mem:BLK (scratch)))])])
20152
20153 (define_peephole2
20154 [(match_scratch:SI 0 "r")
20155 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20156 (clobber (reg:CC FLAGS_REG))
20157 (clobber (mem:BLK (scratch)))])]
20158 "optimize_size || !TARGET_SUB_ESP_8"
20159 [(clobber (match_dup 0))
20160 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20161 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20162 (clobber (mem:BLK (scratch)))])])
20163
20164 ;; Convert esp subtractions to push.
20165 (define_peephole2
20166 [(match_scratch:SI 0 "r")
20167 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20168 (clobber (reg:CC FLAGS_REG))])]
20169 "optimize_size || !TARGET_SUB_ESP_4"
20170 [(clobber (match_dup 0))
20171 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20172
20173 (define_peephole2
20174 [(match_scratch:SI 0 "r")
20175 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20176 (clobber (reg:CC FLAGS_REG))])]
20177 "optimize_size || !TARGET_SUB_ESP_8"
20178 [(clobber (match_dup 0))
20179 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20180 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20181
20182 ;; Convert epilogue deallocator to pop.
20183 (define_peephole2
20184 [(match_scratch:SI 0 "r")
20185 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20186 (clobber (reg:CC FLAGS_REG))
20187 (clobber (mem:BLK (scratch)))])]
20188 "optimize_size || !TARGET_ADD_ESP_4"
20189 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20190 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20191 (clobber (mem:BLK (scratch)))])]
20192 "")
20193
20194 ;; Two pops case is tricky, since pop causes dependency on destination register.
20195 ;; We use two registers if available.
20196 (define_peephole2
20197 [(match_scratch:SI 0 "r")
20198 (match_scratch:SI 1 "r")
20199 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20200 (clobber (reg:CC FLAGS_REG))
20201 (clobber (mem:BLK (scratch)))])]
20202 "optimize_size || !TARGET_ADD_ESP_8"
20203 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20204 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20205 (clobber (mem:BLK (scratch)))])
20206 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20207 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20208 "")
20209
20210 (define_peephole2
20211 [(match_scratch:SI 0 "r")
20212 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20213 (clobber (reg:CC FLAGS_REG))
20214 (clobber (mem:BLK (scratch)))])]
20215 "optimize_size"
20216 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20217 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20218 (clobber (mem:BLK (scratch)))])
20219 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20220 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20221 "")
20222
20223 ;; Convert esp additions to pop.
20224 (define_peephole2
20225 [(match_scratch:SI 0 "r")
20226 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20227 (clobber (reg:CC FLAGS_REG))])]
20228 ""
20229 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20230 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20231 "")
20232
20233 ;; Two pops case is tricky, since pop causes dependency on destination register.
20234 ;; We use two registers if available.
20235 (define_peephole2
20236 [(match_scratch:SI 0 "r")
20237 (match_scratch:SI 1 "r")
20238 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20239 (clobber (reg:CC FLAGS_REG))])]
20240 ""
20241 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20242 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20243 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20244 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20245 "")
20246
20247 (define_peephole2
20248 [(match_scratch:SI 0 "r")
20249 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20250 (clobber (reg:CC FLAGS_REG))])]
20251 "optimize_size"
20252 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20253 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20254 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20255 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20256 "")
20257 \f
20258 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20259 ;; required and register dies. Similarly for 128 to plus -128.
20260 (define_peephole2
20261 [(set (match_operand 0 "flags_reg_operand" "")
20262 (match_operator 1 "compare_operator"
20263 [(match_operand 2 "register_operand" "")
20264 (match_operand 3 "const_int_operand" "")]))]
20265 "(INTVAL (operands[3]) == -1
20266 || INTVAL (operands[3]) == 1
20267 || INTVAL (operands[3]) == 128)
20268 && ix86_match_ccmode (insn, CCGCmode)
20269 && peep2_reg_dead_p (1, operands[2])"
20270 [(parallel [(set (match_dup 0)
20271 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20272 (clobber (match_dup 2))])]
20273 "")
20274 \f
20275 (define_peephole2
20276 [(match_scratch:DI 0 "r")
20277 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20278 (clobber (reg:CC FLAGS_REG))
20279 (clobber (mem:BLK (scratch)))])]
20280 "optimize_size || !TARGET_SUB_ESP_4"
20281 [(clobber (match_dup 0))
20282 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20283 (clobber (mem:BLK (scratch)))])])
20284
20285 (define_peephole2
20286 [(match_scratch:DI 0 "r")
20287 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20288 (clobber (reg:CC FLAGS_REG))
20289 (clobber (mem:BLK (scratch)))])]
20290 "optimize_size || !TARGET_SUB_ESP_8"
20291 [(clobber (match_dup 0))
20292 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20293 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20294 (clobber (mem:BLK (scratch)))])])
20295
20296 ;; Convert esp subtractions to push.
20297 (define_peephole2
20298 [(match_scratch:DI 0 "r")
20299 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20300 (clobber (reg:CC FLAGS_REG))])]
20301 "optimize_size || !TARGET_SUB_ESP_4"
20302 [(clobber (match_dup 0))
20303 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20304
20305 (define_peephole2
20306 [(match_scratch:DI 0 "r")
20307 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20308 (clobber (reg:CC FLAGS_REG))])]
20309 "optimize_size || !TARGET_SUB_ESP_8"
20310 [(clobber (match_dup 0))
20311 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20312 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20313
20314 ;; Convert epilogue deallocator to pop.
20315 (define_peephole2
20316 [(match_scratch:DI 0 "r")
20317 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20318 (clobber (reg:CC FLAGS_REG))
20319 (clobber (mem:BLK (scratch)))])]
20320 "optimize_size || !TARGET_ADD_ESP_4"
20321 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20322 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20323 (clobber (mem:BLK (scratch)))])]
20324 "")
20325
20326 ;; Two pops case is tricky, since pop causes dependency on destination register.
20327 ;; We use two registers if available.
20328 (define_peephole2
20329 [(match_scratch:DI 0 "r")
20330 (match_scratch:DI 1 "r")
20331 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20332 (clobber (reg:CC FLAGS_REG))
20333 (clobber (mem:BLK (scratch)))])]
20334 "optimize_size || !TARGET_ADD_ESP_8"
20335 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20336 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20337 (clobber (mem:BLK (scratch)))])
20338 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20339 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20340 "")
20341
20342 (define_peephole2
20343 [(match_scratch:DI 0 "r")
20344 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20345 (clobber (reg:CC FLAGS_REG))
20346 (clobber (mem:BLK (scratch)))])]
20347 "optimize_size"
20348 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20349 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20350 (clobber (mem:BLK (scratch)))])
20351 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20352 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20353 "")
20354
20355 ;; Convert esp additions to pop.
20356 (define_peephole2
20357 [(match_scratch:DI 0 "r")
20358 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20359 (clobber (reg:CC FLAGS_REG))])]
20360 ""
20361 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20362 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20363 "")
20364
20365 ;; Two pops case is tricky, since pop causes dependency on destination register.
20366 ;; We use two registers if available.
20367 (define_peephole2
20368 [(match_scratch:DI 0 "r")
20369 (match_scratch:DI 1 "r")
20370 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20371 (clobber (reg:CC FLAGS_REG))])]
20372 ""
20373 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20374 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20375 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20376 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20377 "")
20378
20379 (define_peephole2
20380 [(match_scratch:DI 0 "r")
20381 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20382 (clobber (reg:CC FLAGS_REG))])]
20383 "optimize_size"
20384 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20385 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20386 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20387 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20388 "")
20389 \f
20390 ;; Convert imul by three, five and nine into lea
20391 (define_peephole2
20392 [(parallel
20393 [(set (match_operand:SI 0 "register_operand" "")
20394 (mult:SI (match_operand:SI 1 "register_operand" "")
20395 (match_operand:SI 2 "const_int_operand" "")))
20396 (clobber (reg:CC FLAGS_REG))])]
20397 "INTVAL (operands[2]) == 3
20398 || INTVAL (operands[2]) == 5
20399 || INTVAL (operands[2]) == 9"
20400 [(set (match_dup 0)
20401 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20402 (match_dup 1)))]
20403 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20404
20405 (define_peephole2
20406 [(parallel
20407 [(set (match_operand:SI 0 "register_operand" "")
20408 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20409 (match_operand:SI 2 "const_int_operand" "")))
20410 (clobber (reg:CC FLAGS_REG))])]
20411 "!optimize_size
20412 && (INTVAL (operands[2]) == 3
20413 || INTVAL (operands[2]) == 5
20414 || INTVAL (operands[2]) == 9)"
20415 [(set (match_dup 0) (match_dup 1))
20416 (set (match_dup 0)
20417 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20418 (match_dup 0)))]
20419 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20420
20421 (define_peephole2
20422 [(parallel
20423 [(set (match_operand:DI 0 "register_operand" "")
20424 (mult:DI (match_operand:DI 1 "register_operand" "")
20425 (match_operand:DI 2 "const_int_operand" "")))
20426 (clobber (reg:CC FLAGS_REG))])]
20427 "TARGET_64BIT
20428 && (INTVAL (operands[2]) == 3
20429 || INTVAL (operands[2]) == 5
20430 || INTVAL (operands[2]) == 9)"
20431 [(set (match_dup 0)
20432 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20433 (match_dup 1)))]
20434 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20435
20436 (define_peephole2
20437 [(parallel
20438 [(set (match_operand:DI 0 "register_operand" "")
20439 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20440 (match_operand:DI 2 "const_int_operand" "")))
20441 (clobber (reg:CC FLAGS_REG))])]
20442 "TARGET_64BIT
20443 && !optimize_size
20444 && (INTVAL (operands[2]) == 3
20445 || INTVAL (operands[2]) == 5
20446 || INTVAL (operands[2]) == 9)"
20447 [(set (match_dup 0) (match_dup 1))
20448 (set (match_dup 0)
20449 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20450 (match_dup 0)))]
20451 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20452
20453 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20454 ;; imul $32bit_imm, reg, reg is direct decoded.
20455 (define_peephole2
20456 [(match_scratch:DI 3 "r")
20457 (parallel [(set (match_operand:DI 0 "register_operand" "")
20458 (mult:DI (match_operand:DI 1 "memory_operand" "")
20459 (match_operand:DI 2 "immediate_operand" "")))
20460 (clobber (reg:CC FLAGS_REG))])]
20461 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20462 && !satisfies_constraint_K (operands[2])"
20463 [(set (match_dup 3) (match_dup 1))
20464 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20465 (clobber (reg:CC FLAGS_REG))])]
20466 "")
20467
20468 (define_peephole2
20469 [(match_scratch:SI 3 "r")
20470 (parallel [(set (match_operand:SI 0 "register_operand" "")
20471 (mult:SI (match_operand:SI 1 "memory_operand" "")
20472 (match_operand:SI 2 "immediate_operand" "")))
20473 (clobber (reg:CC FLAGS_REG))])]
20474 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20475 && !satisfies_constraint_K (operands[2])"
20476 [(set (match_dup 3) (match_dup 1))
20477 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20478 (clobber (reg:CC FLAGS_REG))])]
20479 "")
20480
20481 (define_peephole2
20482 [(match_scratch:SI 3 "r")
20483 (parallel [(set (match_operand:DI 0 "register_operand" "")
20484 (zero_extend:DI
20485 (mult:SI (match_operand:SI 1 "memory_operand" "")
20486 (match_operand:SI 2 "immediate_operand" ""))))
20487 (clobber (reg:CC FLAGS_REG))])]
20488 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20489 && !satisfies_constraint_K (operands[2])"
20490 [(set (match_dup 3) (match_dup 1))
20491 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20492 (clobber (reg:CC FLAGS_REG))])]
20493 "")
20494
20495 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20496 ;; Convert it into imul reg, reg
20497 ;; It would be better to force assembler to encode instruction using long
20498 ;; immediate, but there is apparently no way to do so.
20499 (define_peephole2
20500 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20501 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20502 (match_operand:DI 2 "const_int_operand" "")))
20503 (clobber (reg:CC FLAGS_REG))])
20504 (match_scratch:DI 3 "r")]
20505 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20506 && satisfies_constraint_K (operands[2])"
20507 [(set (match_dup 3) (match_dup 2))
20508 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20509 (clobber (reg:CC FLAGS_REG))])]
20510 {
20511 if (!rtx_equal_p (operands[0], operands[1]))
20512 emit_move_insn (operands[0], operands[1]);
20513 })
20514
20515 (define_peephole2
20516 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20517 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20518 (match_operand:SI 2 "const_int_operand" "")))
20519 (clobber (reg:CC FLAGS_REG))])
20520 (match_scratch:SI 3 "r")]
20521 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20522 && satisfies_constraint_K (operands[2])"
20523 [(set (match_dup 3) (match_dup 2))
20524 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20525 (clobber (reg:CC FLAGS_REG))])]
20526 {
20527 if (!rtx_equal_p (operands[0], operands[1]))
20528 emit_move_insn (operands[0], operands[1]);
20529 })
20530
20531 (define_peephole2
20532 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20533 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20534 (match_operand:HI 2 "immediate_operand" "")))
20535 (clobber (reg:CC FLAGS_REG))])
20536 (match_scratch:HI 3 "r")]
20537 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20538 [(set (match_dup 3) (match_dup 2))
20539 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20540 (clobber (reg:CC FLAGS_REG))])]
20541 {
20542 if (!rtx_equal_p (operands[0], operands[1]))
20543 emit_move_insn (operands[0], operands[1]);
20544 })
20545
20546 ;; After splitting up read-modify operations, array accesses with memory
20547 ;; operands might end up in form:
20548 ;; sall $2, %eax
20549 ;; movl 4(%esp), %edx
20550 ;; addl %edx, %eax
20551 ;; instead of pre-splitting:
20552 ;; sall $2, %eax
20553 ;; addl 4(%esp), %eax
20554 ;; Turn it into:
20555 ;; movl 4(%esp), %edx
20556 ;; leal (%edx,%eax,4), %eax
20557
20558 (define_peephole2
20559 [(parallel [(set (match_operand 0 "register_operand" "")
20560 (ashift (match_operand 1 "register_operand" "")
20561 (match_operand 2 "const_int_operand" "")))
20562 (clobber (reg:CC FLAGS_REG))])
20563 (set (match_operand 3 "register_operand")
20564 (match_operand 4 "x86_64_general_operand" ""))
20565 (parallel [(set (match_operand 5 "register_operand" "")
20566 (plus (match_operand 6 "register_operand" "")
20567 (match_operand 7 "register_operand" "")))
20568 (clobber (reg:CC FLAGS_REG))])]
20569 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20570 /* Validate MODE for lea. */
20571 && ((!TARGET_PARTIAL_REG_STALL
20572 && (GET_MODE (operands[0]) == QImode
20573 || GET_MODE (operands[0]) == HImode))
20574 || GET_MODE (operands[0]) == SImode
20575 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20576 /* We reorder load and the shift. */
20577 && !rtx_equal_p (operands[1], operands[3])
20578 && !reg_overlap_mentioned_p (operands[0], operands[4])
20579 /* Last PLUS must consist of operand 0 and 3. */
20580 && !rtx_equal_p (operands[0], operands[3])
20581 && (rtx_equal_p (operands[3], operands[6])
20582 || rtx_equal_p (operands[3], operands[7]))
20583 && (rtx_equal_p (operands[0], operands[6])
20584 || rtx_equal_p (operands[0], operands[7]))
20585 /* The intermediate operand 0 must die or be same as output. */
20586 && (rtx_equal_p (operands[0], operands[5])
20587 || peep2_reg_dead_p (3, operands[0]))"
20588 [(set (match_dup 3) (match_dup 4))
20589 (set (match_dup 0) (match_dup 1))]
20590 {
20591 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20592 int scale = 1 << INTVAL (operands[2]);
20593 rtx index = gen_lowpart (Pmode, operands[1]);
20594 rtx base = gen_lowpart (Pmode, operands[3]);
20595 rtx dest = gen_lowpart (mode, operands[5]);
20596
20597 operands[1] = gen_rtx_PLUS (Pmode, base,
20598 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20599 if (mode != Pmode)
20600 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20601 operands[0] = dest;
20602 })
20603 \f
20604 ;; Call-value patterns last so that the wildcard operand does not
20605 ;; disrupt insn-recog's switch tables.
20606
20607 (define_insn "*call_value_pop_0"
20608 [(set (match_operand 0 "" "")
20609 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20610 (match_operand:SI 2 "" "")))
20611 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20612 (match_operand:SI 3 "immediate_operand" "")))]
20613 "!TARGET_64BIT"
20614 {
20615 if (SIBLING_CALL_P (insn))
20616 return "jmp\t%P1";
20617 else
20618 return "call\t%P1";
20619 }
20620 [(set_attr "type" "callv")])
20621
20622 (define_insn "*call_value_pop_1"
20623 [(set (match_operand 0 "" "")
20624 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20625 (match_operand:SI 2 "" "")))
20626 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20627 (match_operand:SI 3 "immediate_operand" "i")))]
20628 "!TARGET_64BIT"
20629 {
20630 if (constant_call_address_operand (operands[1], Pmode))
20631 {
20632 if (SIBLING_CALL_P (insn))
20633 return "jmp\t%P1";
20634 else
20635 return "call\t%P1";
20636 }
20637 if (SIBLING_CALL_P (insn))
20638 return "jmp\t%A1";
20639 else
20640 return "call\t%A1";
20641 }
20642 [(set_attr "type" "callv")])
20643
20644 (define_insn "*call_value_0"
20645 [(set (match_operand 0 "" "")
20646 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20647 (match_operand:SI 2 "" "")))]
20648 "!TARGET_64BIT"
20649 {
20650 if (SIBLING_CALL_P (insn))
20651 return "jmp\t%P1";
20652 else
20653 return "call\t%P1";
20654 }
20655 [(set_attr "type" "callv")])
20656
20657 (define_insn "*call_value_0_rex64"
20658 [(set (match_operand 0 "" "")
20659 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20660 (match_operand:DI 2 "const_int_operand" "")))]
20661 "TARGET_64BIT"
20662 {
20663 if (SIBLING_CALL_P (insn))
20664 return "jmp\t%P1";
20665 else
20666 return "call\t%P1";
20667 }
20668 [(set_attr "type" "callv")])
20669
20670 (define_insn "*call_value_1"
20671 [(set (match_operand 0 "" "")
20672 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20673 (match_operand:SI 2 "" "")))]
20674 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20675 {
20676 if (constant_call_address_operand (operands[1], Pmode))
20677 return "call\t%P1";
20678 return "call\t%A1";
20679 }
20680 [(set_attr "type" "callv")])
20681
20682 (define_insn "*sibcall_value_1"
20683 [(set (match_operand 0 "" "")
20684 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20685 (match_operand:SI 2 "" "")))]
20686 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20687 {
20688 if (constant_call_address_operand (operands[1], Pmode))
20689 return "jmp\t%P1";
20690 return "jmp\t%A1";
20691 }
20692 [(set_attr "type" "callv")])
20693
20694 (define_insn "*call_value_1_rex64"
20695 [(set (match_operand 0 "" "")
20696 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20697 (match_operand:DI 2 "" "")))]
20698 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20699 {
20700 if (constant_call_address_operand (operands[1], Pmode))
20701 return "call\t%P1";
20702 return "call\t%A1";
20703 }
20704 [(set_attr "type" "callv")])
20705
20706 (define_insn "*sibcall_value_1_rex64"
20707 [(set (match_operand 0 "" "")
20708 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20709 (match_operand:DI 2 "" "")))]
20710 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20711 "jmp\t%P1"
20712 [(set_attr "type" "callv")])
20713
20714 (define_insn "*sibcall_value_1_rex64_v"
20715 [(set (match_operand 0 "" "")
20716 (call (mem:QI (reg:DI R11_REG))
20717 (match_operand:DI 1 "" "")))]
20718 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20719 "jmp\t*%%r11"
20720 [(set_attr "type" "callv")])
20721 \f
20722 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20723 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20724 ;; caught for use by garbage collectors and the like. Using an insn that
20725 ;; maps to SIGILL makes it more likely the program will rightfully die.
20726 ;; Keeping with tradition, "6" is in honor of #UD.
20727 (define_insn "trap"
20728 [(trap_if (const_int 1) (const_int 6))]
20729 ""
20730 { return ASM_SHORT "0x0b0f"; }
20731 [(set_attr "length" "2")])
20732
20733 (define_expand "sse_prologue_save"
20734 [(parallel [(set (match_operand:BLK 0 "" "")
20735 (unspec:BLK [(reg:DI 22)
20736 (reg:DI 23)
20737 (reg:DI 24)
20738 (reg:DI 25)
20739 (reg:DI 26)
20740 (reg:DI 27)
20741 (reg:DI 28)
20742 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20743 (use (match_operand:DI 1 "register_operand" ""))
20744 (use (match_operand:DI 2 "immediate_operand" ""))
20745 (use (label_ref:DI (match_operand 3 "" "")))])]
20746 "TARGET_64BIT"
20747 "")
20748
20749 (define_insn "*sse_prologue_save_insn"
20750 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20751 (match_operand:DI 4 "const_int_operand" "n")))
20752 (unspec:BLK [(reg:DI 22)
20753 (reg:DI 23)
20754 (reg:DI 24)
20755 (reg:DI 25)
20756 (reg:DI 26)
20757 (reg:DI 27)
20758 (reg:DI 28)
20759 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20760 (use (match_operand:DI 1 "register_operand" "r"))
20761 (use (match_operand:DI 2 "const_int_operand" "i"))
20762 (use (label_ref:DI (match_operand 3 "" "X")))]
20763 "TARGET_64BIT
20764 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20765 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20766 "*
20767 {
20768 int i;
20769 operands[0] = gen_rtx_MEM (Pmode,
20770 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20771 output_asm_insn (\"jmp\\t%A1\", operands);
20772 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20773 {
20774 operands[4] = adjust_address (operands[0], DImode, i*16);
20775 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20776 PUT_MODE (operands[4], TImode);
20777 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20778 output_asm_insn (\"rex\", operands);
20779 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20780 }
20781 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20782 CODE_LABEL_NUMBER (operands[3]));
20783 RET;
20784 }
20785 "
20786 [(set_attr "type" "other")
20787 (set_attr "length_immediate" "0")
20788 (set_attr "length_address" "0")
20789 (set_attr "length" "135")
20790 (set_attr "memory" "store")
20791 (set_attr "modrm" "0")
20792 (set_attr "mode" "DI")])
20793
20794 (define_expand "prefetch"
20795 [(prefetch (match_operand 0 "address_operand" "")
20796 (match_operand:SI 1 "const_int_operand" "")
20797 (match_operand:SI 2 "const_int_operand" ""))]
20798 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20799 {
20800 int rw = INTVAL (operands[1]);
20801 int locality = INTVAL (operands[2]);
20802
20803 gcc_assert (rw == 0 || rw == 1);
20804 gcc_assert (locality >= 0 && locality <= 3);
20805 gcc_assert (GET_MODE (operands[0]) == Pmode
20806 || GET_MODE (operands[0]) == VOIDmode);
20807
20808 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20809 supported by SSE counterpart or the SSE prefetch is not available
20810 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20811 of locality. */
20812 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20813 operands[2] = GEN_INT (3);
20814 else
20815 operands[1] = const0_rtx;
20816 })
20817
20818 (define_insn "*prefetch_sse"
20819 [(prefetch (match_operand:SI 0 "address_operand" "p")
20820 (const_int 0)
20821 (match_operand:SI 1 "const_int_operand" ""))]
20822 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20823 {
20824 static const char * const patterns[4] = {
20825 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20826 };
20827
20828 int locality = INTVAL (operands[1]);
20829 gcc_assert (locality >= 0 && locality <= 3);
20830
20831 return patterns[locality];
20832 }
20833 [(set_attr "type" "sse")
20834 (set_attr "memory" "none")])
20835
20836 (define_insn "*prefetch_sse_rex"
20837 [(prefetch (match_operand:DI 0 "address_operand" "p")
20838 (const_int 0)
20839 (match_operand:SI 1 "const_int_operand" ""))]
20840 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20841 {
20842 static const char * const patterns[4] = {
20843 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20844 };
20845
20846 int locality = INTVAL (operands[1]);
20847 gcc_assert (locality >= 0 && locality <= 3);
20848
20849 return patterns[locality];
20850 }
20851 [(set_attr "type" "sse")
20852 (set_attr "memory" "none")])
20853
20854 (define_insn "*prefetch_3dnow"
20855 [(prefetch (match_operand:SI 0 "address_operand" "p")
20856 (match_operand:SI 1 "const_int_operand" "n")
20857 (const_int 3))]
20858 "TARGET_3DNOW && !TARGET_64BIT"
20859 {
20860 if (INTVAL (operands[1]) == 0)
20861 return "prefetch\t%a0";
20862 else
20863 return "prefetchw\t%a0";
20864 }
20865 [(set_attr "type" "mmx")
20866 (set_attr "memory" "none")])
20867
20868 (define_insn "*prefetch_3dnow_rex"
20869 [(prefetch (match_operand:DI 0 "address_operand" "p")
20870 (match_operand:SI 1 "const_int_operand" "n")
20871 (const_int 3))]
20872 "TARGET_3DNOW && TARGET_64BIT"
20873 {
20874 if (INTVAL (operands[1]) == 0)
20875 return "prefetch\t%a0";
20876 else
20877 return "prefetchw\t%a0";
20878 }
20879 [(set_attr "type" "mmx")
20880 (set_attr "memory" "none")])
20881
20882 (define_expand "stack_protect_set"
20883 [(match_operand 0 "memory_operand" "")
20884 (match_operand 1 "memory_operand" "")]
20885 ""
20886 {
20887 #ifdef TARGET_THREAD_SSP_OFFSET
20888 if (TARGET_64BIT)
20889 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20890 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20891 else
20892 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20893 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20894 #else
20895 if (TARGET_64BIT)
20896 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20897 else
20898 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20899 #endif
20900 DONE;
20901 })
20902
20903 (define_insn "stack_protect_set_si"
20904 [(set (match_operand:SI 0 "memory_operand" "=m")
20905 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20906 (set (match_scratch:SI 2 "=&r") (const_int 0))
20907 (clobber (reg:CC FLAGS_REG))]
20908 ""
20909 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20910 [(set_attr "type" "multi")])
20911
20912 (define_insn "stack_protect_set_di"
20913 [(set (match_operand:DI 0 "memory_operand" "=m")
20914 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20915 (set (match_scratch:DI 2 "=&r") (const_int 0))
20916 (clobber (reg:CC FLAGS_REG))]
20917 "TARGET_64BIT"
20918 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20919 [(set_attr "type" "multi")])
20920
20921 (define_insn "stack_tls_protect_set_si"
20922 [(set (match_operand:SI 0 "memory_operand" "=m")
20923 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20924 (set (match_scratch:SI 2 "=&r") (const_int 0))
20925 (clobber (reg:CC FLAGS_REG))]
20926 ""
20927 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20928 [(set_attr "type" "multi")])
20929
20930 (define_insn "stack_tls_protect_set_di"
20931 [(set (match_operand:DI 0 "memory_operand" "=m")
20932 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20933 (set (match_scratch:DI 2 "=&r") (const_int 0))
20934 (clobber (reg:CC FLAGS_REG))]
20935 "TARGET_64BIT"
20936 {
20937 /* The kernel uses a different segment register for performance reasons; a
20938 system call would not have to trash the userspace segment register,
20939 which would be expensive */
20940 if (ix86_cmodel != CM_KERNEL)
20941 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20942 else
20943 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20944 }
20945 [(set_attr "type" "multi")])
20946
20947 (define_expand "stack_protect_test"
20948 [(match_operand 0 "memory_operand" "")
20949 (match_operand 1 "memory_operand" "")
20950 (match_operand 2 "" "")]
20951 ""
20952 {
20953 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20954 ix86_compare_op0 = operands[0];
20955 ix86_compare_op1 = operands[1];
20956 ix86_compare_emitted = flags;
20957
20958 #ifdef TARGET_THREAD_SSP_OFFSET
20959 if (TARGET_64BIT)
20960 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20961 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20962 else
20963 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20964 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20965 #else
20966 if (TARGET_64BIT)
20967 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20968 else
20969 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20970 #endif
20971 emit_jump_insn (gen_beq (operands[2]));
20972 DONE;
20973 })
20974
20975 (define_insn "stack_protect_test_si"
20976 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20977 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20978 (match_operand:SI 2 "memory_operand" "m")]
20979 UNSPEC_SP_TEST))
20980 (clobber (match_scratch:SI 3 "=&r"))]
20981 ""
20982 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20983 [(set_attr "type" "multi")])
20984
20985 (define_insn "stack_protect_test_di"
20986 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20987 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20988 (match_operand:DI 2 "memory_operand" "m")]
20989 UNSPEC_SP_TEST))
20990 (clobber (match_scratch:DI 3 "=&r"))]
20991 "TARGET_64BIT"
20992 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20993 [(set_attr "type" "multi")])
20994
20995 (define_insn "stack_tls_protect_test_si"
20996 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20997 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20998 (match_operand:SI 2 "const_int_operand" "i")]
20999 UNSPEC_SP_TLS_TEST))
21000 (clobber (match_scratch:SI 3 "=r"))]
21001 ""
21002 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21003 [(set_attr "type" "multi")])
21004
21005 (define_insn "stack_tls_protect_test_di"
21006 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21007 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21008 (match_operand:DI 2 "const_int_operand" "i")]
21009 UNSPEC_SP_TLS_TEST))
21010 (clobber (match_scratch:DI 3 "=r"))]
21011 "TARGET_64BIT"
21012 {
21013 /* The kernel uses a different segment register for performance reasons; a
21014 system call would not have to trash the userspace segment register,
21015 which would be expensive */
21016 if (ix86_cmodel != CM_KERNEL)
21017 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21018 else
21019 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21020 }
21021 [(set_attr "type" "multi")])
21022
21023 (include "mmx.md")
21024 (include "sse.md")
21025 (include "sync.md")