invoke.texi (core2): Add item.
[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,core2,generic32,generic64"
198 (const (symbol_ref "ix86_tune")))
199
200 ;; A basic instruction type. Refinements due to arguments to be
201 ;; provided in other attributes.
202 (define_attr "type"
203 "other,multi,
204 alu,alu1,negnot,imov,imovx,lea,
205 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
206 icmp,test,ibr,setcc,icmov,
207 push,pop,call,callv,leave,
208 str,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 || standard_80387_constant_p (operands[1])
2791 || GET_CODE (operands[1]) != CONST_DOUBLE
2792 || memory_operand (operands[0], XFmode))"
2793 {
2794 switch (which_alternative)
2795 {
2796 case 0:
2797 return output_387_reg_move (insn, operands);
2798
2799 case 1:
2800 /* There is no non-popping store to memory for XFmode. So if
2801 we need one, follow the store with a load. */
2802 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2803 return "fstp%z0\t%y0\;fld%z0\t%y0";
2804 else
2805 return "fstp%z0\t%y0";
2806
2807 case 2:
2808 return standard_80387_constant_opcode (operands[1]);
2809
2810 case 3: case 4:
2811 return "#";
2812 default:
2813 gcc_unreachable ();
2814 }
2815 }
2816 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2817 (set_attr "mode" "XF,XF,XF,SI,SI")])
2818
2819 (define_insn "*movxf_integer"
2820 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2821 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2822 "!optimize_size
2823 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2824 && (reload_in_progress || reload_completed
2825 || standard_80387_constant_p (operands[1])
2826 || GET_CODE (operands[1]) != CONST_DOUBLE
2827 || memory_operand (operands[0], XFmode))"
2828 {
2829 switch (which_alternative)
2830 {
2831 case 0:
2832 return output_387_reg_move (insn, operands);
2833
2834 case 1:
2835 /* There is no non-popping store to memory for XFmode. So if
2836 we need one, follow the store with a load. */
2837 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2838 return "fstp%z0\t%y0\;fld%z0\t%y0";
2839 else
2840 return "fstp%z0\t%y0";
2841
2842 case 2:
2843 return standard_80387_constant_opcode (operands[1]);
2844
2845 case 3: case 4:
2846 return "#";
2847
2848 default:
2849 gcc_unreachable ();
2850 }
2851 }
2852 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2853 (set_attr "mode" "XF,XF,XF,SI,SI")])
2854
2855 (define_split
2856 [(set (match_operand 0 "nonimmediate_operand" "")
2857 (match_operand 1 "general_operand" ""))]
2858 "reload_completed
2859 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2860 && GET_MODE (operands[0]) == XFmode
2861 && ! (ANY_FP_REG_P (operands[0]) ||
2862 (GET_CODE (operands[0]) == SUBREG
2863 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2864 && ! (ANY_FP_REG_P (operands[1]) ||
2865 (GET_CODE (operands[1]) == SUBREG
2866 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2867 [(const_int 0)]
2868 "ix86_split_long_move (operands); DONE;")
2869
2870 (define_split
2871 [(set (match_operand 0 "register_operand" "")
2872 (match_operand 1 "memory_operand" ""))]
2873 "reload_completed
2874 && GET_CODE (operands[1]) == MEM
2875 && (GET_MODE (operands[0]) == XFmode
2876 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2877 && constant_pool_reference_p (operands[1])"
2878 [(set (match_dup 0) (match_dup 1))]
2879 {
2880 rtx c = avoid_constant_pool_reference (operands[1]);
2881 rtx r = operands[0];
2882
2883 if (GET_CODE (r) == SUBREG)
2884 r = SUBREG_REG (r);
2885
2886 if (SSE_REG_P (r))
2887 {
2888 if (!standard_sse_constant_p (c))
2889 FAIL;
2890 }
2891 else if (FP_REG_P (r))
2892 {
2893 if (!standard_80387_constant_p (c))
2894 FAIL;
2895 }
2896 else if (MMX_REG_P (r))
2897 FAIL;
2898
2899 operands[1] = c;
2900 })
2901
2902 (define_insn "swapxf"
2903 [(set (match_operand:XF 0 "register_operand" "+f")
2904 (match_operand:XF 1 "register_operand" "+f"))
2905 (set (match_dup 1)
2906 (match_dup 0))]
2907 "TARGET_80387"
2908 {
2909 if (STACK_TOP_P (operands[0]))
2910 return "fxch\t%1";
2911 else
2912 return "fxch\t%0";
2913 }
2914 [(set_attr "type" "fxch")
2915 (set_attr "mode" "XF")])
2916
2917 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2918 (define_split
2919 [(set (match_operand:X87MODEF 0 "register_operand" "")
2920 (match_operand:X87MODEF 1 "immediate_operand" ""))]
2921 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2922 && (standard_80387_constant_p (operands[1]) == 8
2923 || standard_80387_constant_p (operands[1]) == 9)"
2924 [(set (match_dup 0)(match_dup 1))
2925 (set (match_dup 0)
2926 (neg:X87MODEF (match_dup 0)))]
2927 {
2928 REAL_VALUE_TYPE r;
2929
2930 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2931 if (real_isnegzero (&r))
2932 operands[1] = CONST0_RTX (<MODE>mode);
2933 else
2934 operands[1] = CONST1_RTX (<MODE>mode);
2935 })
2936
2937 (define_expand "movtf"
2938 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2939 (match_operand:TF 1 "nonimmediate_operand" ""))]
2940 "TARGET_64BIT"
2941 {
2942 ix86_expand_move (TFmode, operands);
2943 DONE;
2944 })
2945
2946 (define_insn "*movtf_internal"
2947 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2948 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2949 "TARGET_64BIT
2950 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2951 {
2952 switch (which_alternative)
2953 {
2954 case 0:
2955 case 1:
2956 return "#";
2957 case 2:
2958 if (get_attr_mode (insn) == MODE_V4SF)
2959 return "xorps\t%0, %0";
2960 else
2961 return "pxor\t%0, %0";
2962 case 3:
2963 case 4:
2964 if (get_attr_mode (insn) == MODE_V4SF)
2965 return "movaps\t{%1, %0|%0, %1}";
2966 else
2967 return "movdqa\t{%1, %0|%0, %1}";
2968 default:
2969 gcc_unreachable ();
2970 }
2971 }
2972 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2973 (set (attr "mode")
2974 (cond [(eq_attr "alternative" "2,3")
2975 (if_then_else
2976 (ne (symbol_ref "optimize_size")
2977 (const_int 0))
2978 (const_string "V4SF")
2979 (const_string "TI"))
2980 (eq_attr "alternative" "4")
2981 (if_then_else
2982 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2983 (const_int 0))
2984 (ne (symbol_ref "optimize_size")
2985 (const_int 0)))
2986 (const_string "V4SF")
2987 (const_string "TI"))]
2988 (const_string "DI")))])
2989
2990 (define_split
2991 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2992 (match_operand:TF 1 "general_operand" ""))]
2993 "reload_completed && !SSE_REG_P (operands[0])
2994 && !SSE_REG_P (operands[1])"
2995 [(const_int 0)]
2996 "ix86_split_long_move (operands); DONE;")
2997 \f
2998 ;; Zero extension instructions
2999
3000 (define_expand "zero_extendhisi2"
3001 [(set (match_operand:SI 0 "register_operand" "")
3002 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3003 ""
3004 {
3005 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3006 {
3007 operands[1] = force_reg (HImode, operands[1]);
3008 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3009 DONE;
3010 }
3011 })
3012
3013 (define_insn "zero_extendhisi2_and"
3014 [(set (match_operand:SI 0 "register_operand" "=r")
3015 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3016 (clobber (reg:CC FLAGS_REG))]
3017 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3018 "#"
3019 [(set_attr "type" "alu1")
3020 (set_attr "mode" "SI")])
3021
3022 (define_split
3023 [(set (match_operand:SI 0 "register_operand" "")
3024 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3025 (clobber (reg:CC FLAGS_REG))]
3026 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3027 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3028 (clobber (reg:CC FLAGS_REG))])]
3029 "")
3030
3031 (define_insn "*zero_extendhisi2_movzwl"
3032 [(set (match_operand:SI 0 "register_operand" "=r")
3033 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3034 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3035 "movz{wl|x}\t{%1, %0|%0, %1}"
3036 [(set_attr "type" "imovx")
3037 (set_attr "mode" "SI")])
3038
3039 (define_expand "zero_extendqihi2"
3040 [(parallel
3041 [(set (match_operand:HI 0 "register_operand" "")
3042 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3043 (clobber (reg:CC FLAGS_REG))])]
3044 ""
3045 "")
3046
3047 (define_insn "*zero_extendqihi2_and"
3048 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3049 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3050 (clobber (reg:CC FLAGS_REG))]
3051 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3052 "#"
3053 [(set_attr "type" "alu1")
3054 (set_attr "mode" "HI")])
3055
3056 (define_insn "*zero_extendqihi2_movzbw_and"
3057 [(set (match_operand:HI 0 "register_operand" "=r,r")
3058 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3059 (clobber (reg:CC FLAGS_REG))]
3060 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3061 "#"
3062 [(set_attr "type" "imovx,alu1")
3063 (set_attr "mode" "HI")])
3064
3065 ; zero extend to SImode here to avoid partial register stalls
3066 (define_insn "*zero_extendqihi2_movzbl"
3067 [(set (match_operand:HI 0 "register_operand" "=r")
3068 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3069 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3070 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3071 [(set_attr "type" "imovx")
3072 (set_attr "mode" "SI")])
3073
3074 ;; For the movzbw case strip only the clobber
3075 (define_split
3076 [(set (match_operand:HI 0 "register_operand" "")
3077 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3078 (clobber (reg:CC FLAGS_REG))]
3079 "reload_completed
3080 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3081 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3082 [(set (match_operand:HI 0 "register_operand" "")
3083 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3084
3085 ;; When source and destination does not overlap, clear destination
3086 ;; first and then do the movb
3087 (define_split
3088 [(set (match_operand:HI 0 "register_operand" "")
3089 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3090 (clobber (reg:CC FLAGS_REG))]
3091 "reload_completed
3092 && ANY_QI_REG_P (operands[0])
3093 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3094 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3095 [(set (match_dup 0) (const_int 0))
3096 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3097 "operands[2] = gen_lowpart (QImode, operands[0]);")
3098
3099 ;; Rest is handled by single and.
3100 (define_split
3101 [(set (match_operand:HI 0 "register_operand" "")
3102 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3103 (clobber (reg:CC FLAGS_REG))]
3104 "reload_completed
3105 && true_regnum (operands[0]) == true_regnum (operands[1])"
3106 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3107 (clobber (reg:CC FLAGS_REG))])]
3108 "")
3109
3110 (define_expand "zero_extendqisi2"
3111 [(parallel
3112 [(set (match_operand:SI 0 "register_operand" "")
3113 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3114 (clobber (reg:CC FLAGS_REG))])]
3115 ""
3116 "")
3117
3118 (define_insn "*zero_extendqisi2_and"
3119 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3120 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3121 (clobber (reg:CC FLAGS_REG))]
3122 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3123 "#"
3124 [(set_attr "type" "alu1")
3125 (set_attr "mode" "SI")])
3126
3127 (define_insn "*zero_extendqisi2_movzbw_and"
3128 [(set (match_operand:SI 0 "register_operand" "=r,r")
3129 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3130 (clobber (reg:CC FLAGS_REG))]
3131 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3132 "#"
3133 [(set_attr "type" "imovx,alu1")
3134 (set_attr "mode" "SI")])
3135
3136 (define_insn "*zero_extendqisi2_movzbw"
3137 [(set (match_operand:SI 0 "register_operand" "=r")
3138 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3139 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3140 "movz{bl|x}\t{%1, %0|%0, %1}"
3141 [(set_attr "type" "imovx")
3142 (set_attr "mode" "SI")])
3143
3144 ;; For the movzbl case strip only the clobber
3145 (define_split
3146 [(set (match_operand:SI 0 "register_operand" "")
3147 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3148 (clobber (reg:CC FLAGS_REG))]
3149 "reload_completed
3150 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3151 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3152 [(set (match_dup 0)
3153 (zero_extend:SI (match_dup 1)))])
3154
3155 ;; When source and destination does not overlap, clear destination
3156 ;; first and then do the movb
3157 (define_split
3158 [(set (match_operand:SI 0 "register_operand" "")
3159 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3160 (clobber (reg:CC FLAGS_REG))]
3161 "reload_completed
3162 && ANY_QI_REG_P (operands[0])
3163 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3164 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3165 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3166 [(set (match_dup 0) (const_int 0))
3167 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3168 "operands[2] = gen_lowpart (QImode, operands[0]);")
3169
3170 ;; Rest is handled by single and.
3171 (define_split
3172 [(set (match_operand:SI 0 "register_operand" "")
3173 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3174 (clobber (reg:CC FLAGS_REG))]
3175 "reload_completed
3176 && true_regnum (operands[0]) == true_regnum (operands[1])"
3177 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3178 (clobber (reg:CC FLAGS_REG))])]
3179 "")
3180
3181 ;; %%% Kill me once multi-word ops are sane.
3182 (define_expand "zero_extendsidi2"
3183 [(set (match_operand:DI 0 "register_operand" "=r")
3184 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3185 ""
3186 "if (!TARGET_64BIT)
3187 {
3188 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3189 DONE;
3190 }
3191 ")
3192
3193 (define_insn "zero_extendsidi2_32"
3194 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3195 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3196 (clobber (reg:CC FLAGS_REG))]
3197 "!TARGET_64BIT"
3198 "@
3199 #
3200 #
3201 #
3202 movd\t{%1, %0|%0, %1}
3203 movd\t{%1, %0|%0, %1}"
3204 [(set_attr "mode" "SI,SI,SI,DI,TI")
3205 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3206
3207 (define_insn "zero_extendsidi2_rex64"
3208 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3209 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3210 "TARGET_64BIT"
3211 "@
3212 mov\t{%k1, %k0|%k0, %k1}
3213 #
3214 movd\t{%1, %0|%0, %1}
3215 movd\t{%1, %0|%0, %1}"
3216 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3217 (set_attr "mode" "SI,DI,SI,SI")])
3218
3219 (define_split
3220 [(set (match_operand:DI 0 "memory_operand" "")
3221 (zero_extend:DI (match_dup 0)))]
3222 "TARGET_64BIT"
3223 [(set (match_dup 4) (const_int 0))]
3224 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3225
3226 (define_split
3227 [(set (match_operand:DI 0 "register_operand" "")
3228 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3229 (clobber (reg:CC FLAGS_REG))]
3230 "!TARGET_64BIT && reload_completed
3231 && true_regnum (operands[0]) == true_regnum (operands[1])"
3232 [(set (match_dup 4) (const_int 0))]
3233 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3234
3235 (define_split
3236 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3237 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3238 (clobber (reg:CC FLAGS_REG))]
3239 "!TARGET_64BIT && reload_completed
3240 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3241 [(set (match_dup 3) (match_dup 1))
3242 (set (match_dup 4) (const_int 0))]
3243 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3244
3245 (define_insn "zero_extendhidi2"
3246 [(set (match_operand:DI 0 "register_operand" "=r")
3247 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3248 "TARGET_64BIT"
3249 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3250 [(set_attr "type" "imovx")
3251 (set_attr "mode" "DI")])
3252
3253 (define_insn "zero_extendqidi2"
3254 [(set (match_operand:DI 0 "register_operand" "=r")
3255 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3256 "TARGET_64BIT"
3257 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3258 [(set_attr "type" "imovx")
3259 (set_attr "mode" "DI")])
3260 \f
3261 ;; Sign extension instructions
3262
3263 (define_expand "extendsidi2"
3264 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3265 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3266 (clobber (reg:CC FLAGS_REG))
3267 (clobber (match_scratch:SI 2 ""))])]
3268 ""
3269 {
3270 if (TARGET_64BIT)
3271 {
3272 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3273 DONE;
3274 }
3275 })
3276
3277 (define_insn "*extendsidi2_1"
3278 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3279 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3280 (clobber (reg:CC FLAGS_REG))
3281 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3282 "!TARGET_64BIT"
3283 "#")
3284
3285 (define_insn "extendsidi2_rex64"
3286 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3287 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3288 "TARGET_64BIT"
3289 "@
3290 {cltq|cdqe}
3291 movs{lq|x}\t{%1,%0|%0, %1}"
3292 [(set_attr "type" "imovx")
3293 (set_attr "mode" "DI")
3294 (set_attr "prefix_0f" "0")
3295 (set_attr "modrm" "0,1")])
3296
3297 (define_insn "extendhidi2"
3298 [(set (match_operand:DI 0 "register_operand" "=r")
3299 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3300 "TARGET_64BIT"
3301 "movs{wq|x}\t{%1,%0|%0, %1}"
3302 [(set_attr "type" "imovx")
3303 (set_attr "mode" "DI")])
3304
3305 (define_insn "extendqidi2"
3306 [(set (match_operand:DI 0 "register_operand" "=r")
3307 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3308 "TARGET_64BIT"
3309 "movs{bq|x}\t{%1,%0|%0, %1}"
3310 [(set_attr "type" "imovx")
3311 (set_attr "mode" "DI")])
3312
3313 ;; Extend to memory case when source register does die.
3314 (define_split
3315 [(set (match_operand:DI 0 "memory_operand" "")
3316 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3317 (clobber (reg:CC FLAGS_REG))
3318 (clobber (match_operand:SI 2 "register_operand" ""))]
3319 "(reload_completed
3320 && dead_or_set_p (insn, operands[1])
3321 && !reg_mentioned_p (operands[1], operands[0]))"
3322 [(set (match_dup 3) (match_dup 1))
3323 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3324 (clobber (reg:CC FLAGS_REG))])
3325 (set (match_dup 4) (match_dup 1))]
3326 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3327
3328 ;; Extend to memory case when source register does not die.
3329 (define_split
3330 [(set (match_operand:DI 0 "memory_operand" "")
3331 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3332 (clobber (reg:CC FLAGS_REG))
3333 (clobber (match_operand:SI 2 "register_operand" ""))]
3334 "reload_completed"
3335 [(const_int 0)]
3336 {
3337 split_di (&operands[0], 1, &operands[3], &operands[4]);
3338
3339 emit_move_insn (operands[3], operands[1]);
3340
3341 /* Generate a cltd if possible and doing so it profitable. */
3342 if (true_regnum (operands[1]) == 0
3343 && true_regnum (operands[2]) == 1
3344 && (optimize_size || TARGET_USE_CLTD))
3345 {
3346 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3347 }
3348 else
3349 {
3350 emit_move_insn (operands[2], operands[1]);
3351 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3352 }
3353 emit_move_insn (operands[4], operands[2]);
3354 DONE;
3355 })
3356
3357 ;; Extend to register case. Optimize case where source and destination
3358 ;; registers match and cases where we can use cltd.
3359 (define_split
3360 [(set (match_operand:DI 0 "register_operand" "")
3361 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3362 (clobber (reg:CC FLAGS_REG))
3363 (clobber (match_scratch:SI 2 ""))]
3364 "reload_completed"
3365 [(const_int 0)]
3366 {
3367 split_di (&operands[0], 1, &operands[3], &operands[4]);
3368
3369 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3370 emit_move_insn (operands[3], operands[1]);
3371
3372 /* Generate a cltd if possible and doing so it profitable. */
3373 if (true_regnum (operands[3]) == 0
3374 && (optimize_size || TARGET_USE_CLTD))
3375 {
3376 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3377 DONE;
3378 }
3379
3380 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3381 emit_move_insn (operands[4], operands[1]);
3382
3383 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3384 DONE;
3385 })
3386
3387 (define_insn "extendhisi2"
3388 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3389 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3390 ""
3391 {
3392 switch (get_attr_prefix_0f (insn))
3393 {
3394 case 0:
3395 return "{cwtl|cwde}";
3396 default:
3397 return "movs{wl|x}\t{%1,%0|%0, %1}";
3398 }
3399 }
3400 [(set_attr "type" "imovx")
3401 (set_attr "mode" "SI")
3402 (set (attr "prefix_0f")
3403 ;; movsx is short decodable while cwtl is vector decoded.
3404 (if_then_else (and (eq_attr "cpu" "!k6")
3405 (eq_attr "alternative" "0"))
3406 (const_string "0")
3407 (const_string "1")))
3408 (set (attr "modrm")
3409 (if_then_else (eq_attr "prefix_0f" "0")
3410 (const_string "0")
3411 (const_string "1")))])
3412
3413 (define_insn "*extendhisi2_zext"
3414 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3415 (zero_extend:DI
3416 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3417 "TARGET_64BIT"
3418 {
3419 switch (get_attr_prefix_0f (insn))
3420 {
3421 case 0:
3422 return "{cwtl|cwde}";
3423 default:
3424 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3425 }
3426 }
3427 [(set_attr "type" "imovx")
3428 (set_attr "mode" "SI")
3429 (set (attr "prefix_0f")
3430 ;; movsx is short decodable while cwtl is vector decoded.
3431 (if_then_else (and (eq_attr "cpu" "!k6")
3432 (eq_attr "alternative" "0"))
3433 (const_string "0")
3434 (const_string "1")))
3435 (set (attr "modrm")
3436 (if_then_else (eq_attr "prefix_0f" "0")
3437 (const_string "0")
3438 (const_string "1")))])
3439
3440 (define_insn "extendqihi2"
3441 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3442 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3443 ""
3444 {
3445 switch (get_attr_prefix_0f (insn))
3446 {
3447 case 0:
3448 return "{cbtw|cbw}";
3449 default:
3450 return "movs{bw|x}\t{%1,%0|%0, %1}";
3451 }
3452 }
3453 [(set_attr "type" "imovx")
3454 (set_attr "mode" "HI")
3455 (set (attr "prefix_0f")
3456 ;; movsx is short decodable while cwtl is vector decoded.
3457 (if_then_else (and (eq_attr "cpu" "!k6")
3458 (eq_attr "alternative" "0"))
3459 (const_string "0")
3460 (const_string "1")))
3461 (set (attr "modrm")
3462 (if_then_else (eq_attr "prefix_0f" "0")
3463 (const_string "0")
3464 (const_string "1")))])
3465
3466 (define_insn "extendqisi2"
3467 [(set (match_operand:SI 0 "register_operand" "=r")
3468 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3469 ""
3470 "movs{bl|x}\t{%1,%0|%0, %1}"
3471 [(set_attr "type" "imovx")
3472 (set_attr "mode" "SI")])
3473
3474 (define_insn "*extendqisi2_zext"
3475 [(set (match_operand:DI 0 "register_operand" "=r")
3476 (zero_extend:DI
3477 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3478 "TARGET_64BIT"
3479 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3480 [(set_attr "type" "imovx")
3481 (set_attr "mode" "SI")])
3482 \f
3483 ;; Conversions between float and double.
3484
3485 ;; These are all no-ops in the model used for the 80387. So just
3486 ;; emit moves.
3487
3488 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3489 (define_insn "*dummy_extendsfdf2"
3490 [(set (match_operand:DF 0 "push_operand" "=<")
3491 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3492 "0"
3493 "#")
3494
3495 (define_split
3496 [(set (match_operand:DF 0 "push_operand" "")
3497 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3498 "!TARGET_64BIT"
3499 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3500 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3501
3502 (define_split
3503 [(set (match_operand:DF 0 "push_operand" "")
3504 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3505 "TARGET_64BIT"
3506 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3507 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3508
3509 (define_insn "*dummy_extendsfxf2"
3510 [(set (match_operand:XF 0 "push_operand" "=<")
3511 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3512 "0"
3513 "#")
3514
3515 (define_split
3516 [(set (match_operand:XF 0 "push_operand" "")
3517 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3518 ""
3519 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3520 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3521 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3522
3523 (define_split
3524 [(set (match_operand:XF 0 "push_operand" "")
3525 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3526 "TARGET_64BIT"
3527 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3528 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3529 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3530
3531 (define_split
3532 [(set (match_operand:XF 0 "push_operand" "")
3533 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3534 ""
3535 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3536 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3537 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3538
3539 (define_split
3540 [(set (match_operand:XF 0 "push_operand" "")
3541 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3542 "TARGET_64BIT"
3543 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3544 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3545 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3546
3547 (define_expand "extendsfdf2"
3548 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3549 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3550 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3551 {
3552 /* ??? Needed for compress_float_constant since all fp constants
3553 are LEGITIMATE_CONSTANT_P. */
3554 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3555 {
3556 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3557 && standard_80387_constant_p (operands[1]) > 0)
3558 {
3559 operands[1] = simplify_const_unary_operation
3560 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3561 emit_move_insn_1 (operands[0], operands[1]);
3562 DONE;
3563 }
3564 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3565 }
3566 })
3567
3568 (define_insn "*extendsfdf2_mixed"
3569 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3570 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3571 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3572 {
3573 switch (which_alternative)
3574 {
3575 case 0:
3576 return output_387_reg_move (insn, operands);
3577
3578 case 1:
3579 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3580 return "fstp%z0\t%y0";
3581 else
3582 return "fst%z0\t%y0";
3583
3584 case 2:
3585 return "cvtss2sd\t{%1, %0|%0, %1}";
3586
3587 default:
3588 gcc_unreachable ();
3589 }
3590 }
3591 [(set_attr "type" "fmov,fmov,ssecvt")
3592 (set_attr "mode" "SF,XF,DF")])
3593
3594 (define_insn "*extendsfdf2_sse"
3595 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3596 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3597 "TARGET_SSE2 && TARGET_SSE_MATH"
3598 "cvtss2sd\t{%1, %0|%0, %1}"
3599 [(set_attr "type" "ssecvt")
3600 (set_attr "mode" "DF")])
3601
3602 (define_insn "*extendsfdf2_i387"
3603 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3604 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3605 "TARGET_80387"
3606 {
3607 switch (which_alternative)
3608 {
3609 case 0:
3610 return output_387_reg_move (insn, operands);
3611
3612 case 1:
3613 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3614 return "fstp%z0\t%y0";
3615 else
3616 return "fst%z0\t%y0";
3617
3618 default:
3619 gcc_unreachable ();
3620 }
3621 }
3622 [(set_attr "type" "fmov")
3623 (set_attr "mode" "SF,XF")])
3624
3625 (define_expand "extendsfxf2"
3626 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3627 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3628 "TARGET_80387"
3629 {
3630 /* ??? Needed for compress_float_constant since all fp constants
3631 are LEGITIMATE_CONSTANT_P. */
3632 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3633 {
3634 if (standard_80387_constant_p (operands[1]) > 0)
3635 {
3636 operands[1] = simplify_const_unary_operation
3637 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3638 emit_move_insn_1 (operands[0], operands[1]);
3639 DONE;
3640 }
3641 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3642 }
3643 })
3644
3645 (define_insn "*extendsfxf2_i387"
3646 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3647 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3648 "TARGET_80387"
3649 {
3650 switch (which_alternative)
3651 {
3652 case 0:
3653 return output_387_reg_move (insn, operands);
3654
3655 case 1:
3656 /* There is no non-popping store to memory for XFmode. So if
3657 we need one, follow the store with a load. */
3658 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3659 return "fstp%z0\t%y0";
3660 else
3661 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3662
3663 default:
3664 gcc_unreachable ();
3665 }
3666 }
3667 [(set_attr "type" "fmov")
3668 (set_attr "mode" "SF,XF")])
3669
3670 (define_expand "extenddfxf2"
3671 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3672 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3673 "TARGET_80387"
3674 {
3675 /* ??? Needed for compress_float_constant since all fp constants
3676 are LEGITIMATE_CONSTANT_P. */
3677 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3678 {
3679 if (standard_80387_constant_p (operands[1]) > 0)
3680 {
3681 operands[1] = simplify_const_unary_operation
3682 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3683 emit_move_insn_1 (operands[0], operands[1]);
3684 DONE;
3685 }
3686 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3687 }
3688 })
3689
3690 (define_insn "*extenddfxf2_i387"
3691 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3692 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3693 "TARGET_80387"
3694 {
3695 switch (which_alternative)
3696 {
3697 case 0:
3698 return output_387_reg_move (insn, operands);
3699
3700 case 1:
3701 /* There is no non-popping store to memory for XFmode. So if
3702 we need one, follow the store with a load. */
3703 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3704 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3705 else
3706 return "fstp%z0\t%y0";
3707
3708 default:
3709 gcc_unreachable ();
3710 }
3711 }
3712 [(set_attr "type" "fmov")
3713 (set_attr "mode" "DF,XF")])
3714
3715 ;; %%% This seems bad bad news.
3716 ;; This cannot output into an f-reg because there is no way to be sure
3717 ;; of truncating in that case. Otherwise this is just like a simple move
3718 ;; insn. So we pretend we can output to a reg in order to get better
3719 ;; register preferencing, but we really use a stack slot.
3720
3721 ;; Conversion from DFmode to SFmode.
3722
3723 (define_expand "truncdfsf2"
3724 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3725 (float_truncate:SF
3726 (match_operand:DF 1 "nonimmediate_operand" "")))]
3727 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3728 {
3729 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3730 ;
3731 else if (flag_unsafe_math_optimizations)
3732 ;
3733 else
3734 {
3735 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3736 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3737 DONE;
3738 }
3739 })
3740
3741 (define_expand "truncdfsf2_with_temp"
3742 [(parallel [(set (match_operand:SF 0 "" "")
3743 (float_truncate:SF (match_operand:DF 1 "" "")))
3744 (clobber (match_operand:SF 2 "" ""))])]
3745 "")
3746
3747 (define_insn "*truncdfsf_fast_mixed"
3748 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3749 (float_truncate:SF
3750 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3751 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3752 {
3753 switch (which_alternative)
3754 {
3755 case 0:
3756 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3757 return "fstp%z0\t%y0";
3758 else
3759 return "fst%z0\t%y0";
3760 case 1:
3761 return output_387_reg_move (insn, operands);
3762 case 2:
3763 return "cvtsd2ss\t{%1, %0|%0, %1}";
3764 default:
3765 gcc_unreachable ();
3766 }
3767 }
3768 [(set_attr "type" "fmov,fmov,ssecvt")
3769 (set_attr "mode" "SF")])
3770
3771 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3772 ;; because nothing we do here is unsafe.
3773 (define_insn "*truncdfsf_fast_sse"
3774 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3775 (float_truncate:SF
3776 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3777 "TARGET_SSE2 && TARGET_SSE_MATH"
3778 "cvtsd2ss\t{%1, %0|%0, %1}"
3779 [(set_attr "type" "ssecvt")
3780 (set_attr "mode" "SF")])
3781
3782 (define_insn "*truncdfsf_fast_i387"
3783 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3784 (float_truncate:SF
3785 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3786 "TARGET_80387 && flag_unsafe_math_optimizations"
3787 "* return output_387_reg_move (insn, operands);"
3788 [(set_attr "type" "fmov")
3789 (set_attr "mode" "SF")])
3790
3791 (define_insn "*truncdfsf_mixed"
3792 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3793 (float_truncate:SF
3794 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3795 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3796 "TARGET_MIX_SSE_I387"
3797 {
3798 switch (which_alternative)
3799 {
3800 case 0:
3801 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3802 return "fstp%z0\t%y0";
3803 else
3804 return "fst%z0\t%y0";
3805 case 1:
3806 return "#";
3807 case 2:
3808 return "cvtsd2ss\t{%1, %0|%0, %1}";
3809 default:
3810 gcc_unreachable ();
3811 }
3812 }
3813 [(set_attr "type" "fmov,multi,ssecvt")
3814 (set_attr "unit" "*,i387,*")
3815 (set_attr "mode" "SF")])
3816
3817 (define_insn "*truncdfsf_i387"
3818 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3819 (float_truncate:SF
3820 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3821 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3822 "TARGET_80387"
3823 {
3824 switch (which_alternative)
3825 {
3826 case 0:
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 case 1:
3832 return "#";
3833 default:
3834 gcc_unreachable ();
3835 }
3836 }
3837 [(set_attr "type" "fmov,multi")
3838 (set_attr "unit" "*,i387")
3839 (set_attr "mode" "SF")])
3840
3841 (define_insn "*truncdfsf2_i387_1"
3842 [(set (match_operand:SF 0 "memory_operand" "=m")
3843 (float_truncate:SF
3844 (match_operand:DF 1 "register_operand" "f")))]
3845 "TARGET_80387
3846 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3847 && !TARGET_MIX_SSE_I387"
3848 {
3849 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850 return "fstp%z0\t%y0";
3851 else
3852 return "fst%z0\t%y0";
3853 }
3854 [(set_attr "type" "fmov")
3855 (set_attr "mode" "SF")])
3856
3857 (define_split
3858 [(set (match_operand:SF 0 "register_operand" "")
3859 (float_truncate:SF
3860 (match_operand:DF 1 "fp_register_operand" "")))
3861 (clobber (match_operand 2 "" ""))]
3862 "reload_completed"
3863 [(set (match_dup 2) (match_dup 1))
3864 (set (match_dup 0) (match_dup 2))]
3865 {
3866 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3867 })
3868
3869 ;; Conversion from XFmode to SFmode.
3870
3871 (define_expand "truncxfsf2"
3872 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3873 (float_truncate:SF
3874 (match_operand:XF 1 "register_operand" "")))
3875 (clobber (match_dup 2))])]
3876 "TARGET_80387"
3877 {
3878 if (flag_unsafe_math_optimizations)
3879 {
3880 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3881 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3882 if (reg != operands[0])
3883 emit_move_insn (operands[0], reg);
3884 DONE;
3885 }
3886 else
3887 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3888 })
3889
3890 (define_insn "*truncxfsf2_mixed"
3891 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3892 (float_truncate:SF
3893 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3894 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3895 "TARGET_MIX_SSE_I387"
3896 {
3897 gcc_assert (!which_alternative);
3898 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3899 return "fstp%z0\t%y0";
3900 else
3901 return "fst%z0\t%y0";
3902 }
3903 [(set_attr "type" "fmov,multi,multi,multi")
3904 (set_attr "unit" "*,i387,i387,i387")
3905 (set_attr "mode" "SF")])
3906
3907 (define_insn "truncxfsf2_i387_noop"
3908 [(set (match_operand:SF 0 "register_operand" "=f")
3909 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3910 "TARGET_80387 && flag_unsafe_math_optimizations"
3911 {
3912 return output_387_reg_move (insn, operands);
3913 }
3914 [(set_attr "type" "fmov")
3915 (set_attr "mode" "SF")])
3916
3917 (define_insn "*truncxfsf2_i387"
3918 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3919 (float_truncate:SF
3920 (match_operand:XF 1 "register_operand" "f,f,f")))
3921 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3922 "TARGET_80387"
3923 {
3924 gcc_assert (!which_alternative);
3925 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3926 return "fstp%z0\t%y0";
3927 else
3928 return "fst%z0\t%y0";
3929 }
3930 [(set_attr "type" "fmov,multi,multi")
3931 (set_attr "unit" "*,i387,i387")
3932 (set_attr "mode" "SF")])
3933
3934 (define_insn "*truncxfsf2_i387_1"
3935 [(set (match_operand:SF 0 "memory_operand" "=m")
3936 (float_truncate:SF
3937 (match_operand:XF 1 "register_operand" "f")))]
3938 "TARGET_80387"
3939 {
3940 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3941 return "fstp%z0\t%y0";
3942 else
3943 return "fst%z0\t%y0";
3944 }
3945 [(set_attr "type" "fmov")
3946 (set_attr "mode" "SF")])
3947
3948 (define_split
3949 [(set (match_operand:SF 0 "register_operand" "")
3950 (float_truncate:SF
3951 (match_operand:XF 1 "register_operand" "")))
3952 (clobber (match_operand:SF 2 "memory_operand" ""))]
3953 "TARGET_80387 && reload_completed"
3954 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3955 (set (match_dup 0) (match_dup 2))]
3956 "")
3957
3958 (define_split
3959 [(set (match_operand:SF 0 "memory_operand" "")
3960 (float_truncate:SF
3961 (match_operand:XF 1 "register_operand" "")))
3962 (clobber (match_operand:SF 2 "memory_operand" ""))]
3963 "TARGET_80387"
3964 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3965 "")
3966
3967 ;; Conversion from XFmode to DFmode.
3968
3969 (define_expand "truncxfdf2"
3970 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3971 (float_truncate:DF
3972 (match_operand:XF 1 "register_operand" "")))
3973 (clobber (match_dup 2))])]
3974 "TARGET_80387"
3975 {
3976 if (flag_unsafe_math_optimizations)
3977 {
3978 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3979 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3980 if (reg != operands[0])
3981 emit_move_insn (operands[0], reg);
3982 DONE;
3983 }
3984 else
3985 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3986 })
3987
3988 (define_insn "*truncxfdf2_mixed"
3989 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3990 (float_truncate:DF
3991 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3992 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3993 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3994 {
3995 gcc_assert (!which_alternative);
3996 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3997 return "fstp%z0\t%y0";
3998 else
3999 return "fst%z0\t%y0";
4000 }
4001 [(set_attr "type" "fmov,multi,multi,multi")
4002 (set_attr "unit" "*,i387,i387,i387")
4003 (set_attr "mode" "DF")])
4004
4005 (define_insn "truncxfdf2_i387_noop"
4006 [(set (match_operand:DF 0 "register_operand" "=f")
4007 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4008 "TARGET_80387 && flag_unsafe_math_optimizations"
4009 {
4010 return output_387_reg_move (insn, operands);
4011 }
4012 [(set_attr "type" "fmov")
4013 (set_attr "mode" "DF")])
4014
4015 (define_insn "*truncxfdf2_i387"
4016 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4017 (float_truncate:DF
4018 (match_operand:XF 1 "register_operand" "f,f,f")))
4019 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4020 "TARGET_80387"
4021 {
4022 gcc_assert (!which_alternative);
4023 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4024 return "fstp%z0\t%y0";
4025 else
4026 return "fst%z0\t%y0";
4027 }
4028 [(set_attr "type" "fmov,multi,multi")
4029 (set_attr "unit" "*,i387,i387")
4030 (set_attr "mode" "DF")])
4031
4032 (define_insn "*truncxfdf2_i387_1"
4033 [(set (match_operand:DF 0 "memory_operand" "=m")
4034 (float_truncate:DF
4035 (match_operand:XF 1 "register_operand" "f")))]
4036 "TARGET_80387"
4037 {
4038 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4039 return "fstp%z0\t%y0";
4040 else
4041 return "fst%z0\t%y0";
4042 }
4043 [(set_attr "type" "fmov")
4044 (set_attr "mode" "DF")])
4045
4046 (define_split
4047 [(set (match_operand:DF 0 "register_operand" "")
4048 (float_truncate:DF
4049 (match_operand:XF 1 "register_operand" "")))
4050 (clobber (match_operand:DF 2 "memory_operand" ""))]
4051 "TARGET_80387 && reload_completed"
4052 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4053 (set (match_dup 0) (match_dup 2))]
4054 "")
4055
4056 (define_split
4057 [(set (match_operand:DF 0 "memory_operand" "")
4058 (float_truncate:DF
4059 (match_operand:XF 1 "register_operand" "")))
4060 (clobber (match_operand:DF 2 "memory_operand" ""))]
4061 "TARGET_80387"
4062 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4063 "")
4064 \f
4065 ;; Signed conversion to DImode.
4066
4067 (define_expand "fix_truncxfdi2"
4068 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4069 (fix:DI (match_operand:XF 1 "register_operand" "")))
4070 (clobber (reg:CC FLAGS_REG))])]
4071 "TARGET_80387"
4072 {
4073 if (TARGET_FISTTP)
4074 {
4075 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4076 DONE;
4077 }
4078 })
4079
4080 (define_expand "fix_trunc<mode>di2"
4081 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4082 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4083 (clobber (reg:CC FLAGS_REG))])]
4084 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4085 {
4086 if (TARGET_FISTTP
4087 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4088 {
4089 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4090 DONE;
4091 }
4092 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4093 {
4094 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4095 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4096 if (out != operands[0])
4097 emit_move_insn (operands[0], out);
4098 DONE;
4099 }
4100 })
4101
4102 ;; Signed conversion to SImode.
4103
4104 (define_expand "fix_truncxfsi2"
4105 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4106 (fix:SI (match_operand:XF 1 "register_operand" "")))
4107 (clobber (reg:CC FLAGS_REG))])]
4108 "TARGET_80387"
4109 {
4110 if (TARGET_FISTTP)
4111 {
4112 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4113 DONE;
4114 }
4115 })
4116
4117 (define_expand "fix_trunc<mode>si2"
4118 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4119 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4120 (clobber (reg:CC FLAGS_REG))])]
4121 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4122 {
4123 if (TARGET_FISTTP
4124 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4125 {
4126 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4127 DONE;
4128 }
4129 if (SSE_FLOAT_MODE_P (<MODE>mode))
4130 {
4131 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4132 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4133 if (out != operands[0])
4134 emit_move_insn (operands[0], out);
4135 DONE;
4136 }
4137 })
4138
4139 ;; Signed conversion to HImode.
4140
4141 (define_expand "fix_trunc<mode>hi2"
4142 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4143 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4144 (clobber (reg:CC FLAGS_REG))])]
4145 "TARGET_80387
4146 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4147 {
4148 if (TARGET_FISTTP)
4149 {
4150 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4151 DONE;
4152 }
4153 })
4154
4155 ;; When SSE is available, it is always faster to use it!
4156 (define_insn "fix_truncsfdi_sse"
4157 [(set (match_operand:DI 0 "register_operand" "=r,r")
4158 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4159 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4160 "cvttss2si{q}\t{%1, %0|%0, %1}"
4161 [(set_attr "type" "sseicvt")
4162 (set_attr "mode" "SF")
4163 (set_attr "athlon_decode" "double,vector")])
4164
4165 (define_insn "fix_truncdfdi_sse"
4166 [(set (match_operand:DI 0 "register_operand" "=r,r")
4167 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4168 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4169 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4170 [(set_attr "type" "sseicvt")
4171 (set_attr "mode" "DF")
4172 (set_attr "athlon_decode" "double,vector")])
4173
4174 (define_insn "fix_truncsfsi_sse"
4175 [(set (match_operand:SI 0 "register_operand" "=r,r")
4176 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4177 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4178 "cvttss2si\t{%1, %0|%0, %1}"
4179 [(set_attr "type" "sseicvt")
4180 (set_attr "mode" "DF")
4181 (set_attr "athlon_decode" "double,vector")])
4182
4183 (define_insn "fix_truncdfsi_sse"
4184 [(set (match_operand:SI 0 "register_operand" "=r,r")
4185 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4186 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4187 "cvttsd2si\t{%1, %0|%0, %1}"
4188 [(set_attr "type" "sseicvt")
4189 (set_attr "mode" "DF")
4190 (set_attr "athlon_decode" "double,vector")])
4191
4192 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4193 (define_peephole2
4194 [(set (match_operand:DF 0 "register_operand" "")
4195 (match_operand:DF 1 "memory_operand" ""))
4196 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4197 (fix:SSEMODEI24 (match_dup 0)))]
4198 "!TARGET_K8
4199 && peep2_reg_dead_p (2, operands[0])"
4200 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4201 "")
4202
4203 (define_peephole2
4204 [(set (match_operand:SF 0 "register_operand" "")
4205 (match_operand:SF 1 "memory_operand" ""))
4206 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4207 (fix:SSEMODEI24 (match_dup 0)))]
4208 "!TARGET_K8
4209 && peep2_reg_dead_p (2, operands[0])"
4210 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4211 "")
4212
4213 ;; Avoid vector decoded forms of the instruction.
4214 (define_peephole2
4215 [(match_scratch:DF 2 "Y")
4216 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4217 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4218 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4219 [(set (match_dup 2) (match_dup 1))
4220 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4221 "")
4222
4223 (define_peephole2
4224 [(match_scratch:SF 2 "x")
4225 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4226 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4227 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4228 [(set (match_dup 2) (match_dup 1))
4229 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4230 "")
4231
4232 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4233 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4234 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4235 "TARGET_FISTTP
4236 && FLOAT_MODE_P (GET_MODE (operands[1]))
4237 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4238 && (TARGET_64BIT || <MODE>mode != DImode))
4239 && TARGET_SSE_MATH)
4240 && !(reload_completed || reload_in_progress)"
4241 "#"
4242 "&& 1"
4243 [(const_int 0)]
4244 {
4245 if (memory_operand (operands[0], VOIDmode))
4246 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4247 else
4248 {
4249 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4250 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4251 operands[1],
4252 operands[2]));
4253 }
4254 DONE;
4255 }
4256 [(set_attr "type" "fisttp")
4257 (set_attr "mode" "<MODE>")])
4258
4259 (define_insn "fix_trunc<mode>_i387_fisttp"
4260 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4261 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4262 (clobber (match_scratch:XF 2 "=&1f"))]
4263 "TARGET_FISTTP
4264 && FLOAT_MODE_P (GET_MODE (operands[1]))
4265 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4266 && (TARGET_64BIT || <MODE>mode != DImode))
4267 && TARGET_SSE_MATH)"
4268 "* return output_fix_trunc (insn, operands, 1);"
4269 [(set_attr "type" "fisttp")
4270 (set_attr "mode" "<MODE>")])
4271
4272 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4273 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4274 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4275 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4276 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4277 "TARGET_FISTTP
4278 && FLOAT_MODE_P (GET_MODE (operands[1]))
4279 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4280 && (TARGET_64BIT || <MODE>mode != DImode))
4281 && TARGET_SSE_MATH)"
4282 "#"
4283 [(set_attr "type" "fisttp")
4284 (set_attr "mode" "<MODE>")])
4285
4286 (define_split
4287 [(set (match_operand:X87MODEI 0 "register_operand" "")
4288 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4289 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4290 (clobber (match_scratch 3 ""))]
4291 "reload_completed"
4292 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4293 (clobber (match_dup 3))])
4294 (set (match_dup 0) (match_dup 2))]
4295 "")
4296
4297 (define_split
4298 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4299 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4300 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4301 (clobber (match_scratch 3 ""))]
4302 "reload_completed"
4303 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4304 (clobber (match_dup 3))])]
4305 "")
4306
4307 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4308 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4309 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4310 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4311 ;; function in i386.c.
4312 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4313 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4314 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4315 (clobber (reg:CC FLAGS_REG))]
4316 "TARGET_80387 && !TARGET_FISTTP
4317 && FLOAT_MODE_P (GET_MODE (operands[1]))
4318 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4319 && (TARGET_64BIT || <MODE>mode != DImode))
4320 && !(reload_completed || reload_in_progress)"
4321 "#"
4322 "&& 1"
4323 [(const_int 0)]
4324 {
4325 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4326
4327 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4328 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4329 if (memory_operand (operands[0], VOIDmode))
4330 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4331 operands[2], operands[3]));
4332 else
4333 {
4334 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4335 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4336 operands[2], operands[3],
4337 operands[4]));
4338 }
4339 DONE;
4340 }
4341 [(set_attr "type" "fistp")
4342 (set_attr "i387_cw" "trunc")
4343 (set_attr "mode" "<MODE>")])
4344
4345 (define_insn "fix_truncdi_i387"
4346 [(set (match_operand:DI 0 "memory_operand" "=m")
4347 (fix:DI (match_operand 1 "register_operand" "f")))
4348 (use (match_operand:HI 2 "memory_operand" "m"))
4349 (use (match_operand:HI 3 "memory_operand" "m"))
4350 (clobber (match_scratch:XF 4 "=&1f"))]
4351 "TARGET_80387 && !TARGET_FISTTP
4352 && FLOAT_MODE_P (GET_MODE (operands[1]))
4353 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4354 "* return output_fix_trunc (insn, operands, 0);"
4355 [(set_attr "type" "fistp")
4356 (set_attr "i387_cw" "trunc")
4357 (set_attr "mode" "DI")])
4358
4359 (define_insn "fix_truncdi_i387_with_temp"
4360 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4361 (fix:DI (match_operand 1 "register_operand" "f,f")))
4362 (use (match_operand:HI 2 "memory_operand" "m,m"))
4363 (use (match_operand:HI 3 "memory_operand" "m,m"))
4364 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4365 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4366 "TARGET_80387 && !TARGET_FISTTP
4367 && FLOAT_MODE_P (GET_MODE (operands[1]))
4368 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4369 "#"
4370 [(set_attr "type" "fistp")
4371 (set_attr "i387_cw" "trunc")
4372 (set_attr "mode" "DI")])
4373
4374 (define_split
4375 [(set (match_operand:DI 0 "register_operand" "")
4376 (fix:DI (match_operand 1 "register_operand" "")))
4377 (use (match_operand:HI 2 "memory_operand" ""))
4378 (use (match_operand:HI 3 "memory_operand" ""))
4379 (clobber (match_operand:DI 4 "memory_operand" ""))
4380 (clobber (match_scratch 5 ""))]
4381 "reload_completed"
4382 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4383 (use (match_dup 2))
4384 (use (match_dup 3))
4385 (clobber (match_dup 5))])
4386 (set (match_dup 0) (match_dup 4))]
4387 "")
4388
4389 (define_split
4390 [(set (match_operand:DI 0 "memory_operand" "")
4391 (fix:DI (match_operand 1 "register_operand" "")))
4392 (use (match_operand:HI 2 "memory_operand" ""))
4393 (use (match_operand:HI 3 "memory_operand" ""))
4394 (clobber (match_operand:DI 4 "memory_operand" ""))
4395 (clobber (match_scratch 5 ""))]
4396 "reload_completed"
4397 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4398 (use (match_dup 2))
4399 (use (match_dup 3))
4400 (clobber (match_dup 5))])]
4401 "")
4402
4403 (define_insn "fix_trunc<mode>_i387"
4404 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4405 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4406 (use (match_operand:HI 2 "memory_operand" "m"))
4407 (use (match_operand:HI 3 "memory_operand" "m"))]
4408 "TARGET_80387 && !TARGET_FISTTP
4409 && FLOAT_MODE_P (GET_MODE (operands[1]))
4410 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4411 "* return output_fix_trunc (insn, operands, 0);"
4412 [(set_attr "type" "fistp")
4413 (set_attr "i387_cw" "trunc")
4414 (set_attr "mode" "<MODE>")])
4415
4416 (define_insn "fix_trunc<mode>_i387_with_temp"
4417 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4418 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4419 (use (match_operand:HI 2 "memory_operand" "m,m"))
4420 (use (match_operand:HI 3 "memory_operand" "m,m"))
4421 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4422 "TARGET_80387 && !TARGET_FISTTP
4423 && FLOAT_MODE_P (GET_MODE (operands[1]))
4424 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4425 "#"
4426 [(set_attr "type" "fistp")
4427 (set_attr "i387_cw" "trunc")
4428 (set_attr "mode" "<MODE>")])
4429
4430 (define_split
4431 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4432 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4433 (use (match_operand:HI 2 "memory_operand" ""))
4434 (use (match_operand:HI 3 "memory_operand" ""))
4435 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4436 "reload_completed"
4437 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4438 (use (match_dup 2))
4439 (use (match_dup 3))])
4440 (set (match_dup 0) (match_dup 4))]
4441 "")
4442
4443 (define_split
4444 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4445 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4446 (use (match_operand:HI 2 "memory_operand" ""))
4447 (use (match_operand:HI 3 "memory_operand" ""))
4448 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4449 "reload_completed"
4450 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4451 (use (match_dup 2))
4452 (use (match_dup 3))])]
4453 "")
4454
4455 (define_insn "x86_fnstcw_1"
4456 [(set (match_operand:HI 0 "memory_operand" "=m")
4457 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4458 "TARGET_80387"
4459 "fnstcw\t%0"
4460 [(set_attr "length" "2")
4461 (set_attr "mode" "HI")
4462 (set_attr "unit" "i387")])
4463
4464 (define_insn "x86_fldcw_1"
4465 [(set (reg:HI FPCR_REG)
4466 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4467 "TARGET_80387"
4468 "fldcw\t%0"
4469 [(set_attr "length" "2")
4470 (set_attr "mode" "HI")
4471 (set_attr "unit" "i387")
4472 (set_attr "athlon_decode" "vector")])
4473 \f
4474 ;; Conversion between fixed point and floating point.
4475
4476 ;; Even though we only accept memory inputs, the backend _really_
4477 ;; wants to be able to do this between registers.
4478
4479 (define_expand "floathisf2"
4480 [(set (match_operand:SF 0 "register_operand" "")
4481 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4482 "TARGET_80387 || TARGET_SSE_MATH"
4483 {
4484 if (TARGET_SSE_MATH)
4485 {
4486 emit_insn (gen_floatsisf2 (operands[0],
4487 convert_to_mode (SImode, operands[1], 0)));
4488 DONE;
4489 }
4490 })
4491
4492 (define_insn "*floathisf2_i387"
4493 [(set (match_operand:SF 0 "register_operand" "=f,f")
4494 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4495 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4496 "@
4497 fild%z1\t%1
4498 #"
4499 [(set_attr "type" "fmov,multi")
4500 (set_attr "mode" "SF")
4501 (set_attr "unit" "*,i387")
4502 (set_attr "fp_int_src" "true")])
4503
4504 (define_expand "floatsisf2"
4505 [(set (match_operand:SF 0 "register_operand" "")
4506 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4507 "TARGET_80387 || TARGET_SSE_MATH"
4508 "")
4509
4510 (define_insn "*floatsisf2_mixed"
4511 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4512 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4513 "TARGET_MIX_SSE_I387"
4514 "@
4515 fild%z1\t%1
4516 #
4517 cvtsi2ss\t{%1, %0|%0, %1}
4518 cvtsi2ss\t{%1, %0|%0, %1}"
4519 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4520 (set_attr "mode" "SF")
4521 (set_attr "unit" "*,i387,*,*")
4522 (set_attr "athlon_decode" "*,*,vector,double")
4523 (set_attr "fp_int_src" "true")])
4524
4525 (define_insn "*floatsisf2_sse"
4526 [(set (match_operand:SF 0 "register_operand" "=x,x")
4527 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4528 "TARGET_SSE_MATH"
4529 "cvtsi2ss\t{%1, %0|%0, %1}"
4530 [(set_attr "type" "sseicvt")
4531 (set_attr "mode" "SF")
4532 (set_attr "athlon_decode" "vector,double")
4533 (set_attr "fp_int_src" "true")])
4534
4535 (define_insn "*floatsisf2_i387"
4536 [(set (match_operand:SF 0 "register_operand" "=f,f")
4537 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4538 "TARGET_80387"
4539 "@
4540 fild%z1\t%1
4541 #"
4542 [(set_attr "type" "fmov,multi")
4543 (set_attr "mode" "SF")
4544 (set_attr "unit" "*,i387")
4545 (set_attr "fp_int_src" "true")])
4546
4547 (define_expand "floatdisf2"
4548 [(set (match_operand:SF 0 "register_operand" "")
4549 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4550 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4551 "")
4552
4553 (define_insn "*floatdisf2_mixed"
4554 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4555 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4556 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4557 "@
4558 fild%z1\t%1
4559 #
4560 cvtsi2ss{q}\t{%1, %0|%0, %1}
4561 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4562 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4563 (set_attr "mode" "SF")
4564 (set_attr "unit" "*,i387,*,*")
4565 (set_attr "athlon_decode" "*,*,vector,double")
4566 (set_attr "fp_int_src" "true")])
4567
4568 (define_insn "*floatdisf2_sse"
4569 [(set (match_operand:SF 0 "register_operand" "=x,x")
4570 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4571 "TARGET_64BIT && TARGET_SSE_MATH"
4572 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4573 [(set_attr "type" "sseicvt")
4574 (set_attr "mode" "SF")
4575 (set_attr "athlon_decode" "vector,double")
4576 (set_attr "fp_int_src" "true")])
4577
4578 (define_insn "*floatdisf2_i387"
4579 [(set (match_operand:SF 0 "register_operand" "=f,f")
4580 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4581 "TARGET_80387"
4582 "@
4583 fild%z1\t%1
4584 #"
4585 [(set_attr "type" "fmov,multi")
4586 (set_attr "mode" "SF")
4587 (set_attr "unit" "*,i387")
4588 (set_attr "fp_int_src" "true")])
4589
4590 (define_expand "floathidf2"
4591 [(set (match_operand:DF 0 "register_operand" "")
4592 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4593 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4594 {
4595 if (TARGET_SSE2 && TARGET_SSE_MATH)
4596 {
4597 emit_insn (gen_floatsidf2 (operands[0],
4598 convert_to_mode (SImode, operands[1], 0)));
4599 DONE;
4600 }
4601 })
4602
4603 (define_insn "*floathidf2_i387"
4604 [(set (match_operand:DF 0 "register_operand" "=f,f")
4605 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4606 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4607 "@
4608 fild%z1\t%1
4609 #"
4610 [(set_attr "type" "fmov,multi")
4611 (set_attr "mode" "DF")
4612 (set_attr "unit" "*,i387")
4613 (set_attr "fp_int_src" "true")])
4614
4615 (define_expand "floatsidf2"
4616 [(set (match_operand:DF 0 "register_operand" "")
4617 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4618 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4619 "")
4620
4621 (define_insn "*floatsidf2_mixed"
4622 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4623 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4624 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4625 "@
4626 fild%z1\t%1
4627 #
4628 cvtsi2sd\t{%1, %0|%0, %1}
4629 cvtsi2sd\t{%1, %0|%0, %1}"
4630 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4631 (set_attr "mode" "DF")
4632 (set_attr "unit" "*,i387,*,*")
4633 (set_attr "athlon_decode" "*,*,double,direct")
4634 (set_attr "fp_int_src" "true")])
4635
4636 (define_insn "*floatsidf2_sse"
4637 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4638 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4639 "TARGET_SSE2 && TARGET_SSE_MATH"
4640 "cvtsi2sd\t{%1, %0|%0, %1}"
4641 [(set_attr "type" "sseicvt")
4642 (set_attr "mode" "DF")
4643 (set_attr "athlon_decode" "double,direct")
4644 (set_attr "fp_int_src" "true")])
4645
4646 (define_insn "*floatsidf2_i387"
4647 [(set (match_operand:DF 0 "register_operand" "=f,f")
4648 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4649 "TARGET_80387"
4650 "@
4651 fild%z1\t%1
4652 #"
4653 [(set_attr "type" "fmov,multi")
4654 (set_attr "mode" "DF")
4655 (set_attr "unit" "*,i387")
4656 (set_attr "fp_int_src" "true")])
4657
4658 (define_expand "floatdidf2"
4659 [(set (match_operand:DF 0 "register_operand" "")
4660 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4661 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4662 "")
4663
4664 (define_insn "*floatdidf2_mixed"
4665 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4666 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4667 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4668 "@
4669 fild%z1\t%1
4670 #
4671 cvtsi2sd{q}\t{%1, %0|%0, %1}
4672 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4673 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4674 (set_attr "mode" "DF")
4675 (set_attr "unit" "*,i387,*,*")
4676 (set_attr "athlon_decode" "*,*,double,direct")
4677 (set_attr "fp_int_src" "true")])
4678
4679 (define_insn "*floatdidf2_sse"
4680 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4681 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4682 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4683 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4684 [(set_attr "type" "sseicvt")
4685 (set_attr "mode" "DF")
4686 (set_attr "athlon_decode" "double,direct")
4687 (set_attr "fp_int_src" "true")])
4688
4689 (define_insn "*floatdidf2_i387"
4690 [(set (match_operand:DF 0 "register_operand" "=f,f")
4691 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4692 "TARGET_80387"
4693 "@
4694 fild%z1\t%1
4695 #"
4696 [(set_attr "type" "fmov,multi")
4697 (set_attr "mode" "DF")
4698 (set_attr "unit" "*,i387")
4699 (set_attr "fp_int_src" "true")])
4700
4701 (define_insn "floathixf2"
4702 [(set (match_operand:XF 0 "register_operand" "=f,f")
4703 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4704 "TARGET_80387"
4705 "@
4706 fild%z1\t%1
4707 #"
4708 [(set_attr "type" "fmov,multi")
4709 (set_attr "mode" "XF")
4710 (set_attr "unit" "*,i387")
4711 (set_attr "fp_int_src" "true")])
4712
4713 (define_insn "floatsixf2"
4714 [(set (match_operand:XF 0 "register_operand" "=f,f")
4715 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4716 "TARGET_80387"
4717 "@
4718 fild%z1\t%1
4719 #"
4720 [(set_attr "type" "fmov,multi")
4721 (set_attr "mode" "XF")
4722 (set_attr "unit" "*,i387")
4723 (set_attr "fp_int_src" "true")])
4724
4725 (define_insn "floatdixf2"
4726 [(set (match_operand:XF 0 "register_operand" "=f,f")
4727 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4728 "TARGET_80387"
4729 "@
4730 fild%z1\t%1
4731 #"
4732 [(set_attr "type" "fmov,multi")
4733 (set_attr "mode" "XF")
4734 (set_attr "unit" "*,i387")
4735 (set_attr "fp_int_src" "true")])
4736
4737 ;; %%% Kill these when reload knows how to do it.
4738 (define_split
4739 [(set (match_operand 0 "fp_register_operand" "")
4740 (float (match_operand 1 "register_operand" "")))]
4741 "reload_completed
4742 && TARGET_80387
4743 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4744 [(const_int 0)]
4745 {
4746 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4747 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4748 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4749 ix86_free_from_memory (GET_MODE (operands[1]));
4750 DONE;
4751 })
4752
4753 (define_expand "floatunssisf2"
4754 [(use (match_operand:SF 0 "register_operand" ""))
4755 (use (match_operand:SI 1 "register_operand" ""))]
4756 "!TARGET_64BIT && TARGET_SSE_MATH"
4757 "x86_emit_floatuns (operands); DONE;")
4758
4759 (define_expand "floatunsdisf2"
4760 [(use (match_operand:SF 0 "register_operand" ""))
4761 (use (match_operand:DI 1 "register_operand" ""))]
4762 "TARGET_64BIT && TARGET_SSE_MATH"
4763 "x86_emit_floatuns (operands); DONE;")
4764
4765 (define_expand "floatunsdidf2"
4766 [(use (match_operand:DF 0 "register_operand" ""))
4767 (use (match_operand:DI 1 "register_operand" ""))]
4768 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4769 "x86_emit_floatuns (operands); DONE;")
4770 \f
4771 ;; SSE extract/set expanders
4772
4773 \f
4774 ;; Add instructions
4775
4776 ;; %%% splits for addditi3
4777
4778 (define_expand "addti3"
4779 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4780 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4781 (match_operand:TI 2 "x86_64_general_operand" "")))
4782 (clobber (reg:CC FLAGS_REG))]
4783 "TARGET_64BIT"
4784 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4785
4786 (define_insn "*addti3_1"
4787 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4788 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4789 (match_operand:TI 2 "general_operand" "roiF,riF")))
4790 (clobber (reg:CC FLAGS_REG))]
4791 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4792 "#")
4793
4794 (define_split
4795 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4796 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4797 (match_operand:TI 2 "general_operand" "")))
4798 (clobber (reg:CC FLAGS_REG))]
4799 "TARGET_64BIT && reload_completed"
4800 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4801 UNSPEC_ADD_CARRY))
4802 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4803 (parallel [(set (match_dup 3)
4804 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4805 (match_dup 4))
4806 (match_dup 5)))
4807 (clobber (reg:CC FLAGS_REG))])]
4808 "split_ti (operands+0, 1, operands+0, operands+3);
4809 split_ti (operands+1, 1, operands+1, operands+4);
4810 split_ti (operands+2, 1, operands+2, operands+5);")
4811
4812 ;; %%% splits for addsidi3
4813 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4814 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4815 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4816
4817 (define_expand "adddi3"
4818 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4819 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4820 (match_operand:DI 2 "x86_64_general_operand" "")))
4821 (clobber (reg:CC FLAGS_REG))]
4822 ""
4823 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4824
4825 (define_insn "*adddi3_1"
4826 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4827 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4828 (match_operand:DI 2 "general_operand" "roiF,riF")))
4829 (clobber (reg:CC FLAGS_REG))]
4830 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4831 "#")
4832
4833 (define_split
4834 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4835 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4836 (match_operand:DI 2 "general_operand" "")))
4837 (clobber (reg:CC FLAGS_REG))]
4838 "!TARGET_64BIT && reload_completed"
4839 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4840 UNSPEC_ADD_CARRY))
4841 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4842 (parallel [(set (match_dup 3)
4843 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4844 (match_dup 4))
4845 (match_dup 5)))
4846 (clobber (reg:CC FLAGS_REG))])]
4847 "split_di (operands+0, 1, operands+0, operands+3);
4848 split_di (operands+1, 1, operands+1, operands+4);
4849 split_di (operands+2, 1, operands+2, operands+5);")
4850
4851 (define_insn "adddi3_carry_rex64"
4852 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4853 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4854 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4855 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4856 (clobber (reg:CC FLAGS_REG))]
4857 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4858 "adc{q}\t{%2, %0|%0, %2}"
4859 [(set_attr "type" "alu")
4860 (set_attr "pent_pair" "pu")
4861 (set_attr "mode" "DI")])
4862
4863 (define_insn "*adddi3_cc_rex64"
4864 [(set (reg:CC FLAGS_REG)
4865 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4866 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4867 UNSPEC_ADD_CARRY))
4868 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4869 (plus:DI (match_dup 1) (match_dup 2)))]
4870 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4871 "add{q}\t{%2, %0|%0, %2}"
4872 [(set_attr "type" "alu")
4873 (set_attr "mode" "DI")])
4874
4875 (define_insn "addqi3_carry"
4876 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4877 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4878 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4879 (match_operand:QI 2 "general_operand" "qi,qm")))
4880 (clobber (reg:CC FLAGS_REG))]
4881 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4882 "adc{b}\t{%2, %0|%0, %2}"
4883 [(set_attr "type" "alu")
4884 (set_attr "pent_pair" "pu")
4885 (set_attr "mode" "QI")])
4886
4887 (define_insn "addhi3_carry"
4888 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4889 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4890 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4891 (match_operand:HI 2 "general_operand" "ri,rm")))
4892 (clobber (reg:CC FLAGS_REG))]
4893 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4894 "adc{w}\t{%2, %0|%0, %2}"
4895 [(set_attr "type" "alu")
4896 (set_attr "pent_pair" "pu")
4897 (set_attr "mode" "HI")])
4898
4899 (define_insn "addsi3_carry"
4900 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4901 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4902 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4903 (match_operand:SI 2 "general_operand" "ri,rm")))
4904 (clobber (reg:CC FLAGS_REG))]
4905 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4906 "adc{l}\t{%2, %0|%0, %2}"
4907 [(set_attr "type" "alu")
4908 (set_attr "pent_pair" "pu")
4909 (set_attr "mode" "SI")])
4910
4911 (define_insn "*addsi3_carry_zext"
4912 [(set (match_operand:DI 0 "register_operand" "=r")
4913 (zero_extend:DI
4914 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4915 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4916 (match_operand:SI 2 "general_operand" "rim"))))
4917 (clobber (reg:CC FLAGS_REG))]
4918 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4919 "adc{l}\t{%2, %k0|%k0, %2}"
4920 [(set_attr "type" "alu")
4921 (set_attr "pent_pair" "pu")
4922 (set_attr "mode" "SI")])
4923
4924 (define_insn "*addsi3_cc"
4925 [(set (reg:CC FLAGS_REG)
4926 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4927 (match_operand:SI 2 "general_operand" "ri,rm")]
4928 UNSPEC_ADD_CARRY))
4929 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4930 (plus:SI (match_dup 1) (match_dup 2)))]
4931 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4932 "add{l}\t{%2, %0|%0, %2}"
4933 [(set_attr "type" "alu")
4934 (set_attr "mode" "SI")])
4935
4936 (define_insn "addqi3_cc"
4937 [(set (reg:CC FLAGS_REG)
4938 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4939 (match_operand:QI 2 "general_operand" "qi,qm")]
4940 UNSPEC_ADD_CARRY))
4941 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4942 (plus:QI (match_dup 1) (match_dup 2)))]
4943 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4944 "add{b}\t{%2, %0|%0, %2}"
4945 [(set_attr "type" "alu")
4946 (set_attr "mode" "QI")])
4947
4948 (define_expand "addsi3"
4949 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4950 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4951 (match_operand:SI 2 "general_operand" "")))
4952 (clobber (reg:CC FLAGS_REG))])]
4953 ""
4954 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4955
4956 (define_insn "*lea_1"
4957 [(set (match_operand:SI 0 "register_operand" "=r")
4958 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4959 "!TARGET_64BIT"
4960 "lea{l}\t{%a1, %0|%0, %a1}"
4961 [(set_attr "type" "lea")
4962 (set_attr "mode" "SI")])
4963
4964 (define_insn "*lea_1_rex64"
4965 [(set (match_operand:SI 0 "register_operand" "=r")
4966 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4967 "TARGET_64BIT"
4968 "lea{l}\t{%a1, %0|%0, %a1}"
4969 [(set_attr "type" "lea")
4970 (set_attr "mode" "SI")])
4971
4972 (define_insn "*lea_1_zext"
4973 [(set (match_operand:DI 0 "register_operand" "=r")
4974 (zero_extend:DI
4975 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4976 "TARGET_64BIT"
4977 "lea{l}\t{%a1, %k0|%k0, %a1}"
4978 [(set_attr "type" "lea")
4979 (set_attr "mode" "SI")])
4980
4981 (define_insn "*lea_2_rex64"
4982 [(set (match_operand:DI 0 "register_operand" "=r")
4983 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4984 "TARGET_64BIT"
4985 "lea{q}\t{%a1, %0|%0, %a1}"
4986 [(set_attr "type" "lea")
4987 (set_attr "mode" "DI")])
4988
4989 ;; The lea patterns for non-Pmodes needs to be matched by several
4990 ;; insns converted to real lea by splitters.
4991
4992 (define_insn_and_split "*lea_general_1"
4993 [(set (match_operand 0 "register_operand" "=r")
4994 (plus (plus (match_operand 1 "index_register_operand" "l")
4995 (match_operand 2 "register_operand" "r"))
4996 (match_operand 3 "immediate_operand" "i")))]
4997 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4998 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4999 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5000 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5001 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5002 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5003 || GET_MODE (operands[3]) == VOIDmode)"
5004 "#"
5005 "&& reload_completed"
5006 [(const_int 0)]
5007 {
5008 rtx pat;
5009 operands[0] = gen_lowpart (SImode, operands[0]);
5010 operands[1] = gen_lowpart (Pmode, operands[1]);
5011 operands[2] = gen_lowpart (Pmode, operands[2]);
5012 operands[3] = gen_lowpart (Pmode, operands[3]);
5013 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5014 operands[3]);
5015 if (Pmode != SImode)
5016 pat = gen_rtx_SUBREG (SImode, pat, 0);
5017 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5018 DONE;
5019 }
5020 [(set_attr "type" "lea")
5021 (set_attr "mode" "SI")])
5022
5023 (define_insn_and_split "*lea_general_1_zext"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (zero_extend:DI
5026 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5027 (match_operand:SI 2 "register_operand" "r"))
5028 (match_operand:SI 3 "immediate_operand" "i"))))]
5029 "TARGET_64BIT"
5030 "#"
5031 "&& reload_completed"
5032 [(set (match_dup 0)
5033 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5034 (match_dup 2))
5035 (match_dup 3)) 0)))]
5036 {
5037 operands[1] = gen_lowpart (Pmode, operands[1]);
5038 operands[2] = gen_lowpart (Pmode, operands[2]);
5039 operands[3] = gen_lowpart (Pmode, operands[3]);
5040 }
5041 [(set_attr "type" "lea")
5042 (set_attr "mode" "SI")])
5043
5044 (define_insn_and_split "*lea_general_2"
5045 [(set (match_operand 0 "register_operand" "=r")
5046 (plus (mult (match_operand 1 "index_register_operand" "l")
5047 (match_operand 2 "const248_operand" "i"))
5048 (match_operand 3 "nonmemory_operand" "ri")))]
5049 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5050 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5051 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5052 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5053 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5054 || GET_MODE (operands[3]) == VOIDmode)"
5055 "#"
5056 "&& reload_completed"
5057 [(const_int 0)]
5058 {
5059 rtx pat;
5060 operands[0] = gen_lowpart (SImode, operands[0]);
5061 operands[1] = gen_lowpart (Pmode, operands[1]);
5062 operands[3] = gen_lowpart (Pmode, operands[3]);
5063 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5064 operands[3]);
5065 if (Pmode != SImode)
5066 pat = gen_rtx_SUBREG (SImode, pat, 0);
5067 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5068 DONE;
5069 }
5070 [(set_attr "type" "lea")
5071 (set_attr "mode" "SI")])
5072
5073 (define_insn_and_split "*lea_general_2_zext"
5074 [(set (match_operand:DI 0 "register_operand" "=r")
5075 (zero_extend:DI
5076 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5077 (match_operand:SI 2 "const248_operand" "n"))
5078 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5079 "TARGET_64BIT"
5080 "#"
5081 "&& reload_completed"
5082 [(set (match_dup 0)
5083 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5084 (match_dup 2))
5085 (match_dup 3)) 0)))]
5086 {
5087 operands[1] = gen_lowpart (Pmode, operands[1]);
5088 operands[3] = gen_lowpart (Pmode, operands[3]);
5089 }
5090 [(set_attr "type" "lea")
5091 (set_attr "mode" "SI")])
5092
5093 (define_insn_and_split "*lea_general_3"
5094 [(set (match_operand 0 "register_operand" "=r")
5095 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5096 (match_operand 2 "const248_operand" "i"))
5097 (match_operand 3 "register_operand" "r"))
5098 (match_operand 4 "immediate_operand" "i")))]
5099 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5100 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5101 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5102 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5103 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5104 "#"
5105 "&& reload_completed"
5106 [(const_int 0)]
5107 {
5108 rtx pat;
5109 operands[0] = gen_lowpart (SImode, operands[0]);
5110 operands[1] = gen_lowpart (Pmode, operands[1]);
5111 operands[3] = gen_lowpart (Pmode, operands[3]);
5112 operands[4] = gen_lowpart (Pmode, operands[4]);
5113 pat = gen_rtx_PLUS (Pmode,
5114 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5115 operands[2]),
5116 operands[3]),
5117 operands[4]);
5118 if (Pmode != SImode)
5119 pat = gen_rtx_SUBREG (SImode, pat, 0);
5120 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5121 DONE;
5122 }
5123 [(set_attr "type" "lea")
5124 (set_attr "mode" "SI")])
5125
5126 (define_insn_and_split "*lea_general_3_zext"
5127 [(set (match_operand:DI 0 "register_operand" "=r")
5128 (zero_extend:DI
5129 (plus:SI (plus:SI (mult:SI
5130 (match_operand:SI 1 "index_register_operand" "l")
5131 (match_operand:SI 2 "const248_operand" "n"))
5132 (match_operand:SI 3 "register_operand" "r"))
5133 (match_operand:SI 4 "immediate_operand" "i"))))]
5134 "TARGET_64BIT"
5135 "#"
5136 "&& reload_completed"
5137 [(set (match_dup 0)
5138 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5139 (match_dup 2))
5140 (match_dup 3))
5141 (match_dup 4)) 0)))]
5142 {
5143 operands[1] = gen_lowpart (Pmode, operands[1]);
5144 operands[3] = gen_lowpart (Pmode, operands[3]);
5145 operands[4] = gen_lowpart (Pmode, operands[4]);
5146 }
5147 [(set_attr "type" "lea")
5148 (set_attr "mode" "SI")])
5149
5150 (define_insn "*adddi_1_rex64"
5151 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5152 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5153 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5154 (clobber (reg:CC FLAGS_REG))]
5155 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5156 {
5157 switch (get_attr_type (insn))
5158 {
5159 case TYPE_LEA:
5160 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5161 return "lea{q}\t{%a2, %0|%0, %a2}";
5162
5163 case TYPE_INCDEC:
5164 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5165 if (operands[2] == const1_rtx)
5166 return "inc{q}\t%0";
5167 else
5168 {
5169 gcc_assert (operands[2] == constm1_rtx);
5170 return "dec{q}\t%0";
5171 }
5172
5173 default:
5174 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5175
5176 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5177 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5178 if (GET_CODE (operands[2]) == CONST_INT
5179 /* Avoid overflows. */
5180 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5181 && (INTVAL (operands[2]) == 128
5182 || (INTVAL (operands[2]) < 0
5183 && INTVAL (operands[2]) != -128)))
5184 {
5185 operands[2] = GEN_INT (-INTVAL (operands[2]));
5186 return "sub{q}\t{%2, %0|%0, %2}";
5187 }
5188 return "add{q}\t{%2, %0|%0, %2}";
5189 }
5190 }
5191 [(set (attr "type")
5192 (cond [(eq_attr "alternative" "2")
5193 (const_string "lea")
5194 ; Current assemblers are broken and do not allow @GOTOFF in
5195 ; ought but a memory context.
5196 (match_operand:DI 2 "pic_symbolic_operand" "")
5197 (const_string "lea")
5198 (match_operand:DI 2 "incdec_operand" "")
5199 (const_string "incdec")
5200 ]
5201 (const_string "alu")))
5202 (set_attr "mode" "DI")])
5203
5204 ;; Convert lea to the lea pattern to avoid flags dependency.
5205 (define_split
5206 [(set (match_operand:DI 0 "register_operand" "")
5207 (plus:DI (match_operand:DI 1 "register_operand" "")
5208 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5209 (clobber (reg:CC FLAGS_REG))]
5210 "TARGET_64BIT && reload_completed
5211 && true_regnum (operands[0]) != true_regnum (operands[1])"
5212 [(set (match_dup 0)
5213 (plus:DI (match_dup 1)
5214 (match_dup 2)))]
5215 "")
5216
5217 (define_insn "*adddi_2_rex64"
5218 [(set (reg FLAGS_REG)
5219 (compare
5220 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5221 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5222 (const_int 0)))
5223 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5224 (plus:DI (match_dup 1) (match_dup 2)))]
5225 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5226 && ix86_binary_operator_ok (PLUS, DImode, operands)
5227 /* Current assemblers are broken and do not allow @GOTOFF in
5228 ought but a memory context. */
5229 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5230 {
5231 switch (get_attr_type (insn))
5232 {
5233 case TYPE_INCDEC:
5234 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5235 if (operands[2] == const1_rtx)
5236 return "inc{q}\t%0";
5237 else
5238 {
5239 gcc_assert (operands[2] == constm1_rtx);
5240 return "dec{q}\t%0";
5241 }
5242
5243 default:
5244 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5245 /* ???? We ought to handle there the 32bit case too
5246 - do we need new constraint? */
5247 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5248 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5249 if (GET_CODE (operands[2]) == CONST_INT
5250 /* Avoid overflows. */
5251 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5252 && (INTVAL (operands[2]) == 128
5253 || (INTVAL (operands[2]) < 0
5254 && INTVAL (operands[2]) != -128)))
5255 {
5256 operands[2] = GEN_INT (-INTVAL (operands[2]));
5257 return "sub{q}\t{%2, %0|%0, %2}";
5258 }
5259 return "add{q}\t{%2, %0|%0, %2}";
5260 }
5261 }
5262 [(set (attr "type")
5263 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5264 (const_string "incdec")
5265 (const_string "alu")))
5266 (set_attr "mode" "DI")])
5267
5268 (define_insn "*adddi_3_rex64"
5269 [(set (reg FLAGS_REG)
5270 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5271 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5272 (clobber (match_scratch:DI 0 "=r"))]
5273 "TARGET_64BIT
5274 && ix86_match_ccmode (insn, CCZmode)
5275 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5276 /* Current assemblers are broken and do not allow @GOTOFF in
5277 ought but a memory context. */
5278 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5279 {
5280 switch (get_attr_type (insn))
5281 {
5282 case TYPE_INCDEC:
5283 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5284 if (operands[2] == const1_rtx)
5285 return "inc{q}\t%0";
5286 else
5287 {
5288 gcc_assert (operands[2] == constm1_rtx);
5289 return "dec{q}\t%0";
5290 }
5291
5292 default:
5293 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5294 /* ???? We ought to handle there the 32bit case too
5295 - do we need new constraint? */
5296 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5297 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5298 if (GET_CODE (operands[2]) == CONST_INT
5299 /* Avoid overflows. */
5300 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5301 && (INTVAL (operands[2]) == 128
5302 || (INTVAL (operands[2]) < 0
5303 && INTVAL (operands[2]) != -128)))
5304 {
5305 operands[2] = GEN_INT (-INTVAL (operands[2]));
5306 return "sub{q}\t{%2, %0|%0, %2}";
5307 }
5308 return "add{q}\t{%2, %0|%0, %2}";
5309 }
5310 }
5311 [(set (attr "type")
5312 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5313 (const_string "incdec")
5314 (const_string "alu")))
5315 (set_attr "mode" "DI")])
5316
5317 ; For comparisons against 1, -1 and 128, we may generate better code
5318 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5319 ; is matched then. We can't accept general immediate, because for
5320 ; case of overflows, the result is messed up.
5321 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5322 ; when negated.
5323 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5324 ; only for comparisons not depending on it.
5325 (define_insn "*adddi_4_rex64"
5326 [(set (reg FLAGS_REG)
5327 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5328 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5329 (clobber (match_scratch:DI 0 "=rm"))]
5330 "TARGET_64BIT
5331 && ix86_match_ccmode (insn, CCGCmode)"
5332 {
5333 switch (get_attr_type (insn))
5334 {
5335 case TYPE_INCDEC:
5336 if (operands[2] == constm1_rtx)
5337 return "inc{q}\t%0";
5338 else
5339 {
5340 gcc_assert (operands[2] == const1_rtx);
5341 return "dec{q}\t%0";
5342 }
5343
5344 default:
5345 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5346 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5347 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5348 if ((INTVAL (operands[2]) == -128
5349 || (INTVAL (operands[2]) > 0
5350 && INTVAL (operands[2]) != 128))
5351 /* Avoid overflows. */
5352 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5353 return "sub{q}\t{%2, %0|%0, %2}";
5354 operands[2] = GEN_INT (-INTVAL (operands[2]));
5355 return "add{q}\t{%2, %0|%0, %2}";
5356 }
5357 }
5358 [(set (attr "type")
5359 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5360 (const_string "incdec")
5361 (const_string "alu")))
5362 (set_attr "mode" "DI")])
5363
5364 (define_insn "*adddi_5_rex64"
5365 [(set (reg FLAGS_REG)
5366 (compare
5367 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5368 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5369 (const_int 0)))
5370 (clobber (match_scratch:DI 0 "=r"))]
5371 "TARGET_64BIT
5372 && ix86_match_ccmode (insn, CCGOCmode)
5373 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5374 /* Current assemblers are broken and do not allow @GOTOFF in
5375 ought but a memory context. */
5376 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5377 {
5378 switch (get_attr_type (insn))
5379 {
5380 case TYPE_INCDEC:
5381 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5382 if (operands[2] == const1_rtx)
5383 return "inc{q}\t%0";
5384 else
5385 {
5386 gcc_assert (operands[2] == constm1_rtx);
5387 return "dec{q}\t%0";
5388 }
5389
5390 default:
5391 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5392 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5393 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5394 if (GET_CODE (operands[2]) == CONST_INT
5395 /* Avoid overflows. */
5396 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5397 && (INTVAL (operands[2]) == 128
5398 || (INTVAL (operands[2]) < 0
5399 && INTVAL (operands[2]) != -128)))
5400 {
5401 operands[2] = GEN_INT (-INTVAL (operands[2]));
5402 return "sub{q}\t{%2, %0|%0, %2}";
5403 }
5404 return "add{q}\t{%2, %0|%0, %2}";
5405 }
5406 }
5407 [(set (attr "type")
5408 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5409 (const_string "incdec")
5410 (const_string "alu")))
5411 (set_attr "mode" "DI")])
5412
5413
5414 (define_insn "*addsi_1"
5415 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5416 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5417 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5418 (clobber (reg:CC FLAGS_REG))]
5419 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5420 {
5421 switch (get_attr_type (insn))
5422 {
5423 case TYPE_LEA:
5424 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5425 return "lea{l}\t{%a2, %0|%0, %a2}";
5426
5427 case TYPE_INCDEC:
5428 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5429 if (operands[2] == const1_rtx)
5430 return "inc{l}\t%0";
5431 else
5432 {
5433 gcc_assert (operands[2] == constm1_rtx);
5434 return "dec{l}\t%0";
5435 }
5436
5437 default:
5438 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5439
5440 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5441 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5442 if (GET_CODE (operands[2]) == CONST_INT
5443 && (INTVAL (operands[2]) == 128
5444 || (INTVAL (operands[2]) < 0
5445 && INTVAL (operands[2]) != -128)))
5446 {
5447 operands[2] = GEN_INT (-INTVAL (operands[2]));
5448 return "sub{l}\t{%2, %0|%0, %2}";
5449 }
5450 return "add{l}\t{%2, %0|%0, %2}";
5451 }
5452 }
5453 [(set (attr "type")
5454 (cond [(eq_attr "alternative" "2")
5455 (const_string "lea")
5456 ; Current assemblers are broken and do not allow @GOTOFF in
5457 ; ought but a memory context.
5458 (match_operand:SI 2 "pic_symbolic_operand" "")
5459 (const_string "lea")
5460 (match_operand:SI 2 "incdec_operand" "")
5461 (const_string "incdec")
5462 ]
5463 (const_string "alu")))
5464 (set_attr "mode" "SI")])
5465
5466 ;; Convert lea to the lea pattern to avoid flags dependency.
5467 (define_split
5468 [(set (match_operand 0 "register_operand" "")
5469 (plus (match_operand 1 "register_operand" "")
5470 (match_operand 2 "nonmemory_operand" "")))
5471 (clobber (reg:CC FLAGS_REG))]
5472 "reload_completed
5473 && true_regnum (operands[0]) != true_regnum (operands[1])"
5474 [(const_int 0)]
5475 {
5476 rtx pat;
5477 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5478 may confuse gen_lowpart. */
5479 if (GET_MODE (operands[0]) != Pmode)
5480 {
5481 operands[1] = gen_lowpart (Pmode, operands[1]);
5482 operands[2] = gen_lowpart (Pmode, operands[2]);
5483 }
5484 operands[0] = gen_lowpart (SImode, operands[0]);
5485 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5486 if (Pmode != SImode)
5487 pat = gen_rtx_SUBREG (SImode, pat, 0);
5488 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5489 DONE;
5490 })
5491
5492 ;; It may seem that nonimmediate operand is proper one for operand 1.
5493 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5494 ;; we take care in ix86_binary_operator_ok to not allow two memory
5495 ;; operands so proper swapping will be done in reload. This allow
5496 ;; patterns constructed from addsi_1 to match.
5497 (define_insn "addsi_1_zext"
5498 [(set (match_operand:DI 0 "register_operand" "=r,r")
5499 (zero_extend:DI
5500 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5501 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5502 (clobber (reg:CC FLAGS_REG))]
5503 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5504 {
5505 switch (get_attr_type (insn))
5506 {
5507 case TYPE_LEA:
5508 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5509 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5510
5511 case TYPE_INCDEC:
5512 if (operands[2] == const1_rtx)
5513 return "inc{l}\t%k0";
5514 else
5515 {
5516 gcc_assert (operands[2] == constm1_rtx);
5517 return "dec{l}\t%k0";
5518 }
5519
5520 default:
5521 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5522 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5523 if (GET_CODE (operands[2]) == CONST_INT
5524 && (INTVAL (operands[2]) == 128
5525 || (INTVAL (operands[2]) < 0
5526 && INTVAL (operands[2]) != -128)))
5527 {
5528 operands[2] = GEN_INT (-INTVAL (operands[2]));
5529 return "sub{l}\t{%2, %k0|%k0, %2}";
5530 }
5531 return "add{l}\t{%2, %k0|%k0, %2}";
5532 }
5533 }
5534 [(set (attr "type")
5535 (cond [(eq_attr "alternative" "1")
5536 (const_string "lea")
5537 ; Current assemblers are broken and do not allow @GOTOFF in
5538 ; ought but a memory context.
5539 (match_operand:SI 2 "pic_symbolic_operand" "")
5540 (const_string "lea")
5541 (match_operand:SI 2 "incdec_operand" "")
5542 (const_string "incdec")
5543 ]
5544 (const_string "alu")))
5545 (set_attr "mode" "SI")])
5546
5547 ;; Convert lea to the lea pattern to avoid flags dependency.
5548 (define_split
5549 [(set (match_operand:DI 0 "register_operand" "")
5550 (zero_extend:DI
5551 (plus:SI (match_operand:SI 1 "register_operand" "")
5552 (match_operand:SI 2 "nonmemory_operand" ""))))
5553 (clobber (reg:CC FLAGS_REG))]
5554 "TARGET_64BIT && reload_completed
5555 && true_regnum (operands[0]) != true_regnum (operands[1])"
5556 [(set (match_dup 0)
5557 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5558 {
5559 operands[1] = gen_lowpart (Pmode, operands[1]);
5560 operands[2] = gen_lowpart (Pmode, operands[2]);
5561 })
5562
5563 (define_insn "*addsi_2"
5564 [(set (reg FLAGS_REG)
5565 (compare
5566 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5567 (match_operand:SI 2 "general_operand" "rmni,rni"))
5568 (const_int 0)))
5569 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5570 (plus:SI (match_dup 1) (match_dup 2)))]
5571 "ix86_match_ccmode (insn, CCGOCmode)
5572 && ix86_binary_operator_ok (PLUS, SImode, operands)
5573 /* Current assemblers are broken and do not allow @GOTOFF in
5574 ought but a memory context. */
5575 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5576 {
5577 switch (get_attr_type (insn))
5578 {
5579 case TYPE_INCDEC:
5580 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5581 if (operands[2] == const1_rtx)
5582 return "inc{l}\t%0";
5583 else
5584 {
5585 gcc_assert (operands[2] == constm1_rtx);
5586 return "dec{l}\t%0";
5587 }
5588
5589 default:
5590 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5591 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5592 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5593 if (GET_CODE (operands[2]) == CONST_INT
5594 && (INTVAL (operands[2]) == 128
5595 || (INTVAL (operands[2]) < 0
5596 && INTVAL (operands[2]) != -128)))
5597 {
5598 operands[2] = GEN_INT (-INTVAL (operands[2]));
5599 return "sub{l}\t{%2, %0|%0, %2}";
5600 }
5601 return "add{l}\t{%2, %0|%0, %2}";
5602 }
5603 }
5604 [(set (attr "type")
5605 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5606 (const_string "incdec")
5607 (const_string "alu")))
5608 (set_attr "mode" "SI")])
5609
5610 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5611 (define_insn "*addsi_2_zext"
5612 [(set (reg FLAGS_REG)
5613 (compare
5614 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5615 (match_operand:SI 2 "general_operand" "rmni"))
5616 (const_int 0)))
5617 (set (match_operand:DI 0 "register_operand" "=r")
5618 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5619 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5620 && ix86_binary_operator_ok (PLUS, SImode, operands)
5621 /* Current assemblers are broken and do not allow @GOTOFF in
5622 ought but a memory context. */
5623 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5624 {
5625 switch (get_attr_type (insn))
5626 {
5627 case TYPE_INCDEC:
5628 if (operands[2] == const1_rtx)
5629 return "inc{l}\t%k0";
5630 else
5631 {
5632 gcc_assert (operands[2] == constm1_rtx);
5633 return "dec{l}\t%k0";
5634 }
5635
5636 default:
5637 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5638 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5639 if (GET_CODE (operands[2]) == CONST_INT
5640 && (INTVAL (operands[2]) == 128
5641 || (INTVAL (operands[2]) < 0
5642 && INTVAL (operands[2]) != -128)))
5643 {
5644 operands[2] = GEN_INT (-INTVAL (operands[2]));
5645 return "sub{l}\t{%2, %k0|%k0, %2}";
5646 }
5647 return "add{l}\t{%2, %k0|%k0, %2}";
5648 }
5649 }
5650 [(set (attr "type")
5651 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5652 (const_string "incdec")
5653 (const_string "alu")))
5654 (set_attr "mode" "SI")])
5655
5656 (define_insn "*addsi_3"
5657 [(set (reg FLAGS_REG)
5658 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5659 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5660 (clobber (match_scratch:SI 0 "=r"))]
5661 "ix86_match_ccmode (insn, CCZmode)
5662 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5663 /* Current assemblers are broken and do not allow @GOTOFF in
5664 ought but a memory context. */
5665 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5666 {
5667 switch (get_attr_type (insn))
5668 {
5669 case TYPE_INCDEC:
5670 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5671 if (operands[2] == const1_rtx)
5672 return "inc{l}\t%0";
5673 else
5674 {
5675 gcc_assert (operands[2] == constm1_rtx);
5676 return "dec{l}\t%0";
5677 }
5678
5679 default:
5680 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5682 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5683 if (GET_CODE (operands[2]) == CONST_INT
5684 && (INTVAL (operands[2]) == 128
5685 || (INTVAL (operands[2]) < 0
5686 && INTVAL (operands[2]) != -128)))
5687 {
5688 operands[2] = GEN_INT (-INTVAL (operands[2]));
5689 return "sub{l}\t{%2, %0|%0, %2}";
5690 }
5691 return "add{l}\t{%2, %0|%0, %2}";
5692 }
5693 }
5694 [(set (attr "type")
5695 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5696 (const_string "incdec")
5697 (const_string "alu")))
5698 (set_attr "mode" "SI")])
5699
5700 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5701 (define_insn "*addsi_3_zext"
5702 [(set (reg FLAGS_REG)
5703 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5704 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5705 (set (match_operand:DI 0 "register_operand" "=r")
5706 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5707 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5708 && ix86_binary_operator_ok (PLUS, SImode, operands)
5709 /* Current assemblers are broken and do not allow @GOTOFF in
5710 ought but a memory context. */
5711 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5712 {
5713 switch (get_attr_type (insn))
5714 {
5715 case TYPE_INCDEC:
5716 if (operands[2] == const1_rtx)
5717 return "inc{l}\t%k0";
5718 else
5719 {
5720 gcc_assert (operands[2] == constm1_rtx);
5721 return "dec{l}\t%k0";
5722 }
5723
5724 default:
5725 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5726 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5727 if (GET_CODE (operands[2]) == CONST_INT
5728 && (INTVAL (operands[2]) == 128
5729 || (INTVAL (operands[2]) < 0
5730 && INTVAL (operands[2]) != -128)))
5731 {
5732 operands[2] = GEN_INT (-INTVAL (operands[2]));
5733 return "sub{l}\t{%2, %k0|%k0, %2}";
5734 }
5735 return "add{l}\t{%2, %k0|%k0, %2}";
5736 }
5737 }
5738 [(set (attr "type")
5739 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5740 (const_string "incdec")
5741 (const_string "alu")))
5742 (set_attr "mode" "SI")])
5743
5744 ; For comparisons against 1, -1 and 128, we may generate better code
5745 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5746 ; is matched then. We can't accept general immediate, because for
5747 ; case of overflows, the result is messed up.
5748 ; This pattern also don't hold of 0x80000000, since the value overflows
5749 ; when negated.
5750 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5751 ; only for comparisons not depending on it.
5752 (define_insn "*addsi_4"
5753 [(set (reg FLAGS_REG)
5754 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5755 (match_operand:SI 2 "const_int_operand" "n")))
5756 (clobber (match_scratch:SI 0 "=rm"))]
5757 "ix86_match_ccmode (insn, CCGCmode)
5758 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5759 {
5760 switch (get_attr_type (insn))
5761 {
5762 case TYPE_INCDEC:
5763 if (operands[2] == constm1_rtx)
5764 return "inc{l}\t%0";
5765 else
5766 {
5767 gcc_assert (operands[2] == const1_rtx);
5768 return "dec{l}\t%0";
5769 }
5770
5771 default:
5772 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5773 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5774 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5775 if ((INTVAL (operands[2]) == -128
5776 || (INTVAL (operands[2]) > 0
5777 && INTVAL (operands[2]) != 128)))
5778 return "sub{l}\t{%2, %0|%0, %2}";
5779 operands[2] = GEN_INT (-INTVAL (operands[2]));
5780 return "add{l}\t{%2, %0|%0, %2}";
5781 }
5782 }
5783 [(set (attr "type")
5784 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5785 (const_string "incdec")
5786 (const_string "alu")))
5787 (set_attr "mode" "SI")])
5788
5789 (define_insn "*addsi_5"
5790 [(set (reg FLAGS_REG)
5791 (compare
5792 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5793 (match_operand:SI 2 "general_operand" "rmni"))
5794 (const_int 0)))
5795 (clobber (match_scratch:SI 0 "=r"))]
5796 "ix86_match_ccmode (insn, CCGOCmode)
5797 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5798 /* Current assemblers are broken and do not allow @GOTOFF in
5799 ought but a memory context. */
5800 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5801 {
5802 switch (get_attr_type (insn))
5803 {
5804 case TYPE_INCDEC:
5805 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5806 if (operands[2] == const1_rtx)
5807 return "inc{l}\t%0";
5808 else
5809 {
5810 gcc_assert (operands[2] == constm1_rtx);
5811 return "dec{l}\t%0";
5812 }
5813
5814 default:
5815 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5816 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5817 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5818 if (GET_CODE (operands[2]) == CONST_INT
5819 && (INTVAL (operands[2]) == 128
5820 || (INTVAL (operands[2]) < 0
5821 && INTVAL (operands[2]) != -128)))
5822 {
5823 operands[2] = GEN_INT (-INTVAL (operands[2]));
5824 return "sub{l}\t{%2, %0|%0, %2}";
5825 }
5826 return "add{l}\t{%2, %0|%0, %2}";
5827 }
5828 }
5829 [(set (attr "type")
5830 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5831 (const_string "incdec")
5832 (const_string "alu")))
5833 (set_attr "mode" "SI")])
5834
5835 (define_expand "addhi3"
5836 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5837 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5838 (match_operand:HI 2 "general_operand" "")))
5839 (clobber (reg:CC FLAGS_REG))])]
5840 "TARGET_HIMODE_MATH"
5841 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5842
5843 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5844 ;; type optimizations enabled by define-splits. This is not important
5845 ;; for PII, and in fact harmful because of partial register stalls.
5846
5847 (define_insn "*addhi_1_lea"
5848 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5849 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5850 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5851 (clobber (reg:CC FLAGS_REG))]
5852 "!TARGET_PARTIAL_REG_STALL
5853 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5854 {
5855 switch (get_attr_type (insn))
5856 {
5857 case TYPE_LEA:
5858 return "#";
5859 case TYPE_INCDEC:
5860 if (operands[2] == const1_rtx)
5861 return "inc{w}\t%0";
5862 else
5863 {
5864 gcc_assert (operands[2] == constm1_rtx);
5865 return "dec{w}\t%0";
5866 }
5867
5868 default:
5869 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5870 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5871 if (GET_CODE (operands[2]) == CONST_INT
5872 && (INTVAL (operands[2]) == 128
5873 || (INTVAL (operands[2]) < 0
5874 && INTVAL (operands[2]) != -128)))
5875 {
5876 operands[2] = GEN_INT (-INTVAL (operands[2]));
5877 return "sub{w}\t{%2, %0|%0, %2}";
5878 }
5879 return "add{w}\t{%2, %0|%0, %2}";
5880 }
5881 }
5882 [(set (attr "type")
5883 (if_then_else (eq_attr "alternative" "2")
5884 (const_string "lea")
5885 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5886 (const_string "incdec")
5887 (const_string "alu"))))
5888 (set_attr "mode" "HI,HI,SI")])
5889
5890 (define_insn "*addhi_1"
5891 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5892 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5893 (match_operand:HI 2 "general_operand" "ri,rm")))
5894 (clobber (reg:CC FLAGS_REG))]
5895 "TARGET_PARTIAL_REG_STALL
5896 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5897 {
5898 switch (get_attr_type (insn))
5899 {
5900 case TYPE_INCDEC:
5901 if (operands[2] == const1_rtx)
5902 return "inc{w}\t%0";
5903 else
5904 {
5905 gcc_assert (operands[2] == constm1_rtx);
5906 return "dec{w}\t%0";
5907 }
5908
5909 default:
5910 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5911 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5912 if (GET_CODE (operands[2]) == CONST_INT
5913 && (INTVAL (operands[2]) == 128
5914 || (INTVAL (operands[2]) < 0
5915 && INTVAL (operands[2]) != -128)))
5916 {
5917 operands[2] = GEN_INT (-INTVAL (operands[2]));
5918 return "sub{w}\t{%2, %0|%0, %2}";
5919 }
5920 return "add{w}\t{%2, %0|%0, %2}";
5921 }
5922 }
5923 [(set (attr "type")
5924 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5925 (const_string "incdec")
5926 (const_string "alu")))
5927 (set_attr "mode" "HI")])
5928
5929 (define_insn "*addhi_2"
5930 [(set (reg FLAGS_REG)
5931 (compare
5932 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5933 (match_operand:HI 2 "general_operand" "rmni,rni"))
5934 (const_int 0)))
5935 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5936 (plus:HI (match_dup 1) (match_dup 2)))]
5937 "ix86_match_ccmode (insn, CCGOCmode)
5938 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5939 {
5940 switch (get_attr_type (insn))
5941 {
5942 case TYPE_INCDEC:
5943 if (operands[2] == const1_rtx)
5944 return "inc{w}\t%0";
5945 else
5946 {
5947 gcc_assert (operands[2] == constm1_rtx);
5948 return "dec{w}\t%0";
5949 }
5950
5951 default:
5952 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5953 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5954 if (GET_CODE (operands[2]) == CONST_INT
5955 && (INTVAL (operands[2]) == 128
5956 || (INTVAL (operands[2]) < 0
5957 && INTVAL (operands[2]) != -128)))
5958 {
5959 operands[2] = GEN_INT (-INTVAL (operands[2]));
5960 return "sub{w}\t{%2, %0|%0, %2}";
5961 }
5962 return "add{w}\t{%2, %0|%0, %2}";
5963 }
5964 }
5965 [(set (attr "type")
5966 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5967 (const_string "incdec")
5968 (const_string "alu")))
5969 (set_attr "mode" "HI")])
5970
5971 (define_insn "*addhi_3"
5972 [(set (reg FLAGS_REG)
5973 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5974 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5975 (clobber (match_scratch:HI 0 "=r"))]
5976 "ix86_match_ccmode (insn, CCZmode)
5977 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5978 {
5979 switch (get_attr_type (insn))
5980 {
5981 case TYPE_INCDEC:
5982 if (operands[2] == const1_rtx)
5983 return "inc{w}\t%0";
5984 else
5985 {
5986 gcc_assert (operands[2] == constm1_rtx);
5987 return "dec{w}\t%0";
5988 }
5989
5990 default:
5991 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5992 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5993 if (GET_CODE (operands[2]) == CONST_INT
5994 && (INTVAL (operands[2]) == 128
5995 || (INTVAL (operands[2]) < 0
5996 && INTVAL (operands[2]) != -128)))
5997 {
5998 operands[2] = GEN_INT (-INTVAL (operands[2]));
5999 return "sub{w}\t{%2, %0|%0, %2}";
6000 }
6001 return "add{w}\t{%2, %0|%0, %2}";
6002 }
6003 }
6004 [(set (attr "type")
6005 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6006 (const_string "incdec")
6007 (const_string "alu")))
6008 (set_attr "mode" "HI")])
6009
6010 ; See comments above addsi_4 for details.
6011 (define_insn "*addhi_4"
6012 [(set (reg FLAGS_REG)
6013 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6014 (match_operand:HI 2 "const_int_operand" "n")))
6015 (clobber (match_scratch:HI 0 "=rm"))]
6016 "ix86_match_ccmode (insn, CCGCmode)
6017 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6018 {
6019 switch (get_attr_type (insn))
6020 {
6021 case TYPE_INCDEC:
6022 if (operands[2] == constm1_rtx)
6023 return "inc{w}\t%0";
6024 else
6025 {
6026 gcc_assert (operands[2] == const1_rtx);
6027 return "dec{w}\t%0";
6028 }
6029
6030 default:
6031 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6032 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6033 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6034 if ((INTVAL (operands[2]) == -128
6035 || (INTVAL (operands[2]) > 0
6036 && INTVAL (operands[2]) != 128)))
6037 return "sub{w}\t{%2, %0|%0, %2}";
6038 operands[2] = GEN_INT (-INTVAL (operands[2]));
6039 return "add{w}\t{%2, %0|%0, %2}";
6040 }
6041 }
6042 [(set (attr "type")
6043 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6044 (const_string "incdec")
6045 (const_string "alu")))
6046 (set_attr "mode" "SI")])
6047
6048
6049 (define_insn "*addhi_5"
6050 [(set (reg FLAGS_REG)
6051 (compare
6052 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6053 (match_operand:HI 2 "general_operand" "rmni"))
6054 (const_int 0)))
6055 (clobber (match_scratch:HI 0 "=r"))]
6056 "ix86_match_ccmode (insn, CCGOCmode)
6057 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6058 {
6059 switch (get_attr_type (insn))
6060 {
6061 case TYPE_INCDEC:
6062 if (operands[2] == const1_rtx)
6063 return "inc{w}\t%0";
6064 else
6065 {
6066 gcc_assert (operands[2] == constm1_rtx);
6067 return "dec{w}\t%0";
6068 }
6069
6070 default:
6071 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6072 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6073 if (GET_CODE (operands[2]) == CONST_INT
6074 && (INTVAL (operands[2]) == 128
6075 || (INTVAL (operands[2]) < 0
6076 && INTVAL (operands[2]) != -128)))
6077 {
6078 operands[2] = GEN_INT (-INTVAL (operands[2]));
6079 return "sub{w}\t{%2, %0|%0, %2}";
6080 }
6081 return "add{w}\t{%2, %0|%0, %2}";
6082 }
6083 }
6084 [(set (attr "type")
6085 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6086 (const_string "incdec")
6087 (const_string "alu")))
6088 (set_attr "mode" "HI")])
6089
6090 (define_expand "addqi3"
6091 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6092 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6093 (match_operand:QI 2 "general_operand" "")))
6094 (clobber (reg:CC FLAGS_REG))])]
6095 "TARGET_QIMODE_MATH"
6096 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6097
6098 ;; %%% Potential partial reg stall on alternative 2. What to do?
6099 (define_insn "*addqi_1_lea"
6100 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6101 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6102 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6103 (clobber (reg:CC FLAGS_REG))]
6104 "!TARGET_PARTIAL_REG_STALL
6105 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6106 {
6107 int widen = (which_alternative == 2);
6108 switch (get_attr_type (insn))
6109 {
6110 case TYPE_LEA:
6111 return "#";
6112 case TYPE_INCDEC:
6113 if (operands[2] == const1_rtx)
6114 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6115 else
6116 {
6117 gcc_assert (operands[2] == constm1_rtx);
6118 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6119 }
6120
6121 default:
6122 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6123 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6124 if (GET_CODE (operands[2]) == CONST_INT
6125 && (INTVAL (operands[2]) == 128
6126 || (INTVAL (operands[2]) < 0
6127 && INTVAL (operands[2]) != -128)))
6128 {
6129 operands[2] = GEN_INT (-INTVAL (operands[2]));
6130 if (widen)
6131 return "sub{l}\t{%2, %k0|%k0, %2}";
6132 else
6133 return "sub{b}\t{%2, %0|%0, %2}";
6134 }
6135 if (widen)
6136 return "add{l}\t{%k2, %k0|%k0, %k2}";
6137 else
6138 return "add{b}\t{%2, %0|%0, %2}";
6139 }
6140 }
6141 [(set (attr "type")
6142 (if_then_else (eq_attr "alternative" "3")
6143 (const_string "lea")
6144 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6145 (const_string "incdec")
6146 (const_string "alu"))))
6147 (set_attr "mode" "QI,QI,SI,SI")])
6148
6149 (define_insn "*addqi_1"
6150 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6151 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6152 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6153 (clobber (reg:CC FLAGS_REG))]
6154 "TARGET_PARTIAL_REG_STALL
6155 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6156 {
6157 int widen = (which_alternative == 2);
6158 switch (get_attr_type (insn))
6159 {
6160 case TYPE_INCDEC:
6161 if (operands[2] == const1_rtx)
6162 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6163 else
6164 {
6165 gcc_assert (operands[2] == constm1_rtx);
6166 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6167 }
6168
6169 default:
6170 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6171 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6172 if (GET_CODE (operands[2]) == CONST_INT
6173 && (INTVAL (operands[2]) == 128
6174 || (INTVAL (operands[2]) < 0
6175 && INTVAL (operands[2]) != -128)))
6176 {
6177 operands[2] = GEN_INT (-INTVAL (operands[2]));
6178 if (widen)
6179 return "sub{l}\t{%2, %k0|%k0, %2}";
6180 else
6181 return "sub{b}\t{%2, %0|%0, %2}";
6182 }
6183 if (widen)
6184 return "add{l}\t{%k2, %k0|%k0, %k2}";
6185 else
6186 return "add{b}\t{%2, %0|%0, %2}";
6187 }
6188 }
6189 [(set (attr "type")
6190 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6191 (const_string "incdec")
6192 (const_string "alu")))
6193 (set_attr "mode" "QI,QI,SI")])
6194
6195 (define_insn "*addqi_1_slp"
6196 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6197 (plus:QI (match_dup 0)
6198 (match_operand:QI 1 "general_operand" "qn,qnm")))
6199 (clobber (reg:CC FLAGS_REG))]
6200 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6201 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6202 {
6203 switch (get_attr_type (insn))
6204 {
6205 case TYPE_INCDEC:
6206 if (operands[1] == const1_rtx)
6207 return "inc{b}\t%0";
6208 else
6209 {
6210 gcc_assert (operands[1] == constm1_rtx);
6211 return "dec{b}\t%0";
6212 }
6213
6214 default:
6215 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6216 if (GET_CODE (operands[1]) == CONST_INT
6217 && INTVAL (operands[1]) < 0)
6218 {
6219 operands[1] = GEN_INT (-INTVAL (operands[1]));
6220 return "sub{b}\t{%1, %0|%0, %1}";
6221 }
6222 return "add{b}\t{%1, %0|%0, %1}";
6223 }
6224 }
6225 [(set (attr "type")
6226 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6227 (const_string "incdec")
6228 (const_string "alu1")))
6229 (set (attr "memory")
6230 (if_then_else (match_operand 1 "memory_operand" "")
6231 (const_string "load")
6232 (const_string "none")))
6233 (set_attr "mode" "QI")])
6234
6235 (define_insn "*addqi_2"
6236 [(set (reg FLAGS_REG)
6237 (compare
6238 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6239 (match_operand:QI 2 "general_operand" "qmni,qni"))
6240 (const_int 0)))
6241 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6242 (plus:QI (match_dup 1) (match_dup 2)))]
6243 "ix86_match_ccmode (insn, CCGOCmode)
6244 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6245 {
6246 switch (get_attr_type (insn))
6247 {
6248 case TYPE_INCDEC:
6249 if (operands[2] == const1_rtx)
6250 return "inc{b}\t%0";
6251 else
6252 {
6253 gcc_assert (operands[2] == constm1_rtx
6254 || (GET_CODE (operands[2]) == CONST_INT
6255 && INTVAL (operands[2]) == 255));
6256 return "dec{b}\t%0";
6257 }
6258
6259 default:
6260 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6261 if (GET_CODE (operands[2]) == CONST_INT
6262 && INTVAL (operands[2]) < 0)
6263 {
6264 operands[2] = GEN_INT (-INTVAL (operands[2]));
6265 return "sub{b}\t{%2, %0|%0, %2}";
6266 }
6267 return "add{b}\t{%2, %0|%0, %2}";
6268 }
6269 }
6270 [(set (attr "type")
6271 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6272 (const_string "incdec")
6273 (const_string "alu")))
6274 (set_attr "mode" "QI")])
6275
6276 (define_insn "*addqi_3"
6277 [(set (reg FLAGS_REG)
6278 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6279 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6280 (clobber (match_scratch:QI 0 "=q"))]
6281 "ix86_match_ccmode (insn, CCZmode)
6282 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6283 {
6284 switch (get_attr_type (insn))
6285 {
6286 case TYPE_INCDEC:
6287 if (operands[2] == const1_rtx)
6288 return "inc{b}\t%0";
6289 else
6290 {
6291 gcc_assert (operands[2] == constm1_rtx
6292 || (GET_CODE (operands[2]) == CONST_INT
6293 && INTVAL (operands[2]) == 255));
6294 return "dec{b}\t%0";
6295 }
6296
6297 default:
6298 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6299 if (GET_CODE (operands[2]) == CONST_INT
6300 && INTVAL (operands[2]) < 0)
6301 {
6302 operands[2] = GEN_INT (-INTVAL (operands[2]));
6303 return "sub{b}\t{%2, %0|%0, %2}";
6304 }
6305 return "add{b}\t{%2, %0|%0, %2}";
6306 }
6307 }
6308 [(set (attr "type")
6309 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6310 (const_string "incdec")
6311 (const_string "alu")))
6312 (set_attr "mode" "QI")])
6313
6314 ; See comments above addsi_4 for details.
6315 (define_insn "*addqi_4"
6316 [(set (reg FLAGS_REG)
6317 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6318 (match_operand:QI 2 "const_int_operand" "n")))
6319 (clobber (match_scratch:QI 0 "=qm"))]
6320 "ix86_match_ccmode (insn, CCGCmode)
6321 && (INTVAL (operands[2]) & 0xff) != 0x80"
6322 {
6323 switch (get_attr_type (insn))
6324 {
6325 case TYPE_INCDEC:
6326 if (operands[2] == constm1_rtx
6327 || (GET_CODE (operands[2]) == CONST_INT
6328 && INTVAL (operands[2]) == 255))
6329 return "inc{b}\t%0";
6330 else
6331 {
6332 gcc_assert (operands[2] == const1_rtx);
6333 return "dec{b}\t%0";
6334 }
6335
6336 default:
6337 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6338 if (INTVAL (operands[2]) < 0)
6339 {
6340 operands[2] = GEN_INT (-INTVAL (operands[2]));
6341 return "add{b}\t{%2, %0|%0, %2}";
6342 }
6343 return "sub{b}\t{%2, %0|%0, %2}";
6344 }
6345 }
6346 [(set (attr "type")
6347 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6348 (const_string "incdec")
6349 (const_string "alu")))
6350 (set_attr "mode" "QI")])
6351
6352
6353 (define_insn "*addqi_5"
6354 [(set (reg FLAGS_REG)
6355 (compare
6356 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6357 (match_operand:QI 2 "general_operand" "qmni"))
6358 (const_int 0)))
6359 (clobber (match_scratch:QI 0 "=q"))]
6360 "ix86_match_ccmode (insn, CCGOCmode)
6361 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6362 {
6363 switch (get_attr_type (insn))
6364 {
6365 case TYPE_INCDEC:
6366 if (operands[2] == const1_rtx)
6367 return "inc{b}\t%0";
6368 else
6369 {
6370 gcc_assert (operands[2] == constm1_rtx
6371 || (GET_CODE (operands[2]) == CONST_INT
6372 && INTVAL (operands[2]) == 255));
6373 return "dec{b}\t%0";
6374 }
6375
6376 default:
6377 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6378 if (GET_CODE (operands[2]) == CONST_INT
6379 && INTVAL (operands[2]) < 0)
6380 {
6381 operands[2] = GEN_INT (-INTVAL (operands[2]));
6382 return "sub{b}\t{%2, %0|%0, %2}";
6383 }
6384 return "add{b}\t{%2, %0|%0, %2}";
6385 }
6386 }
6387 [(set (attr "type")
6388 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389 (const_string "incdec")
6390 (const_string "alu")))
6391 (set_attr "mode" "QI")])
6392
6393
6394 (define_insn "addqi_ext_1"
6395 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6396 (const_int 8)
6397 (const_int 8))
6398 (plus:SI
6399 (zero_extract:SI
6400 (match_operand 1 "ext_register_operand" "0")
6401 (const_int 8)
6402 (const_int 8))
6403 (match_operand:QI 2 "general_operand" "Qmn")))
6404 (clobber (reg:CC FLAGS_REG))]
6405 "!TARGET_64BIT"
6406 {
6407 switch (get_attr_type (insn))
6408 {
6409 case TYPE_INCDEC:
6410 if (operands[2] == const1_rtx)
6411 return "inc{b}\t%h0";
6412 else
6413 {
6414 gcc_assert (operands[2] == constm1_rtx
6415 || (GET_CODE (operands[2]) == CONST_INT
6416 && INTVAL (operands[2]) == 255));
6417 return "dec{b}\t%h0";
6418 }
6419
6420 default:
6421 return "add{b}\t{%2, %h0|%h0, %2}";
6422 }
6423 }
6424 [(set (attr "type")
6425 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6426 (const_string "incdec")
6427 (const_string "alu")))
6428 (set_attr "mode" "QI")])
6429
6430 (define_insn "*addqi_ext_1_rex64"
6431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6432 (const_int 8)
6433 (const_int 8))
6434 (plus:SI
6435 (zero_extract:SI
6436 (match_operand 1 "ext_register_operand" "0")
6437 (const_int 8)
6438 (const_int 8))
6439 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6440 (clobber (reg:CC FLAGS_REG))]
6441 "TARGET_64BIT"
6442 {
6443 switch (get_attr_type (insn))
6444 {
6445 case TYPE_INCDEC:
6446 if (operands[2] == const1_rtx)
6447 return "inc{b}\t%h0";
6448 else
6449 {
6450 gcc_assert (operands[2] == constm1_rtx
6451 || (GET_CODE (operands[2]) == CONST_INT
6452 && INTVAL (operands[2]) == 255));
6453 return "dec{b}\t%h0";
6454 }
6455
6456 default:
6457 return "add{b}\t{%2, %h0|%h0, %2}";
6458 }
6459 }
6460 [(set (attr "type")
6461 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6462 (const_string "incdec")
6463 (const_string "alu")))
6464 (set_attr "mode" "QI")])
6465
6466 (define_insn "*addqi_ext_2"
6467 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6468 (const_int 8)
6469 (const_int 8))
6470 (plus:SI
6471 (zero_extract:SI
6472 (match_operand 1 "ext_register_operand" "%0")
6473 (const_int 8)
6474 (const_int 8))
6475 (zero_extract:SI
6476 (match_operand 2 "ext_register_operand" "Q")
6477 (const_int 8)
6478 (const_int 8))))
6479 (clobber (reg:CC FLAGS_REG))]
6480 ""
6481 "add{b}\t{%h2, %h0|%h0, %h2}"
6482 [(set_attr "type" "alu")
6483 (set_attr "mode" "QI")])
6484
6485 ;; The patterns that match these are at the end of this file.
6486
6487 (define_expand "addxf3"
6488 [(set (match_operand:XF 0 "register_operand" "")
6489 (plus:XF (match_operand:XF 1 "register_operand" "")
6490 (match_operand:XF 2 "register_operand" "")))]
6491 "TARGET_80387"
6492 "")
6493
6494 (define_expand "adddf3"
6495 [(set (match_operand:DF 0 "register_operand" "")
6496 (plus:DF (match_operand:DF 1 "register_operand" "")
6497 (match_operand:DF 2 "nonimmediate_operand" "")))]
6498 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6499 "")
6500
6501 (define_expand "addsf3"
6502 [(set (match_operand:SF 0 "register_operand" "")
6503 (plus:SF (match_operand:SF 1 "register_operand" "")
6504 (match_operand:SF 2 "nonimmediate_operand" "")))]
6505 "TARGET_80387 || TARGET_SSE_MATH"
6506 "")
6507 \f
6508 ;; Subtract instructions
6509
6510 ;; %%% splits for subditi3
6511
6512 (define_expand "subti3"
6513 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6514 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6515 (match_operand:TI 2 "x86_64_general_operand" "")))
6516 (clobber (reg:CC FLAGS_REG))])]
6517 "TARGET_64BIT"
6518 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6519
6520 (define_insn "*subti3_1"
6521 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6522 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6523 (match_operand:TI 2 "general_operand" "roiF,riF")))
6524 (clobber (reg:CC FLAGS_REG))]
6525 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6526 "#")
6527
6528 (define_split
6529 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6530 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6531 (match_operand:TI 2 "general_operand" "")))
6532 (clobber (reg:CC FLAGS_REG))]
6533 "TARGET_64BIT && reload_completed"
6534 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6535 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6536 (parallel [(set (match_dup 3)
6537 (minus:DI (match_dup 4)
6538 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6539 (match_dup 5))))
6540 (clobber (reg:CC FLAGS_REG))])]
6541 "split_ti (operands+0, 1, operands+0, operands+3);
6542 split_ti (operands+1, 1, operands+1, operands+4);
6543 split_ti (operands+2, 1, operands+2, operands+5);")
6544
6545 ;; %%% splits for subsidi3
6546
6547 (define_expand "subdi3"
6548 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6549 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6550 (match_operand:DI 2 "x86_64_general_operand" "")))
6551 (clobber (reg:CC FLAGS_REG))])]
6552 ""
6553 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6554
6555 (define_insn "*subdi3_1"
6556 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6557 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6558 (match_operand:DI 2 "general_operand" "roiF,riF")))
6559 (clobber (reg:CC FLAGS_REG))]
6560 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6561 "#")
6562
6563 (define_split
6564 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6565 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6566 (match_operand:DI 2 "general_operand" "")))
6567 (clobber (reg:CC FLAGS_REG))]
6568 "!TARGET_64BIT && reload_completed"
6569 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6570 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6571 (parallel [(set (match_dup 3)
6572 (minus:SI (match_dup 4)
6573 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6574 (match_dup 5))))
6575 (clobber (reg:CC FLAGS_REG))])]
6576 "split_di (operands+0, 1, operands+0, operands+3);
6577 split_di (operands+1, 1, operands+1, operands+4);
6578 split_di (operands+2, 1, operands+2, operands+5);")
6579
6580 (define_insn "subdi3_carry_rex64"
6581 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6582 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6583 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6584 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6585 (clobber (reg:CC FLAGS_REG))]
6586 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6587 "sbb{q}\t{%2, %0|%0, %2}"
6588 [(set_attr "type" "alu")
6589 (set_attr "pent_pair" "pu")
6590 (set_attr "mode" "DI")])
6591
6592 (define_insn "*subdi_1_rex64"
6593 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6594 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6595 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6598 "sub{q}\t{%2, %0|%0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "mode" "DI")])
6601
6602 (define_insn "*subdi_2_rex64"
6603 [(set (reg FLAGS_REG)
6604 (compare
6605 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6606 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6607 (const_int 0)))
6608 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6609 (minus:DI (match_dup 1) (match_dup 2)))]
6610 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6611 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6612 "sub{q}\t{%2, %0|%0, %2}"
6613 [(set_attr "type" "alu")
6614 (set_attr "mode" "DI")])
6615
6616 (define_insn "*subdi_3_rex63"
6617 [(set (reg FLAGS_REG)
6618 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6619 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6620 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6621 (minus:DI (match_dup 1) (match_dup 2)))]
6622 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6623 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6624 "sub{q}\t{%2, %0|%0, %2}"
6625 [(set_attr "type" "alu")
6626 (set_attr "mode" "DI")])
6627
6628 (define_insn "subqi3_carry"
6629 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6630 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6631 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6632 (match_operand:QI 2 "general_operand" "qi,qm"))))
6633 (clobber (reg:CC FLAGS_REG))]
6634 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6635 "sbb{b}\t{%2, %0|%0, %2}"
6636 [(set_attr "type" "alu")
6637 (set_attr "pent_pair" "pu")
6638 (set_attr "mode" "QI")])
6639
6640 (define_insn "subhi3_carry"
6641 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6642 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6643 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6644 (match_operand:HI 2 "general_operand" "ri,rm"))))
6645 (clobber (reg:CC FLAGS_REG))]
6646 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6647 "sbb{w}\t{%2, %0|%0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "pent_pair" "pu")
6650 (set_attr "mode" "HI")])
6651
6652 (define_insn "subsi3_carry"
6653 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6654 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6655 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6656 (match_operand:SI 2 "general_operand" "ri,rm"))))
6657 (clobber (reg:CC FLAGS_REG))]
6658 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6659 "sbb{l}\t{%2, %0|%0, %2}"
6660 [(set_attr "type" "alu")
6661 (set_attr "pent_pair" "pu")
6662 (set_attr "mode" "SI")])
6663
6664 (define_insn "subsi3_carry_zext"
6665 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6666 (zero_extend:DI
6667 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6668 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6669 (match_operand:SI 2 "general_operand" "ri,rm")))))
6670 (clobber (reg:CC FLAGS_REG))]
6671 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6672 "sbb{l}\t{%2, %k0|%k0, %2}"
6673 [(set_attr "type" "alu")
6674 (set_attr "pent_pair" "pu")
6675 (set_attr "mode" "SI")])
6676
6677 (define_expand "subsi3"
6678 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6679 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6680 (match_operand:SI 2 "general_operand" "")))
6681 (clobber (reg:CC FLAGS_REG))])]
6682 ""
6683 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6684
6685 (define_insn "*subsi_1"
6686 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6687 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6688 (match_operand:SI 2 "general_operand" "ri,rm")))
6689 (clobber (reg:CC FLAGS_REG))]
6690 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6691 "sub{l}\t{%2, %0|%0, %2}"
6692 [(set_attr "type" "alu")
6693 (set_attr "mode" "SI")])
6694
6695 (define_insn "*subsi_1_zext"
6696 [(set (match_operand:DI 0 "register_operand" "=r")
6697 (zero_extend:DI
6698 (minus:SI (match_operand:SI 1 "register_operand" "0")
6699 (match_operand:SI 2 "general_operand" "rim"))))
6700 (clobber (reg:CC FLAGS_REG))]
6701 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6702 "sub{l}\t{%2, %k0|%k0, %2}"
6703 [(set_attr "type" "alu")
6704 (set_attr "mode" "SI")])
6705
6706 (define_insn "*subsi_2"
6707 [(set (reg FLAGS_REG)
6708 (compare
6709 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6710 (match_operand:SI 2 "general_operand" "ri,rm"))
6711 (const_int 0)))
6712 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6713 (minus:SI (match_dup 1) (match_dup 2)))]
6714 "ix86_match_ccmode (insn, CCGOCmode)
6715 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6716 "sub{l}\t{%2, %0|%0, %2}"
6717 [(set_attr "type" "alu")
6718 (set_attr "mode" "SI")])
6719
6720 (define_insn "*subsi_2_zext"
6721 [(set (reg FLAGS_REG)
6722 (compare
6723 (minus:SI (match_operand:SI 1 "register_operand" "0")
6724 (match_operand:SI 2 "general_operand" "rim"))
6725 (const_int 0)))
6726 (set (match_operand:DI 0 "register_operand" "=r")
6727 (zero_extend:DI
6728 (minus:SI (match_dup 1)
6729 (match_dup 2))))]
6730 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6731 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6732 "sub{l}\t{%2, %k0|%k0, %2}"
6733 [(set_attr "type" "alu")
6734 (set_attr "mode" "SI")])
6735
6736 (define_insn "*subsi_3"
6737 [(set (reg FLAGS_REG)
6738 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6739 (match_operand:SI 2 "general_operand" "ri,rm")))
6740 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6741 (minus:SI (match_dup 1) (match_dup 2)))]
6742 "ix86_match_ccmode (insn, CCmode)
6743 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6744 "sub{l}\t{%2, %0|%0, %2}"
6745 [(set_attr "type" "alu")
6746 (set_attr "mode" "SI")])
6747
6748 (define_insn "*subsi_3_zext"
6749 [(set (reg FLAGS_REG)
6750 (compare (match_operand:SI 1 "register_operand" "0")
6751 (match_operand:SI 2 "general_operand" "rim")))
6752 (set (match_operand:DI 0 "register_operand" "=r")
6753 (zero_extend:DI
6754 (minus:SI (match_dup 1)
6755 (match_dup 2))))]
6756 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6757 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6758 "sub{l}\t{%2, %1|%1, %2}"
6759 [(set_attr "type" "alu")
6760 (set_attr "mode" "DI")])
6761
6762 (define_expand "subhi3"
6763 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6764 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6765 (match_operand:HI 2 "general_operand" "")))
6766 (clobber (reg:CC FLAGS_REG))])]
6767 "TARGET_HIMODE_MATH"
6768 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6769
6770 (define_insn "*subhi_1"
6771 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6772 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6773 (match_operand:HI 2 "general_operand" "ri,rm")))
6774 (clobber (reg:CC FLAGS_REG))]
6775 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6776 "sub{w}\t{%2, %0|%0, %2}"
6777 [(set_attr "type" "alu")
6778 (set_attr "mode" "HI")])
6779
6780 (define_insn "*subhi_2"
6781 [(set (reg FLAGS_REG)
6782 (compare
6783 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6784 (match_operand:HI 2 "general_operand" "ri,rm"))
6785 (const_int 0)))
6786 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6787 (minus:HI (match_dup 1) (match_dup 2)))]
6788 "ix86_match_ccmode (insn, CCGOCmode)
6789 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6790 "sub{w}\t{%2, %0|%0, %2}"
6791 [(set_attr "type" "alu")
6792 (set_attr "mode" "HI")])
6793
6794 (define_insn "*subhi_3"
6795 [(set (reg FLAGS_REG)
6796 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6797 (match_operand:HI 2 "general_operand" "ri,rm")))
6798 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6799 (minus:HI (match_dup 1) (match_dup 2)))]
6800 "ix86_match_ccmode (insn, CCmode)
6801 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6802 "sub{w}\t{%2, %0|%0, %2}"
6803 [(set_attr "type" "alu")
6804 (set_attr "mode" "HI")])
6805
6806 (define_expand "subqi3"
6807 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6808 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6809 (match_operand:QI 2 "general_operand" "")))
6810 (clobber (reg:CC FLAGS_REG))])]
6811 "TARGET_QIMODE_MATH"
6812 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6813
6814 (define_insn "*subqi_1"
6815 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6816 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6817 (match_operand:QI 2 "general_operand" "qn,qmn")))
6818 (clobber (reg:CC FLAGS_REG))]
6819 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6820 "sub{b}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "mode" "QI")])
6823
6824 (define_insn "*subqi_1_slp"
6825 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6826 (minus:QI (match_dup 0)
6827 (match_operand:QI 1 "general_operand" "qn,qmn")))
6828 (clobber (reg:CC FLAGS_REG))]
6829 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6830 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6831 "sub{b}\t{%1, %0|%0, %1}"
6832 [(set_attr "type" "alu1")
6833 (set_attr "mode" "QI")])
6834
6835 (define_insn "*subqi_2"
6836 [(set (reg FLAGS_REG)
6837 (compare
6838 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6839 (match_operand:QI 2 "general_operand" "qi,qm"))
6840 (const_int 0)))
6841 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6842 (minus:HI (match_dup 1) (match_dup 2)))]
6843 "ix86_match_ccmode (insn, CCGOCmode)
6844 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6845 "sub{b}\t{%2, %0|%0, %2}"
6846 [(set_attr "type" "alu")
6847 (set_attr "mode" "QI")])
6848
6849 (define_insn "*subqi_3"
6850 [(set (reg FLAGS_REG)
6851 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6852 (match_operand:QI 2 "general_operand" "qi,qm")))
6853 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6854 (minus:HI (match_dup 1) (match_dup 2)))]
6855 "ix86_match_ccmode (insn, CCmode)
6856 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6857 "sub{b}\t{%2, %0|%0, %2}"
6858 [(set_attr "type" "alu")
6859 (set_attr "mode" "QI")])
6860
6861 ;; The patterns that match these are at the end of this file.
6862
6863 (define_expand "subxf3"
6864 [(set (match_operand:XF 0 "register_operand" "")
6865 (minus:XF (match_operand:XF 1 "register_operand" "")
6866 (match_operand:XF 2 "register_operand" "")))]
6867 "TARGET_80387"
6868 "")
6869
6870 (define_expand "subdf3"
6871 [(set (match_operand:DF 0 "register_operand" "")
6872 (minus:DF (match_operand:DF 1 "register_operand" "")
6873 (match_operand:DF 2 "nonimmediate_operand" "")))]
6874 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6875 "")
6876
6877 (define_expand "subsf3"
6878 [(set (match_operand:SF 0 "register_operand" "")
6879 (minus:SF (match_operand:SF 1 "register_operand" "")
6880 (match_operand:SF 2 "nonimmediate_operand" "")))]
6881 "TARGET_80387 || TARGET_SSE_MATH"
6882 "")
6883 \f
6884 ;; Multiply instructions
6885
6886 (define_expand "muldi3"
6887 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6888 (mult:DI (match_operand:DI 1 "register_operand" "")
6889 (match_operand:DI 2 "x86_64_general_operand" "")))
6890 (clobber (reg:CC FLAGS_REG))])]
6891 "TARGET_64BIT"
6892 "")
6893
6894 (define_insn "*muldi3_1_rex64"
6895 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6896 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6897 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6898 (clobber (reg:CC FLAGS_REG))]
6899 "TARGET_64BIT
6900 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6901 "@
6902 imul{q}\t{%2, %1, %0|%0, %1, %2}
6903 imul{q}\t{%2, %1, %0|%0, %1, %2}
6904 imul{q}\t{%2, %0|%0, %2}"
6905 [(set_attr "type" "imul")
6906 (set_attr "prefix_0f" "0,0,1")
6907 (set (attr "athlon_decode")
6908 (cond [(eq_attr "cpu" "athlon")
6909 (const_string "vector")
6910 (eq_attr "alternative" "1")
6911 (const_string "vector")
6912 (and (eq_attr "alternative" "2")
6913 (match_operand 1 "memory_operand" ""))
6914 (const_string "vector")]
6915 (const_string "direct")))
6916 (set_attr "mode" "DI")])
6917
6918 (define_expand "mulsi3"
6919 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6920 (mult:SI (match_operand:SI 1 "register_operand" "")
6921 (match_operand:SI 2 "general_operand" "")))
6922 (clobber (reg:CC FLAGS_REG))])]
6923 ""
6924 "")
6925
6926 (define_insn "*mulsi3_1"
6927 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6928 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6929 (match_operand:SI 2 "general_operand" "K,i,mr")))
6930 (clobber (reg:CC FLAGS_REG))]
6931 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6932 "@
6933 imul{l}\t{%2, %1, %0|%0, %1, %2}
6934 imul{l}\t{%2, %1, %0|%0, %1, %2}
6935 imul{l}\t{%2, %0|%0, %2}"
6936 [(set_attr "type" "imul")
6937 (set_attr "prefix_0f" "0,0,1")
6938 (set (attr "athlon_decode")
6939 (cond [(eq_attr "cpu" "athlon")
6940 (const_string "vector")
6941 (eq_attr "alternative" "1")
6942 (const_string "vector")
6943 (and (eq_attr "alternative" "2")
6944 (match_operand 1 "memory_operand" ""))
6945 (const_string "vector")]
6946 (const_string "direct")))
6947 (set_attr "mode" "SI")])
6948
6949 (define_insn "*mulsi3_1_zext"
6950 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6951 (zero_extend:DI
6952 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6953 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6954 (clobber (reg:CC FLAGS_REG))]
6955 "TARGET_64BIT
6956 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6957 "@
6958 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6959 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6960 imul{l}\t{%2, %k0|%k0, %2}"
6961 [(set_attr "type" "imul")
6962 (set_attr "prefix_0f" "0,0,1")
6963 (set (attr "athlon_decode")
6964 (cond [(eq_attr "cpu" "athlon")
6965 (const_string "vector")
6966 (eq_attr "alternative" "1")
6967 (const_string "vector")
6968 (and (eq_attr "alternative" "2")
6969 (match_operand 1 "memory_operand" ""))
6970 (const_string "vector")]
6971 (const_string "direct")))
6972 (set_attr "mode" "SI")])
6973
6974 (define_expand "mulhi3"
6975 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6976 (mult:HI (match_operand:HI 1 "register_operand" "")
6977 (match_operand:HI 2 "general_operand" "")))
6978 (clobber (reg:CC FLAGS_REG))])]
6979 "TARGET_HIMODE_MATH"
6980 "")
6981
6982 (define_insn "*mulhi3_1"
6983 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6984 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6985 (match_operand:HI 2 "general_operand" "K,i,mr")))
6986 (clobber (reg:CC FLAGS_REG))]
6987 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6988 "@
6989 imul{w}\t{%2, %1, %0|%0, %1, %2}
6990 imul{w}\t{%2, %1, %0|%0, %1, %2}
6991 imul{w}\t{%2, %0|%0, %2}"
6992 [(set_attr "type" "imul")
6993 (set_attr "prefix_0f" "0,0,1")
6994 (set (attr "athlon_decode")
6995 (cond [(eq_attr "cpu" "athlon")
6996 (const_string "vector")
6997 (eq_attr "alternative" "1,2")
6998 (const_string "vector")]
6999 (const_string "direct")))
7000 (set_attr "mode" "HI")])
7001
7002 (define_expand "mulqi3"
7003 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7004 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7005 (match_operand:QI 2 "register_operand" "")))
7006 (clobber (reg:CC FLAGS_REG))])]
7007 "TARGET_QIMODE_MATH"
7008 "")
7009
7010 (define_insn "*mulqi3_1"
7011 [(set (match_operand:QI 0 "register_operand" "=a")
7012 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7013 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7014 (clobber (reg:CC FLAGS_REG))]
7015 "TARGET_QIMODE_MATH
7016 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7017 "mul{b}\t%2"
7018 [(set_attr "type" "imul")
7019 (set_attr "length_immediate" "0")
7020 (set (attr "athlon_decode")
7021 (if_then_else (eq_attr "cpu" "athlon")
7022 (const_string "vector")
7023 (const_string "direct")))
7024 (set_attr "mode" "QI")])
7025
7026 (define_expand "umulqihi3"
7027 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7028 (mult:HI (zero_extend:HI
7029 (match_operand:QI 1 "nonimmediate_operand" ""))
7030 (zero_extend:HI
7031 (match_operand:QI 2 "register_operand" ""))))
7032 (clobber (reg:CC FLAGS_REG))])]
7033 "TARGET_QIMODE_MATH"
7034 "")
7035
7036 (define_insn "*umulqihi3_1"
7037 [(set (match_operand:HI 0 "register_operand" "=a")
7038 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7039 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7040 (clobber (reg:CC FLAGS_REG))]
7041 "TARGET_QIMODE_MATH
7042 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7043 "mul{b}\t%2"
7044 [(set_attr "type" "imul")
7045 (set_attr "length_immediate" "0")
7046 (set (attr "athlon_decode")
7047 (if_then_else (eq_attr "cpu" "athlon")
7048 (const_string "vector")
7049 (const_string "direct")))
7050 (set_attr "mode" "QI")])
7051
7052 (define_expand "mulqihi3"
7053 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7054 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7055 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7056 (clobber (reg:CC FLAGS_REG))])]
7057 "TARGET_QIMODE_MATH"
7058 "")
7059
7060 (define_insn "*mulqihi3_insn"
7061 [(set (match_operand:HI 0 "register_operand" "=a")
7062 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7063 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7064 (clobber (reg:CC FLAGS_REG))]
7065 "TARGET_QIMODE_MATH
7066 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7067 "imul{b}\t%2"
7068 [(set_attr "type" "imul")
7069 (set_attr "length_immediate" "0")
7070 (set (attr "athlon_decode")
7071 (if_then_else (eq_attr "cpu" "athlon")
7072 (const_string "vector")
7073 (const_string "direct")))
7074 (set_attr "mode" "QI")])
7075
7076 (define_expand "umulditi3"
7077 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7078 (mult:TI (zero_extend:TI
7079 (match_operand:DI 1 "nonimmediate_operand" ""))
7080 (zero_extend:TI
7081 (match_operand:DI 2 "register_operand" ""))))
7082 (clobber (reg:CC FLAGS_REG))])]
7083 "TARGET_64BIT"
7084 "")
7085
7086 (define_insn "*umulditi3_insn"
7087 [(set (match_operand:TI 0 "register_operand" "=A")
7088 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7089 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7090 (clobber (reg:CC FLAGS_REG))]
7091 "TARGET_64BIT
7092 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7093 "mul{q}\t%2"
7094 [(set_attr "type" "imul")
7095 (set_attr "length_immediate" "0")
7096 (set (attr "athlon_decode")
7097 (if_then_else (eq_attr "cpu" "athlon")
7098 (const_string "vector")
7099 (const_string "double")))
7100 (set_attr "mode" "DI")])
7101
7102 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7103 (define_expand "umulsidi3"
7104 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7105 (mult:DI (zero_extend:DI
7106 (match_operand:SI 1 "nonimmediate_operand" ""))
7107 (zero_extend:DI
7108 (match_operand:SI 2 "register_operand" ""))))
7109 (clobber (reg:CC FLAGS_REG))])]
7110 "!TARGET_64BIT"
7111 "")
7112
7113 (define_insn "*umulsidi3_insn"
7114 [(set (match_operand:DI 0 "register_operand" "=A")
7115 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7116 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7117 (clobber (reg:CC FLAGS_REG))]
7118 "!TARGET_64BIT
7119 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7120 "mul{l}\t%2"
7121 [(set_attr "type" "imul")
7122 (set_attr "length_immediate" "0")
7123 (set (attr "athlon_decode")
7124 (if_then_else (eq_attr "cpu" "athlon")
7125 (const_string "vector")
7126 (const_string "double")))
7127 (set_attr "mode" "SI")])
7128
7129 (define_expand "mulditi3"
7130 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7131 (mult:TI (sign_extend:TI
7132 (match_operand:DI 1 "nonimmediate_operand" ""))
7133 (sign_extend:TI
7134 (match_operand:DI 2 "register_operand" ""))))
7135 (clobber (reg:CC FLAGS_REG))])]
7136 "TARGET_64BIT"
7137 "")
7138
7139 (define_insn "*mulditi3_insn"
7140 [(set (match_operand:TI 0 "register_operand" "=A")
7141 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7142 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7143 (clobber (reg:CC FLAGS_REG))]
7144 "TARGET_64BIT
7145 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7146 "imul{q}\t%2"
7147 [(set_attr "type" "imul")
7148 (set_attr "length_immediate" "0")
7149 (set (attr "athlon_decode")
7150 (if_then_else (eq_attr "cpu" "athlon")
7151 (const_string "vector")
7152 (const_string "double")))
7153 (set_attr "mode" "DI")])
7154
7155 (define_expand "mulsidi3"
7156 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7157 (mult:DI (sign_extend:DI
7158 (match_operand:SI 1 "nonimmediate_operand" ""))
7159 (sign_extend:DI
7160 (match_operand:SI 2 "register_operand" ""))))
7161 (clobber (reg:CC FLAGS_REG))])]
7162 "!TARGET_64BIT"
7163 "")
7164
7165 (define_insn "*mulsidi3_insn"
7166 [(set (match_operand:DI 0 "register_operand" "=A")
7167 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7168 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7169 (clobber (reg:CC FLAGS_REG))]
7170 "!TARGET_64BIT
7171 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7172 "imul{l}\t%2"
7173 [(set_attr "type" "imul")
7174 (set_attr "length_immediate" "0")
7175 (set (attr "athlon_decode")
7176 (if_then_else (eq_attr "cpu" "athlon")
7177 (const_string "vector")
7178 (const_string "double")))
7179 (set_attr "mode" "SI")])
7180
7181 (define_expand "umuldi3_highpart"
7182 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7183 (truncate:DI
7184 (lshiftrt:TI
7185 (mult:TI (zero_extend:TI
7186 (match_operand:DI 1 "nonimmediate_operand" ""))
7187 (zero_extend:TI
7188 (match_operand:DI 2 "register_operand" "")))
7189 (const_int 64))))
7190 (clobber (match_scratch:DI 3 ""))
7191 (clobber (reg:CC FLAGS_REG))])]
7192 "TARGET_64BIT"
7193 "")
7194
7195 (define_insn "*umuldi3_highpart_rex64"
7196 [(set (match_operand:DI 0 "register_operand" "=d")
7197 (truncate:DI
7198 (lshiftrt:TI
7199 (mult:TI (zero_extend:TI
7200 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7201 (zero_extend:TI
7202 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7203 (const_int 64))))
7204 (clobber (match_scratch:DI 3 "=1"))
7205 (clobber (reg:CC FLAGS_REG))]
7206 "TARGET_64BIT
7207 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7208 "mul{q}\t%2"
7209 [(set_attr "type" "imul")
7210 (set_attr "length_immediate" "0")
7211 (set (attr "athlon_decode")
7212 (if_then_else (eq_attr "cpu" "athlon")
7213 (const_string "vector")
7214 (const_string "double")))
7215 (set_attr "mode" "DI")])
7216
7217 (define_expand "umulsi3_highpart"
7218 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7219 (truncate:SI
7220 (lshiftrt:DI
7221 (mult:DI (zero_extend:DI
7222 (match_operand:SI 1 "nonimmediate_operand" ""))
7223 (zero_extend:DI
7224 (match_operand:SI 2 "register_operand" "")))
7225 (const_int 32))))
7226 (clobber (match_scratch:SI 3 ""))
7227 (clobber (reg:CC FLAGS_REG))])]
7228 ""
7229 "")
7230
7231 (define_insn "*umulsi3_highpart_insn"
7232 [(set (match_operand:SI 0 "register_operand" "=d")
7233 (truncate:SI
7234 (lshiftrt:DI
7235 (mult:DI (zero_extend:DI
7236 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7237 (zero_extend:DI
7238 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7239 (const_int 32))))
7240 (clobber (match_scratch:SI 3 "=1"))
7241 (clobber (reg:CC FLAGS_REG))]
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_insn "*umulsi3_highpart_zext"
7253 [(set (match_operand:DI 0 "register_operand" "=d")
7254 (zero_extend:DI (truncate:SI
7255 (lshiftrt:DI
7256 (mult:DI (zero_extend:DI
7257 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7258 (zero_extend:DI
7259 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7260 (const_int 32)))))
7261 (clobber (match_scratch:SI 3 "=1"))
7262 (clobber (reg:CC FLAGS_REG))]
7263 "TARGET_64BIT
7264 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7265 "mul{l}\t%2"
7266 [(set_attr "type" "imul")
7267 (set_attr "length_immediate" "0")
7268 (set (attr "athlon_decode")
7269 (if_then_else (eq_attr "cpu" "athlon")
7270 (const_string "vector")
7271 (const_string "double")))
7272 (set_attr "mode" "SI")])
7273
7274 (define_expand "smuldi3_highpart"
7275 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7276 (truncate:DI
7277 (lshiftrt:TI
7278 (mult:TI (sign_extend:TI
7279 (match_operand:DI 1 "nonimmediate_operand" ""))
7280 (sign_extend:TI
7281 (match_operand:DI 2 "register_operand" "")))
7282 (const_int 64))))
7283 (clobber (match_scratch:DI 3 ""))
7284 (clobber (reg:CC FLAGS_REG))])]
7285 "TARGET_64BIT"
7286 "")
7287
7288 (define_insn "*smuldi3_highpart_rex64"
7289 [(set (match_operand:DI 0 "register_operand" "=d")
7290 (truncate:DI
7291 (lshiftrt:TI
7292 (mult:TI (sign_extend:TI
7293 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7294 (sign_extend:TI
7295 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7296 (const_int 64))))
7297 (clobber (match_scratch:DI 3 "=1"))
7298 (clobber (reg:CC FLAGS_REG))]
7299 "TARGET_64BIT
7300 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7301 "imul{q}\t%2"
7302 [(set_attr "type" "imul")
7303 (set (attr "athlon_decode")
7304 (if_then_else (eq_attr "cpu" "athlon")
7305 (const_string "vector")
7306 (const_string "double")))
7307 (set_attr "mode" "DI")])
7308
7309 (define_expand "smulsi3_highpart"
7310 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7311 (truncate:SI
7312 (lshiftrt:DI
7313 (mult:DI (sign_extend:DI
7314 (match_operand:SI 1 "nonimmediate_operand" ""))
7315 (sign_extend:DI
7316 (match_operand:SI 2 "register_operand" "")))
7317 (const_int 32))))
7318 (clobber (match_scratch:SI 3 ""))
7319 (clobber (reg:CC FLAGS_REG))])]
7320 ""
7321 "")
7322
7323 (define_insn "*smulsi3_highpart_insn"
7324 [(set (match_operand:SI 0 "register_operand" "=d")
7325 (truncate:SI
7326 (lshiftrt:DI
7327 (mult:DI (sign_extend:DI
7328 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7329 (sign_extend:DI
7330 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7331 (const_int 32))))
7332 (clobber (match_scratch:SI 3 "=1"))
7333 (clobber (reg:CC FLAGS_REG))]
7334 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7335 "imul{l}\t%2"
7336 [(set_attr "type" "imul")
7337 (set (attr "athlon_decode")
7338 (if_then_else (eq_attr "cpu" "athlon")
7339 (const_string "vector")
7340 (const_string "double")))
7341 (set_attr "mode" "SI")])
7342
7343 (define_insn "*smulsi3_highpart_zext"
7344 [(set (match_operand:DI 0 "register_operand" "=d")
7345 (zero_extend:DI (truncate:SI
7346 (lshiftrt:DI
7347 (mult:DI (sign_extend:DI
7348 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7349 (sign_extend:DI
7350 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7351 (const_int 32)))))
7352 (clobber (match_scratch:SI 3 "=1"))
7353 (clobber (reg:CC FLAGS_REG))]
7354 "TARGET_64BIT
7355 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7356 "imul{l}\t%2"
7357 [(set_attr "type" "imul")
7358 (set (attr "athlon_decode")
7359 (if_then_else (eq_attr "cpu" "athlon")
7360 (const_string "vector")
7361 (const_string "double")))
7362 (set_attr "mode" "SI")])
7363
7364 ;; The patterns that match these are at the end of this file.
7365
7366 (define_expand "mulxf3"
7367 [(set (match_operand:XF 0 "register_operand" "")
7368 (mult:XF (match_operand:XF 1 "register_operand" "")
7369 (match_operand:XF 2 "register_operand" "")))]
7370 "TARGET_80387"
7371 "")
7372
7373 (define_expand "muldf3"
7374 [(set (match_operand:DF 0 "register_operand" "")
7375 (mult:DF (match_operand:DF 1 "register_operand" "")
7376 (match_operand:DF 2 "nonimmediate_operand" "")))]
7377 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7378 "")
7379
7380 (define_expand "mulsf3"
7381 [(set (match_operand:SF 0 "register_operand" "")
7382 (mult:SF (match_operand:SF 1 "register_operand" "")
7383 (match_operand:SF 2 "nonimmediate_operand" "")))]
7384 "TARGET_80387 || TARGET_SSE_MATH"
7385 "")
7386 \f
7387 ;; Divide instructions
7388
7389 (define_insn "divqi3"
7390 [(set (match_operand:QI 0 "register_operand" "=a")
7391 (div:QI (match_operand:HI 1 "register_operand" "0")
7392 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7393 (clobber (reg:CC FLAGS_REG))]
7394 "TARGET_QIMODE_MATH"
7395 "idiv{b}\t%2"
7396 [(set_attr "type" "idiv")
7397 (set_attr "mode" "QI")])
7398
7399 (define_insn "udivqi3"
7400 [(set (match_operand:QI 0 "register_operand" "=a")
7401 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7402 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7403 (clobber (reg:CC FLAGS_REG))]
7404 "TARGET_QIMODE_MATH"
7405 "div{b}\t%2"
7406 [(set_attr "type" "idiv")
7407 (set_attr "mode" "QI")])
7408
7409 ;; The patterns that match these are at the end of this file.
7410
7411 (define_expand "divxf3"
7412 [(set (match_operand:XF 0 "register_operand" "")
7413 (div:XF (match_operand:XF 1 "register_operand" "")
7414 (match_operand:XF 2 "register_operand" "")))]
7415 "TARGET_80387"
7416 "")
7417
7418 (define_expand "divdf3"
7419 [(set (match_operand:DF 0 "register_operand" "")
7420 (div:DF (match_operand:DF 1 "register_operand" "")
7421 (match_operand:DF 2 "nonimmediate_operand" "")))]
7422 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7423 "")
7424
7425 (define_expand "divsf3"
7426 [(set (match_operand:SF 0 "register_operand" "")
7427 (div:SF (match_operand:SF 1 "register_operand" "")
7428 (match_operand:SF 2 "nonimmediate_operand" "")))]
7429 "TARGET_80387 || TARGET_SSE_MATH"
7430 "")
7431 \f
7432 ;; Remainder instructions.
7433
7434 (define_expand "divmoddi4"
7435 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7436 (div:DI (match_operand:DI 1 "register_operand" "")
7437 (match_operand:DI 2 "nonimmediate_operand" "")))
7438 (set (match_operand:DI 3 "register_operand" "")
7439 (mod:DI (match_dup 1) (match_dup 2)))
7440 (clobber (reg:CC FLAGS_REG))])]
7441 "TARGET_64BIT"
7442 "")
7443
7444 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7445 ;; Penalize eax case slightly because it results in worse scheduling
7446 ;; of code.
7447 (define_insn "*divmoddi4_nocltd_rex64"
7448 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7449 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7450 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7451 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7452 (mod:DI (match_dup 2) (match_dup 3)))
7453 (clobber (reg:CC FLAGS_REG))]
7454 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7455 "#"
7456 [(set_attr "type" "multi")])
7457
7458 (define_insn "*divmoddi4_cltd_rex64"
7459 [(set (match_operand:DI 0 "register_operand" "=a")
7460 (div:DI (match_operand:DI 2 "register_operand" "a")
7461 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7462 (set (match_operand:DI 1 "register_operand" "=&d")
7463 (mod:DI (match_dup 2) (match_dup 3)))
7464 (clobber (reg:CC FLAGS_REG))]
7465 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7466 "#"
7467 [(set_attr "type" "multi")])
7468
7469 (define_insn "*divmoddi_noext_rex64"
7470 [(set (match_operand:DI 0 "register_operand" "=a")
7471 (div:DI (match_operand:DI 1 "register_operand" "0")
7472 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7473 (set (match_operand:DI 3 "register_operand" "=d")
7474 (mod:DI (match_dup 1) (match_dup 2)))
7475 (use (match_operand:DI 4 "register_operand" "3"))
7476 (clobber (reg:CC FLAGS_REG))]
7477 "TARGET_64BIT"
7478 "idiv{q}\t%2"
7479 [(set_attr "type" "idiv")
7480 (set_attr "mode" "DI")])
7481
7482 (define_split
7483 [(set (match_operand:DI 0 "register_operand" "")
7484 (div:DI (match_operand:DI 1 "register_operand" "")
7485 (match_operand:DI 2 "nonimmediate_operand" "")))
7486 (set (match_operand:DI 3 "register_operand" "")
7487 (mod:DI (match_dup 1) (match_dup 2)))
7488 (clobber (reg:CC FLAGS_REG))]
7489 "TARGET_64BIT && reload_completed"
7490 [(parallel [(set (match_dup 3)
7491 (ashiftrt:DI (match_dup 4) (const_int 63)))
7492 (clobber (reg:CC FLAGS_REG))])
7493 (parallel [(set (match_dup 0)
7494 (div:DI (reg:DI 0) (match_dup 2)))
7495 (set (match_dup 3)
7496 (mod:DI (reg:DI 0) (match_dup 2)))
7497 (use (match_dup 3))
7498 (clobber (reg:CC FLAGS_REG))])]
7499 {
7500 /* Avoid use of cltd in favor of a mov+shift. */
7501 if (!TARGET_USE_CLTD && !optimize_size)
7502 {
7503 if (true_regnum (operands[1]))
7504 emit_move_insn (operands[0], operands[1]);
7505 else
7506 emit_move_insn (operands[3], operands[1]);
7507 operands[4] = operands[3];
7508 }
7509 else
7510 {
7511 gcc_assert (!true_regnum (operands[1]));
7512 operands[4] = operands[1];
7513 }
7514 })
7515
7516
7517 (define_expand "divmodsi4"
7518 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7519 (div:SI (match_operand:SI 1 "register_operand" "")
7520 (match_operand:SI 2 "nonimmediate_operand" "")))
7521 (set (match_operand:SI 3 "register_operand" "")
7522 (mod:SI (match_dup 1) (match_dup 2)))
7523 (clobber (reg:CC FLAGS_REG))])]
7524 ""
7525 "")
7526
7527 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7528 ;; Penalize eax case slightly because it results in worse scheduling
7529 ;; of code.
7530 (define_insn "*divmodsi4_nocltd"
7531 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7532 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7533 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7534 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7535 (mod:SI (match_dup 2) (match_dup 3)))
7536 (clobber (reg:CC FLAGS_REG))]
7537 "!optimize_size && !TARGET_USE_CLTD"
7538 "#"
7539 [(set_attr "type" "multi")])
7540
7541 (define_insn "*divmodsi4_cltd"
7542 [(set (match_operand:SI 0 "register_operand" "=a")
7543 (div:SI (match_operand:SI 2 "register_operand" "a")
7544 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7545 (set (match_operand:SI 1 "register_operand" "=&d")
7546 (mod:SI (match_dup 2) (match_dup 3)))
7547 (clobber (reg:CC FLAGS_REG))]
7548 "optimize_size || TARGET_USE_CLTD"
7549 "#"
7550 [(set_attr "type" "multi")])
7551
7552 (define_insn "*divmodsi_noext"
7553 [(set (match_operand:SI 0 "register_operand" "=a")
7554 (div:SI (match_operand:SI 1 "register_operand" "0")
7555 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7556 (set (match_operand:SI 3 "register_operand" "=d")
7557 (mod:SI (match_dup 1) (match_dup 2)))
7558 (use (match_operand:SI 4 "register_operand" "3"))
7559 (clobber (reg:CC FLAGS_REG))]
7560 ""
7561 "idiv{l}\t%2"
7562 [(set_attr "type" "idiv")
7563 (set_attr "mode" "SI")])
7564
7565 (define_split
7566 [(set (match_operand:SI 0 "register_operand" "")
7567 (div:SI (match_operand:SI 1 "register_operand" "")
7568 (match_operand:SI 2 "nonimmediate_operand" "")))
7569 (set (match_operand:SI 3 "register_operand" "")
7570 (mod:SI (match_dup 1) (match_dup 2)))
7571 (clobber (reg:CC FLAGS_REG))]
7572 "reload_completed"
7573 [(parallel [(set (match_dup 3)
7574 (ashiftrt:SI (match_dup 4) (const_int 31)))
7575 (clobber (reg:CC FLAGS_REG))])
7576 (parallel [(set (match_dup 0)
7577 (div:SI (reg:SI 0) (match_dup 2)))
7578 (set (match_dup 3)
7579 (mod:SI (reg:SI 0) (match_dup 2)))
7580 (use (match_dup 3))
7581 (clobber (reg:CC FLAGS_REG))])]
7582 {
7583 /* Avoid use of cltd in favor of a mov+shift. */
7584 if (!TARGET_USE_CLTD && !optimize_size)
7585 {
7586 if (true_regnum (operands[1]))
7587 emit_move_insn (operands[0], operands[1]);
7588 else
7589 emit_move_insn (operands[3], operands[1]);
7590 operands[4] = operands[3];
7591 }
7592 else
7593 {
7594 gcc_assert (!true_regnum (operands[1]));
7595 operands[4] = operands[1];
7596 }
7597 })
7598 ;; %%% Split me.
7599 (define_insn "divmodhi4"
7600 [(set (match_operand:HI 0 "register_operand" "=a")
7601 (div:HI (match_operand:HI 1 "register_operand" "0")
7602 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7603 (set (match_operand:HI 3 "register_operand" "=&d")
7604 (mod:HI (match_dup 1) (match_dup 2)))
7605 (clobber (reg:CC FLAGS_REG))]
7606 "TARGET_HIMODE_MATH"
7607 "cwtd\;idiv{w}\t%2"
7608 [(set_attr "type" "multi")
7609 (set_attr "length_immediate" "0")
7610 (set_attr "mode" "SI")])
7611
7612 (define_insn "udivmoddi4"
7613 [(set (match_operand:DI 0 "register_operand" "=a")
7614 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7615 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7616 (set (match_operand:DI 3 "register_operand" "=&d")
7617 (umod:DI (match_dup 1) (match_dup 2)))
7618 (clobber (reg:CC FLAGS_REG))]
7619 "TARGET_64BIT"
7620 "xor{q}\t%3, %3\;div{q}\t%2"
7621 [(set_attr "type" "multi")
7622 (set_attr "length_immediate" "0")
7623 (set_attr "mode" "DI")])
7624
7625 (define_insn "*udivmoddi4_noext"
7626 [(set (match_operand:DI 0 "register_operand" "=a")
7627 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7628 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7629 (set (match_operand:DI 3 "register_operand" "=d")
7630 (umod:DI (match_dup 1) (match_dup 2)))
7631 (use (match_dup 3))
7632 (clobber (reg:CC FLAGS_REG))]
7633 "TARGET_64BIT"
7634 "div{q}\t%2"
7635 [(set_attr "type" "idiv")
7636 (set_attr "mode" "DI")])
7637
7638 (define_split
7639 [(set (match_operand:DI 0 "register_operand" "")
7640 (udiv:DI (match_operand:DI 1 "register_operand" "")
7641 (match_operand:DI 2 "nonimmediate_operand" "")))
7642 (set (match_operand:DI 3 "register_operand" "")
7643 (umod:DI (match_dup 1) (match_dup 2)))
7644 (clobber (reg:CC FLAGS_REG))]
7645 "TARGET_64BIT && reload_completed"
7646 [(set (match_dup 3) (const_int 0))
7647 (parallel [(set (match_dup 0)
7648 (udiv:DI (match_dup 1) (match_dup 2)))
7649 (set (match_dup 3)
7650 (umod:DI (match_dup 1) (match_dup 2)))
7651 (use (match_dup 3))
7652 (clobber (reg:CC FLAGS_REG))])]
7653 "")
7654
7655 (define_insn "udivmodsi4"
7656 [(set (match_operand:SI 0 "register_operand" "=a")
7657 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7658 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7659 (set (match_operand:SI 3 "register_operand" "=&d")
7660 (umod:SI (match_dup 1) (match_dup 2)))
7661 (clobber (reg:CC FLAGS_REG))]
7662 ""
7663 "xor{l}\t%3, %3\;div{l}\t%2"
7664 [(set_attr "type" "multi")
7665 (set_attr "length_immediate" "0")
7666 (set_attr "mode" "SI")])
7667
7668 (define_insn "*udivmodsi4_noext"
7669 [(set (match_operand:SI 0 "register_operand" "=a")
7670 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7671 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7672 (set (match_operand:SI 3 "register_operand" "=d")
7673 (umod:SI (match_dup 1) (match_dup 2)))
7674 (use (match_dup 3))
7675 (clobber (reg:CC FLAGS_REG))]
7676 ""
7677 "div{l}\t%2"
7678 [(set_attr "type" "idiv")
7679 (set_attr "mode" "SI")])
7680
7681 (define_split
7682 [(set (match_operand:SI 0 "register_operand" "")
7683 (udiv:SI (match_operand:SI 1 "register_operand" "")
7684 (match_operand:SI 2 "nonimmediate_operand" "")))
7685 (set (match_operand:SI 3 "register_operand" "")
7686 (umod:SI (match_dup 1) (match_dup 2)))
7687 (clobber (reg:CC FLAGS_REG))]
7688 "reload_completed"
7689 [(set (match_dup 3) (const_int 0))
7690 (parallel [(set (match_dup 0)
7691 (udiv:SI (match_dup 1) (match_dup 2)))
7692 (set (match_dup 3)
7693 (umod:SI (match_dup 1) (match_dup 2)))
7694 (use (match_dup 3))
7695 (clobber (reg:CC FLAGS_REG))])]
7696 "")
7697
7698 (define_expand "udivmodhi4"
7699 [(set (match_dup 4) (const_int 0))
7700 (parallel [(set (match_operand:HI 0 "register_operand" "")
7701 (udiv:HI (match_operand:HI 1 "register_operand" "")
7702 (match_operand:HI 2 "nonimmediate_operand" "")))
7703 (set (match_operand:HI 3 "register_operand" "")
7704 (umod:HI (match_dup 1) (match_dup 2)))
7705 (use (match_dup 4))
7706 (clobber (reg:CC FLAGS_REG))])]
7707 "TARGET_HIMODE_MATH"
7708 "operands[4] = gen_reg_rtx (HImode);")
7709
7710 (define_insn "*udivmodhi_noext"
7711 [(set (match_operand:HI 0 "register_operand" "=a")
7712 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7713 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7714 (set (match_operand:HI 3 "register_operand" "=d")
7715 (umod:HI (match_dup 1) (match_dup 2)))
7716 (use (match_operand:HI 4 "register_operand" "3"))
7717 (clobber (reg:CC FLAGS_REG))]
7718 ""
7719 "div{w}\t%2"
7720 [(set_attr "type" "idiv")
7721 (set_attr "mode" "HI")])
7722
7723 ;; We cannot use div/idiv for double division, because it causes
7724 ;; "division by zero" on the overflow and that's not what we expect
7725 ;; from truncate. Because true (non truncating) double division is
7726 ;; never generated, we can't create this insn anyway.
7727 ;
7728 ;(define_insn ""
7729 ; [(set (match_operand:SI 0 "register_operand" "=a")
7730 ; (truncate:SI
7731 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7732 ; (zero_extend:DI
7733 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7734 ; (set (match_operand:SI 3 "register_operand" "=d")
7735 ; (truncate:SI
7736 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7737 ; (clobber (reg:CC FLAGS_REG))]
7738 ; ""
7739 ; "div{l}\t{%2, %0|%0, %2}"
7740 ; [(set_attr "type" "idiv")])
7741 \f
7742 ;;- Logical AND instructions
7743
7744 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7745 ;; Note that this excludes ah.
7746
7747 (define_insn "*testdi_1_rex64"
7748 [(set (reg FLAGS_REG)
7749 (compare
7750 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7751 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7752 (const_int 0)))]
7753 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7754 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7755 "@
7756 test{l}\t{%k1, %k0|%k0, %k1}
7757 test{l}\t{%k1, %k0|%k0, %k1}
7758 test{q}\t{%1, %0|%0, %1}
7759 test{q}\t{%1, %0|%0, %1}
7760 test{q}\t{%1, %0|%0, %1}"
7761 [(set_attr "type" "test")
7762 (set_attr "modrm" "0,1,0,1,1")
7763 (set_attr "mode" "SI,SI,DI,DI,DI")
7764 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7765
7766 (define_insn "testsi_1"
7767 [(set (reg FLAGS_REG)
7768 (compare
7769 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7770 (match_operand:SI 1 "general_operand" "in,in,rin"))
7771 (const_int 0)))]
7772 "ix86_match_ccmode (insn, CCNOmode)
7773 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7774 "test{l}\t{%1, %0|%0, %1}"
7775 [(set_attr "type" "test")
7776 (set_attr "modrm" "0,1,1")
7777 (set_attr "mode" "SI")
7778 (set_attr "pent_pair" "uv,np,uv")])
7779
7780 (define_expand "testsi_ccno_1"
7781 [(set (reg:CCNO FLAGS_REG)
7782 (compare:CCNO
7783 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7784 (match_operand:SI 1 "nonmemory_operand" ""))
7785 (const_int 0)))]
7786 ""
7787 "")
7788
7789 (define_insn "*testhi_1"
7790 [(set (reg FLAGS_REG)
7791 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7792 (match_operand:HI 1 "general_operand" "n,n,rn"))
7793 (const_int 0)))]
7794 "ix86_match_ccmode (insn, CCNOmode)
7795 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7796 "test{w}\t{%1, %0|%0, %1}"
7797 [(set_attr "type" "test")
7798 (set_attr "modrm" "0,1,1")
7799 (set_attr "mode" "HI")
7800 (set_attr "pent_pair" "uv,np,uv")])
7801
7802 (define_expand "testqi_ccz_1"
7803 [(set (reg:CCZ FLAGS_REG)
7804 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7805 (match_operand:QI 1 "nonmemory_operand" ""))
7806 (const_int 0)))]
7807 ""
7808 "")
7809
7810 (define_insn "*testqi_1_maybe_si"
7811 [(set (reg FLAGS_REG)
7812 (compare
7813 (and:QI
7814 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7815 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7816 (const_int 0)))]
7817 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7818 && ix86_match_ccmode (insn,
7819 GET_CODE (operands[1]) == CONST_INT
7820 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7821 {
7822 if (which_alternative == 3)
7823 {
7824 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7825 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7826 return "test{l}\t{%1, %k0|%k0, %1}";
7827 }
7828 return "test{b}\t{%1, %0|%0, %1}";
7829 }
7830 [(set_attr "type" "test")
7831 (set_attr "modrm" "0,1,1,1")
7832 (set_attr "mode" "QI,QI,QI,SI")
7833 (set_attr "pent_pair" "uv,np,uv,np")])
7834
7835 (define_insn "*testqi_1"
7836 [(set (reg FLAGS_REG)
7837 (compare
7838 (and:QI
7839 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7840 (match_operand:QI 1 "general_operand" "n,n,qn"))
7841 (const_int 0)))]
7842 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7843 && ix86_match_ccmode (insn, CCNOmode)"
7844 "test{b}\t{%1, %0|%0, %1}"
7845 [(set_attr "type" "test")
7846 (set_attr "modrm" "0,1,1")
7847 (set_attr "mode" "QI")
7848 (set_attr "pent_pair" "uv,np,uv")])
7849
7850 (define_expand "testqi_ext_ccno_0"
7851 [(set (reg:CCNO FLAGS_REG)
7852 (compare:CCNO
7853 (and:SI
7854 (zero_extract:SI
7855 (match_operand 0 "ext_register_operand" "")
7856 (const_int 8)
7857 (const_int 8))
7858 (match_operand 1 "const_int_operand" ""))
7859 (const_int 0)))]
7860 ""
7861 "")
7862
7863 (define_insn "*testqi_ext_0"
7864 [(set (reg FLAGS_REG)
7865 (compare
7866 (and:SI
7867 (zero_extract:SI
7868 (match_operand 0 "ext_register_operand" "Q")
7869 (const_int 8)
7870 (const_int 8))
7871 (match_operand 1 "const_int_operand" "n"))
7872 (const_int 0)))]
7873 "ix86_match_ccmode (insn, CCNOmode)"
7874 "test{b}\t{%1, %h0|%h0, %1}"
7875 [(set_attr "type" "test")
7876 (set_attr "mode" "QI")
7877 (set_attr "length_immediate" "1")
7878 (set_attr "pent_pair" "np")])
7879
7880 (define_insn "*testqi_ext_1"
7881 [(set (reg FLAGS_REG)
7882 (compare
7883 (and:SI
7884 (zero_extract:SI
7885 (match_operand 0 "ext_register_operand" "Q")
7886 (const_int 8)
7887 (const_int 8))
7888 (zero_extend:SI
7889 (match_operand:QI 1 "general_operand" "Qm")))
7890 (const_int 0)))]
7891 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7892 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7893 "test{b}\t{%1, %h0|%h0, %1}"
7894 [(set_attr "type" "test")
7895 (set_attr "mode" "QI")])
7896
7897 (define_insn "*testqi_ext_1_rex64"
7898 [(set (reg FLAGS_REG)
7899 (compare
7900 (and:SI
7901 (zero_extract:SI
7902 (match_operand 0 "ext_register_operand" "Q")
7903 (const_int 8)
7904 (const_int 8))
7905 (zero_extend:SI
7906 (match_operand:QI 1 "register_operand" "Q")))
7907 (const_int 0)))]
7908 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7909 "test{b}\t{%1, %h0|%h0, %1}"
7910 [(set_attr "type" "test")
7911 (set_attr "mode" "QI")])
7912
7913 (define_insn "*testqi_ext_2"
7914 [(set (reg FLAGS_REG)
7915 (compare
7916 (and:SI
7917 (zero_extract:SI
7918 (match_operand 0 "ext_register_operand" "Q")
7919 (const_int 8)
7920 (const_int 8))
7921 (zero_extract:SI
7922 (match_operand 1 "ext_register_operand" "Q")
7923 (const_int 8)
7924 (const_int 8)))
7925 (const_int 0)))]
7926 "ix86_match_ccmode (insn, CCNOmode)"
7927 "test{b}\t{%h1, %h0|%h0, %h1}"
7928 [(set_attr "type" "test")
7929 (set_attr "mode" "QI")])
7930
7931 ;; Combine likes to form bit extractions for some tests. Humor it.
7932 (define_insn "*testqi_ext_3"
7933 [(set (reg FLAGS_REG)
7934 (compare (zero_extract:SI
7935 (match_operand 0 "nonimmediate_operand" "rm")
7936 (match_operand:SI 1 "const_int_operand" "")
7937 (match_operand:SI 2 "const_int_operand" ""))
7938 (const_int 0)))]
7939 "ix86_match_ccmode (insn, CCNOmode)
7940 && INTVAL (operands[1]) > 0
7941 && INTVAL (operands[2]) >= 0
7942 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7943 && (GET_MODE (operands[0]) == SImode
7944 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7945 || GET_MODE (operands[0]) == HImode
7946 || GET_MODE (operands[0]) == QImode)"
7947 "#")
7948
7949 (define_insn "*testqi_ext_3_rex64"
7950 [(set (reg FLAGS_REG)
7951 (compare (zero_extract:DI
7952 (match_operand 0 "nonimmediate_operand" "rm")
7953 (match_operand:DI 1 "const_int_operand" "")
7954 (match_operand:DI 2 "const_int_operand" ""))
7955 (const_int 0)))]
7956 "TARGET_64BIT
7957 && ix86_match_ccmode (insn, CCNOmode)
7958 && INTVAL (operands[1]) > 0
7959 && INTVAL (operands[2]) >= 0
7960 /* Ensure that resulting mask is zero or sign extended operand. */
7961 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7962 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7963 && INTVAL (operands[1]) > 32))
7964 && (GET_MODE (operands[0]) == SImode
7965 || GET_MODE (operands[0]) == DImode
7966 || GET_MODE (operands[0]) == HImode
7967 || GET_MODE (operands[0]) == QImode)"
7968 "#")
7969
7970 (define_split
7971 [(set (match_operand 0 "flags_reg_operand" "")
7972 (match_operator 1 "compare_operator"
7973 [(zero_extract
7974 (match_operand 2 "nonimmediate_operand" "")
7975 (match_operand 3 "const_int_operand" "")
7976 (match_operand 4 "const_int_operand" ""))
7977 (const_int 0)]))]
7978 "ix86_match_ccmode (insn, CCNOmode)"
7979 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7980 {
7981 rtx val = operands[2];
7982 HOST_WIDE_INT len = INTVAL (operands[3]);
7983 HOST_WIDE_INT pos = INTVAL (operands[4]);
7984 HOST_WIDE_INT mask;
7985 enum machine_mode mode, submode;
7986
7987 mode = GET_MODE (val);
7988 if (GET_CODE (val) == MEM)
7989 {
7990 /* ??? Combine likes to put non-volatile mem extractions in QImode
7991 no matter the size of the test. So find a mode that works. */
7992 if (! MEM_VOLATILE_P (val))
7993 {
7994 mode = smallest_mode_for_size (pos + len, MODE_INT);
7995 val = adjust_address (val, mode, 0);
7996 }
7997 }
7998 else if (GET_CODE (val) == SUBREG
7999 && (submode = GET_MODE (SUBREG_REG (val)),
8000 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8001 && pos + len <= GET_MODE_BITSIZE (submode))
8002 {
8003 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8004 mode = submode;
8005 val = SUBREG_REG (val);
8006 }
8007 else if (mode == HImode && pos + len <= 8)
8008 {
8009 /* Small HImode tests can be converted to QImode. */
8010 mode = QImode;
8011 val = gen_lowpart (QImode, val);
8012 }
8013
8014 if (len == HOST_BITS_PER_WIDE_INT)
8015 mask = -1;
8016 else
8017 mask = ((HOST_WIDE_INT)1 << len) - 1;
8018 mask <<= pos;
8019
8020 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8021 })
8022
8023 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8024 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8025 ;; this is relatively important trick.
8026 ;; Do the conversion only post-reload to avoid limiting of the register class
8027 ;; to QI regs.
8028 (define_split
8029 [(set (match_operand 0 "flags_reg_operand" "")
8030 (match_operator 1 "compare_operator"
8031 [(and (match_operand 2 "register_operand" "")
8032 (match_operand 3 "const_int_operand" ""))
8033 (const_int 0)]))]
8034 "reload_completed
8035 && QI_REG_P (operands[2])
8036 && GET_MODE (operands[2]) != QImode
8037 && ((ix86_match_ccmode (insn, CCZmode)
8038 && !(INTVAL (operands[3]) & ~(255 << 8)))
8039 || (ix86_match_ccmode (insn, CCNOmode)
8040 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8041 [(set (match_dup 0)
8042 (match_op_dup 1
8043 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8044 (match_dup 3))
8045 (const_int 0)]))]
8046 "operands[2] = gen_lowpart (SImode, operands[2]);
8047 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8048
8049 (define_split
8050 [(set (match_operand 0 "flags_reg_operand" "")
8051 (match_operator 1 "compare_operator"
8052 [(and (match_operand 2 "nonimmediate_operand" "")
8053 (match_operand 3 "const_int_operand" ""))
8054 (const_int 0)]))]
8055 "reload_completed
8056 && GET_MODE (operands[2]) != QImode
8057 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8058 && ((ix86_match_ccmode (insn, CCZmode)
8059 && !(INTVAL (operands[3]) & ~255))
8060 || (ix86_match_ccmode (insn, CCNOmode)
8061 && !(INTVAL (operands[3]) & ~127)))"
8062 [(set (match_dup 0)
8063 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8064 (const_int 0)]))]
8065 "operands[2] = gen_lowpart (QImode, operands[2]);
8066 operands[3] = gen_lowpart (QImode, operands[3]);")
8067
8068
8069 ;; %%% This used to optimize known byte-wide and operations to memory,
8070 ;; and sometimes to QImode registers. If this is considered useful,
8071 ;; it should be done with splitters.
8072
8073 (define_expand "anddi3"
8074 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8075 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8076 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8077 (clobber (reg:CC FLAGS_REG))]
8078 "TARGET_64BIT"
8079 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8080
8081 (define_insn "*anddi_1_rex64"
8082 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8083 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8084 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8085 (clobber (reg:CC FLAGS_REG))]
8086 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8087 {
8088 switch (get_attr_type (insn))
8089 {
8090 case TYPE_IMOVX:
8091 {
8092 enum machine_mode mode;
8093
8094 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8095 if (INTVAL (operands[2]) == 0xff)
8096 mode = QImode;
8097 else
8098 {
8099 gcc_assert (INTVAL (operands[2]) == 0xffff);
8100 mode = HImode;
8101 }
8102
8103 operands[1] = gen_lowpart (mode, operands[1]);
8104 if (mode == QImode)
8105 return "movz{bq|x}\t{%1,%0|%0, %1}";
8106 else
8107 return "movz{wq|x}\t{%1,%0|%0, %1}";
8108 }
8109
8110 default:
8111 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8112 if (get_attr_mode (insn) == MODE_SI)
8113 return "and{l}\t{%k2, %k0|%k0, %k2}";
8114 else
8115 return "and{q}\t{%2, %0|%0, %2}";
8116 }
8117 }
8118 [(set_attr "type" "alu,alu,alu,imovx")
8119 (set_attr "length_immediate" "*,*,*,0")
8120 (set_attr "mode" "SI,DI,DI,DI")])
8121
8122 (define_insn "*anddi_2"
8123 [(set (reg FLAGS_REG)
8124 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8125 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8126 (const_int 0)))
8127 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8128 (and:DI (match_dup 1) (match_dup 2)))]
8129 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8130 && ix86_binary_operator_ok (AND, DImode, operands)"
8131 "@
8132 and{l}\t{%k2, %k0|%k0, %k2}
8133 and{q}\t{%2, %0|%0, %2}
8134 and{q}\t{%2, %0|%0, %2}"
8135 [(set_attr "type" "alu")
8136 (set_attr "mode" "SI,DI,DI")])
8137
8138 (define_expand "andsi3"
8139 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8140 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8141 (match_operand:SI 2 "general_operand" "")))
8142 (clobber (reg:CC FLAGS_REG))]
8143 ""
8144 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8145
8146 (define_insn "*andsi_1"
8147 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8148 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8149 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8150 (clobber (reg:CC FLAGS_REG))]
8151 "ix86_binary_operator_ok (AND, SImode, operands)"
8152 {
8153 switch (get_attr_type (insn))
8154 {
8155 case TYPE_IMOVX:
8156 {
8157 enum machine_mode mode;
8158
8159 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8160 if (INTVAL (operands[2]) == 0xff)
8161 mode = QImode;
8162 else
8163 {
8164 gcc_assert (INTVAL (operands[2]) == 0xffff);
8165 mode = HImode;
8166 }
8167
8168 operands[1] = gen_lowpart (mode, operands[1]);
8169 if (mode == QImode)
8170 return "movz{bl|x}\t{%1,%0|%0, %1}";
8171 else
8172 return "movz{wl|x}\t{%1,%0|%0, %1}";
8173 }
8174
8175 default:
8176 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8177 return "and{l}\t{%2, %0|%0, %2}";
8178 }
8179 }
8180 [(set_attr "type" "alu,alu,imovx")
8181 (set_attr "length_immediate" "*,*,0")
8182 (set_attr "mode" "SI")])
8183
8184 (define_split
8185 [(set (match_operand 0 "register_operand" "")
8186 (and (match_dup 0)
8187 (const_int -65536)))
8188 (clobber (reg:CC FLAGS_REG))]
8189 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8190 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8191 "operands[1] = gen_lowpart (HImode, operands[0]);")
8192
8193 (define_split
8194 [(set (match_operand 0 "ext_register_operand" "")
8195 (and (match_dup 0)
8196 (const_int -256)))
8197 (clobber (reg:CC FLAGS_REG))]
8198 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8199 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8200 "operands[1] = gen_lowpart (QImode, operands[0]);")
8201
8202 (define_split
8203 [(set (match_operand 0 "ext_register_operand" "")
8204 (and (match_dup 0)
8205 (const_int -65281)))
8206 (clobber (reg:CC FLAGS_REG))]
8207 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8208 [(parallel [(set (zero_extract:SI (match_dup 0)
8209 (const_int 8)
8210 (const_int 8))
8211 (xor:SI
8212 (zero_extract:SI (match_dup 0)
8213 (const_int 8)
8214 (const_int 8))
8215 (zero_extract:SI (match_dup 0)
8216 (const_int 8)
8217 (const_int 8))))
8218 (clobber (reg:CC FLAGS_REG))])]
8219 "operands[0] = gen_lowpart (SImode, operands[0]);")
8220
8221 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8222 (define_insn "*andsi_1_zext"
8223 [(set (match_operand:DI 0 "register_operand" "=r")
8224 (zero_extend:DI
8225 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8226 (match_operand:SI 2 "general_operand" "rim"))))
8227 (clobber (reg:CC FLAGS_REG))]
8228 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8229 "and{l}\t{%2, %k0|%k0, %2}"
8230 [(set_attr "type" "alu")
8231 (set_attr "mode" "SI")])
8232
8233 (define_insn "*andsi_2"
8234 [(set (reg FLAGS_REG)
8235 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8236 (match_operand:SI 2 "general_operand" "rim,ri"))
8237 (const_int 0)))
8238 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8239 (and:SI (match_dup 1) (match_dup 2)))]
8240 "ix86_match_ccmode (insn, CCNOmode)
8241 && ix86_binary_operator_ok (AND, SImode, operands)"
8242 "and{l}\t{%2, %0|%0, %2}"
8243 [(set_attr "type" "alu")
8244 (set_attr "mode" "SI")])
8245
8246 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8247 (define_insn "*andsi_2_zext"
8248 [(set (reg FLAGS_REG)
8249 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8250 (match_operand:SI 2 "general_operand" "rim"))
8251 (const_int 0)))
8252 (set (match_operand:DI 0 "register_operand" "=r")
8253 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8254 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8255 && ix86_binary_operator_ok (AND, SImode, operands)"
8256 "and{l}\t{%2, %k0|%k0, %2}"
8257 [(set_attr "type" "alu")
8258 (set_attr "mode" "SI")])
8259
8260 (define_expand "andhi3"
8261 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8262 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8263 (match_operand:HI 2 "general_operand" "")))
8264 (clobber (reg:CC FLAGS_REG))]
8265 "TARGET_HIMODE_MATH"
8266 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8267
8268 (define_insn "*andhi_1"
8269 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8270 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8271 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8272 (clobber (reg:CC FLAGS_REG))]
8273 "ix86_binary_operator_ok (AND, HImode, operands)"
8274 {
8275 switch (get_attr_type (insn))
8276 {
8277 case TYPE_IMOVX:
8278 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8279 gcc_assert (INTVAL (operands[2]) == 0xff);
8280 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8281
8282 default:
8283 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8284
8285 return "and{w}\t{%2, %0|%0, %2}";
8286 }
8287 }
8288 [(set_attr "type" "alu,alu,imovx")
8289 (set_attr "length_immediate" "*,*,0")
8290 (set_attr "mode" "HI,HI,SI")])
8291
8292 (define_insn "*andhi_2"
8293 [(set (reg FLAGS_REG)
8294 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8295 (match_operand:HI 2 "general_operand" "rim,ri"))
8296 (const_int 0)))
8297 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8298 (and:HI (match_dup 1) (match_dup 2)))]
8299 "ix86_match_ccmode (insn, CCNOmode)
8300 && ix86_binary_operator_ok (AND, HImode, operands)"
8301 "and{w}\t{%2, %0|%0, %2}"
8302 [(set_attr "type" "alu")
8303 (set_attr "mode" "HI")])
8304
8305 (define_expand "andqi3"
8306 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8307 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8308 (match_operand:QI 2 "general_operand" "")))
8309 (clobber (reg:CC FLAGS_REG))]
8310 "TARGET_QIMODE_MATH"
8311 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8312
8313 ;; %%% Potential partial reg stall on alternative 2. What to do?
8314 (define_insn "*andqi_1"
8315 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8316 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8317 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8318 (clobber (reg:CC FLAGS_REG))]
8319 "ix86_binary_operator_ok (AND, QImode, operands)"
8320 "@
8321 and{b}\t{%2, %0|%0, %2}
8322 and{b}\t{%2, %0|%0, %2}
8323 and{l}\t{%k2, %k0|%k0, %k2}"
8324 [(set_attr "type" "alu")
8325 (set_attr "mode" "QI,QI,SI")])
8326
8327 (define_insn "*andqi_1_slp"
8328 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8329 (and:QI (match_dup 0)
8330 (match_operand:QI 1 "general_operand" "qi,qmi")))
8331 (clobber (reg:CC FLAGS_REG))]
8332 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8333 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8334 "and{b}\t{%1, %0|%0, %1}"
8335 [(set_attr "type" "alu1")
8336 (set_attr "mode" "QI")])
8337
8338 (define_insn "*andqi_2_maybe_si"
8339 [(set (reg FLAGS_REG)
8340 (compare (and:QI
8341 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8342 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8343 (const_int 0)))
8344 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8345 (and:QI (match_dup 1) (match_dup 2)))]
8346 "ix86_binary_operator_ok (AND, QImode, operands)
8347 && ix86_match_ccmode (insn,
8348 GET_CODE (operands[2]) == CONST_INT
8349 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8350 {
8351 if (which_alternative == 2)
8352 {
8353 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8354 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8355 return "and{l}\t{%2, %k0|%k0, %2}";
8356 }
8357 return "and{b}\t{%2, %0|%0, %2}";
8358 }
8359 [(set_attr "type" "alu")
8360 (set_attr "mode" "QI,QI,SI")])
8361
8362 (define_insn "*andqi_2"
8363 [(set (reg FLAGS_REG)
8364 (compare (and:QI
8365 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8366 (match_operand:QI 2 "general_operand" "qim,qi"))
8367 (const_int 0)))
8368 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8369 (and:QI (match_dup 1) (match_dup 2)))]
8370 "ix86_match_ccmode (insn, CCNOmode)
8371 && ix86_binary_operator_ok (AND, QImode, operands)"
8372 "and{b}\t{%2, %0|%0, %2}"
8373 [(set_attr "type" "alu")
8374 (set_attr "mode" "QI")])
8375
8376 (define_insn "*andqi_2_slp"
8377 [(set (reg FLAGS_REG)
8378 (compare (and:QI
8379 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8380 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8381 (const_int 0)))
8382 (set (strict_low_part (match_dup 0))
8383 (and:QI (match_dup 0) (match_dup 1)))]
8384 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8385 && ix86_match_ccmode (insn, CCNOmode)
8386 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8387 "and{b}\t{%1, %0|%0, %1}"
8388 [(set_attr "type" "alu1")
8389 (set_attr "mode" "QI")])
8390
8391 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8392 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8393 ;; for a QImode operand, which of course failed.
8394
8395 (define_insn "andqi_ext_0"
8396 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8397 (const_int 8)
8398 (const_int 8))
8399 (and:SI
8400 (zero_extract:SI
8401 (match_operand 1 "ext_register_operand" "0")
8402 (const_int 8)
8403 (const_int 8))
8404 (match_operand 2 "const_int_operand" "n")))
8405 (clobber (reg:CC FLAGS_REG))]
8406 ""
8407 "and{b}\t{%2, %h0|%h0, %2}"
8408 [(set_attr "type" "alu")
8409 (set_attr "length_immediate" "1")
8410 (set_attr "mode" "QI")])
8411
8412 ;; Generated by peephole translating test to and. This shows up
8413 ;; often in fp comparisons.
8414
8415 (define_insn "*andqi_ext_0_cc"
8416 [(set (reg FLAGS_REG)
8417 (compare
8418 (and:SI
8419 (zero_extract:SI
8420 (match_operand 1 "ext_register_operand" "0")
8421 (const_int 8)
8422 (const_int 8))
8423 (match_operand 2 "const_int_operand" "n"))
8424 (const_int 0)))
8425 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8426 (const_int 8)
8427 (const_int 8))
8428 (and:SI
8429 (zero_extract:SI
8430 (match_dup 1)
8431 (const_int 8)
8432 (const_int 8))
8433 (match_dup 2)))]
8434 "ix86_match_ccmode (insn, CCNOmode)"
8435 "and{b}\t{%2, %h0|%h0, %2}"
8436 [(set_attr "type" "alu")
8437 (set_attr "length_immediate" "1")
8438 (set_attr "mode" "QI")])
8439
8440 (define_insn "*andqi_ext_1"
8441 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8442 (const_int 8)
8443 (const_int 8))
8444 (and:SI
8445 (zero_extract:SI
8446 (match_operand 1 "ext_register_operand" "0")
8447 (const_int 8)
8448 (const_int 8))
8449 (zero_extend:SI
8450 (match_operand:QI 2 "general_operand" "Qm"))))
8451 (clobber (reg:CC FLAGS_REG))]
8452 "!TARGET_64BIT"
8453 "and{b}\t{%2, %h0|%h0, %2}"
8454 [(set_attr "type" "alu")
8455 (set_attr "length_immediate" "0")
8456 (set_attr "mode" "QI")])
8457
8458 (define_insn "*andqi_ext_1_rex64"
8459 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8460 (const_int 8)
8461 (const_int 8))
8462 (and:SI
8463 (zero_extract:SI
8464 (match_operand 1 "ext_register_operand" "0")
8465 (const_int 8)
8466 (const_int 8))
8467 (zero_extend:SI
8468 (match_operand 2 "ext_register_operand" "Q"))))
8469 (clobber (reg:CC FLAGS_REG))]
8470 "TARGET_64BIT"
8471 "and{b}\t{%2, %h0|%h0, %2}"
8472 [(set_attr "type" "alu")
8473 (set_attr "length_immediate" "0")
8474 (set_attr "mode" "QI")])
8475
8476 (define_insn "*andqi_ext_2"
8477 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8478 (const_int 8)
8479 (const_int 8))
8480 (and:SI
8481 (zero_extract:SI
8482 (match_operand 1 "ext_register_operand" "%0")
8483 (const_int 8)
8484 (const_int 8))
8485 (zero_extract:SI
8486 (match_operand 2 "ext_register_operand" "Q")
8487 (const_int 8)
8488 (const_int 8))))
8489 (clobber (reg:CC FLAGS_REG))]
8490 ""
8491 "and{b}\t{%h2, %h0|%h0, %h2}"
8492 [(set_attr "type" "alu")
8493 (set_attr "length_immediate" "0")
8494 (set_attr "mode" "QI")])
8495
8496 ;; Convert wide AND instructions with immediate operand to shorter QImode
8497 ;; equivalents when possible.
8498 ;; Don't do the splitting with memory operands, since it introduces risk
8499 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8500 ;; for size, but that can (should?) be handled by generic code instead.
8501 (define_split
8502 [(set (match_operand 0 "register_operand" "")
8503 (and (match_operand 1 "register_operand" "")
8504 (match_operand 2 "const_int_operand" "")))
8505 (clobber (reg:CC FLAGS_REG))]
8506 "reload_completed
8507 && QI_REG_P (operands[0])
8508 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8509 && !(~INTVAL (operands[2]) & ~(255 << 8))
8510 && GET_MODE (operands[0]) != QImode"
8511 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8512 (and:SI (zero_extract:SI (match_dup 1)
8513 (const_int 8) (const_int 8))
8514 (match_dup 2)))
8515 (clobber (reg:CC FLAGS_REG))])]
8516 "operands[0] = gen_lowpart (SImode, operands[0]);
8517 operands[1] = gen_lowpart (SImode, operands[1]);
8518 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8519
8520 ;; Since AND can be encoded with sign extended immediate, this is only
8521 ;; profitable when 7th bit is not set.
8522 (define_split
8523 [(set (match_operand 0 "register_operand" "")
8524 (and (match_operand 1 "general_operand" "")
8525 (match_operand 2 "const_int_operand" "")))
8526 (clobber (reg:CC FLAGS_REG))]
8527 "reload_completed
8528 && ANY_QI_REG_P (operands[0])
8529 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8530 && !(~INTVAL (operands[2]) & ~255)
8531 && !(INTVAL (operands[2]) & 128)
8532 && GET_MODE (operands[0]) != QImode"
8533 [(parallel [(set (strict_low_part (match_dup 0))
8534 (and:QI (match_dup 1)
8535 (match_dup 2)))
8536 (clobber (reg:CC FLAGS_REG))])]
8537 "operands[0] = gen_lowpart (QImode, operands[0]);
8538 operands[1] = gen_lowpart (QImode, operands[1]);
8539 operands[2] = gen_lowpart (QImode, operands[2]);")
8540 \f
8541 ;; Logical inclusive OR instructions
8542
8543 ;; %%% This used to optimize known byte-wide and operations to memory.
8544 ;; If this is considered useful, it should be done with splitters.
8545
8546 (define_expand "iordi3"
8547 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8548 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8549 (match_operand:DI 2 "x86_64_general_operand" "")))
8550 (clobber (reg:CC FLAGS_REG))]
8551 "TARGET_64BIT"
8552 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8553
8554 (define_insn "*iordi_1_rex64"
8555 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8556 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8557 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8558 (clobber (reg:CC FLAGS_REG))]
8559 "TARGET_64BIT
8560 && ix86_binary_operator_ok (IOR, DImode, operands)"
8561 "or{q}\t{%2, %0|%0, %2}"
8562 [(set_attr "type" "alu")
8563 (set_attr "mode" "DI")])
8564
8565 (define_insn "*iordi_2_rex64"
8566 [(set (reg FLAGS_REG)
8567 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8568 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8569 (const_int 0)))
8570 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8571 (ior:DI (match_dup 1) (match_dup 2)))]
8572 "TARGET_64BIT
8573 && ix86_match_ccmode (insn, CCNOmode)
8574 && ix86_binary_operator_ok (IOR, DImode, operands)"
8575 "or{q}\t{%2, %0|%0, %2}"
8576 [(set_attr "type" "alu")
8577 (set_attr "mode" "DI")])
8578
8579 (define_insn "*iordi_3_rex64"
8580 [(set (reg FLAGS_REG)
8581 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8582 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8583 (const_int 0)))
8584 (clobber (match_scratch:DI 0 "=r"))]
8585 "TARGET_64BIT
8586 && ix86_match_ccmode (insn, CCNOmode)
8587 && ix86_binary_operator_ok (IOR, DImode, operands)"
8588 "or{q}\t{%2, %0|%0, %2}"
8589 [(set_attr "type" "alu")
8590 (set_attr "mode" "DI")])
8591
8592
8593 (define_expand "iorsi3"
8594 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8595 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8596 (match_operand:SI 2 "general_operand" "")))
8597 (clobber (reg:CC FLAGS_REG))]
8598 ""
8599 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8600
8601 (define_insn "*iorsi_1"
8602 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8603 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8604 (match_operand:SI 2 "general_operand" "ri,rmi")))
8605 (clobber (reg:CC FLAGS_REG))]
8606 "ix86_binary_operator_ok (IOR, SImode, operands)"
8607 "or{l}\t{%2, %0|%0, %2}"
8608 [(set_attr "type" "alu")
8609 (set_attr "mode" "SI")])
8610
8611 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8612 (define_insn "*iorsi_1_zext"
8613 [(set (match_operand:DI 0 "register_operand" "=rm")
8614 (zero_extend:DI
8615 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8616 (match_operand:SI 2 "general_operand" "rim"))))
8617 (clobber (reg:CC FLAGS_REG))]
8618 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8619 "or{l}\t{%2, %k0|%k0, %2}"
8620 [(set_attr "type" "alu")
8621 (set_attr "mode" "SI")])
8622
8623 (define_insn "*iorsi_1_zext_imm"
8624 [(set (match_operand:DI 0 "register_operand" "=rm")
8625 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8626 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8627 (clobber (reg:CC FLAGS_REG))]
8628 "TARGET_64BIT"
8629 "or{l}\t{%2, %k0|%k0, %2}"
8630 [(set_attr "type" "alu")
8631 (set_attr "mode" "SI")])
8632
8633 (define_insn "*iorsi_2"
8634 [(set (reg FLAGS_REG)
8635 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8636 (match_operand:SI 2 "general_operand" "rim,ri"))
8637 (const_int 0)))
8638 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8639 (ior:SI (match_dup 1) (match_dup 2)))]
8640 "ix86_match_ccmode (insn, CCNOmode)
8641 && ix86_binary_operator_ok (IOR, SImode, operands)"
8642 "or{l}\t{%2, %0|%0, %2}"
8643 [(set_attr "type" "alu")
8644 (set_attr "mode" "SI")])
8645
8646 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8647 ;; ??? Special case for immediate operand is missing - it is tricky.
8648 (define_insn "*iorsi_2_zext"
8649 [(set (reg FLAGS_REG)
8650 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8651 (match_operand:SI 2 "general_operand" "rim"))
8652 (const_int 0)))
8653 (set (match_operand:DI 0 "register_operand" "=r")
8654 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8655 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8656 && ix86_binary_operator_ok (IOR, SImode, operands)"
8657 "or{l}\t{%2, %k0|%k0, %2}"
8658 [(set_attr "type" "alu")
8659 (set_attr "mode" "SI")])
8660
8661 (define_insn "*iorsi_2_zext_imm"
8662 [(set (reg FLAGS_REG)
8663 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8664 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8665 (const_int 0)))
8666 (set (match_operand:DI 0 "register_operand" "=r")
8667 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8668 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8669 && ix86_binary_operator_ok (IOR, SImode, operands)"
8670 "or{l}\t{%2, %k0|%k0, %2}"
8671 [(set_attr "type" "alu")
8672 (set_attr "mode" "SI")])
8673
8674 (define_insn "*iorsi_3"
8675 [(set (reg FLAGS_REG)
8676 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8677 (match_operand:SI 2 "general_operand" "rim"))
8678 (const_int 0)))
8679 (clobber (match_scratch:SI 0 "=r"))]
8680 "ix86_match_ccmode (insn, CCNOmode)
8681 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8682 "or{l}\t{%2, %0|%0, %2}"
8683 [(set_attr "type" "alu")
8684 (set_attr "mode" "SI")])
8685
8686 (define_expand "iorhi3"
8687 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8688 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8689 (match_operand:HI 2 "general_operand" "")))
8690 (clobber (reg:CC FLAGS_REG))]
8691 "TARGET_HIMODE_MATH"
8692 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8693
8694 (define_insn "*iorhi_1"
8695 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8696 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8697 (match_operand:HI 2 "general_operand" "rmi,ri")))
8698 (clobber (reg:CC FLAGS_REG))]
8699 "ix86_binary_operator_ok (IOR, HImode, operands)"
8700 "or{w}\t{%2, %0|%0, %2}"
8701 [(set_attr "type" "alu")
8702 (set_attr "mode" "HI")])
8703
8704 (define_insn "*iorhi_2"
8705 [(set (reg FLAGS_REG)
8706 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8707 (match_operand:HI 2 "general_operand" "rim,ri"))
8708 (const_int 0)))
8709 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8710 (ior:HI (match_dup 1) (match_dup 2)))]
8711 "ix86_match_ccmode (insn, CCNOmode)
8712 && ix86_binary_operator_ok (IOR, HImode, operands)"
8713 "or{w}\t{%2, %0|%0, %2}"
8714 [(set_attr "type" "alu")
8715 (set_attr "mode" "HI")])
8716
8717 (define_insn "*iorhi_3"
8718 [(set (reg FLAGS_REG)
8719 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8720 (match_operand:HI 2 "general_operand" "rim"))
8721 (const_int 0)))
8722 (clobber (match_scratch:HI 0 "=r"))]
8723 "ix86_match_ccmode (insn, CCNOmode)
8724 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8725 "or{w}\t{%2, %0|%0, %2}"
8726 [(set_attr "type" "alu")
8727 (set_attr "mode" "HI")])
8728
8729 (define_expand "iorqi3"
8730 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8731 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8732 (match_operand:QI 2 "general_operand" "")))
8733 (clobber (reg:CC FLAGS_REG))]
8734 "TARGET_QIMODE_MATH"
8735 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8736
8737 ;; %%% Potential partial reg stall on alternative 2. What to do?
8738 (define_insn "*iorqi_1"
8739 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8740 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8741 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8742 (clobber (reg:CC FLAGS_REG))]
8743 "ix86_binary_operator_ok (IOR, QImode, operands)"
8744 "@
8745 or{b}\t{%2, %0|%0, %2}
8746 or{b}\t{%2, %0|%0, %2}
8747 or{l}\t{%k2, %k0|%k0, %k2}"
8748 [(set_attr "type" "alu")
8749 (set_attr "mode" "QI,QI,SI")])
8750
8751 (define_insn "*iorqi_1_slp"
8752 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8753 (ior:QI (match_dup 0)
8754 (match_operand:QI 1 "general_operand" "qmi,qi")))
8755 (clobber (reg:CC FLAGS_REG))]
8756 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8757 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8758 "or{b}\t{%1, %0|%0, %1}"
8759 [(set_attr "type" "alu1")
8760 (set_attr "mode" "QI")])
8761
8762 (define_insn "*iorqi_2"
8763 [(set (reg FLAGS_REG)
8764 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8765 (match_operand:QI 2 "general_operand" "qim,qi"))
8766 (const_int 0)))
8767 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8768 (ior:QI (match_dup 1) (match_dup 2)))]
8769 "ix86_match_ccmode (insn, CCNOmode)
8770 && ix86_binary_operator_ok (IOR, QImode, operands)"
8771 "or{b}\t{%2, %0|%0, %2}"
8772 [(set_attr "type" "alu")
8773 (set_attr "mode" "QI")])
8774
8775 (define_insn "*iorqi_2_slp"
8776 [(set (reg FLAGS_REG)
8777 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8778 (match_operand:QI 1 "general_operand" "qim,qi"))
8779 (const_int 0)))
8780 (set (strict_low_part (match_dup 0))
8781 (ior:QI (match_dup 0) (match_dup 1)))]
8782 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8783 && ix86_match_ccmode (insn, CCNOmode)
8784 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8785 "or{b}\t{%1, %0|%0, %1}"
8786 [(set_attr "type" "alu1")
8787 (set_attr "mode" "QI")])
8788
8789 (define_insn "*iorqi_3"
8790 [(set (reg FLAGS_REG)
8791 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8792 (match_operand:QI 2 "general_operand" "qim"))
8793 (const_int 0)))
8794 (clobber (match_scratch:QI 0 "=q"))]
8795 "ix86_match_ccmode (insn, CCNOmode)
8796 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8797 "or{b}\t{%2, %0|%0, %2}"
8798 [(set_attr "type" "alu")
8799 (set_attr "mode" "QI")])
8800
8801 (define_insn "iorqi_ext_0"
8802 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8803 (const_int 8)
8804 (const_int 8))
8805 (ior:SI
8806 (zero_extract:SI
8807 (match_operand 1 "ext_register_operand" "0")
8808 (const_int 8)
8809 (const_int 8))
8810 (match_operand 2 "const_int_operand" "n")))
8811 (clobber (reg:CC FLAGS_REG))]
8812 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8813 "or{b}\t{%2, %h0|%h0, %2}"
8814 [(set_attr "type" "alu")
8815 (set_attr "length_immediate" "1")
8816 (set_attr "mode" "QI")])
8817
8818 (define_insn "*iorqi_ext_1"
8819 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8820 (const_int 8)
8821 (const_int 8))
8822 (ior:SI
8823 (zero_extract:SI
8824 (match_operand 1 "ext_register_operand" "0")
8825 (const_int 8)
8826 (const_int 8))
8827 (zero_extend:SI
8828 (match_operand:QI 2 "general_operand" "Qm"))))
8829 (clobber (reg:CC FLAGS_REG))]
8830 "!TARGET_64BIT
8831 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8832 "or{b}\t{%2, %h0|%h0, %2}"
8833 [(set_attr "type" "alu")
8834 (set_attr "length_immediate" "0")
8835 (set_attr "mode" "QI")])
8836
8837 (define_insn "*iorqi_ext_1_rex64"
8838 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8839 (const_int 8)
8840 (const_int 8))
8841 (ior:SI
8842 (zero_extract:SI
8843 (match_operand 1 "ext_register_operand" "0")
8844 (const_int 8)
8845 (const_int 8))
8846 (zero_extend:SI
8847 (match_operand 2 "ext_register_operand" "Q"))))
8848 (clobber (reg:CC FLAGS_REG))]
8849 "TARGET_64BIT
8850 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8851 "or{b}\t{%2, %h0|%h0, %2}"
8852 [(set_attr "type" "alu")
8853 (set_attr "length_immediate" "0")
8854 (set_attr "mode" "QI")])
8855
8856 (define_insn "*iorqi_ext_2"
8857 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8858 (const_int 8)
8859 (const_int 8))
8860 (ior:SI
8861 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8862 (const_int 8)
8863 (const_int 8))
8864 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8865 (const_int 8)
8866 (const_int 8))))
8867 (clobber (reg:CC FLAGS_REG))]
8868 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8869 "ior{b}\t{%h2, %h0|%h0, %h2}"
8870 [(set_attr "type" "alu")
8871 (set_attr "length_immediate" "0")
8872 (set_attr "mode" "QI")])
8873
8874 (define_split
8875 [(set (match_operand 0 "register_operand" "")
8876 (ior (match_operand 1 "register_operand" "")
8877 (match_operand 2 "const_int_operand" "")))
8878 (clobber (reg:CC FLAGS_REG))]
8879 "reload_completed
8880 && QI_REG_P (operands[0])
8881 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8882 && !(INTVAL (operands[2]) & ~(255 << 8))
8883 && GET_MODE (operands[0]) != QImode"
8884 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8885 (ior:SI (zero_extract:SI (match_dup 1)
8886 (const_int 8) (const_int 8))
8887 (match_dup 2)))
8888 (clobber (reg:CC FLAGS_REG))])]
8889 "operands[0] = gen_lowpart (SImode, operands[0]);
8890 operands[1] = gen_lowpart (SImode, operands[1]);
8891 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8892
8893 ;; Since OR can be encoded with sign extended immediate, this is only
8894 ;; profitable when 7th bit is set.
8895 (define_split
8896 [(set (match_operand 0 "register_operand" "")
8897 (ior (match_operand 1 "general_operand" "")
8898 (match_operand 2 "const_int_operand" "")))
8899 (clobber (reg:CC FLAGS_REG))]
8900 "reload_completed
8901 && ANY_QI_REG_P (operands[0])
8902 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8903 && !(INTVAL (operands[2]) & ~255)
8904 && (INTVAL (operands[2]) & 128)
8905 && GET_MODE (operands[0]) != QImode"
8906 [(parallel [(set (strict_low_part (match_dup 0))
8907 (ior:QI (match_dup 1)
8908 (match_dup 2)))
8909 (clobber (reg:CC FLAGS_REG))])]
8910 "operands[0] = gen_lowpart (QImode, operands[0]);
8911 operands[1] = gen_lowpart (QImode, operands[1]);
8912 operands[2] = gen_lowpart (QImode, operands[2]);")
8913 \f
8914 ;; Logical XOR instructions
8915
8916 ;; %%% This used to optimize known byte-wide and operations to memory.
8917 ;; If this is considered useful, it should be done with splitters.
8918
8919 (define_expand "xordi3"
8920 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8921 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8922 (match_operand:DI 2 "x86_64_general_operand" "")))
8923 (clobber (reg:CC FLAGS_REG))]
8924 "TARGET_64BIT"
8925 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8926
8927 (define_insn "*xordi_1_rex64"
8928 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8929 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8930 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8931 (clobber (reg:CC FLAGS_REG))]
8932 "TARGET_64BIT
8933 && ix86_binary_operator_ok (XOR, DImode, operands)"
8934 "@
8935 xor{q}\t{%2, %0|%0, %2}
8936 xor{q}\t{%2, %0|%0, %2}"
8937 [(set_attr "type" "alu")
8938 (set_attr "mode" "DI,DI")])
8939
8940 (define_insn "*xordi_2_rex64"
8941 [(set (reg FLAGS_REG)
8942 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8943 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8944 (const_int 0)))
8945 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8946 (xor:DI (match_dup 1) (match_dup 2)))]
8947 "TARGET_64BIT
8948 && ix86_match_ccmode (insn, CCNOmode)
8949 && ix86_binary_operator_ok (XOR, DImode, operands)"
8950 "@
8951 xor{q}\t{%2, %0|%0, %2}
8952 xor{q}\t{%2, %0|%0, %2}"
8953 [(set_attr "type" "alu")
8954 (set_attr "mode" "DI,DI")])
8955
8956 (define_insn "*xordi_3_rex64"
8957 [(set (reg FLAGS_REG)
8958 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8959 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8960 (const_int 0)))
8961 (clobber (match_scratch:DI 0 "=r"))]
8962 "TARGET_64BIT
8963 && ix86_match_ccmode (insn, CCNOmode)
8964 && ix86_binary_operator_ok (XOR, DImode, operands)"
8965 "xor{q}\t{%2, %0|%0, %2}"
8966 [(set_attr "type" "alu")
8967 (set_attr "mode" "DI")])
8968
8969 (define_expand "xorsi3"
8970 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8971 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8972 (match_operand:SI 2 "general_operand" "")))
8973 (clobber (reg:CC FLAGS_REG))]
8974 ""
8975 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8976
8977 (define_insn "*xorsi_1"
8978 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8979 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8980 (match_operand:SI 2 "general_operand" "ri,rm")))
8981 (clobber (reg:CC FLAGS_REG))]
8982 "ix86_binary_operator_ok (XOR, SImode, operands)"
8983 "xor{l}\t{%2, %0|%0, %2}"
8984 [(set_attr "type" "alu")
8985 (set_attr "mode" "SI")])
8986
8987 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8988 ;; Add speccase for immediates
8989 (define_insn "*xorsi_1_zext"
8990 [(set (match_operand:DI 0 "register_operand" "=r")
8991 (zero_extend:DI
8992 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8993 (match_operand:SI 2 "general_operand" "rim"))))
8994 (clobber (reg:CC FLAGS_REG))]
8995 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8996 "xor{l}\t{%2, %k0|%k0, %2}"
8997 [(set_attr "type" "alu")
8998 (set_attr "mode" "SI")])
8999
9000 (define_insn "*xorsi_1_zext_imm"
9001 [(set (match_operand:DI 0 "register_operand" "=r")
9002 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9003 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9004 (clobber (reg:CC FLAGS_REG))]
9005 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9006 "xor{l}\t{%2, %k0|%k0, %2}"
9007 [(set_attr "type" "alu")
9008 (set_attr "mode" "SI")])
9009
9010 (define_insn "*xorsi_2"
9011 [(set (reg FLAGS_REG)
9012 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9013 (match_operand:SI 2 "general_operand" "rim,ri"))
9014 (const_int 0)))
9015 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9016 (xor:SI (match_dup 1) (match_dup 2)))]
9017 "ix86_match_ccmode (insn, CCNOmode)
9018 && ix86_binary_operator_ok (XOR, SImode, operands)"
9019 "xor{l}\t{%2, %0|%0, %2}"
9020 [(set_attr "type" "alu")
9021 (set_attr "mode" "SI")])
9022
9023 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9024 ;; ??? Special case for immediate operand is missing - it is tricky.
9025 (define_insn "*xorsi_2_zext"
9026 [(set (reg FLAGS_REG)
9027 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9028 (match_operand:SI 2 "general_operand" "rim"))
9029 (const_int 0)))
9030 (set (match_operand:DI 0 "register_operand" "=r")
9031 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9032 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9033 && ix86_binary_operator_ok (XOR, SImode, operands)"
9034 "xor{l}\t{%2, %k0|%k0, %2}"
9035 [(set_attr "type" "alu")
9036 (set_attr "mode" "SI")])
9037
9038 (define_insn "*xorsi_2_zext_imm"
9039 [(set (reg FLAGS_REG)
9040 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9041 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9042 (const_int 0)))
9043 (set (match_operand:DI 0 "register_operand" "=r")
9044 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9045 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9046 && ix86_binary_operator_ok (XOR, SImode, operands)"
9047 "xor{l}\t{%2, %k0|%k0, %2}"
9048 [(set_attr "type" "alu")
9049 (set_attr "mode" "SI")])
9050
9051 (define_insn "*xorsi_3"
9052 [(set (reg FLAGS_REG)
9053 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9054 (match_operand:SI 2 "general_operand" "rim"))
9055 (const_int 0)))
9056 (clobber (match_scratch:SI 0 "=r"))]
9057 "ix86_match_ccmode (insn, CCNOmode)
9058 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9059 "xor{l}\t{%2, %0|%0, %2}"
9060 [(set_attr "type" "alu")
9061 (set_attr "mode" "SI")])
9062
9063 (define_expand "xorhi3"
9064 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9065 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9066 (match_operand:HI 2 "general_operand" "")))
9067 (clobber (reg:CC FLAGS_REG))]
9068 "TARGET_HIMODE_MATH"
9069 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9070
9071 (define_insn "*xorhi_1"
9072 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9073 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9074 (match_operand:HI 2 "general_operand" "rmi,ri")))
9075 (clobber (reg:CC FLAGS_REG))]
9076 "ix86_binary_operator_ok (XOR, HImode, operands)"
9077 "xor{w}\t{%2, %0|%0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "mode" "HI")])
9080
9081 (define_insn "*xorhi_2"
9082 [(set (reg FLAGS_REG)
9083 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9084 (match_operand:HI 2 "general_operand" "rim,ri"))
9085 (const_int 0)))
9086 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9087 (xor:HI (match_dup 1) (match_dup 2)))]
9088 "ix86_match_ccmode (insn, CCNOmode)
9089 && ix86_binary_operator_ok (XOR, HImode, operands)"
9090 "xor{w}\t{%2, %0|%0, %2}"
9091 [(set_attr "type" "alu")
9092 (set_attr "mode" "HI")])
9093
9094 (define_insn "*xorhi_3"
9095 [(set (reg FLAGS_REG)
9096 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9097 (match_operand:HI 2 "general_operand" "rim"))
9098 (const_int 0)))
9099 (clobber (match_scratch:HI 0 "=r"))]
9100 "ix86_match_ccmode (insn, CCNOmode)
9101 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9102 "xor{w}\t{%2, %0|%0, %2}"
9103 [(set_attr "type" "alu")
9104 (set_attr "mode" "HI")])
9105
9106 (define_expand "xorqi3"
9107 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9108 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9109 (match_operand:QI 2 "general_operand" "")))
9110 (clobber (reg:CC FLAGS_REG))]
9111 "TARGET_QIMODE_MATH"
9112 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9113
9114 ;; %%% Potential partial reg stall on alternative 2. What to do?
9115 (define_insn "*xorqi_1"
9116 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9117 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9118 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "ix86_binary_operator_ok (XOR, QImode, operands)"
9121 "@
9122 xor{b}\t{%2, %0|%0, %2}
9123 xor{b}\t{%2, %0|%0, %2}
9124 xor{l}\t{%k2, %k0|%k0, %k2}"
9125 [(set_attr "type" "alu")
9126 (set_attr "mode" "QI,QI,SI")])
9127
9128 (define_insn "*xorqi_1_slp"
9129 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9130 (xor:QI (match_dup 0)
9131 (match_operand:QI 1 "general_operand" "qi,qmi")))
9132 (clobber (reg:CC FLAGS_REG))]
9133 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9134 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9135 "xor{b}\t{%1, %0|%0, %1}"
9136 [(set_attr "type" "alu1")
9137 (set_attr "mode" "QI")])
9138
9139 (define_insn "xorqi_ext_0"
9140 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9141 (const_int 8)
9142 (const_int 8))
9143 (xor:SI
9144 (zero_extract:SI
9145 (match_operand 1 "ext_register_operand" "0")
9146 (const_int 8)
9147 (const_int 8))
9148 (match_operand 2 "const_int_operand" "n")))
9149 (clobber (reg:CC FLAGS_REG))]
9150 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9151 "xor{b}\t{%2, %h0|%h0, %2}"
9152 [(set_attr "type" "alu")
9153 (set_attr "length_immediate" "1")
9154 (set_attr "mode" "QI")])
9155
9156 (define_insn "*xorqi_ext_1"
9157 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9158 (const_int 8)
9159 (const_int 8))
9160 (xor:SI
9161 (zero_extract:SI
9162 (match_operand 1 "ext_register_operand" "0")
9163 (const_int 8)
9164 (const_int 8))
9165 (zero_extend:SI
9166 (match_operand:QI 2 "general_operand" "Qm"))))
9167 (clobber (reg:CC FLAGS_REG))]
9168 "!TARGET_64BIT
9169 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170 "xor{b}\t{%2, %h0|%h0, %2}"
9171 [(set_attr "type" "alu")
9172 (set_attr "length_immediate" "0")
9173 (set_attr "mode" "QI")])
9174
9175 (define_insn "*xorqi_ext_1_rex64"
9176 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9177 (const_int 8)
9178 (const_int 8))
9179 (xor:SI
9180 (zero_extract:SI
9181 (match_operand 1 "ext_register_operand" "0")
9182 (const_int 8)
9183 (const_int 8))
9184 (zero_extend:SI
9185 (match_operand 2 "ext_register_operand" "Q"))))
9186 (clobber (reg:CC FLAGS_REG))]
9187 "TARGET_64BIT
9188 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9189 "xor{b}\t{%2, %h0|%h0, %2}"
9190 [(set_attr "type" "alu")
9191 (set_attr "length_immediate" "0")
9192 (set_attr "mode" "QI")])
9193
9194 (define_insn "*xorqi_ext_2"
9195 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9196 (const_int 8)
9197 (const_int 8))
9198 (xor:SI
9199 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9200 (const_int 8)
9201 (const_int 8))
9202 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9203 (const_int 8)
9204 (const_int 8))))
9205 (clobber (reg:CC FLAGS_REG))]
9206 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9207 "xor{b}\t{%h2, %h0|%h0, %h2}"
9208 [(set_attr "type" "alu")
9209 (set_attr "length_immediate" "0")
9210 (set_attr "mode" "QI")])
9211
9212 (define_insn "*xorqi_cc_1"
9213 [(set (reg FLAGS_REG)
9214 (compare
9215 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9216 (match_operand:QI 2 "general_operand" "qim,qi"))
9217 (const_int 0)))
9218 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9219 (xor:QI (match_dup 1) (match_dup 2)))]
9220 "ix86_match_ccmode (insn, CCNOmode)
9221 && ix86_binary_operator_ok (XOR, QImode, operands)"
9222 "xor{b}\t{%2, %0|%0, %2}"
9223 [(set_attr "type" "alu")
9224 (set_attr "mode" "QI")])
9225
9226 (define_insn "*xorqi_2_slp"
9227 [(set (reg FLAGS_REG)
9228 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9229 (match_operand:QI 1 "general_operand" "qim,qi"))
9230 (const_int 0)))
9231 (set (strict_low_part (match_dup 0))
9232 (xor:QI (match_dup 0) (match_dup 1)))]
9233 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9234 && ix86_match_ccmode (insn, CCNOmode)
9235 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9236 "xor{b}\t{%1, %0|%0, %1}"
9237 [(set_attr "type" "alu1")
9238 (set_attr "mode" "QI")])
9239
9240 (define_insn "*xorqi_cc_2"
9241 [(set (reg FLAGS_REG)
9242 (compare
9243 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9244 (match_operand:QI 2 "general_operand" "qim"))
9245 (const_int 0)))
9246 (clobber (match_scratch:QI 0 "=q"))]
9247 "ix86_match_ccmode (insn, CCNOmode)
9248 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9249 "xor{b}\t{%2, %0|%0, %2}"
9250 [(set_attr "type" "alu")
9251 (set_attr "mode" "QI")])
9252
9253 (define_insn "*xorqi_cc_ext_1"
9254 [(set (reg FLAGS_REG)
9255 (compare
9256 (xor:SI
9257 (zero_extract:SI
9258 (match_operand 1 "ext_register_operand" "0")
9259 (const_int 8)
9260 (const_int 8))
9261 (match_operand:QI 2 "general_operand" "qmn"))
9262 (const_int 0)))
9263 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9264 (const_int 8)
9265 (const_int 8))
9266 (xor:SI
9267 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9268 (match_dup 2)))]
9269 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9270 "xor{b}\t{%2, %h0|%h0, %2}"
9271 [(set_attr "type" "alu")
9272 (set_attr "mode" "QI")])
9273
9274 (define_insn "*xorqi_cc_ext_1_rex64"
9275 [(set (reg FLAGS_REG)
9276 (compare
9277 (xor:SI
9278 (zero_extract:SI
9279 (match_operand 1 "ext_register_operand" "0")
9280 (const_int 8)
9281 (const_int 8))
9282 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9283 (const_int 0)))
9284 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
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 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9291 "xor{b}\t{%2, %h0|%h0, %2}"
9292 [(set_attr "type" "alu")
9293 (set_attr "mode" "QI")])
9294
9295 (define_expand "xorqi_cc_ext_1"
9296 [(parallel [
9297 (set (reg:CCNO FLAGS_REG)
9298 (compare:CCNO
9299 (xor:SI
9300 (zero_extract:SI
9301 (match_operand 1 "ext_register_operand" "")
9302 (const_int 8)
9303 (const_int 8))
9304 (match_operand:QI 2 "general_operand" ""))
9305 (const_int 0)))
9306 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9307 (const_int 8)
9308 (const_int 8))
9309 (xor:SI
9310 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9311 (match_dup 2)))])]
9312 ""
9313 "")
9314
9315 (define_split
9316 [(set (match_operand 0 "register_operand" "")
9317 (xor (match_operand 1 "register_operand" "")
9318 (match_operand 2 "const_int_operand" "")))
9319 (clobber (reg:CC FLAGS_REG))]
9320 "reload_completed
9321 && QI_REG_P (operands[0])
9322 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9323 && !(INTVAL (operands[2]) & ~(255 << 8))
9324 && GET_MODE (operands[0]) != QImode"
9325 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9326 (xor:SI (zero_extract:SI (match_dup 1)
9327 (const_int 8) (const_int 8))
9328 (match_dup 2)))
9329 (clobber (reg:CC FLAGS_REG))])]
9330 "operands[0] = gen_lowpart (SImode, operands[0]);
9331 operands[1] = gen_lowpart (SImode, operands[1]);
9332 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9333
9334 ;; Since XOR can be encoded with sign extended immediate, this is only
9335 ;; profitable when 7th bit is set.
9336 (define_split
9337 [(set (match_operand 0 "register_operand" "")
9338 (xor (match_operand 1 "general_operand" "")
9339 (match_operand 2 "const_int_operand" "")))
9340 (clobber (reg:CC FLAGS_REG))]
9341 "reload_completed
9342 && ANY_QI_REG_P (operands[0])
9343 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9344 && !(INTVAL (operands[2]) & ~255)
9345 && (INTVAL (operands[2]) & 128)
9346 && GET_MODE (operands[0]) != QImode"
9347 [(parallel [(set (strict_low_part (match_dup 0))
9348 (xor:QI (match_dup 1)
9349 (match_dup 2)))
9350 (clobber (reg:CC FLAGS_REG))])]
9351 "operands[0] = gen_lowpart (QImode, operands[0]);
9352 operands[1] = gen_lowpart (QImode, operands[1]);
9353 operands[2] = gen_lowpart (QImode, operands[2]);")
9354 \f
9355 ;; Negation instructions
9356
9357 (define_expand "negti2"
9358 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9359 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))])]
9361 "TARGET_64BIT"
9362 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9363
9364 (define_insn "*negti2_1"
9365 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9366 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9367 (clobber (reg:CC FLAGS_REG))]
9368 "TARGET_64BIT
9369 && ix86_unary_operator_ok (NEG, TImode, operands)"
9370 "#")
9371
9372 (define_split
9373 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9374 (neg:TI (match_operand:TI 1 "general_operand" "")))
9375 (clobber (reg:CC FLAGS_REG))]
9376 "TARGET_64BIT && reload_completed"
9377 [(parallel
9378 [(set (reg:CCZ FLAGS_REG)
9379 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9380 (set (match_dup 0) (neg:DI (match_dup 2)))])
9381 (parallel
9382 [(set (match_dup 1)
9383 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9384 (match_dup 3))
9385 (const_int 0)))
9386 (clobber (reg:CC FLAGS_REG))])
9387 (parallel
9388 [(set (match_dup 1)
9389 (neg:DI (match_dup 1)))
9390 (clobber (reg:CC FLAGS_REG))])]
9391 "split_ti (operands+1, 1, operands+2, operands+3);
9392 split_ti (operands+0, 1, operands+0, operands+1);")
9393
9394 (define_expand "negdi2"
9395 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9396 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9397 (clobber (reg:CC FLAGS_REG))])]
9398 ""
9399 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9400
9401 (define_insn "*negdi2_1"
9402 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9403 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9404 (clobber (reg:CC FLAGS_REG))]
9405 "!TARGET_64BIT
9406 && ix86_unary_operator_ok (NEG, DImode, operands)"
9407 "#")
9408
9409 (define_split
9410 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9411 (neg:DI (match_operand:DI 1 "general_operand" "")))
9412 (clobber (reg:CC FLAGS_REG))]
9413 "!TARGET_64BIT && reload_completed"
9414 [(parallel
9415 [(set (reg:CCZ FLAGS_REG)
9416 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9417 (set (match_dup 0) (neg:SI (match_dup 2)))])
9418 (parallel
9419 [(set (match_dup 1)
9420 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9421 (match_dup 3))
9422 (const_int 0)))
9423 (clobber (reg:CC FLAGS_REG))])
9424 (parallel
9425 [(set (match_dup 1)
9426 (neg:SI (match_dup 1)))
9427 (clobber (reg:CC FLAGS_REG))])]
9428 "split_di (operands+1, 1, operands+2, operands+3);
9429 split_di (operands+0, 1, operands+0, operands+1);")
9430
9431 (define_insn "*negdi2_1_rex64"
9432 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9433 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9434 (clobber (reg:CC FLAGS_REG))]
9435 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9436 "neg{q}\t%0"
9437 [(set_attr "type" "negnot")
9438 (set_attr "mode" "DI")])
9439
9440 ;; The problem with neg is that it does not perform (compare x 0),
9441 ;; it really performs (compare 0 x), which leaves us with the zero
9442 ;; flag being the only useful item.
9443
9444 (define_insn "*negdi2_cmpz_rex64"
9445 [(set (reg:CCZ FLAGS_REG)
9446 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9447 (const_int 0)))
9448 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9449 (neg:DI (match_dup 1)))]
9450 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9451 "neg{q}\t%0"
9452 [(set_attr "type" "negnot")
9453 (set_attr "mode" "DI")])
9454
9455
9456 (define_expand "negsi2"
9457 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9458 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9459 (clobber (reg:CC FLAGS_REG))])]
9460 ""
9461 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9462
9463 (define_insn "*negsi2_1"
9464 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9465 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9466 (clobber (reg:CC FLAGS_REG))]
9467 "ix86_unary_operator_ok (NEG, SImode, operands)"
9468 "neg{l}\t%0"
9469 [(set_attr "type" "negnot")
9470 (set_attr "mode" "SI")])
9471
9472 ;; Combine is quite creative about this pattern.
9473 (define_insn "*negsi2_1_zext"
9474 [(set (match_operand:DI 0 "register_operand" "=r")
9475 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9476 (const_int 32)))
9477 (const_int 32)))
9478 (clobber (reg:CC FLAGS_REG))]
9479 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9480 "neg{l}\t%k0"
9481 [(set_attr "type" "negnot")
9482 (set_attr "mode" "SI")])
9483
9484 ;; The problem with neg is that it does not perform (compare x 0),
9485 ;; it really performs (compare 0 x), which leaves us with the zero
9486 ;; flag being the only useful item.
9487
9488 (define_insn "*negsi2_cmpz"
9489 [(set (reg:CCZ FLAGS_REG)
9490 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9491 (const_int 0)))
9492 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9493 (neg:SI (match_dup 1)))]
9494 "ix86_unary_operator_ok (NEG, SImode, operands)"
9495 "neg{l}\t%0"
9496 [(set_attr "type" "negnot")
9497 (set_attr "mode" "SI")])
9498
9499 (define_insn "*negsi2_cmpz_zext"
9500 [(set (reg:CCZ FLAGS_REG)
9501 (compare:CCZ (lshiftrt:DI
9502 (neg:DI (ashift:DI
9503 (match_operand:DI 1 "register_operand" "0")
9504 (const_int 32)))
9505 (const_int 32))
9506 (const_int 0)))
9507 (set (match_operand:DI 0 "register_operand" "=r")
9508 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9509 (const_int 32)))
9510 (const_int 32)))]
9511 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9512 "neg{l}\t%k0"
9513 [(set_attr "type" "negnot")
9514 (set_attr "mode" "SI")])
9515
9516 (define_expand "neghi2"
9517 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9518 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9519 (clobber (reg:CC FLAGS_REG))])]
9520 "TARGET_HIMODE_MATH"
9521 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9522
9523 (define_insn "*neghi2_1"
9524 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9525 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9526 (clobber (reg:CC FLAGS_REG))]
9527 "ix86_unary_operator_ok (NEG, HImode, operands)"
9528 "neg{w}\t%0"
9529 [(set_attr "type" "negnot")
9530 (set_attr "mode" "HI")])
9531
9532 (define_insn "*neghi2_cmpz"
9533 [(set (reg:CCZ FLAGS_REG)
9534 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9535 (const_int 0)))
9536 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9537 (neg:HI (match_dup 1)))]
9538 "ix86_unary_operator_ok (NEG, HImode, operands)"
9539 "neg{w}\t%0"
9540 [(set_attr "type" "negnot")
9541 (set_attr "mode" "HI")])
9542
9543 (define_expand "negqi2"
9544 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9545 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9546 (clobber (reg:CC FLAGS_REG))])]
9547 "TARGET_QIMODE_MATH"
9548 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9549
9550 (define_insn "*negqi2_1"
9551 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9552 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9553 (clobber (reg:CC FLAGS_REG))]
9554 "ix86_unary_operator_ok (NEG, QImode, operands)"
9555 "neg{b}\t%0"
9556 [(set_attr "type" "negnot")
9557 (set_attr "mode" "QI")])
9558
9559 (define_insn "*negqi2_cmpz"
9560 [(set (reg:CCZ FLAGS_REG)
9561 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9562 (const_int 0)))
9563 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9564 (neg:QI (match_dup 1)))]
9565 "ix86_unary_operator_ok (NEG, QImode, operands)"
9566 "neg{b}\t%0"
9567 [(set_attr "type" "negnot")
9568 (set_attr "mode" "QI")])
9569
9570 ;; Changing of sign for FP values is doable using integer unit too.
9571
9572 (define_expand "negsf2"
9573 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9574 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9575 "TARGET_80387 || TARGET_SSE_MATH"
9576 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9577
9578 (define_expand "abssf2"
9579 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9580 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9581 "TARGET_80387 || TARGET_SSE_MATH"
9582 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9583
9584 (define_insn "*absnegsf2_mixed"
9585 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9586 (match_operator:SF 3 "absneg_operator"
9587 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9588 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9589 (clobber (reg:CC FLAGS_REG))]
9590 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9591 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9592 "#")
9593
9594 (define_insn "*absnegsf2_sse"
9595 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9596 (match_operator:SF 3 "absneg_operator"
9597 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9598 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9599 (clobber (reg:CC FLAGS_REG))]
9600 "TARGET_SSE_MATH
9601 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9602 "#")
9603
9604 (define_insn "*absnegsf2_i387"
9605 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9606 (match_operator:SF 3 "absneg_operator"
9607 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9608 (use (match_operand 2 "" ""))
9609 (clobber (reg:CC FLAGS_REG))]
9610 "TARGET_80387 && !TARGET_SSE_MATH
9611 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9612 "#")
9613
9614 (define_expand "copysignsf3"
9615 [(match_operand:SF 0 "register_operand" "")
9616 (match_operand:SF 1 "nonmemory_operand" "")
9617 (match_operand:SF 2 "register_operand" "")]
9618 "TARGET_SSE_MATH"
9619 {
9620 ix86_expand_copysign (operands);
9621 DONE;
9622 })
9623
9624 (define_insn_and_split "copysignsf3_const"
9625 [(set (match_operand:SF 0 "register_operand" "=x")
9626 (unspec:SF
9627 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9628 (match_operand:SF 2 "register_operand" "0")
9629 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9630 UNSPEC_COPYSIGN))]
9631 "TARGET_SSE_MATH"
9632 "#"
9633 "&& reload_completed"
9634 [(const_int 0)]
9635 {
9636 ix86_split_copysign_const (operands);
9637 DONE;
9638 })
9639
9640 (define_insn "copysignsf3_var"
9641 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9642 (unspec:SF
9643 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9644 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9645 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9646 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9647 UNSPEC_COPYSIGN))
9648 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9649 "TARGET_SSE_MATH"
9650 "#")
9651
9652 (define_split
9653 [(set (match_operand:SF 0 "register_operand" "")
9654 (unspec:SF
9655 [(match_operand:SF 2 "register_operand" "")
9656 (match_operand:SF 3 "register_operand" "")
9657 (match_operand:V4SF 4 "" "")
9658 (match_operand:V4SF 5 "" "")]
9659 UNSPEC_COPYSIGN))
9660 (clobber (match_scratch:V4SF 1 ""))]
9661 "TARGET_SSE_MATH && reload_completed"
9662 [(const_int 0)]
9663 {
9664 ix86_split_copysign_var (operands);
9665 DONE;
9666 })
9667
9668 (define_expand "negdf2"
9669 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9670 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9671 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9672 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9673
9674 (define_expand "absdf2"
9675 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9676 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9677 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9678 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9679
9680 (define_insn "*absnegdf2_mixed"
9681 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9682 (match_operator:DF 3 "absneg_operator"
9683 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9684 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9685 (clobber (reg:CC FLAGS_REG))]
9686 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9687 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9688 "#")
9689
9690 (define_insn "*absnegdf2_sse"
9691 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9692 (match_operator:DF 3 "absneg_operator"
9693 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9694 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9695 (clobber (reg:CC FLAGS_REG))]
9696 "TARGET_SSE2 && TARGET_SSE_MATH
9697 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9698 "#")
9699
9700 (define_insn "*absnegdf2_i387"
9701 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9702 (match_operator:DF 3 "absneg_operator"
9703 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9704 (use (match_operand 2 "" ""))
9705 (clobber (reg:CC FLAGS_REG))]
9706 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9707 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9708 "#")
9709
9710 (define_expand "copysigndf3"
9711 [(match_operand:DF 0 "register_operand" "")
9712 (match_operand:DF 1 "nonmemory_operand" "")
9713 (match_operand:DF 2 "register_operand" "")]
9714 "TARGET_SSE2 && TARGET_SSE_MATH"
9715 {
9716 ix86_expand_copysign (operands);
9717 DONE;
9718 })
9719
9720 (define_insn_and_split "copysigndf3_const"
9721 [(set (match_operand:DF 0 "register_operand" "=x")
9722 (unspec:DF
9723 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9724 (match_operand:DF 2 "register_operand" "0")
9725 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9726 UNSPEC_COPYSIGN))]
9727 "TARGET_SSE2 && TARGET_SSE_MATH"
9728 "#"
9729 "&& reload_completed"
9730 [(const_int 0)]
9731 {
9732 ix86_split_copysign_const (operands);
9733 DONE;
9734 })
9735
9736 (define_insn "copysigndf3_var"
9737 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9738 (unspec:DF
9739 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9740 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9741 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9742 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9743 UNSPEC_COPYSIGN))
9744 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9745 "TARGET_SSE2 && TARGET_SSE_MATH"
9746 "#")
9747
9748 (define_split
9749 [(set (match_operand:DF 0 "register_operand" "")
9750 (unspec:DF
9751 [(match_operand:DF 2 "register_operand" "")
9752 (match_operand:DF 3 "register_operand" "")
9753 (match_operand:V2DF 4 "" "")
9754 (match_operand:V2DF 5 "" "")]
9755 UNSPEC_COPYSIGN))
9756 (clobber (match_scratch:V2DF 1 ""))]
9757 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9758 [(const_int 0)]
9759 {
9760 ix86_split_copysign_var (operands);
9761 DONE;
9762 })
9763
9764 (define_expand "negxf2"
9765 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9766 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9767 "TARGET_80387"
9768 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9769
9770 (define_expand "absxf2"
9771 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9772 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9773 "TARGET_80387"
9774 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9775
9776 (define_insn "*absnegxf2_i387"
9777 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9778 (match_operator:XF 3 "absneg_operator"
9779 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9780 (use (match_operand 2 "" ""))
9781 (clobber (reg:CC FLAGS_REG))]
9782 "TARGET_80387
9783 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9784 "#")
9785
9786 ;; Splitters for fp abs and neg.
9787
9788 (define_split
9789 [(set (match_operand 0 "fp_register_operand" "")
9790 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9791 (use (match_operand 2 "" ""))
9792 (clobber (reg:CC FLAGS_REG))]
9793 "reload_completed"
9794 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9795
9796 (define_split
9797 [(set (match_operand 0 "register_operand" "")
9798 (match_operator 3 "absneg_operator"
9799 [(match_operand 1 "register_operand" "")]))
9800 (use (match_operand 2 "nonimmediate_operand" ""))
9801 (clobber (reg:CC FLAGS_REG))]
9802 "reload_completed && SSE_REG_P (operands[0])"
9803 [(set (match_dup 0) (match_dup 3))]
9804 {
9805 enum machine_mode mode = GET_MODE (operands[0]);
9806 enum machine_mode vmode = GET_MODE (operands[2]);
9807 rtx tmp;
9808
9809 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9810 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9811 if (operands_match_p (operands[0], operands[2]))
9812 {
9813 tmp = operands[1];
9814 operands[1] = operands[2];
9815 operands[2] = tmp;
9816 }
9817 if (GET_CODE (operands[3]) == ABS)
9818 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9819 else
9820 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9821 operands[3] = tmp;
9822 })
9823
9824 (define_split
9825 [(set (match_operand:SF 0 "register_operand" "")
9826 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9827 (use (match_operand:V4SF 2 "" ""))
9828 (clobber (reg:CC FLAGS_REG))]
9829 "reload_completed"
9830 [(parallel [(set (match_dup 0) (match_dup 1))
9831 (clobber (reg:CC FLAGS_REG))])]
9832 {
9833 rtx tmp;
9834 operands[0] = gen_lowpart (SImode, operands[0]);
9835 if (GET_CODE (operands[1]) == ABS)
9836 {
9837 tmp = gen_int_mode (0x7fffffff, SImode);
9838 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9839 }
9840 else
9841 {
9842 tmp = gen_int_mode (0x80000000, SImode);
9843 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9844 }
9845 operands[1] = tmp;
9846 })
9847
9848 (define_split
9849 [(set (match_operand:DF 0 "register_operand" "")
9850 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9851 (use (match_operand 2 "" ""))
9852 (clobber (reg:CC FLAGS_REG))]
9853 "reload_completed"
9854 [(parallel [(set (match_dup 0) (match_dup 1))
9855 (clobber (reg:CC FLAGS_REG))])]
9856 {
9857 rtx tmp;
9858 if (TARGET_64BIT)
9859 {
9860 tmp = gen_lowpart (DImode, operands[0]);
9861 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9862 operands[0] = tmp;
9863
9864 if (GET_CODE (operands[1]) == ABS)
9865 tmp = const0_rtx;
9866 else
9867 tmp = gen_rtx_NOT (DImode, tmp);
9868 }
9869 else
9870 {
9871 operands[0] = gen_highpart (SImode, operands[0]);
9872 if (GET_CODE (operands[1]) == ABS)
9873 {
9874 tmp = gen_int_mode (0x7fffffff, SImode);
9875 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9876 }
9877 else
9878 {
9879 tmp = gen_int_mode (0x80000000, SImode);
9880 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9881 }
9882 }
9883 operands[1] = tmp;
9884 })
9885
9886 (define_split
9887 [(set (match_operand:XF 0 "register_operand" "")
9888 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9889 (use (match_operand 2 "" ""))
9890 (clobber (reg:CC FLAGS_REG))]
9891 "reload_completed"
9892 [(parallel [(set (match_dup 0) (match_dup 1))
9893 (clobber (reg:CC FLAGS_REG))])]
9894 {
9895 rtx tmp;
9896 operands[0] = gen_rtx_REG (SImode,
9897 true_regnum (operands[0])
9898 + (TARGET_64BIT ? 1 : 2));
9899 if (GET_CODE (operands[1]) == ABS)
9900 {
9901 tmp = GEN_INT (0x7fff);
9902 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9903 }
9904 else
9905 {
9906 tmp = GEN_INT (0x8000);
9907 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9908 }
9909 operands[1] = tmp;
9910 })
9911
9912 (define_split
9913 [(set (match_operand 0 "memory_operand" "")
9914 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9915 (use (match_operand 2 "" ""))
9916 (clobber (reg:CC FLAGS_REG))]
9917 "reload_completed"
9918 [(parallel [(set (match_dup 0) (match_dup 1))
9919 (clobber (reg:CC FLAGS_REG))])]
9920 {
9921 enum machine_mode mode = GET_MODE (operands[0]);
9922 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9923 rtx tmp;
9924
9925 operands[0] = adjust_address (operands[0], QImode, size - 1);
9926 if (GET_CODE (operands[1]) == ABS)
9927 {
9928 tmp = gen_int_mode (0x7f, QImode);
9929 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9930 }
9931 else
9932 {
9933 tmp = gen_int_mode (0x80, QImode);
9934 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9935 }
9936 operands[1] = tmp;
9937 })
9938
9939 ;; Conditionalize these after reload. If they match before reload, we
9940 ;; lose the clobber and ability to use integer instructions.
9941
9942 (define_insn "*negsf2_1"
9943 [(set (match_operand:SF 0 "register_operand" "=f")
9944 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9945 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9946 "fchs"
9947 [(set_attr "type" "fsgn")
9948 (set_attr "mode" "SF")])
9949
9950 (define_insn "*negdf2_1"
9951 [(set (match_operand:DF 0 "register_operand" "=f")
9952 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9953 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9954 "fchs"
9955 [(set_attr "type" "fsgn")
9956 (set_attr "mode" "DF")])
9957
9958 (define_insn "*negxf2_1"
9959 [(set (match_operand:XF 0 "register_operand" "=f")
9960 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9961 "TARGET_80387"
9962 "fchs"
9963 [(set_attr "type" "fsgn")
9964 (set_attr "mode" "XF")])
9965
9966 (define_insn "*abssf2_1"
9967 [(set (match_operand:SF 0 "register_operand" "=f")
9968 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9969 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9970 "fabs"
9971 [(set_attr "type" "fsgn")
9972 (set_attr "mode" "SF")])
9973
9974 (define_insn "*absdf2_1"
9975 [(set (match_operand:DF 0 "register_operand" "=f")
9976 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9977 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9978 "fabs"
9979 [(set_attr "type" "fsgn")
9980 (set_attr "mode" "DF")])
9981
9982 (define_insn "*absxf2_1"
9983 [(set (match_operand:XF 0 "register_operand" "=f")
9984 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9985 "TARGET_80387"
9986 "fabs"
9987 [(set_attr "type" "fsgn")
9988 (set_attr "mode" "DF")])
9989
9990 (define_insn "*negextendsfdf2"
9991 [(set (match_operand:DF 0 "register_operand" "=f")
9992 (neg:DF (float_extend:DF
9993 (match_operand:SF 1 "register_operand" "0"))))]
9994 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9995 "fchs"
9996 [(set_attr "type" "fsgn")
9997 (set_attr "mode" "DF")])
9998
9999 (define_insn "*negextenddfxf2"
10000 [(set (match_operand:XF 0 "register_operand" "=f")
10001 (neg:XF (float_extend:XF
10002 (match_operand:DF 1 "register_operand" "0"))))]
10003 "TARGET_80387"
10004 "fchs"
10005 [(set_attr "type" "fsgn")
10006 (set_attr "mode" "XF")])
10007
10008 (define_insn "*negextendsfxf2"
10009 [(set (match_operand:XF 0 "register_operand" "=f")
10010 (neg:XF (float_extend:XF
10011 (match_operand:SF 1 "register_operand" "0"))))]
10012 "TARGET_80387"
10013 "fchs"
10014 [(set_attr "type" "fsgn")
10015 (set_attr "mode" "XF")])
10016
10017 (define_insn "*absextendsfdf2"
10018 [(set (match_operand:DF 0 "register_operand" "=f")
10019 (abs:DF (float_extend:DF
10020 (match_operand:SF 1 "register_operand" "0"))))]
10021 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10022 "fabs"
10023 [(set_attr "type" "fsgn")
10024 (set_attr "mode" "DF")])
10025
10026 (define_insn "*absextenddfxf2"
10027 [(set (match_operand:XF 0 "register_operand" "=f")
10028 (abs:XF (float_extend:XF
10029 (match_operand:DF 1 "register_operand" "0"))))]
10030 "TARGET_80387"
10031 "fabs"
10032 [(set_attr "type" "fsgn")
10033 (set_attr "mode" "XF")])
10034
10035 (define_insn "*absextendsfxf2"
10036 [(set (match_operand:XF 0 "register_operand" "=f")
10037 (abs:XF (float_extend:XF
10038 (match_operand:SF 1 "register_operand" "0"))))]
10039 "TARGET_80387"
10040 "fabs"
10041 [(set_attr "type" "fsgn")
10042 (set_attr "mode" "XF")])
10043 \f
10044 ;; One complement instructions
10045
10046 (define_expand "one_cmpldi2"
10047 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10048 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10049 "TARGET_64BIT"
10050 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10051
10052 (define_insn "*one_cmpldi2_1_rex64"
10053 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10054 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10055 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10056 "not{q}\t%0"
10057 [(set_attr "type" "negnot")
10058 (set_attr "mode" "DI")])
10059
10060 (define_insn "*one_cmpldi2_2_rex64"
10061 [(set (reg FLAGS_REG)
10062 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10063 (const_int 0)))
10064 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10065 (not:DI (match_dup 1)))]
10066 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10067 && ix86_unary_operator_ok (NOT, DImode, operands)"
10068 "#"
10069 [(set_attr "type" "alu1")
10070 (set_attr "mode" "DI")])
10071
10072 (define_split
10073 [(set (match_operand 0 "flags_reg_operand" "")
10074 (match_operator 2 "compare_operator"
10075 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10076 (const_int 0)]))
10077 (set (match_operand:DI 1 "nonimmediate_operand" "")
10078 (not:DI (match_dup 3)))]
10079 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10080 [(parallel [(set (match_dup 0)
10081 (match_op_dup 2
10082 [(xor:DI (match_dup 3) (const_int -1))
10083 (const_int 0)]))
10084 (set (match_dup 1)
10085 (xor:DI (match_dup 3) (const_int -1)))])]
10086 "")
10087
10088 (define_expand "one_cmplsi2"
10089 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10090 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10091 ""
10092 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10093
10094 (define_insn "*one_cmplsi2_1"
10095 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10096 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10097 "ix86_unary_operator_ok (NOT, SImode, operands)"
10098 "not{l}\t%0"
10099 [(set_attr "type" "negnot")
10100 (set_attr "mode" "SI")])
10101
10102 ;; ??? Currently never generated - xor is used instead.
10103 (define_insn "*one_cmplsi2_1_zext"
10104 [(set (match_operand:DI 0 "register_operand" "=r")
10105 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10106 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10107 "not{l}\t%k0"
10108 [(set_attr "type" "negnot")
10109 (set_attr "mode" "SI")])
10110
10111 (define_insn "*one_cmplsi2_2"
10112 [(set (reg FLAGS_REG)
10113 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10114 (const_int 0)))
10115 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10116 (not:SI (match_dup 1)))]
10117 "ix86_match_ccmode (insn, CCNOmode)
10118 && ix86_unary_operator_ok (NOT, SImode, operands)"
10119 "#"
10120 [(set_attr "type" "alu1")
10121 (set_attr "mode" "SI")])
10122
10123 (define_split
10124 [(set (match_operand 0 "flags_reg_operand" "")
10125 (match_operator 2 "compare_operator"
10126 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10127 (const_int 0)]))
10128 (set (match_operand:SI 1 "nonimmediate_operand" "")
10129 (not:SI (match_dup 3)))]
10130 "ix86_match_ccmode (insn, CCNOmode)"
10131 [(parallel [(set (match_dup 0)
10132 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10133 (const_int 0)]))
10134 (set (match_dup 1)
10135 (xor:SI (match_dup 3) (const_int -1)))])]
10136 "")
10137
10138 ;; ??? Currently never generated - xor is used instead.
10139 (define_insn "*one_cmplsi2_2_zext"
10140 [(set (reg FLAGS_REG)
10141 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10142 (const_int 0)))
10143 (set (match_operand:DI 0 "register_operand" "=r")
10144 (zero_extend:DI (not:SI (match_dup 1))))]
10145 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10146 && ix86_unary_operator_ok (NOT, SImode, operands)"
10147 "#"
10148 [(set_attr "type" "alu1")
10149 (set_attr "mode" "SI")])
10150
10151 (define_split
10152 [(set (match_operand 0 "flags_reg_operand" "")
10153 (match_operator 2 "compare_operator"
10154 [(not:SI (match_operand:SI 3 "register_operand" ""))
10155 (const_int 0)]))
10156 (set (match_operand:DI 1 "register_operand" "")
10157 (zero_extend:DI (not:SI (match_dup 3))))]
10158 "ix86_match_ccmode (insn, CCNOmode)"
10159 [(parallel [(set (match_dup 0)
10160 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10161 (const_int 0)]))
10162 (set (match_dup 1)
10163 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10164 "")
10165
10166 (define_expand "one_cmplhi2"
10167 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10168 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10169 "TARGET_HIMODE_MATH"
10170 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10171
10172 (define_insn "*one_cmplhi2_1"
10173 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10174 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10175 "ix86_unary_operator_ok (NOT, HImode, operands)"
10176 "not{w}\t%0"
10177 [(set_attr "type" "negnot")
10178 (set_attr "mode" "HI")])
10179
10180 (define_insn "*one_cmplhi2_2"
10181 [(set (reg FLAGS_REG)
10182 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10183 (const_int 0)))
10184 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10185 (not:HI (match_dup 1)))]
10186 "ix86_match_ccmode (insn, CCNOmode)
10187 && ix86_unary_operator_ok (NEG, HImode, operands)"
10188 "#"
10189 [(set_attr "type" "alu1")
10190 (set_attr "mode" "HI")])
10191
10192 (define_split
10193 [(set (match_operand 0 "flags_reg_operand" "")
10194 (match_operator 2 "compare_operator"
10195 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10196 (const_int 0)]))
10197 (set (match_operand:HI 1 "nonimmediate_operand" "")
10198 (not:HI (match_dup 3)))]
10199 "ix86_match_ccmode (insn, CCNOmode)"
10200 [(parallel [(set (match_dup 0)
10201 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10202 (const_int 0)]))
10203 (set (match_dup 1)
10204 (xor:HI (match_dup 3) (const_int -1)))])]
10205 "")
10206
10207 ;; %%% Potential partial reg stall on alternative 1. What to do?
10208 (define_expand "one_cmplqi2"
10209 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10210 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10211 "TARGET_QIMODE_MATH"
10212 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10213
10214 (define_insn "*one_cmplqi2_1"
10215 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10216 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10217 "ix86_unary_operator_ok (NOT, QImode, operands)"
10218 "@
10219 not{b}\t%0
10220 not{l}\t%k0"
10221 [(set_attr "type" "negnot")
10222 (set_attr "mode" "QI,SI")])
10223
10224 (define_insn "*one_cmplqi2_2"
10225 [(set (reg FLAGS_REG)
10226 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10227 (const_int 0)))
10228 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10229 (not:QI (match_dup 1)))]
10230 "ix86_match_ccmode (insn, CCNOmode)
10231 && ix86_unary_operator_ok (NOT, QImode, operands)"
10232 "#"
10233 [(set_attr "type" "alu1")
10234 (set_attr "mode" "QI")])
10235
10236 (define_split
10237 [(set (match_operand 0 "flags_reg_operand" "")
10238 (match_operator 2 "compare_operator"
10239 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10240 (const_int 0)]))
10241 (set (match_operand:QI 1 "nonimmediate_operand" "")
10242 (not:QI (match_dup 3)))]
10243 "ix86_match_ccmode (insn, CCNOmode)"
10244 [(parallel [(set (match_dup 0)
10245 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10246 (const_int 0)]))
10247 (set (match_dup 1)
10248 (xor:QI (match_dup 3) (const_int -1)))])]
10249 "")
10250 \f
10251 ;; Arithmetic shift instructions
10252
10253 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10254 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10255 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10256 ;; from the assembler input.
10257 ;;
10258 ;; This instruction shifts the target reg/mem as usual, but instead of
10259 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10260 ;; is a left shift double, bits are taken from the high order bits of
10261 ;; reg, else if the insn is a shift right double, bits are taken from the
10262 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10263 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10264 ;;
10265 ;; Since sh[lr]d does not change the `reg' operand, that is done
10266 ;; separately, making all shifts emit pairs of shift double and normal
10267 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10268 ;; support a 63 bit shift, each shift where the count is in a reg expands
10269 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10270 ;;
10271 ;; If the shift count is a constant, we need never emit more than one
10272 ;; shift pair, instead using moves and sign extension for counts greater
10273 ;; than 31.
10274
10275 (define_expand "ashlti3"
10276 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10277 (ashift:TI (match_operand:TI 1 "register_operand" "")
10278 (match_operand:QI 2 "nonmemory_operand" "")))
10279 (clobber (reg:CC FLAGS_REG))])]
10280 "TARGET_64BIT"
10281 {
10282 if (! immediate_operand (operands[2], QImode))
10283 {
10284 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10285 DONE;
10286 }
10287 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10288 DONE;
10289 })
10290
10291 (define_insn "ashlti3_1"
10292 [(set (match_operand:TI 0 "register_operand" "=r")
10293 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10294 (match_operand:QI 2 "register_operand" "c")))
10295 (clobber (match_scratch:DI 3 "=&r"))
10296 (clobber (reg:CC FLAGS_REG))]
10297 "TARGET_64BIT"
10298 "#"
10299 [(set_attr "type" "multi")])
10300
10301 (define_insn "*ashlti3_2"
10302 [(set (match_operand:TI 0 "register_operand" "=r")
10303 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10304 (match_operand:QI 2 "immediate_operand" "O")))
10305 (clobber (reg:CC FLAGS_REG))]
10306 "TARGET_64BIT"
10307 "#"
10308 [(set_attr "type" "multi")])
10309
10310 (define_split
10311 [(set (match_operand:TI 0 "register_operand" "")
10312 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10313 (match_operand:QI 2 "register_operand" "")))
10314 (clobber (match_scratch:DI 3 ""))
10315 (clobber (reg:CC FLAGS_REG))]
10316 "TARGET_64BIT && reload_completed"
10317 [(const_int 0)]
10318 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10319
10320 (define_split
10321 [(set (match_operand:TI 0 "register_operand" "")
10322 (ashift:TI (match_operand:TI 1 "register_operand" "")
10323 (match_operand:QI 2 "immediate_operand" "")))
10324 (clobber (reg:CC FLAGS_REG))]
10325 "TARGET_64BIT && reload_completed"
10326 [(const_int 0)]
10327 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10328
10329 (define_insn "x86_64_shld"
10330 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10331 (ior:DI (ashift:DI (match_dup 0)
10332 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10333 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10334 (minus:QI (const_int 64) (match_dup 2)))))
10335 (clobber (reg:CC FLAGS_REG))]
10336 "TARGET_64BIT"
10337 "@
10338 shld{q}\t{%2, %1, %0|%0, %1, %2}
10339 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10340 [(set_attr "type" "ishift")
10341 (set_attr "prefix_0f" "1")
10342 (set_attr "mode" "DI")
10343 (set_attr "athlon_decode" "vector")])
10344
10345 (define_expand "x86_64_shift_adj"
10346 [(set (reg:CCZ FLAGS_REG)
10347 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10348 (const_int 64))
10349 (const_int 0)))
10350 (set (match_operand:DI 0 "register_operand" "")
10351 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10352 (match_operand:DI 1 "register_operand" "")
10353 (match_dup 0)))
10354 (set (match_dup 1)
10355 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10356 (match_operand:DI 3 "register_operand" "r")
10357 (match_dup 1)))]
10358 "TARGET_64BIT"
10359 "")
10360
10361 (define_expand "ashldi3"
10362 [(set (match_operand:DI 0 "shiftdi_operand" "")
10363 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10364 (match_operand:QI 2 "nonmemory_operand" "")))]
10365 ""
10366 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10367
10368 (define_insn "*ashldi3_1_rex64"
10369 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10370 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10371 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10372 (clobber (reg:CC FLAGS_REG))]
10373 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10374 {
10375 switch (get_attr_type (insn))
10376 {
10377 case TYPE_ALU:
10378 gcc_assert (operands[2] == const1_rtx);
10379 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10380 return "add{q}\t{%0, %0|%0, %0}";
10381
10382 case TYPE_LEA:
10383 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10384 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10385 operands[1] = gen_rtx_MULT (DImode, operands[1],
10386 GEN_INT (1 << INTVAL (operands[2])));
10387 return "lea{q}\t{%a1, %0|%0, %a1}";
10388
10389 default:
10390 if (REG_P (operands[2]))
10391 return "sal{q}\t{%b2, %0|%0, %b2}";
10392 else if (operands[2] == const1_rtx
10393 && (TARGET_SHIFT1 || optimize_size))
10394 return "sal{q}\t%0";
10395 else
10396 return "sal{q}\t{%2, %0|%0, %2}";
10397 }
10398 }
10399 [(set (attr "type")
10400 (cond [(eq_attr "alternative" "1")
10401 (const_string "lea")
10402 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10403 (const_int 0))
10404 (match_operand 0 "register_operand" ""))
10405 (match_operand 2 "const1_operand" ""))
10406 (const_string "alu")
10407 ]
10408 (const_string "ishift")))
10409 (set_attr "mode" "DI")])
10410
10411 ;; Convert lea to the lea pattern to avoid flags dependency.
10412 (define_split
10413 [(set (match_operand:DI 0 "register_operand" "")
10414 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10415 (match_operand:QI 2 "immediate_operand" "")))
10416 (clobber (reg:CC FLAGS_REG))]
10417 "TARGET_64BIT && reload_completed
10418 && true_regnum (operands[0]) != true_regnum (operands[1])"
10419 [(set (match_dup 0)
10420 (mult:DI (match_dup 1)
10421 (match_dup 2)))]
10422 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10423
10424 ;; This pattern can't accept a variable shift count, since shifts by
10425 ;; zero don't affect the flags. We assume that shifts by constant
10426 ;; zero are optimized away.
10427 (define_insn "*ashldi3_cmp_rex64"
10428 [(set (reg FLAGS_REG)
10429 (compare
10430 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10431 (match_operand:QI 2 "immediate_operand" "e"))
10432 (const_int 0)))
10433 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10434 (ashift:DI (match_dup 1) (match_dup 2)))]
10435 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10436 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10437 && (optimize_size
10438 || !TARGET_PARTIAL_FLAG_REG_STALL
10439 || (operands[2] == const1_rtx
10440 && (TARGET_SHIFT1
10441 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10442 {
10443 switch (get_attr_type (insn))
10444 {
10445 case TYPE_ALU:
10446 gcc_assert (operands[2] == const1_rtx);
10447 return "add{q}\t{%0, %0|%0, %0}";
10448
10449 default:
10450 if (REG_P (operands[2]))
10451 return "sal{q}\t{%b2, %0|%0, %b2}";
10452 else if (operands[2] == const1_rtx
10453 && (TARGET_SHIFT1 || optimize_size))
10454 return "sal{q}\t%0";
10455 else
10456 return "sal{q}\t{%2, %0|%0, %2}";
10457 }
10458 }
10459 [(set (attr "type")
10460 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10461 (const_int 0))
10462 (match_operand 0 "register_operand" ""))
10463 (match_operand 2 "const1_operand" ""))
10464 (const_string "alu")
10465 ]
10466 (const_string "ishift")))
10467 (set_attr "mode" "DI")])
10468
10469 (define_insn "*ashldi3_cconly_rex64"
10470 [(set (reg FLAGS_REG)
10471 (compare
10472 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10473 (match_operand:QI 2 "immediate_operand" "e"))
10474 (const_int 0)))
10475 (clobber (match_scratch:DI 0 "=r"))]
10476 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10477 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10478 && (optimize_size
10479 || !TARGET_PARTIAL_FLAG_REG_STALL
10480 || (operands[2] == const1_rtx
10481 && (TARGET_SHIFT1
10482 || TARGET_DOUBLE_WITH_ADD)))"
10483 {
10484 switch (get_attr_type (insn))
10485 {
10486 case TYPE_ALU:
10487 gcc_assert (operands[2] == const1_rtx);
10488 return "add{q}\t{%0, %0|%0, %0}";
10489
10490 default:
10491 if (REG_P (operands[2]))
10492 return "sal{q}\t{%b2, %0|%0, %b2}";
10493 else if (operands[2] == const1_rtx
10494 && (TARGET_SHIFT1 || optimize_size))
10495 return "sal{q}\t%0";
10496 else
10497 return "sal{q}\t{%2, %0|%0, %2}";
10498 }
10499 }
10500 [(set (attr "type")
10501 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10502 (const_int 0))
10503 (match_operand 0 "register_operand" ""))
10504 (match_operand 2 "const1_operand" ""))
10505 (const_string "alu")
10506 ]
10507 (const_string "ishift")))
10508 (set_attr "mode" "DI")])
10509
10510 (define_insn "*ashldi3_1"
10511 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10512 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10513 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10514 (clobber (reg:CC FLAGS_REG))]
10515 "!TARGET_64BIT"
10516 "#"
10517 [(set_attr "type" "multi")])
10518
10519 ;; By default we don't ask for a scratch register, because when DImode
10520 ;; values are manipulated, registers are already at a premium. But if
10521 ;; we have one handy, we won't turn it away.
10522 (define_peephole2
10523 [(match_scratch:SI 3 "r")
10524 (parallel [(set (match_operand:DI 0 "register_operand" "")
10525 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10526 (match_operand:QI 2 "nonmemory_operand" "")))
10527 (clobber (reg:CC FLAGS_REG))])
10528 (match_dup 3)]
10529 "!TARGET_64BIT && TARGET_CMOVE"
10530 [(const_int 0)]
10531 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10532
10533 (define_split
10534 [(set (match_operand:DI 0 "register_operand" "")
10535 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10536 (match_operand:QI 2 "nonmemory_operand" "")))
10537 (clobber (reg:CC FLAGS_REG))]
10538 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10539 ? flow2_completed : reload_completed)"
10540 [(const_int 0)]
10541 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10542
10543 (define_insn "x86_shld_1"
10544 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10545 (ior:SI (ashift:SI (match_dup 0)
10546 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10547 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10548 (minus:QI (const_int 32) (match_dup 2)))))
10549 (clobber (reg:CC FLAGS_REG))]
10550 ""
10551 "@
10552 shld{l}\t{%2, %1, %0|%0, %1, %2}
10553 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10554 [(set_attr "type" "ishift")
10555 (set_attr "prefix_0f" "1")
10556 (set_attr "mode" "SI")
10557 (set_attr "pent_pair" "np")
10558 (set_attr "athlon_decode" "vector")])
10559
10560 (define_expand "x86_shift_adj_1"
10561 [(set (reg:CCZ FLAGS_REG)
10562 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10563 (const_int 32))
10564 (const_int 0)))
10565 (set (match_operand:SI 0 "register_operand" "")
10566 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10567 (match_operand:SI 1 "register_operand" "")
10568 (match_dup 0)))
10569 (set (match_dup 1)
10570 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10571 (match_operand:SI 3 "register_operand" "r")
10572 (match_dup 1)))]
10573 "TARGET_CMOVE"
10574 "")
10575
10576 (define_expand "x86_shift_adj_2"
10577 [(use (match_operand:SI 0 "register_operand" ""))
10578 (use (match_operand:SI 1 "register_operand" ""))
10579 (use (match_operand:QI 2 "register_operand" ""))]
10580 ""
10581 {
10582 rtx label = gen_label_rtx ();
10583 rtx tmp;
10584
10585 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10586
10587 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10588 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10589 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10590 gen_rtx_LABEL_REF (VOIDmode, label),
10591 pc_rtx);
10592 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10593 JUMP_LABEL (tmp) = label;
10594
10595 emit_move_insn (operands[0], operands[1]);
10596 ix86_expand_clear (operands[1]);
10597
10598 emit_label (label);
10599 LABEL_NUSES (label) = 1;
10600
10601 DONE;
10602 })
10603
10604 (define_expand "ashlsi3"
10605 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10606 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10607 (match_operand:QI 2 "nonmemory_operand" "")))
10608 (clobber (reg:CC FLAGS_REG))]
10609 ""
10610 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10611
10612 (define_insn "*ashlsi3_1"
10613 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10614 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10615 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10616 (clobber (reg:CC FLAGS_REG))]
10617 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10618 {
10619 switch (get_attr_type (insn))
10620 {
10621 case TYPE_ALU:
10622 gcc_assert (operands[2] == const1_rtx);
10623 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10624 return "add{l}\t{%0, %0|%0, %0}";
10625
10626 case TYPE_LEA:
10627 return "#";
10628
10629 default:
10630 if (REG_P (operands[2]))
10631 return "sal{l}\t{%b2, %0|%0, %b2}";
10632 else if (operands[2] == const1_rtx
10633 && (TARGET_SHIFT1 || optimize_size))
10634 return "sal{l}\t%0";
10635 else
10636 return "sal{l}\t{%2, %0|%0, %2}";
10637 }
10638 }
10639 [(set (attr "type")
10640 (cond [(eq_attr "alternative" "1")
10641 (const_string "lea")
10642 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10643 (const_int 0))
10644 (match_operand 0 "register_operand" ""))
10645 (match_operand 2 "const1_operand" ""))
10646 (const_string "alu")
10647 ]
10648 (const_string "ishift")))
10649 (set_attr "mode" "SI")])
10650
10651 ;; Convert lea to the lea pattern to avoid flags dependency.
10652 (define_split
10653 [(set (match_operand 0 "register_operand" "")
10654 (ashift (match_operand 1 "index_register_operand" "")
10655 (match_operand:QI 2 "const_int_operand" "")))
10656 (clobber (reg:CC FLAGS_REG))]
10657 "reload_completed
10658 && true_regnum (operands[0]) != true_regnum (operands[1])
10659 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10660 [(const_int 0)]
10661 {
10662 rtx pat;
10663 enum machine_mode mode = GET_MODE (operands[0]);
10664
10665 if (GET_MODE_SIZE (mode) < 4)
10666 operands[0] = gen_lowpart (SImode, operands[0]);
10667 if (mode != Pmode)
10668 operands[1] = gen_lowpart (Pmode, operands[1]);
10669 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10670
10671 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10672 if (Pmode != SImode)
10673 pat = gen_rtx_SUBREG (SImode, pat, 0);
10674 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10675 DONE;
10676 })
10677
10678 ;; Rare case of shifting RSP is handled by generating move and shift
10679 (define_split
10680 [(set (match_operand 0 "register_operand" "")
10681 (ashift (match_operand 1 "register_operand" "")
10682 (match_operand:QI 2 "const_int_operand" "")))
10683 (clobber (reg:CC FLAGS_REG))]
10684 "reload_completed
10685 && true_regnum (operands[0]) != true_regnum (operands[1])"
10686 [(const_int 0)]
10687 {
10688 rtx pat, clob;
10689 emit_move_insn (operands[0], operands[1]);
10690 pat = gen_rtx_SET (VOIDmode, operands[0],
10691 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10692 operands[0], operands[2]));
10693 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10694 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10695 DONE;
10696 })
10697
10698 (define_insn "*ashlsi3_1_zext"
10699 [(set (match_operand:DI 0 "register_operand" "=r,r")
10700 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10701 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10702 (clobber (reg:CC FLAGS_REG))]
10703 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10704 {
10705 switch (get_attr_type (insn))
10706 {
10707 case TYPE_ALU:
10708 gcc_assert (operands[2] == const1_rtx);
10709 return "add{l}\t{%k0, %k0|%k0, %k0}";
10710
10711 case TYPE_LEA:
10712 return "#";
10713
10714 default:
10715 if (REG_P (operands[2]))
10716 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10717 else if (operands[2] == const1_rtx
10718 && (TARGET_SHIFT1 || optimize_size))
10719 return "sal{l}\t%k0";
10720 else
10721 return "sal{l}\t{%2, %k0|%k0, %2}";
10722 }
10723 }
10724 [(set (attr "type")
10725 (cond [(eq_attr "alternative" "1")
10726 (const_string "lea")
10727 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10728 (const_int 0))
10729 (match_operand 2 "const1_operand" ""))
10730 (const_string "alu")
10731 ]
10732 (const_string "ishift")))
10733 (set_attr "mode" "SI")])
10734
10735 ;; Convert lea to the lea pattern to avoid flags dependency.
10736 (define_split
10737 [(set (match_operand:DI 0 "register_operand" "")
10738 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10739 (match_operand:QI 2 "const_int_operand" ""))))
10740 (clobber (reg:CC FLAGS_REG))]
10741 "TARGET_64BIT && reload_completed
10742 && true_regnum (operands[0]) != true_regnum (operands[1])"
10743 [(set (match_dup 0) (zero_extend:DI
10744 (subreg:SI (mult:SI (match_dup 1)
10745 (match_dup 2)) 0)))]
10746 {
10747 operands[1] = gen_lowpart (Pmode, operands[1]);
10748 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10749 })
10750
10751 ;; This pattern can't accept a variable shift count, since shifts by
10752 ;; zero don't affect the flags. We assume that shifts by constant
10753 ;; zero are optimized away.
10754 (define_insn "*ashlsi3_cmp"
10755 [(set (reg FLAGS_REG)
10756 (compare
10757 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10758 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10759 (const_int 0)))
10760 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10761 (ashift:SI (match_dup 1) (match_dup 2)))]
10762 "ix86_match_ccmode (insn, CCGOCmode)
10763 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10764 && (optimize_size
10765 || !TARGET_PARTIAL_FLAG_REG_STALL
10766 || (operands[2] == const1_rtx
10767 && (TARGET_SHIFT1
10768 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10769 {
10770 switch (get_attr_type (insn))
10771 {
10772 case TYPE_ALU:
10773 gcc_assert (operands[2] == const1_rtx);
10774 return "add{l}\t{%0, %0|%0, %0}";
10775
10776 default:
10777 if (REG_P (operands[2]))
10778 return "sal{l}\t{%b2, %0|%0, %b2}";
10779 else if (operands[2] == const1_rtx
10780 && (TARGET_SHIFT1 || optimize_size))
10781 return "sal{l}\t%0";
10782 else
10783 return "sal{l}\t{%2, %0|%0, %2}";
10784 }
10785 }
10786 [(set (attr "type")
10787 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10788 (const_int 0))
10789 (match_operand 0 "register_operand" ""))
10790 (match_operand 2 "const1_operand" ""))
10791 (const_string "alu")
10792 ]
10793 (const_string "ishift")))
10794 (set_attr "mode" "SI")])
10795
10796 (define_insn "*ashlsi3_cconly"
10797 [(set (reg FLAGS_REG)
10798 (compare
10799 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10800 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10801 (const_int 0)))
10802 (clobber (match_scratch:SI 0 "=r"))]
10803 "ix86_match_ccmode (insn, CCGOCmode)
10804 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10805 && (optimize_size
10806 || !TARGET_PARTIAL_FLAG_REG_STALL
10807 || (operands[2] == const1_rtx
10808 && (TARGET_SHIFT1
10809 || TARGET_DOUBLE_WITH_ADD)))"
10810 {
10811 switch (get_attr_type (insn))
10812 {
10813 case TYPE_ALU:
10814 gcc_assert (operands[2] == const1_rtx);
10815 return "add{l}\t{%0, %0|%0, %0}";
10816
10817 default:
10818 if (REG_P (operands[2]))
10819 return "sal{l}\t{%b2, %0|%0, %b2}";
10820 else if (operands[2] == const1_rtx
10821 && (TARGET_SHIFT1 || optimize_size))
10822 return "sal{l}\t%0";
10823 else
10824 return "sal{l}\t{%2, %0|%0, %2}";
10825 }
10826 }
10827 [(set (attr "type")
10828 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10829 (const_int 0))
10830 (match_operand 0 "register_operand" ""))
10831 (match_operand 2 "const1_operand" ""))
10832 (const_string "alu")
10833 ]
10834 (const_string "ishift")))
10835 (set_attr "mode" "SI")])
10836
10837 (define_insn "*ashlsi3_cmp_zext"
10838 [(set (reg FLAGS_REG)
10839 (compare
10840 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10841 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10842 (const_int 0)))
10843 (set (match_operand:DI 0 "register_operand" "=r")
10844 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10845 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10846 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10847 && (optimize_size
10848 || !TARGET_PARTIAL_FLAG_REG_STALL
10849 || (operands[2] == const1_rtx
10850 && (TARGET_SHIFT1
10851 || TARGET_DOUBLE_WITH_ADD)))"
10852 {
10853 switch (get_attr_type (insn))
10854 {
10855 case TYPE_ALU:
10856 gcc_assert (operands[2] == const1_rtx);
10857 return "add{l}\t{%k0, %k0|%k0, %k0}";
10858
10859 default:
10860 if (REG_P (operands[2]))
10861 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10862 else if (operands[2] == const1_rtx
10863 && (TARGET_SHIFT1 || optimize_size))
10864 return "sal{l}\t%k0";
10865 else
10866 return "sal{l}\t{%2, %k0|%k0, %2}";
10867 }
10868 }
10869 [(set (attr "type")
10870 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10871 (const_int 0))
10872 (match_operand 2 "const1_operand" ""))
10873 (const_string "alu")
10874 ]
10875 (const_string "ishift")))
10876 (set_attr "mode" "SI")])
10877
10878 (define_expand "ashlhi3"
10879 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10880 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10881 (match_operand:QI 2 "nonmemory_operand" "")))
10882 (clobber (reg:CC FLAGS_REG))]
10883 "TARGET_HIMODE_MATH"
10884 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10885
10886 (define_insn "*ashlhi3_1_lea"
10887 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10888 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10889 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10890 (clobber (reg:CC FLAGS_REG))]
10891 "!TARGET_PARTIAL_REG_STALL
10892 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10893 {
10894 switch (get_attr_type (insn))
10895 {
10896 case TYPE_LEA:
10897 return "#";
10898 case TYPE_ALU:
10899 gcc_assert (operands[2] == const1_rtx);
10900 return "add{w}\t{%0, %0|%0, %0}";
10901
10902 default:
10903 if (REG_P (operands[2]))
10904 return "sal{w}\t{%b2, %0|%0, %b2}";
10905 else if (operands[2] == const1_rtx
10906 && (TARGET_SHIFT1 || optimize_size))
10907 return "sal{w}\t%0";
10908 else
10909 return "sal{w}\t{%2, %0|%0, %2}";
10910 }
10911 }
10912 [(set (attr "type")
10913 (cond [(eq_attr "alternative" "1")
10914 (const_string "lea")
10915 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10916 (const_int 0))
10917 (match_operand 0 "register_operand" ""))
10918 (match_operand 2 "const1_operand" ""))
10919 (const_string "alu")
10920 ]
10921 (const_string "ishift")))
10922 (set_attr "mode" "HI,SI")])
10923
10924 (define_insn "*ashlhi3_1"
10925 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10926 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10927 (match_operand:QI 2 "nonmemory_operand" "cI")))
10928 (clobber (reg:CC FLAGS_REG))]
10929 "TARGET_PARTIAL_REG_STALL
10930 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10931 {
10932 switch (get_attr_type (insn))
10933 {
10934 case TYPE_ALU:
10935 gcc_assert (operands[2] == const1_rtx);
10936 return "add{w}\t{%0, %0|%0, %0}";
10937
10938 default:
10939 if (REG_P (operands[2]))
10940 return "sal{w}\t{%b2, %0|%0, %b2}";
10941 else if (operands[2] == const1_rtx
10942 && (TARGET_SHIFT1 || optimize_size))
10943 return "sal{w}\t%0";
10944 else
10945 return "sal{w}\t{%2, %0|%0, %2}";
10946 }
10947 }
10948 [(set (attr "type")
10949 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10950 (const_int 0))
10951 (match_operand 0 "register_operand" ""))
10952 (match_operand 2 "const1_operand" ""))
10953 (const_string "alu")
10954 ]
10955 (const_string "ishift")))
10956 (set_attr "mode" "HI")])
10957
10958 ;; This pattern can't accept a variable shift count, since shifts by
10959 ;; zero don't affect the flags. We assume that shifts by constant
10960 ;; zero are optimized away.
10961 (define_insn "*ashlhi3_cmp"
10962 [(set (reg FLAGS_REG)
10963 (compare
10964 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10965 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10966 (const_int 0)))
10967 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10968 (ashift:HI (match_dup 1) (match_dup 2)))]
10969 "ix86_match_ccmode (insn, CCGOCmode)
10970 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10971 && (optimize_size
10972 || !TARGET_PARTIAL_FLAG_REG_STALL
10973 || (operands[2] == const1_rtx
10974 && (TARGET_SHIFT1
10975 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10976 {
10977 switch (get_attr_type (insn))
10978 {
10979 case TYPE_ALU:
10980 gcc_assert (operands[2] == const1_rtx);
10981 return "add{w}\t{%0, %0|%0, %0}";
10982
10983 default:
10984 if (REG_P (operands[2]))
10985 return "sal{w}\t{%b2, %0|%0, %b2}";
10986 else if (operands[2] == const1_rtx
10987 && (TARGET_SHIFT1 || optimize_size))
10988 return "sal{w}\t%0";
10989 else
10990 return "sal{w}\t{%2, %0|%0, %2}";
10991 }
10992 }
10993 [(set (attr "type")
10994 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10995 (const_int 0))
10996 (match_operand 0 "register_operand" ""))
10997 (match_operand 2 "const1_operand" ""))
10998 (const_string "alu")
10999 ]
11000 (const_string "ishift")))
11001 (set_attr "mode" "HI")])
11002
11003 (define_insn "*ashlhi3_cconly"
11004 [(set (reg FLAGS_REG)
11005 (compare
11006 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11007 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11008 (const_int 0)))
11009 (clobber (match_scratch:HI 0 "=r"))]
11010 "ix86_match_ccmode (insn, CCGOCmode)
11011 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11012 && (optimize_size
11013 || !TARGET_PARTIAL_FLAG_REG_STALL
11014 || (operands[2] == const1_rtx
11015 && (TARGET_SHIFT1
11016 || TARGET_DOUBLE_WITH_ADD)))"
11017 {
11018 switch (get_attr_type (insn))
11019 {
11020 case TYPE_ALU:
11021 gcc_assert (operands[2] == const1_rtx);
11022 return "add{w}\t{%0, %0|%0, %0}";
11023
11024 default:
11025 if (REG_P (operands[2]))
11026 return "sal{w}\t{%b2, %0|%0, %b2}";
11027 else if (operands[2] == const1_rtx
11028 && (TARGET_SHIFT1 || optimize_size))
11029 return "sal{w}\t%0";
11030 else
11031 return "sal{w}\t{%2, %0|%0, %2}";
11032 }
11033 }
11034 [(set (attr "type")
11035 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11036 (const_int 0))
11037 (match_operand 0 "register_operand" ""))
11038 (match_operand 2 "const1_operand" ""))
11039 (const_string "alu")
11040 ]
11041 (const_string "ishift")))
11042 (set_attr "mode" "HI")])
11043
11044 (define_expand "ashlqi3"
11045 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11046 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11047 (match_operand:QI 2 "nonmemory_operand" "")))
11048 (clobber (reg:CC FLAGS_REG))]
11049 "TARGET_QIMODE_MATH"
11050 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11051
11052 ;; %%% Potential partial reg stall on alternative 2. What to do?
11053
11054 (define_insn "*ashlqi3_1_lea"
11055 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11056 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11057 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11058 (clobber (reg:CC FLAGS_REG))]
11059 "!TARGET_PARTIAL_REG_STALL
11060 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11061 {
11062 switch (get_attr_type (insn))
11063 {
11064 case TYPE_LEA:
11065 return "#";
11066 case TYPE_ALU:
11067 gcc_assert (operands[2] == const1_rtx);
11068 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11069 return "add{l}\t{%k0, %k0|%k0, %k0}";
11070 else
11071 return "add{b}\t{%0, %0|%0, %0}";
11072
11073 default:
11074 if (REG_P (operands[2]))
11075 {
11076 if (get_attr_mode (insn) == MODE_SI)
11077 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11078 else
11079 return "sal{b}\t{%b2, %0|%0, %b2}";
11080 }
11081 else if (operands[2] == const1_rtx
11082 && (TARGET_SHIFT1 || optimize_size))
11083 {
11084 if (get_attr_mode (insn) == MODE_SI)
11085 return "sal{l}\t%0";
11086 else
11087 return "sal{b}\t%0";
11088 }
11089 else
11090 {
11091 if (get_attr_mode (insn) == MODE_SI)
11092 return "sal{l}\t{%2, %k0|%k0, %2}";
11093 else
11094 return "sal{b}\t{%2, %0|%0, %2}";
11095 }
11096 }
11097 }
11098 [(set (attr "type")
11099 (cond [(eq_attr "alternative" "2")
11100 (const_string "lea")
11101 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11102 (const_int 0))
11103 (match_operand 0 "register_operand" ""))
11104 (match_operand 2 "const1_operand" ""))
11105 (const_string "alu")
11106 ]
11107 (const_string "ishift")))
11108 (set_attr "mode" "QI,SI,SI")])
11109
11110 (define_insn "*ashlqi3_1"
11111 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11112 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11113 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11114 (clobber (reg:CC FLAGS_REG))]
11115 "TARGET_PARTIAL_REG_STALL
11116 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11117 {
11118 switch (get_attr_type (insn))
11119 {
11120 case TYPE_ALU:
11121 gcc_assert (operands[2] == const1_rtx);
11122 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11123 return "add{l}\t{%k0, %k0|%k0, %k0}";
11124 else
11125 return "add{b}\t{%0, %0|%0, %0}";
11126
11127 default:
11128 if (REG_P (operands[2]))
11129 {
11130 if (get_attr_mode (insn) == MODE_SI)
11131 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11132 else
11133 return "sal{b}\t{%b2, %0|%0, %b2}";
11134 }
11135 else if (operands[2] == const1_rtx
11136 && (TARGET_SHIFT1 || optimize_size))
11137 {
11138 if (get_attr_mode (insn) == MODE_SI)
11139 return "sal{l}\t%0";
11140 else
11141 return "sal{b}\t%0";
11142 }
11143 else
11144 {
11145 if (get_attr_mode (insn) == MODE_SI)
11146 return "sal{l}\t{%2, %k0|%k0, %2}";
11147 else
11148 return "sal{b}\t{%2, %0|%0, %2}";
11149 }
11150 }
11151 }
11152 [(set (attr "type")
11153 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11154 (const_int 0))
11155 (match_operand 0 "register_operand" ""))
11156 (match_operand 2 "const1_operand" ""))
11157 (const_string "alu")
11158 ]
11159 (const_string "ishift")))
11160 (set_attr "mode" "QI,SI")])
11161
11162 ;; This pattern can't accept a variable shift count, since shifts by
11163 ;; zero don't affect the flags. We assume that shifts by constant
11164 ;; zero are optimized away.
11165 (define_insn "*ashlqi3_cmp"
11166 [(set (reg FLAGS_REG)
11167 (compare
11168 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11169 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11170 (const_int 0)))
11171 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11172 (ashift:QI (match_dup 1) (match_dup 2)))]
11173 "ix86_match_ccmode (insn, CCGOCmode)
11174 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11175 && (optimize_size
11176 || !TARGET_PARTIAL_FLAG_REG_STALL
11177 || (operands[2] == const1_rtx
11178 && (TARGET_SHIFT1
11179 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11180 {
11181 switch (get_attr_type (insn))
11182 {
11183 case TYPE_ALU:
11184 gcc_assert (operands[2] == const1_rtx);
11185 return "add{b}\t{%0, %0|%0, %0}";
11186
11187 default:
11188 if (REG_P (operands[2]))
11189 return "sal{b}\t{%b2, %0|%0, %b2}";
11190 else if (operands[2] == const1_rtx
11191 && (TARGET_SHIFT1 || optimize_size))
11192 return "sal{b}\t%0";
11193 else
11194 return "sal{b}\t{%2, %0|%0, %2}";
11195 }
11196 }
11197 [(set (attr "type")
11198 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11199 (const_int 0))
11200 (match_operand 0 "register_operand" ""))
11201 (match_operand 2 "const1_operand" ""))
11202 (const_string "alu")
11203 ]
11204 (const_string "ishift")))
11205 (set_attr "mode" "QI")])
11206
11207 (define_insn "*ashlqi3_cconly"
11208 [(set (reg FLAGS_REG)
11209 (compare
11210 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11211 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11212 (const_int 0)))
11213 (clobber (match_scratch:QI 0 "=q"))]
11214 "ix86_match_ccmode (insn, CCGOCmode)
11215 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11216 && (optimize_size
11217 || !TARGET_PARTIAL_FLAG_REG_STALL
11218 || (operands[2] == const1_rtx
11219 && (TARGET_SHIFT1
11220 || TARGET_DOUBLE_WITH_ADD)))"
11221 {
11222 switch (get_attr_type (insn))
11223 {
11224 case TYPE_ALU:
11225 gcc_assert (operands[2] == const1_rtx);
11226 return "add{b}\t{%0, %0|%0, %0}";
11227
11228 default:
11229 if (REG_P (operands[2]))
11230 return "sal{b}\t{%b2, %0|%0, %b2}";
11231 else if (operands[2] == const1_rtx
11232 && (TARGET_SHIFT1 || optimize_size))
11233 return "sal{b}\t%0";
11234 else
11235 return "sal{b}\t{%2, %0|%0, %2}";
11236 }
11237 }
11238 [(set (attr "type")
11239 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11240 (const_int 0))
11241 (match_operand 0 "register_operand" ""))
11242 (match_operand 2 "const1_operand" ""))
11243 (const_string "alu")
11244 ]
11245 (const_string "ishift")))
11246 (set_attr "mode" "QI")])
11247
11248 ;; See comment above `ashldi3' about how this works.
11249
11250 (define_expand "ashrti3"
11251 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11252 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11253 (match_operand:QI 2 "nonmemory_operand" "")))
11254 (clobber (reg:CC FLAGS_REG))])]
11255 "TARGET_64BIT"
11256 {
11257 if (! immediate_operand (operands[2], QImode))
11258 {
11259 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11260 DONE;
11261 }
11262 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11263 DONE;
11264 })
11265
11266 (define_insn "ashrti3_1"
11267 [(set (match_operand:TI 0 "register_operand" "=r")
11268 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11269 (match_operand:QI 2 "register_operand" "c")))
11270 (clobber (match_scratch:DI 3 "=&r"))
11271 (clobber (reg:CC FLAGS_REG))]
11272 "TARGET_64BIT"
11273 "#"
11274 [(set_attr "type" "multi")])
11275
11276 (define_insn "*ashrti3_2"
11277 [(set (match_operand:TI 0 "register_operand" "=r")
11278 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11279 (match_operand:QI 2 "immediate_operand" "O")))
11280 (clobber (reg:CC FLAGS_REG))]
11281 "TARGET_64BIT"
11282 "#"
11283 [(set_attr "type" "multi")])
11284
11285 (define_split
11286 [(set (match_operand:TI 0 "register_operand" "")
11287 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11288 (match_operand:QI 2 "register_operand" "")))
11289 (clobber (match_scratch:DI 3 ""))
11290 (clobber (reg:CC FLAGS_REG))]
11291 "TARGET_64BIT && reload_completed"
11292 [(const_int 0)]
11293 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11294
11295 (define_split
11296 [(set (match_operand:TI 0 "register_operand" "")
11297 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11298 (match_operand:QI 2 "immediate_operand" "")))
11299 (clobber (reg:CC FLAGS_REG))]
11300 "TARGET_64BIT && reload_completed"
11301 [(const_int 0)]
11302 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11303
11304 (define_insn "x86_64_shrd"
11305 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11306 (ior:DI (ashiftrt:DI (match_dup 0)
11307 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11308 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11309 (minus:QI (const_int 64) (match_dup 2)))))
11310 (clobber (reg:CC FLAGS_REG))]
11311 "TARGET_64BIT"
11312 "@
11313 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11314 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11315 [(set_attr "type" "ishift")
11316 (set_attr "prefix_0f" "1")
11317 (set_attr "mode" "DI")
11318 (set_attr "athlon_decode" "vector")])
11319
11320 (define_expand "ashrdi3"
11321 [(set (match_operand:DI 0 "shiftdi_operand" "")
11322 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11323 (match_operand:QI 2 "nonmemory_operand" "")))]
11324 ""
11325 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11326
11327 (define_insn "*ashrdi3_63_rex64"
11328 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11329 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11330 (match_operand:DI 2 "const_int_operand" "i,i")))
11331 (clobber (reg:CC FLAGS_REG))]
11332 "TARGET_64BIT && INTVAL (operands[2]) == 63
11333 && (TARGET_USE_CLTD || optimize_size)
11334 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11335 "@
11336 {cqto|cqo}
11337 sar{q}\t{%2, %0|%0, %2}"
11338 [(set_attr "type" "imovx,ishift")
11339 (set_attr "prefix_0f" "0,*")
11340 (set_attr "length_immediate" "0,*")
11341 (set_attr "modrm" "0,1")
11342 (set_attr "mode" "DI")])
11343
11344 (define_insn "*ashrdi3_1_one_bit_rex64"
11345 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11346 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11347 (match_operand:QI 2 "const1_operand" "")))
11348 (clobber (reg:CC FLAGS_REG))]
11349 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11350 && (TARGET_SHIFT1 || optimize_size)"
11351 "sar{q}\t%0"
11352 [(set_attr "type" "ishift")
11353 (set (attr "length")
11354 (if_then_else (match_operand:DI 0 "register_operand" "")
11355 (const_string "2")
11356 (const_string "*")))])
11357
11358 (define_insn "*ashrdi3_1_rex64"
11359 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11360 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11361 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11362 (clobber (reg:CC FLAGS_REG))]
11363 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11364 "@
11365 sar{q}\t{%2, %0|%0, %2}
11366 sar{q}\t{%b2, %0|%0, %b2}"
11367 [(set_attr "type" "ishift")
11368 (set_attr "mode" "DI")])
11369
11370 ;; This pattern can't accept a variable shift count, since shifts by
11371 ;; zero don't affect the flags. We assume that shifts by constant
11372 ;; zero are optimized away.
11373 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11374 [(set (reg FLAGS_REG)
11375 (compare
11376 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11377 (match_operand:QI 2 "const1_operand" ""))
11378 (const_int 0)))
11379 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11380 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11381 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11382 && (TARGET_SHIFT1 || optimize_size)
11383 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11384 "sar{q}\t%0"
11385 [(set_attr "type" "ishift")
11386 (set (attr "length")
11387 (if_then_else (match_operand:DI 0 "register_operand" "")
11388 (const_string "2")
11389 (const_string "*")))])
11390
11391 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11392 [(set (reg FLAGS_REG)
11393 (compare
11394 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11395 (match_operand:QI 2 "const1_operand" ""))
11396 (const_int 0)))
11397 (clobber (match_scratch:DI 0 "=r"))]
11398 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11399 && (TARGET_SHIFT1 || optimize_size)
11400 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11401 "sar{q}\t%0"
11402 [(set_attr "type" "ishift")
11403 (set_attr "length" "2")])
11404
11405 ;; This pattern can't accept a variable shift count, since shifts by
11406 ;; zero don't affect the flags. We assume that shifts by constant
11407 ;; zero are optimized away.
11408 (define_insn "*ashrdi3_cmp_rex64"
11409 [(set (reg FLAGS_REG)
11410 (compare
11411 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412 (match_operand:QI 2 "const_int_operand" "n"))
11413 (const_int 0)))
11414 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11415 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11416 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11417 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11418 && (optimize_size
11419 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11420 "sar{q}\t{%2, %0|%0, %2}"
11421 [(set_attr "type" "ishift")
11422 (set_attr "mode" "DI")])
11423
11424 (define_insn "*ashrdi3_cconly_rex64"
11425 [(set (reg FLAGS_REG)
11426 (compare
11427 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11428 (match_operand:QI 2 "const_int_operand" "n"))
11429 (const_int 0)))
11430 (clobber (match_scratch:DI 0 "=r"))]
11431 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11432 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11433 && (optimize_size
11434 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11435 "sar{q}\t{%2, %0|%0, %2}"
11436 [(set_attr "type" "ishift")
11437 (set_attr "mode" "DI")])
11438
11439 (define_insn "*ashrdi3_1"
11440 [(set (match_operand:DI 0 "register_operand" "=r")
11441 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11442 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11443 (clobber (reg:CC FLAGS_REG))]
11444 "!TARGET_64BIT"
11445 "#"
11446 [(set_attr "type" "multi")])
11447
11448 ;; By default we don't ask for a scratch register, because when DImode
11449 ;; values are manipulated, registers are already at a premium. But if
11450 ;; we have one handy, we won't turn it away.
11451 (define_peephole2
11452 [(match_scratch:SI 3 "r")
11453 (parallel [(set (match_operand:DI 0 "register_operand" "")
11454 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11455 (match_operand:QI 2 "nonmemory_operand" "")))
11456 (clobber (reg:CC FLAGS_REG))])
11457 (match_dup 3)]
11458 "!TARGET_64BIT && TARGET_CMOVE"
11459 [(const_int 0)]
11460 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11461
11462 (define_split
11463 [(set (match_operand:DI 0 "register_operand" "")
11464 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11465 (match_operand:QI 2 "nonmemory_operand" "")))
11466 (clobber (reg:CC FLAGS_REG))]
11467 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11468 ? flow2_completed : reload_completed)"
11469 [(const_int 0)]
11470 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11471
11472 (define_insn "x86_shrd_1"
11473 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11474 (ior:SI (ashiftrt:SI (match_dup 0)
11475 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11476 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11477 (minus:QI (const_int 32) (match_dup 2)))))
11478 (clobber (reg:CC FLAGS_REG))]
11479 ""
11480 "@
11481 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11482 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11483 [(set_attr "type" "ishift")
11484 (set_attr "prefix_0f" "1")
11485 (set_attr "pent_pair" "np")
11486 (set_attr "mode" "SI")])
11487
11488 (define_expand "x86_shift_adj_3"
11489 [(use (match_operand:SI 0 "register_operand" ""))
11490 (use (match_operand:SI 1 "register_operand" ""))
11491 (use (match_operand:QI 2 "register_operand" ""))]
11492 ""
11493 {
11494 rtx label = gen_label_rtx ();
11495 rtx tmp;
11496
11497 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11498
11499 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11500 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11501 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11502 gen_rtx_LABEL_REF (VOIDmode, label),
11503 pc_rtx);
11504 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11505 JUMP_LABEL (tmp) = label;
11506
11507 emit_move_insn (operands[0], operands[1]);
11508 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11509
11510 emit_label (label);
11511 LABEL_NUSES (label) = 1;
11512
11513 DONE;
11514 })
11515
11516 (define_insn "ashrsi3_31"
11517 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11518 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11519 (match_operand:SI 2 "const_int_operand" "i,i")))
11520 (clobber (reg:CC FLAGS_REG))]
11521 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11522 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11523 "@
11524 {cltd|cdq}
11525 sar{l}\t{%2, %0|%0, %2}"
11526 [(set_attr "type" "imovx,ishift")
11527 (set_attr "prefix_0f" "0,*")
11528 (set_attr "length_immediate" "0,*")
11529 (set_attr "modrm" "0,1")
11530 (set_attr "mode" "SI")])
11531
11532 (define_insn "*ashrsi3_31_zext"
11533 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11534 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11535 (match_operand:SI 2 "const_int_operand" "i,i"))))
11536 (clobber (reg:CC FLAGS_REG))]
11537 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11538 && INTVAL (operands[2]) == 31
11539 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11540 "@
11541 {cltd|cdq}
11542 sar{l}\t{%2, %k0|%k0, %2}"
11543 [(set_attr "type" "imovx,ishift")
11544 (set_attr "prefix_0f" "0,*")
11545 (set_attr "length_immediate" "0,*")
11546 (set_attr "modrm" "0,1")
11547 (set_attr "mode" "SI")])
11548
11549 (define_expand "ashrsi3"
11550 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11551 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11552 (match_operand:QI 2 "nonmemory_operand" "")))
11553 (clobber (reg:CC FLAGS_REG))]
11554 ""
11555 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11556
11557 (define_insn "*ashrsi3_1_one_bit"
11558 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11559 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11560 (match_operand:QI 2 "const1_operand" "")))
11561 (clobber (reg:CC FLAGS_REG))]
11562 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11563 && (TARGET_SHIFT1 || optimize_size)"
11564 "sar{l}\t%0"
11565 [(set_attr "type" "ishift")
11566 (set (attr "length")
11567 (if_then_else (match_operand:SI 0 "register_operand" "")
11568 (const_string "2")
11569 (const_string "*")))])
11570
11571 (define_insn "*ashrsi3_1_one_bit_zext"
11572 [(set (match_operand:DI 0 "register_operand" "=r")
11573 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11574 (match_operand:QI 2 "const1_operand" ""))))
11575 (clobber (reg:CC FLAGS_REG))]
11576 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11577 && (TARGET_SHIFT1 || optimize_size)"
11578 "sar{l}\t%k0"
11579 [(set_attr "type" "ishift")
11580 (set_attr "length" "2")])
11581
11582 (define_insn "*ashrsi3_1"
11583 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11584 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11585 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11586 (clobber (reg:CC FLAGS_REG))]
11587 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11588 "@
11589 sar{l}\t{%2, %0|%0, %2}
11590 sar{l}\t{%b2, %0|%0, %b2}"
11591 [(set_attr "type" "ishift")
11592 (set_attr "mode" "SI")])
11593
11594 (define_insn "*ashrsi3_1_zext"
11595 [(set (match_operand:DI 0 "register_operand" "=r,r")
11596 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11597 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11598 (clobber (reg:CC FLAGS_REG))]
11599 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11600 "@
11601 sar{l}\t{%2, %k0|%k0, %2}
11602 sar{l}\t{%b2, %k0|%k0, %b2}"
11603 [(set_attr "type" "ishift")
11604 (set_attr "mode" "SI")])
11605
11606 ;; This pattern can't accept a variable shift count, since shifts by
11607 ;; zero don't affect the flags. We assume that shifts by constant
11608 ;; zero are optimized away.
11609 (define_insn "*ashrsi3_one_bit_cmp"
11610 [(set (reg FLAGS_REG)
11611 (compare
11612 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11613 (match_operand:QI 2 "const1_operand" ""))
11614 (const_int 0)))
11615 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11616 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11617 "ix86_match_ccmode (insn, CCGOCmode)
11618 && (TARGET_SHIFT1 || optimize_size)
11619 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11620 "sar{l}\t%0"
11621 [(set_attr "type" "ishift")
11622 (set (attr "length")
11623 (if_then_else (match_operand:SI 0 "register_operand" "")
11624 (const_string "2")
11625 (const_string "*")))])
11626
11627 (define_insn "*ashrsi3_one_bit_cconly"
11628 [(set (reg FLAGS_REG)
11629 (compare
11630 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11631 (match_operand:QI 2 "const1_operand" ""))
11632 (const_int 0)))
11633 (clobber (match_scratch:SI 0 "=r"))]
11634 "ix86_match_ccmode (insn, CCGOCmode)
11635 && (TARGET_SHIFT1 || optimize_size)
11636 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11637 "sar{l}\t%0"
11638 [(set_attr "type" "ishift")
11639 (set_attr "length" "2")])
11640
11641 (define_insn "*ashrsi3_one_bit_cmp_zext"
11642 [(set (reg FLAGS_REG)
11643 (compare
11644 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11645 (match_operand:QI 2 "const1_operand" ""))
11646 (const_int 0)))
11647 (set (match_operand:DI 0 "register_operand" "=r")
11648 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11649 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11650 && (TARGET_SHIFT1 || optimize_size)
11651 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11652 "sar{l}\t%k0"
11653 [(set_attr "type" "ishift")
11654 (set_attr "length" "2")])
11655
11656 ;; This pattern can't accept a variable shift count, since shifts by
11657 ;; zero don't affect the flags. We assume that shifts by constant
11658 ;; zero are optimized away.
11659 (define_insn "*ashrsi3_cmp"
11660 [(set (reg FLAGS_REG)
11661 (compare
11662 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11663 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11664 (const_int 0)))
11665 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11666 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11667 "ix86_match_ccmode (insn, CCGOCmode)
11668 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11669 && (optimize_size
11670 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11671 "sar{l}\t{%2, %0|%0, %2}"
11672 [(set_attr "type" "ishift")
11673 (set_attr "mode" "SI")])
11674
11675 (define_insn "*ashrsi3_cconly"
11676 [(set (reg FLAGS_REG)
11677 (compare
11678 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11679 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11680 (const_int 0)))
11681 (clobber (match_scratch:SI 0 "=r"))]
11682 "ix86_match_ccmode (insn, CCGOCmode)
11683 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11684 && (optimize_size
11685 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11686 "sar{l}\t{%2, %0|%0, %2}"
11687 [(set_attr "type" "ishift")
11688 (set_attr "mode" "SI")])
11689
11690 (define_insn "*ashrsi3_cmp_zext"
11691 [(set (reg FLAGS_REG)
11692 (compare
11693 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11694 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11695 (const_int 0)))
11696 (set (match_operand:DI 0 "register_operand" "=r")
11697 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11698 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11699 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11700 && (optimize_size
11701 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11702 "sar{l}\t{%2, %k0|%k0, %2}"
11703 [(set_attr "type" "ishift")
11704 (set_attr "mode" "SI")])
11705
11706 (define_expand "ashrhi3"
11707 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11708 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11709 (match_operand:QI 2 "nonmemory_operand" "")))
11710 (clobber (reg:CC FLAGS_REG))]
11711 "TARGET_HIMODE_MATH"
11712 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11713
11714 (define_insn "*ashrhi3_1_one_bit"
11715 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11716 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717 (match_operand:QI 2 "const1_operand" "")))
11718 (clobber (reg:CC FLAGS_REG))]
11719 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11720 && (TARGET_SHIFT1 || optimize_size)"
11721 "sar{w}\t%0"
11722 [(set_attr "type" "ishift")
11723 (set (attr "length")
11724 (if_then_else (match_operand 0 "register_operand" "")
11725 (const_string "2")
11726 (const_string "*")))])
11727
11728 (define_insn "*ashrhi3_1"
11729 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11730 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11731 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11732 (clobber (reg:CC FLAGS_REG))]
11733 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11734 "@
11735 sar{w}\t{%2, %0|%0, %2}
11736 sar{w}\t{%b2, %0|%0, %b2}"
11737 [(set_attr "type" "ishift")
11738 (set_attr "mode" "HI")])
11739
11740 ;; This pattern can't accept a variable shift count, since shifts by
11741 ;; zero don't affect the flags. We assume that shifts by constant
11742 ;; zero are optimized away.
11743 (define_insn "*ashrhi3_one_bit_cmp"
11744 [(set (reg FLAGS_REG)
11745 (compare
11746 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11747 (match_operand:QI 2 "const1_operand" ""))
11748 (const_int 0)))
11749 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11750 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11751 "ix86_match_ccmode (insn, CCGOCmode)
11752 && (TARGET_SHIFT1 || optimize_size)
11753 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11754 "sar{w}\t%0"
11755 [(set_attr "type" "ishift")
11756 (set (attr "length")
11757 (if_then_else (match_operand 0 "register_operand" "")
11758 (const_string "2")
11759 (const_string "*")))])
11760
11761 (define_insn "*ashrhi3_one_bit_cconly"
11762 [(set (reg FLAGS_REG)
11763 (compare
11764 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11765 (match_operand:QI 2 "const1_operand" ""))
11766 (const_int 0)))
11767 (clobber (match_scratch:HI 0 "=r"))]
11768 "ix86_match_ccmode (insn, CCGOCmode)
11769 && (TARGET_SHIFT1 || optimize_size)
11770 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11771 "sar{w}\t%0"
11772 [(set_attr "type" "ishift")
11773 (set_attr "length" "2")])
11774
11775 ;; This pattern can't accept a variable shift count, since shifts by
11776 ;; zero don't affect the flags. We assume that shifts by constant
11777 ;; zero are optimized away.
11778 (define_insn "*ashrhi3_cmp"
11779 [(set (reg FLAGS_REG)
11780 (compare
11781 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11782 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11783 (const_int 0)))
11784 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11785 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11786 "ix86_match_ccmode (insn, CCGOCmode)
11787 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11788 && (optimize_size
11789 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11790 "sar{w}\t{%2, %0|%0, %2}"
11791 [(set_attr "type" "ishift")
11792 (set_attr "mode" "HI")])
11793
11794 (define_insn "*ashrhi3_cconly"
11795 [(set (reg FLAGS_REG)
11796 (compare
11797 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11798 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11799 (const_int 0)))
11800 (clobber (match_scratch:HI 0 "=r"))]
11801 "ix86_match_ccmode (insn, CCGOCmode)
11802 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11803 && (optimize_size
11804 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11805 "sar{w}\t{%2, %0|%0, %2}"
11806 [(set_attr "type" "ishift")
11807 (set_attr "mode" "HI")])
11808
11809 (define_expand "ashrqi3"
11810 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11811 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11812 (match_operand:QI 2 "nonmemory_operand" "")))
11813 (clobber (reg:CC FLAGS_REG))]
11814 "TARGET_QIMODE_MATH"
11815 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11816
11817 (define_insn "*ashrqi3_1_one_bit"
11818 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11819 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11820 (match_operand:QI 2 "const1_operand" "")))
11821 (clobber (reg:CC FLAGS_REG))]
11822 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11823 && (TARGET_SHIFT1 || optimize_size)"
11824 "sar{b}\t%0"
11825 [(set_attr "type" "ishift")
11826 (set (attr "length")
11827 (if_then_else (match_operand 0 "register_operand" "")
11828 (const_string "2")
11829 (const_string "*")))])
11830
11831 (define_insn "*ashrqi3_1_one_bit_slp"
11832 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11833 (ashiftrt:QI (match_dup 0)
11834 (match_operand:QI 1 "const1_operand" "")))
11835 (clobber (reg:CC FLAGS_REG))]
11836 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11837 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11838 && (TARGET_SHIFT1 || optimize_size)"
11839 "sar{b}\t%0"
11840 [(set_attr "type" "ishift1")
11841 (set (attr "length")
11842 (if_then_else (match_operand 0 "register_operand" "")
11843 (const_string "2")
11844 (const_string "*")))])
11845
11846 (define_insn "*ashrqi3_1"
11847 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11848 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11849 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11850 (clobber (reg:CC FLAGS_REG))]
11851 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11852 "@
11853 sar{b}\t{%2, %0|%0, %2}
11854 sar{b}\t{%b2, %0|%0, %b2}"
11855 [(set_attr "type" "ishift")
11856 (set_attr "mode" "QI")])
11857
11858 (define_insn "*ashrqi3_1_slp"
11859 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11860 (ashiftrt:QI (match_dup 0)
11861 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11862 (clobber (reg:CC FLAGS_REG))]
11863 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11864 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11865 "@
11866 sar{b}\t{%1, %0|%0, %1}
11867 sar{b}\t{%b1, %0|%0, %b1}"
11868 [(set_attr "type" "ishift1")
11869 (set_attr "mode" "QI")])
11870
11871 ;; This pattern can't accept a variable shift count, since shifts by
11872 ;; zero don't affect the flags. We assume that shifts by constant
11873 ;; zero are optimized away.
11874 (define_insn "*ashrqi3_one_bit_cmp"
11875 [(set (reg FLAGS_REG)
11876 (compare
11877 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11878 (match_operand:QI 2 "const1_operand" "I"))
11879 (const_int 0)))
11880 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11881 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11882 "ix86_match_ccmode (insn, CCGOCmode)
11883 && (TARGET_SHIFT1 || optimize_size)
11884 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11885 "sar{b}\t%0"
11886 [(set_attr "type" "ishift")
11887 (set (attr "length")
11888 (if_then_else (match_operand 0 "register_operand" "")
11889 (const_string "2")
11890 (const_string "*")))])
11891
11892 (define_insn "*ashrqi3_one_bit_cconly"
11893 [(set (reg FLAGS_REG)
11894 (compare
11895 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11896 (match_operand:QI 2 "const1_operand" "I"))
11897 (const_int 0)))
11898 (clobber (match_scratch:QI 0 "=q"))]
11899 "ix86_match_ccmode (insn, CCGOCmode)
11900 && (TARGET_SHIFT1 || optimize_size)
11901 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11902 "sar{b}\t%0"
11903 [(set_attr "type" "ishift")
11904 (set_attr "length" "2")])
11905
11906 ;; This pattern can't accept a variable shift count, since shifts by
11907 ;; zero don't affect the flags. We assume that shifts by constant
11908 ;; zero are optimized away.
11909 (define_insn "*ashrqi3_cmp"
11910 [(set (reg FLAGS_REG)
11911 (compare
11912 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11913 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11914 (const_int 0)))
11915 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11916 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11917 "ix86_match_ccmode (insn, CCGOCmode)
11918 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11919 && (optimize_size
11920 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11921 "sar{b}\t{%2, %0|%0, %2}"
11922 [(set_attr "type" "ishift")
11923 (set_attr "mode" "QI")])
11924
11925 (define_insn "*ashrqi3_cconly"
11926 [(set (reg FLAGS_REG)
11927 (compare
11928 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11929 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11930 (const_int 0)))
11931 (clobber (match_scratch:QI 0 "=q"))]
11932 "ix86_match_ccmode (insn, CCGOCmode)
11933 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11934 && (optimize_size
11935 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11936 "sar{b}\t{%2, %0|%0, %2}"
11937 [(set_attr "type" "ishift")
11938 (set_attr "mode" "QI")])
11939
11940 \f
11941 ;; Logical shift instructions
11942
11943 ;; See comment above `ashldi3' about how this works.
11944
11945 (define_expand "lshrti3"
11946 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11947 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11948 (match_operand:QI 2 "nonmemory_operand" "")))
11949 (clobber (reg:CC FLAGS_REG))])]
11950 "TARGET_64BIT"
11951 {
11952 if (! immediate_operand (operands[2], QImode))
11953 {
11954 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11955 DONE;
11956 }
11957 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11958 DONE;
11959 })
11960
11961 (define_insn "lshrti3_1"
11962 [(set (match_operand:TI 0 "register_operand" "=r")
11963 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11964 (match_operand:QI 2 "register_operand" "c")))
11965 (clobber (match_scratch:DI 3 "=&r"))
11966 (clobber (reg:CC FLAGS_REG))]
11967 "TARGET_64BIT"
11968 "#"
11969 [(set_attr "type" "multi")])
11970
11971 (define_insn "*lshrti3_2"
11972 [(set (match_operand:TI 0 "register_operand" "=r")
11973 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11974 (match_operand:QI 2 "immediate_operand" "O")))
11975 (clobber (reg:CC FLAGS_REG))]
11976 "TARGET_64BIT"
11977 "#"
11978 [(set_attr "type" "multi")])
11979
11980 (define_split
11981 [(set (match_operand:TI 0 "register_operand" "")
11982 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11983 (match_operand:QI 2 "register_operand" "")))
11984 (clobber (match_scratch:DI 3 ""))
11985 (clobber (reg:CC FLAGS_REG))]
11986 "TARGET_64BIT && reload_completed"
11987 [(const_int 0)]
11988 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11989
11990 (define_split
11991 [(set (match_operand:TI 0 "register_operand" "")
11992 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11993 (match_operand:QI 2 "immediate_operand" "")))
11994 (clobber (reg:CC FLAGS_REG))]
11995 "TARGET_64BIT && reload_completed"
11996 [(const_int 0)]
11997 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11998
11999 (define_expand "lshrdi3"
12000 [(set (match_operand:DI 0 "shiftdi_operand" "")
12001 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12002 (match_operand:QI 2 "nonmemory_operand" "")))]
12003 ""
12004 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12005
12006 (define_insn "*lshrdi3_1_one_bit_rex64"
12007 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12008 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12009 (match_operand:QI 2 "const1_operand" "")))
12010 (clobber (reg:CC FLAGS_REG))]
12011 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12012 && (TARGET_SHIFT1 || optimize_size)"
12013 "shr{q}\t%0"
12014 [(set_attr "type" "ishift")
12015 (set (attr "length")
12016 (if_then_else (match_operand:DI 0 "register_operand" "")
12017 (const_string "2")
12018 (const_string "*")))])
12019
12020 (define_insn "*lshrdi3_1_rex64"
12021 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12022 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12023 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12024 (clobber (reg:CC FLAGS_REG))]
12025 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12026 "@
12027 shr{q}\t{%2, %0|%0, %2}
12028 shr{q}\t{%b2, %0|%0, %b2}"
12029 [(set_attr "type" "ishift")
12030 (set_attr "mode" "DI")])
12031
12032 ;; This pattern can't accept a variable shift count, since shifts by
12033 ;; zero don't affect the flags. We assume that shifts by constant
12034 ;; zero are optimized away.
12035 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12036 [(set (reg FLAGS_REG)
12037 (compare
12038 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12039 (match_operand:QI 2 "const1_operand" ""))
12040 (const_int 0)))
12041 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12042 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12043 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12044 && (TARGET_SHIFT1 || optimize_size)
12045 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12046 "shr{q}\t%0"
12047 [(set_attr "type" "ishift")
12048 (set (attr "length")
12049 (if_then_else (match_operand:DI 0 "register_operand" "")
12050 (const_string "2")
12051 (const_string "*")))])
12052
12053 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12054 [(set (reg FLAGS_REG)
12055 (compare
12056 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12057 (match_operand:QI 2 "const1_operand" ""))
12058 (const_int 0)))
12059 (clobber (match_scratch:DI 0 "=r"))]
12060 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12061 && (TARGET_SHIFT1 || optimize_size)
12062 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12063 "shr{q}\t%0"
12064 [(set_attr "type" "ishift")
12065 (set_attr "length" "2")])
12066
12067 ;; This pattern can't accept a variable shift count, since shifts by
12068 ;; zero don't affect the flags. We assume that shifts by constant
12069 ;; zero are optimized away.
12070 (define_insn "*lshrdi3_cmp_rex64"
12071 [(set (reg FLAGS_REG)
12072 (compare
12073 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074 (match_operand:QI 2 "const_int_operand" "e"))
12075 (const_int 0)))
12076 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12077 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12078 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12079 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12080 && (optimize_size
12081 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12082 "shr{q}\t{%2, %0|%0, %2}"
12083 [(set_attr "type" "ishift")
12084 (set_attr "mode" "DI")])
12085
12086 (define_insn "*lshrdi3_cconly_rex64"
12087 [(set (reg FLAGS_REG)
12088 (compare
12089 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12090 (match_operand:QI 2 "const_int_operand" "e"))
12091 (const_int 0)))
12092 (clobber (match_scratch:DI 0 "=r"))]
12093 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12094 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12095 && (optimize_size
12096 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12097 "shr{q}\t{%2, %0|%0, %2}"
12098 [(set_attr "type" "ishift")
12099 (set_attr "mode" "DI")])
12100
12101 (define_insn "*lshrdi3_1"
12102 [(set (match_operand:DI 0 "register_operand" "=r")
12103 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12104 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12105 (clobber (reg:CC FLAGS_REG))]
12106 "!TARGET_64BIT"
12107 "#"
12108 [(set_attr "type" "multi")])
12109
12110 ;; By default we don't ask for a scratch register, because when DImode
12111 ;; values are manipulated, registers are already at a premium. But if
12112 ;; we have one handy, we won't turn it away.
12113 (define_peephole2
12114 [(match_scratch:SI 3 "r")
12115 (parallel [(set (match_operand:DI 0 "register_operand" "")
12116 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12117 (match_operand:QI 2 "nonmemory_operand" "")))
12118 (clobber (reg:CC FLAGS_REG))])
12119 (match_dup 3)]
12120 "!TARGET_64BIT && TARGET_CMOVE"
12121 [(const_int 0)]
12122 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12123
12124 (define_split
12125 [(set (match_operand:DI 0 "register_operand" "")
12126 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12127 (match_operand:QI 2 "nonmemory_operand" "")))
12128 (clobber (reg:CC FLAGS_REG))]
12129 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12130 ? flow2_completed : reload_completed)"
12131 [(const_int 0)]
12132 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12133
12134 (define_expand "lshrsi3"
12135 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12136 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12137 (match_operand:QI 2 "nonmemory_operand" "")))
12138 (clobber (reg:CC FLAGS_REG))]
12139 ""
12140 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12141
12142 (define_insn "*lshrsi3_1_one_bit"
12143 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12144 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12145 (match_operand:QI 2 "const1_operand" "")))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12148 && (TARGET_SHIFT1 || optimize_size)"
12149 "shr{l}\t%0"
12150 [(set_attr "type" "ishift")
12151 (set (attr "length")
12152 (if_then_else (match_operand:SI 0 "register_operand" "")
12153 (const_string "2")
12154 (const_string "*")))])
12155
12156 (define_insn "*lshrsi3_1_one_bit_zext"
12157 [(set (match_operand:DI 0 "register_operand" "=r")
12158 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12159 (match_operand:QI 2 "const1_operand" "")))
12160 (clobber (reg:CC FLAGS_REG))]
12161 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12162 && (TARGET_SHIFT1 || optimize_size)"
12163 "shr{l}\t%k0"
12164 [(set_attr "type" "ishift")
12165 (set_attr "length" "2")])
12166
12167 (define_insn "*lshrsi3_1"
12168 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12169 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12170 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12171 (clobber (reg:CC FLAGS_REG))]
12172 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12173 "@
12174 shr{l}\t{%2, %0|%0, %2}
12175 shr{l}\t{%b2, %0|%0, %b2}"
12176 [(set_attr "type" "ishift")
12177 (set_attr "mode" "SI")])
12178
12179 (define_insn "*lshrsi3_1_zext"
12180 [(set (match_operand:DI 0 "register_operand" "=r,r")
12181 (zero_extend:DI
12182 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12183 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12184 (clobber (reg:CC FLAGS_REG))]
12185 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12186 "@
12187 shr{l}\t{%2, %k0|%k0, %2}
12188 shr{l}\t{%b2, %k0|%k0, %b2}"
12189 [(set_attr "type" "ishift")
12190 (set_attr "mode" "SI")])
12191
12192 ;; This pattern can't accept a variable shift count, since shifts by
12193 ;; zero don't affect the flags. We assume that shifts by constant
12194 ;; zero are optimized away.
12195 (define_insn "*lshrsi3_one_bit_cmp"
12196 [(set (reg FLAGS_REG)
12197 (compare
12198 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12199 (match_operand:QI 2 "const1_operand" ""))
12200 (const_int 0)))
12201 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12202 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12203 "ix86_match_ccmode (insn, CCGOCmode)
12204 && (TARGET_SHIFT1 || optimize_size)
12205 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12206 "shr{l}\t%0"
12207 [(set_attr "type" "ishift")
12208 (set (attr "length")
12209 (if_then_else (match_operand:SI 0 "register_operand" "")
12210 (const_string "2")
12211 (const_string "*")))])
12212
12213 (define_insn "*lshrsi3_one_bit_cconly"
12214 [(set (reg FLAGS_REG)
12215 (compare
12216 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12217 (match_operand:QI 2 "const1_operand" ""))
12218 (const_int 0)))
12219 (clobber (match_scratch:SI 0 "=r"))]
12220 "ix86_match_ccmode (insn, CCGOCmode)
12221 && (TARGET_SHIFT1 || optimize_size)
12222 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12223 "shr{l}\t%0"
12224 [(set_attr "type" "ishift")
12225 (set_attr "length" "2")])
12226
12227 (define_insn "*lshrsi3_cmp_one_bit_zext"
12228 [(set (reg FLAGS_REG)
12229 (compare
12230 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12231 (match_operand:QI 2 "const1_operand" ""))
12232 (const_int 0)))
12233 (set (match_operand:DI 0 "register_operand" "=r")
12234 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12235 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12236 && (TARGET_SHIFT1 || optimize_size)
12237 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12238 "shr{l}\t%k0"
12239 [(set_attr "type" "ishift")
12240 (set_attr "length" "2")])
12241
12242 ;; This pattern can't accept a variable shift count, since shifts by
12243 ;; zero don't affect the flags. We assume that shifts by constant
12244 ;; zero are optimized away.
12245 (define_insn "*lshrsi3_cmp"
12246 [(set (reg FLAGS_REG)
12247 (compare
12248 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12249 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12250 (const_int 0)))
12251 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12252 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12253 "ix86_match_ccmode (insn, CCGOCmode)
12254 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12255 && (optimize_size
12256 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12257 "shr{l}\t{%2, %0|%0, %2}"
12258 [(set_attr "type" "ishift")
12259 (set_attr "mode" "SI")])
12260
12261 (define_insn "*lshrsi3_cconly"
12262 [(set (reg FLAGS_REG)
12263 (compare
12264 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12265 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12266 (const_int 0)))
12267 (clobber (match_scratch:SI 0 "=r"))]
12268 "ix86_match_ccmode (insn, CCGOCmode)
12269 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12270 && (optimize_size
12271 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12272 "shr{l}\t{%2, %0|%0, %2}"
12273 [(set_attr "type" "ishift")
12274 (set_attr "mode" "SI")])
12275
12276 (define_insn "*lshrsi3_cmp_zext"
12277 [(set (reg FLAGS_REG)
12278 (compare
12279 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12280 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12281 (const_int 0)))
12282 (set (match_operand:DI 0 "register_operand" "=r")
12283 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12284 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12285 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12286 && (optimize_size
12287 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12288 "shr{l}\t{%2, %k0|%k0, %2}"
12289 [(set_attr "type" "ishift")
12290 (set_attr "mode" "SI")])
12291
12292 (define_expand "lshrhi3"
12293 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12294 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12295 (match_operand:QI 2 "nonmemory_operand" "")))
12296 (clobber (reg:CC FLAGS_REG))]
12297 "TARGET_HIMODE_MATH"
12298 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12299
12300 (define_insn "*lshrhi3_1_one_bit"
12301 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12302 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12303 (match_operand:QI 2 "const1_operand" "")))
12304 (clobber (reg:CC FLAGS_REG))]
12305 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12306 && (TARGET_SHIFT1 || optimize_size)"
12307 "shr{w}\t%0"
12308 [(set_attr "type" "ishift")
12309 (set (attr "length")
12310 (if_then_else (match_operand 0 "register_operand" "")
12311 (const_string "2")
12312 (const_string "*")))])
12313
12314 (define_insn "*lshrhi3_1"
12315 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12316 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12317 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12318 (clobber (reg:CC FLAGS_REG))]
12319 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12320 "@
12321 shr{w}\t{%2, %0|%0, %2}
12322 shr{w}\t{%b2, %0|%0, %b2}"
12323 [(set_attr "type" "ishift")
12324 (set_attr "mode" "HI")])
12325
12326 ;; This pattern can't accept a variable shift count, since shifts by
12327 ;; zero don't affect the flags. We assume that shifts by constant
12328 ;; zero are optimized away.
12329 (define_insn "*lshrhi3_one_bit_cmp"
12330 [(set (reg FLAGS_REG)
12331 (compare
12332 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12333 (match_operand:QI 2 "const1_operand" ""))
12334 (const_int 0)))
12335 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12336 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12337 "ix86_match_ccmode (insn, CCGOCmode)
12338 && (TARGET_SHIFT1 || optimize_size)
12339 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12340 "shr{w}\t%0"
12341 [(set_attr "type" "ishift")
12342 (set (attr "length")
12343 (if_then_else (match_operand:SI 0 "register_operand" "")
12344 (const_string "2")
12345 (const_string "*")))])
12346
12347 (define_insn "*lshrhi3_one_bit_cconly"
12348 [(set (reg FLAGS_REG)
12349 (compare
12350 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12351 (match_operand:QI 2 "const1_operand" ""))
12352 (const_int 0)))
12353 (clobber (match_scratch:HI 0 "=r"))]
12354 "ix86_match_ccmode (insn, CCGOCmode)
12355 && (TARGET_SHIFT1 || optimize_size)
12356 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12357 "shr{w}\t%0"
12358 [(set_attr "type" "ishift")
12359 (set_attr "length" "2")])
12360
12361 ;; This pattern can't accept a variable shift count, since shifts by
12362 ;; zero don't affect the flags. We assume that shifts by constant
12363 ;; zero are optimized away.
12364 (define_insn "*lshrhi3_cmp"
12365 [(set (reg FLAGS_REG)
12366 (compare
12367 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12369 (const_int 0)))
12370 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12371 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12372 "ix86_match_ccmode (insn, CCGOCmode)
12373 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12374 && (optimize_size
12375 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12376 "shr{w}\t{%2, %0|%0, %2}"
12377 [(set_attr "type" "ishift")
12378 (set_attr "mode" "HI")])
12379
12380 (define_insn "*lshrhi3_cconly"
12381 [(set (reg FLAGS_REG)
12382 (compare
12383 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12384 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12385 (const_int 0)))
12386 (clobber (match_scratch:HI 0 "=r"))]
12387 "ix86_match_ccmode (insn, CCGOCmode)
12388 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12389 && (optimize_size
12390 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12391 "shr{w}\t{%2, %0|%0, %2}"
12392 [(set_attr "type" "ishift")
12393 (set_attr "mode" "HI")])
12394
12395 (define_expand "lshrqi3"
12396 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12397 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12398 (match_operand:QI 2 "nonmemory_operand" "")))
12399 (clobber (reg:CC FLAGS_REG))]
12400 "TARGET_QIMODE_MATH"
12401 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12402
12403 (define_insn "*lshrqi3_1_one_bit"
12404 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12405 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12406 (match_operand:QI 2 "const1_operand" "")))
12407 (clobber (reg:CC FLAGS_REG))]
12408 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12409 && (TARGET_SHIFT1 || optimize_size)"
12410 "shr{b}\t%0"
12411 [(set_attr "type" "ishift")
12412 (set (attr "length")
12413 (if_then_else (match_operand 0 "register_operand" "")
12414 (const_string "2")
12415 (const_string "*")))])
12416
12417 (define_insn "*lshrqi3_1_one_bit_slp"
12418 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12419 (lshiftrt:QI (match_dup 0)
12420 (match_operand:QI 1 "const1_operand" "")))
12421 (clobber (reg:CC FLAGS_REG))]
12422 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12423 && (TARGET_SHIFT1 || optimize_size)"
12424 "shr{b}\t%0"
12425 [(set_attr "type" "ishift1")
12426 (set (attr "length")
12427 (if_then_else (match_operand 0 "register_operand" "")
12428 (const_string "2")
12429 (const_string "*")))])
12430
12431 (define_insn "*lshrqi3_1"
12432 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12433 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12434 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12435 (clobber (reg:CC FLAGS_REG))]
12436 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12437 "@
12438 shr{b}\t{%2, %0|%0, %2}
12439 shr{b}\t{%b2, %0|%0, %b2}"
12440 [(set_attr "type" "ishift")
12441 (set_attr "mode" "QI")])
12442
12443 (define_insn "*lshrqi3_1_slp"
12444 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12445 (lshiftrt:QI (match_dup 0)
12446 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12447 (clobber (reg:CC FLAGS_REG))]
12448 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12449 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12450 "@
12451 shr{b}\t{%1, %0|%0, %1}
12452 shr{b}\t{%b1, %0|%0, %b1}"
12453 [(set_attr "type" "ishift1")
12454 (set_attr "mode" "QI")])
12455
12456 ;; This pattern can't accept a variable shift count, since shifts by
12457 ;; zero don't affect the flags. We assume that shifts by constant
12458 ;; zero are optimized away.
12459 (define_insn "*lshrqi2_one_bit_cmp"
12460 [(set (reg FLAGS_REG)
12461 (compare
12462 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12463 (match_operand:QI 2 "const1_operand" ""))
12464 (const_int 0)))
12465 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12466 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12467 "ix86_match_ccmode (insn, CCGOCmode)
12468 && (TARGET_SHIFT1 || optimize_size)
12469 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12470 "shr{b}\t%0"
12471 [(set_attr "type" "ishift")
12472 (set (attr "length")
12473 (if_then_else (match_operand:SI 0 "register_operand" "")
12474 (const_string "2")
12475 (const_string "*")))])
12476
12477 (define_insn "*lshrqi2_one_bit_cconly"
12478 [(set (reg FLAGS_REG)
12479 (compare
12480 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12481 (match_operand:QI 2 "const1_operand" ""))
12482 (const_int 0)))
12483 (clobber (match_scratch:QI 0 "=q"))]
12484 "ix86_match_ccmode (insn, CCGOCmode)
12485 && (TARGET_SHIFT1 || optimize_size)
12486 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12487 "shr{b}\t%0"
12488 [(set_attr "type" "ishift")
12489 (set_attr "length" "2")])
12490
12491 ;; This pattern can't accept a variable shift count, since shifts by
12492 ;; zero don't affect the flags. We assume that shifts by constant
12493 ;; zero are optimized away.
12494 (define_insn "*lshrqi2_cmp"
12495 [(set (reg FLAGS_REG)
12496 (compare
12497 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12498 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12499 (const_int 0)))
12500 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12501 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12502 "ix86_match_ccmode (insn, CCGOCmode)
12503 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12504 && (optimize_size
12505 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12506 "shr{b}\t{%2, %0|%0, %2}"
12507 [(set_attr "type" "ishift")
12508 (set_attr "mode" "QI")])
12509
12510 (define_insn "*lshrqi2_cconly"
12511 [(set (reg FLAGS_REG)
12512 (compare
12513 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12514 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12515 (const_int 0)))
12516 (clobber (match_scratch:QI 0 "=q"))]
12517 "ix86_match_ccmode (insn, CCGOCmode)
12518 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12519 && (optimize_size
12520 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12521 "shr{b}\t{%2, %0|%0, %2}"
12522 [(set_attr "type" "ishift")
12523 (set_attr "mode" "QI")])
12524 \f
12525 ;; Rotate instructions
12526
12527 (define_expand "rotldi3"
12528 [(set (match_operand:DI 0 "shiftdi_operand" "")
12529 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12530 (match_operand:QI 2 "nonmemory_operand" "")))
12531 (clobber (reg:CC FLAGS_REG))]
12532 ""
12533 {
12534 if (TARGET_64BIT)
12535 {
12536 ix86_expand_binary_operator (ROTATE, DImode, operands);
12537 DONE;
12538 }
12539 if (!const_1_to_31_operand (operands[2], VOIDmode))
12540 FAIL;
12541 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12542 DONE;
12543 })
12544
12545 ;; Implement rotation using two double-precision shift instructions
12546 ;; and a scratch register.
12547 (define_insn_and_split "ix86_rotldi3"
12548 [(set (match_operand:DI 0 "register_operand" "=r")
12549 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12550 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12551 (clobber (reg:CC FLAGS_REG))
12552 (clobber (match_scratch:SI 3 "=&r"))]
12553 "!TARGET_64BIT"
12554 ""
12555 "&& reload_completed"
12556 [(set (match_dup 3) (match_dup 4))
12557 (parallel
12558 [(set (match_dup 4)
12559 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12560 (lshiftrt:SI (match_dup 5)
12561 (minus:QI (const_int 32) (match_dup 2)))))
12562 (clobber (reg:CC FLAGS_REG))])
12563 (parallel
12564 [(set (match_dup 5)
12565 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12566 (lshiftrt:SI (match_dup 3)
12567 (minus:QI (const_int 32) (match_dup 2)))))
12568 (clobber (reg:CC FLAGS_REG))])]
12569 "split_di (operands, 1, operands + 4, operands + 5);")
12570
12571 (define_insn "*rotlsi3_1_one_bit_rex64"
12572 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12573 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12574 (match_operand:QI 2 "const1_operand" "")))
12575 (clobber (reg:CC FLAGS_REG))]
12576 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12577 && (TARGET_SHIFT1 || optimize_size)"
12578 "rol{q}\t%0"
12579 [(set_attr "type" "rotate")
12580 (set (attr "length")
12581 (if_then_else (match_operand:DI 0 "register_operand" "")
12582 (const_string "2")
12583 (const_string "*")))])
12584
12585 (define_insn "*rotldi3_1_rex64"
12586 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12587 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12588 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12589 (clobber (reg:CC FLAGS_REG))]
12590 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12591 "@
12592 rol{q}\t{%2, %0|%0, %2}
12593 rol{q}\t{%b2, %0|%0, %b2}"
12594 [(set_attr "type" "rotate")
12595 (set_attr "mode" "DI")])
12596
12597 (define_expand "rotlsi3"
12598 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12599 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12600 (match_operand:QI 2 "nonmemory_operand" "")))
12601 (clobber (reg:CC FLAGS_REG))]
12602 ""
12603 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12604
12605 (define_insn "*rotlsi3_1_one_bit"
12606 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12607 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12608 (match_operand:QI 2 "const1_operand" "")))
12609 (clobber (reg:CC FLAGS_REG))]
12610 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12611 && (TARGET_SHIFT1 || optimize_size)"
12612 "rol{l}\t%0"
12613 [(set_attr "type" "rotate")
12614 (set (attr "length")
12615 (if_then_else (match_operand:SI 0 "register_operand" "")
12616 (const_string "2")
12617 (const_string "*")))])
12618
12619 (define_insn "*rotlsi3_1_one_bit_zext"
12620 [(set (match_operand:DI 0 "register_operand" "=r")
12621 (zero_extend:DI
12622 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12623 (match_operand:QI 2 "const1_operand" ""))))
12624 (clobber (reg:CC FLAGS_REG))]
12625 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12626 && (TARGET_SHIFT1 || optimize_size)"
12627 "rol{l}\t%k0"
12628 [(set_attr "type" "rotate")
12629 (set_attr "length" "2")])
12630
12631 (define_insn "*rotlsi3_1"
12632 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12633 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12634 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12635 (clobber (reg:CC FLAGS_REG))]
12636 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12637 "@
12638 rol{l}\t{%2, %0|%0, %2}
12639 rol{l}\t{%b2, %0|%0, %b2}"
12640 [(set_attr "type" "rotate")
12641 (set_attr "mode" "SI")])
12642
12643 (define_insn "*rotlsi3_1_zext"
12644 [(set (match_operand:DI 0 "register_operand" "=r,r")
12645 (zero_extend:DI
12646 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12647 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12648 (clobber (reg:CC FLAGS_REG))]
12649 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12650 "@
12651 rol{l}\t{%2, %k0|%k0, %2}
12652 rol{l}\t{%b2, %k0|%k0, %b2}"
12653 [(set_attr "type" "rotate")
12654 (set_attr "mode" "SI")])
12655
12656 (define_expand "rotlhi3"
12657 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12658 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12659 (match_operand:QI 2 "nonmemory_operand" "")))
12660 (clobber (reg:CC FLAGS_REG))]
12661 "TARGET_HIMODE_MATH"
12662 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12663
12664 (define_insn "*rotlhi3_1_one_bit"
12665 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12666 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12667 (match_operand:QI 2 "const1_operand" "")))
12668 (clobber (reg:CC FLAGS_REG))]
12669 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12670 && (TARGET_SHIFT1 || optimize_size)"
12671 "rol{w}\t%0"
12672 [(set_attr "type" "rotate")
12673 (set (attr "length")
12674 (if_then_else (match_operand 0 "register_operand" "")
12675 (const_string "2")
12676 (const_string "*")))])
12677
12678 (define_insn "*rotlhi3_1"
12679 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12680 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12681 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12682 (clobber (reg:CC FLAGS_REG))]
12683 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12684 "@
12685 rol{w}\t{%2, %0|%0, %2}
12686 rol{w}\t{%b2, %0|%0, %b2}"
12687 [(set_attr "type" "rotate")
12688 (set_attr "mode" "HI")])
12689
12690 (define_expand "rotlqi3"
12691 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12692 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12693 (match_operand:QI 2 "nonmemory_operand" "")))
12694 (clobber (reg:CC FLAGS_REG))]
12695 "TARGET_QIMODE_MATH"
12696 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12697
12698 (define_insn "*rotlqi3_1_one_bit_slp"
12699 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12700 (rotate:QI (match_dup 0)
12701 (match_operand:QI 1 "const1_operand" "")))
12702 (clobber (reg:CC FLAGS_REG))]
12703 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12704 && (TARGET_SHIFT1 || optimize_size)"
12705 "rol{b}\t%0"
12706 [(set_attr "type" "rotate1")
12707 (set (attr "length")
12708 (if_then_else (match_operand 0 "register_operand" "")
12709 (const_string "2")
12710 (const_string "*")))])
12711
12712 (define_insn "*rotlqi3_1_one_bit"
12713 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12714 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12715 (match_operand:QI 2 "const1_operand" "")))
12716 (clobber (reg:CC FLAGS_REG))]
12717 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12718 && (TARGET_SHIFT1 || optimize_size)"
12719 "rol{b}\t%0"
12720 [(set_attr "type" "rotate")
12721 (set (attr "length")
12722 (if_then_else (match_operand 0 "register_operand" "")
12723 (const_string "2")
12724 (const_string "*")))])
12725
12726 (define_insn "*rotlqi3_1_slp"
12727 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12728 (rotate:QI (match_dup 0)
12729 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12730 (clobber (reg:CC FLAGS_REG))]
12731 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12732 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12733 "@
12734 rol{b}\t{%1, %0|%0, %1}
12735 rol{b}\t{%b1, %0|%0, %b1}"
12736 [(set_attr "type" "rotate1")
12737 (set_attr "mode" "QI")])
12738
12739 (define_insn "*rotlqi3_1"
12740 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12741 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12742 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12743 (clobber (reg:CC FLAGS_REG))]
12744 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12745 "@
12746 rol{b}\t{%2, %0|%0, %2}
12747 rol{b}\t{%b2, %0|%0, %b2}"
12748 [(set_attr "type" "rotate")
12749 (set_attr "mode" "QI")])
12750
12751 (define_expand "rotrdi3"
12752 [(set (match_operand:DI 0 "shiftdi_operand" "")
12753 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12754 (match_operand:QI 2 "nonmemory_operand" "")))
12755 (clobber (reg:CC FLAGS_REG))]
12756 ""
12757 {
12758 if (TARGET_64BIT)
12759 {
12760 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12761 DONE;
12762 }
12763 if (!const_1_to_31_operand (operands[2], VOIDmode))
12764 FAIL;
12765 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12766 DONE;
12767 })
12768
12769 ;; Implement rotation using two double-precision shift instructions
12770 ;; and a scratch register.
12771 (define_insn_and_split "ix86_rotrdi3"
12772 [(set (match_operand:DI 0 "register_operand" "=r")
12773 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12774 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12775 (clobber (reg:CC FLAGS_REG))
12776 (clobber (match_scratch:SI 3 "=&r"))]
12777 "!TARGET_64BIT"
12778 ""
12779 "&& reload_completed"
12780 [(set (match_dup 3) (match_dup 4))
12781 (parallel
12782 [(set (match_dup 4)
12783 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12784 (ashift:SI (match_dup 5)
12785 (minus:QI (const_int 32) (match_dup 2)))))
12786 (clobber (reg:CC FLAGS_REG))])
12787 (parallel
12788 [(set (match_dup 5)
12789 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12790 (ashift:SI (match_dup 3)
12791 (minus:QI (const_int 32) (match_dup 2)))))
12792 (clobber (reg:CC FLAGS_REG))])]
12793 "split_di (operands, 1, operands + 4, operands + 5);")
12794
12795 (define_insn "*rotrdi3_1_one_bit_rex64"
12796 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12797 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12798 (match_operand:QI 2 "const1_operand" "")))
12799 (clobber (reg:CC FLAGS_REG))]
12800 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12801 && (TARGET_SHIFT1 || optimize_size)"
12802 "ror{q}\t%0"
12803 [(set_attr "type" "rotate")
12804 (set (attr "length")
12805 (if_then_else (match_operand:DI 0 "register_operand" "")
12806 (const_string "2")
12807 (const_string "*")))])
12808
12809 (define_insn "*rotrdi3_1_rex64"
12810 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12811 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12812 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12813 (clobber (reg:CC FLAGS_REG))]
12814 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12815 "@
12816 ror{q}\t{%2, %0|%0, %2}
12817 ror{q}\t{%b2, %0|%0, %b2}"
12818 [(set_attr "type" "rotate")
12819 (set_attr "mode" "DI")])
12820
12821 (define_expand "rotrsi3"
12822 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12823 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12824 (match_operand:QI 2 "nonmemory_operand" "")))
12825 (clobber (reg:CC FLAGS_REG))]
12826 ""
12827 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12828
12829 (define_insn "*rotrsi3_1_one_bit"
12830 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12831 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12832 (match_operand:QI 2 "const1_operand" "")))
12833 (clobber (reg:CC FLAGS_REG))]
12834 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12835 && (TARGET_SHIFT1 || optimize_size)"
12836 "ror{l}\t%0"
12837 [(set_attr "type" "rotate")
12838 (set (attr "length")
12839 (if_then_else (match_operand:SI 0 "register_operand" "")
12840 (const_string "2")
12841 (const_string "*")))])
12842
12843 (define_insn "*rotrsi3_1_one_bit_zext"
12844 [(set (match_operand:DI 0 "register_operand" "=r")
12845 (zero_extend:DI
12846 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12847 (match_operand:QI 2 "const1_operand" ""))))
12848 (clobber (reg:CC FLAGS_REG))]
12849 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12850 && (TARGET_SHIFT1 || optimize_size)"
12851 "ror{l}\t%k0"
12852 [(set_attr "type" "rotate")
12853 (set (attr "length")
12854 (if_then_else (match_operand:SI 0 "register_operand" "")
12855 (const_string "2")
12856 (const_string "*")))])
12857
12858 (define_insn "*rotrsi3_1"
12859 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12860 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12861 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12862 (clobber (reg:CC FLAGS_REG))]
12863 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12864 "@
12865 ror{l}\t{%2, %0|%0, %2}
12866 ror{l}\t{%b2, %0|%0, %b2}"
12867 [(set_attr "type" "rotate")
12868 (set_attr "mode" "SI")])
12869
12870 (define_insn "*rotrsi3_1_zext"
12871 [(set (match_operand:DI 0 "register_operand" "=r,r")
12872 (zero_extend:DI
12873 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12874 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12875 (clobber (reg:CC FLAGS_REG))]
12876 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12877 "@
12878 ror{l}\t{%2, %k0|%k0, %2}
12879 ror{l}\t{%b2, %k0|%k0, %b2}"
12880 [(set_attr "type" "rotate")
12881 (set_attr "mode" "SI")])
12882
12883 (define_expand "rotrhi3"
12884 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12885 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12886 (match_operand:QI 2 "nonmemory_operand" "")))
12887 (clobber (reg:CC FLAGS_REG))]
12888 "TARGET_HIMODE_MATH"
12889 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12890
12891 (define_insn "*rotrhi3_one_bit"
12892 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12893 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12894 (match_operand:QI 2 "const1_operand" "")))
12895 (clobber (reg:CC FLAGS_REG))]
12896 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12897 && (TARGET_SHIFT1 || optimize_size)"
12898 "ror{w}\t%0"
12899 [(set_attr "type" "rotate")
12900 (set (attr "length")
12901 (if_then_else (match_operand 0 "register_operand" "")
12902 (const_string "2")
12903 (const_string "*")))])
12904
12905 (define_insn "*rotrhi3"
12906 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12907 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12908 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12909 (clobber (reg:CC FLAGS_REG))]
12910 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12911 "@
12912 ror{w}\t{%2, %0|%0, %2}
12913 ror{w}\t{%b2, %0|%0, %b2}"
12914 [(set_attr "type" "rotate")
12915 (set_attr "mode" "HI")])
12916
12917 (define_expand "rotrqi3"
12918 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12919 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12920 (match_operand:QI 2 "nonmemory_operand" "")))
12921 (clobber (reg:CC FLAGS_REG))]
12922 "TARGET_QIMODE_MATH"
12923 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12924
12925 (define_insn "*rotrqi3_1_one_bit"
12926 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12927 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12928 (match_operand:QI 2 "const1_operand" "")))
12929 (clobber (reg:CC FLAGS_REG))]
12930 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12931 && (TARGET_SHIFT1 || optimize_size)"
12932 "ror{b}\t%0"
12933 [(set_attr "type" "rotate")
12934 (set (attr "length")
12935 (if_then_else (match_operand 0 "register_operand" "")
12936 (const_string "2")
12937 (const_string "*")))])
12938
12939 (define_insn "*rotrqi3_1_one_bit_slp"
12940 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12941 (rotatert:QI (match_dup 0)
12942 (match_operand:QI 1 "const1_operand" "")))
12943 (clobber (reg:CC FLAGS_REG))]
12944 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12945 && (TARGET_SHIFT1 || optimize_size)"
12946 "ror{b}\t%0"
12947 [(set_attr "type" "rotate1")
12948 (set (attr "length")
12949 (if_then_else (match_operand 0 "register_operand" "")
12950 (const_string "2")
12951 (const_string "*")))])
12952
12953 (define_insn "*rotrqi3_1"
12954 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12955 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12956 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12957 (clobber (reg:CC FLAGS_REG))]
12958 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12959 "@
12960 ror{b}\t{%2, %0|%0, %2}
12961 ror{b}\t{%b2, %0|%0, %b2}"
12962 [(set_attr "type" "rotate")
12963 (set_attr "mode" "QI")])
12964
12965 (define_insn "*rotrqi3_1_slp"
12966 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12967 (rotatert:QI (match_dup 0)
12968 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12969 (clobber (reg:CC FLAGS_REG))]
12970 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12971 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12972 "@
12973 ror{b}\t{%1, %0|%0, %1}
12974 ror{b}\t{%b1, %0|%0, %b1}"
12975 [(set_attr "type" "rotate1")
12976 (set_attr "mode" "QI")])
12977 \f
12978 ;; Bit set / bit test instructions
12979
12980 (define_expand "extv"
12981 [(set (match_operand:SI 0 "register_operand" "")
12982 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12983 (match_operand:SI 2 "const8_operand" "")
12984 (match_operand:SI 3 "const8_operand" "")))]
12985 ""
12986 {
12987 /* Handle extractions from %ah et al. */
12988 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12989 FAIL;
12990
12991 /* From mips.md: extract_bit_field doesn't verify that our source
12992 matches the predicate, so check it again here. */
12993 if (! ext_register_operand (operands[1], VOIDmode))
12994 FAIL;
12995 })
12996
12997 (define_expand "extzv"
12998 [(set (match_operand:SI 0 "register_operand" "")
12999 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13000 (match_operand:SI 2 "const8_operand" "")
13001 (match_operand:SI 3 "const8_operand" "")))]
13002 ""
13003 {
13004 /* Handle extractions from %ah et al. */
13005 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13006 FAIL;
13007
13008 /* From mips.md: extract_bit_field doesn't verify that our source
13009 matches the predicate, so check it again here. */
13010 if (! ext_register_operand (operands[1], VOIDmode))
13011 FAIL;
13012 })
13013
13014 (define_expand "insv"
13015 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13016 (match_operand 1 "const8_operand" "")
13017 (match_operand 2 "const8_operand" ""))
13018 (match_operand 3 "register_operand" ""))]
13019 ""
13020 {
13021 /* Handle insertions to %ah et al. */
13022 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13023 FAIL;
13024
13025 /* From mips.md: insert_bit_field doesn't verify that our source
13026 matches the predicate, so check it again here. */
13027 if (! ext_register_operand (operands[0], VOIDmode))
13028 FAIL;
13029
13030 if (TARGET_64BIT)
13031 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13032 else
13033 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13034
13035 DONE;
13036 })
13037
13038 ;; %%% bts, btr, btc, bt.
13039 ;; In general these instructions are *slow* when applied to memory,
13040 ;; since they enforce atomic operation. When applied to registers,
13041 ;; it depends on the cpu implementation. They're never faster than
13042 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13043 ;; no point. But in 64-bit, we can't hold the relevant immediates
13044 ;; within the instruction itself, so operating on bits in the high
13045 ;; 32-bits of a register becomes easier.
13046 ;;
13047 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13048 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13049 ;; negdf respectively, so they can never be disabled entirely.
13050
13051 (define_insn "*btsq"
13052 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13053 (const_int 1)
13054 (match_operand:DI 1 "const_0_to_63_operand" ""))
13055 (const_int 1))
13056 (clobber (reg:CC FLAGS_REG))]
13057 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13058 "bts{q} %1,%0"
13059 [(set_attr "type" "alu1")])
13060
13061 (define_insn "*btrq"
13062 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13063 (const_int 1)
13064 (match_operand:DI 1 "const_0_to_63_operand" ""))
13065 (const_int 0))
13066 (clobber (reg:CC FLAGS_REG))]
13067 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13068 "btr{q} %1,%0"
13069 [(set_attr "type" "alu1")])
13070
13071 (define_insn "*btcq"
13072 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13073 (const_int 1)
13074 (match_operand:DI 1 "const_0_to_63_operand" ""))
13075 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13076 (clobber (reg:CC FLAGS_REG))]
13077 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13078 "btc{q} %1,%0"
13079 [(set_attr "type" "alu1")])
13080
13081 ;; Allow Nocona to avoid these instructions if a register is available.
13082
13083 (define_peephole2
13084 [(match_scratch:DI 2 "r")
13085 (parallel [(set (zero_extract:DI
13086 (match_operand:DI 0 "register_operand" "")
13087 (const_int 1)
13088 (match_operand:DI 1 "const_0_to_63_operand" ""))
13089 (const_int 1))
13090 (clobber (reg:CC FLAGS_REG))])]
13091 "TARGET_64BIT && !TARGET_USE_BT"
13092 [(const_int 0)]
13093 {
13094 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13095 rtx op1;
13096
13097 if (HOST_BITS_PER_WIDE_INT >= 64)
13098 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13099 else if (i < HOST_BITS_PER_WIDE_INT)
13100 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13101 else
13102 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13103
13104 op1 = immed_double_const (lo, hi, DImode);
13105 if (i >= 31)
13106 {
13107 emit_move_insn (operands[2], op1);
13108 op1 = operands[2];
13109 }
13110
13111 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13112 DONE;
13113 })
13114
13115 (define_peephole2
13116 [(match_scratch:DI 2 "r")
13117 (parallel [(set (zero_extract:DI
13118 (match_operand:DI 0 "register_operand" "")
13119 (const_int 1)
13120 (match_operand:DI 1 "const_0_to_63_operand" ""))
13121 (const_int 0))
13122 (clobber (reg:CC FLAGS_REG))])]
13123 "TARGET_64BIT && !TARGET_USE_BT"
13124 [(const_int 0)]
13125 {
13126 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13127 rtx op1;
13128
13129 if (HOST_BITS_PER_WIDE_INT >= 64)
13130 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13131 else if (i < HOST_BITS_PER_WIDE_INT)
13132 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13133 else
13134 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13135
13136 op1 = immed_double_const (~lo, ~hi, DImode);
13137 if (i >= 32)
13138 {
13139 emit_move_insn (operands[2], op1);
13140 op1 = operands[2];
13141 }
13142
13143 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13144 DONE;
13145 })
13146
13147 (define_peephole2
13148 [(match_scratch:DI 2 "r")
13149 (parallel [(set (zero_extract:DI
13150 (match_operand:DI 0 "register_operand" "")
13151 (const_int 1)
13152 (match_operand:DI 1 "const_0_to_63_operand" ""))
13153 (not:DI (zero_extract:DI
13154 (match_dup 0) (const_int 1) (match_dup 1))))
13155 (clobber (reg:CC FLAGS_REG))])]
13156 "TARGET_64BIT && !TARGET_USE_BT"
13157 [(const_int 0)]
13158 {
13159 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13160 rtx op1;
13161
13162 if (HOST_BITS_PER_WIDE_INT >= 64)
13163 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13164 else if (i < HOST_BITS_PER_WIDE_INT)
13165 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13166 else
13167 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13168
13169 op1 = immed_double_const (lo, hi, DImode);
13170 if (i >= 31)
13171 {
13172 emit_move_insn (operands[2], op1);
13173 op1 = operands[2];
13174 }
13175
13176 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13177 DONE;
13178 })
13179 \f
13180 ;; Store-flag instructions.
13181
13182 ;; For all sCOND expanders, also expand the compare or test insn that
13183 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13184
13185 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13186 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13187 ;; way, which can later delete the movzx if only QImode is needed.
13188
13189 (define_expand "seq"
13190 [(set (match_operand:QI 0 "register_operand" "")
13191 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13192 ""
13193 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13194
13195 (define_expand "sne"
13196 [(set (match_operand:QI 0 "register_operand" "")
13197 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13198 ""
13199 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13200
13201 (define_expand "sgt"
13202 [(set (match_operand:QI 0 "register_operand" "")
13203 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13204 ""
13205 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13206
13207 (define_expand "sgtu"
13208 [(set (match_operand:QI 0 "register_operand" "")
13209 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13210 ""
13211 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13212
13213 (define_expand "slt"
13214 [(set (match_operand:QI 0 "register_operand" "")
13215 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13216 ""
13217 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13218
13219 (define_expand "sltu"
13220 [(set (match_operand:QI 0 "register_operand" "")
13221 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13222 ""
13223 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13224
13225 (define_expand "sge"
13226 [(set (match_operand:QI 0 "register_operand" "")
13227 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13228 ""
13229 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13230
13231 (define_expand "sgeu"
13232 [(set (match_operand:QI 0 "register_operand" "")
13233 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13234 ""
13235 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13236
13237 (define_expand "sle"
13238 [(set (match_operand:QI 0 "register_operand" "")
13239 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13240 ""
13241 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13242
13243 (define_expand "sleu"
13244 [(set (match_operand:QI 0 "register_operand" "")
13245 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13246 ""
13247 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13248
13249 (define_expand "sunordered"
13250 [(set (match_operand:QI 0 "register_operand" "")
13251 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252 "TARGET_80387 || TARGET_SSE"
13253 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13254
13255 (define_expand "sordered"
13256 [(set (match_operand:QI 0 "register_operand" "")
13257 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258 "TARGET_80387"
13259 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13260
13261 (define_expand "suneq"
13262 [(set (match_operand:QI 0 "register_operand" "")
13263 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264 "TARGET_80387 || TARGET_SSE"
13265 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13266
13267 (define_expand "sunge"
13268 [(set (match_operand:QI 0 "register_operand" "")
13269 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13270 "TARGET_80387 || TARGET_SSE"
13271 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13272
13273 (define_expand "sungt"
13274 [(set (match_operand:QI 0 "register_operand" "")
13275 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13276 "TARGET_80387 || TARGET_SSE"
13277 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13278
13279 (define_expand "sunle"
13280 [(set (match_operand:QI 0 "register_operand" "")
13281 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13282 "TARGET_80387 || TARGET_SSE"
13283 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13284
13285 (define_expand "sunlt"
13286 [(set (match_operand:QI 0 "register_operand" "")
13287 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13288 "TARGET_80387 || TARGET_SSE"
13289 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13290
13291 (define_expand "sltgt"
13292 [(set (match_operand:QI 0 "register_operand" "")
13293 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294 "TARGET_80387 || TARGET_SSE"
13295 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13296
13297 (define_insn "*setcc_1"
13298 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13299 (match_operator:QI 1 "ix86_comparison_operator"
13300 [(reg FLAGS_REG) (const_int 0)]))]
13301 ""
13302 "set%C1\t%0"
13303 [(set_attr "type" "setcc")
13304 (set_attr "mode" "QI")])
13305
13306 (define_insn "*setcc_2"
13307 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13308 (match_operator:QI 1 "ix86_comparison_operator"
13309 [(reg FLAGS_REG) (const_int 0)]))]
13310 ""
13311 "set%C1\t%0"
13312 [(set_attr "type" "setcc")
13313 (set_attr "mode" "QI")])
13314
13315 ;; In general it is not safe to assume too much about CCmode registers,
13316 ;; so simplify-rtx stops when it sees a second one. Under certain
13317 ;; conditions this is safe on x86, so help combine not create
13318 ;;
13319 ;; seta %al
13320 ;; testb %al, %al
13321 ;; sete %al
13322
13323 (define_split
13324 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13325 (ne: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 PUT_MODE (operands[1], QImode);
13332 })
13333
13334 (define_split
13335 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13336 (ne:QI (match_operator 1 "ix86_comparison_operator"
13337 [(reg FLAGS_REG) (const_int 0)])
13338 (const_int 0)))]
13339 ""
13340 [(set (match_dup 0) (match_dup 1))]
13341 {
13342 PUT_MODE (operands[1], QImode);
13343 })
13344
13345 (define_split
13346 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13347 (eq:QI (match_operator 1 "ix86_comparison_operator"
13348 [(reg FLAGS_REG) (const_int 0)])
13349 (const_int 0)))]
13350 ""
13351 [(set (match_dup 0) (match_dup 1))]
13352 {
13353 rtx new_op1 = copy_rtx (operands[1]);
13354 operands[1] = new_op1;
13355 PUT_MODE (new_op1, QImode);
13356 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13357 GET_MODE (XEXP (new_op1, 0))));
13358
13359 /* Make sure that (a) the CCmode we have for the flags is strong
13360 enough for the reversed compare or (b) we have a valid FP compare. */
13361 if (! ix86_comparison_operator (new_op1, VOIDmode))
13362 FAIL;
13363 })
13364
13365 (define_split
13366 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13367 (eq:QI (match_operator 1 "ix86_comparison_operator"
13368 [(reg FLAGS_REG) (const_int 0)])
13369 (const_int 0)))]
13370 ""
13371 [(set (match_dup 0) (match_dup 1))]
13372 {
13373 rtx new_op1 = copy_rtx (operands[1]);
13374 operands[1] = new_op1;
13375 PUT_MODE (new_op1, QImode);
13376 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13377 GET_MODE (XEXP (new_op1, 0))));
13378
13379 /* Make sure that (a) the CCmode we have for the flags is strong
13380 enough for the reversed compare or (b) we have a valid FP compare. */
13381 if (! ix86_comparison_operator (new_op1, VOIDmode))
13382 FAIL;
13383 })
13384
13385 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13386 ;; subsequent logical operations are used to imitate conditional moves.
13387 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13388 ;; it directly.
13389
13390 (define_insn "*sse_setccsf"
13391 [(set (match_operand:SF 0 "register_operand" "=x")
13392 (match_operator:SF 1 "sse_comparison_operator"
13393 [(match_operand:SF 2 "register_operand" "0")
13394 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13395 "TARGET_SSE"
13396 "cmp%D1ss\t{%3, %0|%0, %3}"
13397 [(set_attr "type" "ssecmp")
13398 (set_attr "mode" "SF")])
13399
13400 (define_insn "*sse_setccdf"
13401 [(set (match_operand:DF 0 "register_operand" "=Y")
13402 (match_operator:DF 1 "sse_comparison_operator"
13403 [(match_operand:DF 2 "register_operand" "0")
13404 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13405 "TARGET_SSE2"
13406 "cmp%D1sd\t{%3, %0|%0, %3}"
13407 [(set_attr "type" "ssecmp")
13408 (set_attr "mode" "DF")])
13409 \f
13410 ;; Basic conditional jump instructions.
13411 ;; We ignore the overflow flag for signed branch instructions.
13412
13413 ;; For all bCOND expanders, also expand the compare or test insn that
13414 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13415
13416 (define_expand "beq"
13417 [(set (pc)
13418 (if_then_else (match_dup 1)
13419 (label_ref (match_operand 0 "" ""))
13420 (pc)))]
13421 ""
13422 "ix86_expand_branch (EQ, operands[0]); DONE;")
13423
13424 (define_expand "bne"
13425 [(set (pc)
13426 (if_then_else (match_dup 1)
13427 (label_ref (match_operand 0 "" ""))
13428 (pc)))]
13429 ""
13430 "ix86_expand_branch (NE, operands[0]); DONE;")
13431
13432 (define_expand "bgt"
13433 [(set (pc)
13434 (if_then_else (match_dup 1)
13435 (label_ref (match_operand 0 "" ""))
13436 (pc)))]
13437 ""
13438 "ix86_expand_branch (GT, operands[0]); DONE;")
13439
13440 (define_expand "bgtu"
13441 [(set (pc)
13442 (if_then_else (match_dup 1)
13443 (label_ref (match_operand 0 "" ""))
13444 (pc)))]
13445 ""
13446 "ix86_expand_branch (GTU, operands[0]); DONE;")
13447
13448 (define_expand "blt"
13449 [(set (pc)
13450 (if_then_else (match_dup 1)
13451 (label_ref (match_operand 0 "" ""))
13452 (pc)))]
13453 ""
13454 "ix86_expand_branch (LT, operands[0]); DONE;")
13455
13456 (define_expand "bltu"
13457 [(set (pc)
13458 (if_then_else (match_dup 1)
13459 (label_ref (match_operand 0 "" ""))
13460 (pc)))]
13461 ""
13462 "ix86_expand_branch (LTU, operands[0]); DONE;")
13463
13464 (define_expand "bge"
13465 [(set (pc)
13466 (if_then_else (match_dup 1)
13467 (label_ref (match_operand 0 "" ""))
13468 (pc)))]
13469 ""
13470 "ix86_expand_branch (GE, operands[0]); DONE;")
13471
13472 (define_expand "bgeu"
13473 [(set (pc)
13474 (if_then_else (match_dup 1)
13475 (label_ref (match_operand 0 "" ""))
13476 (pc)))]
13477 ""
13478 "ix86_expand_branch (GEU, operands[0]); DONE;")
13479
13480 (define_expand "ble"
13481 [(set (pc)
13482 (if_then_else (match_dup 1)
13483 (label_ref (match_operand 0 "" ""))
13484 (pc)))]
13485 ""
13486 "ix86_expand_branch (LE, operands[0]); DONE;")
13487
13488 (define_expand "bleu"
13489 [(set (pc)
13490 (if_then_else (match_dup 1)
13491 (label_ref (match_operand 0 "" ""))
13492 (pc)))]
13493 ""
13494 "ix86_expand_branch (LEU, operands[0]); DONE;")
13495
13496 (define_expand "bunordered"
13497 [(set (pc)
13498 (if_then_else (match_dup 1)
13499 (label_ref (match_operand 0 "" ""))
13500 (pc)))]
13501 "TARGET_80387 || TARGET_SSE_MATH"
13502 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13503
13504 (define_expand "bordered"
13505 [(set (pc)
13506 (if_then_else (match_dup 1)
13507 (label_ref (match_operand 0 "" ""))
13508 (pc)))]
13509 "TARGET_80387 || TARGET_SSE_MATH"
13510 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13511
13512 (define_expand "buneq"
13513 [(set (pc)
13514 (if_then_else (match_dup 1)
13515 (label_ref (match_operand 0 "" ""))
13516 (pc)))]
13517 "TARGET_80387 || TARGET_SSE_MATH"
13518 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13519
13520 (define_expand "bunge"
13521 [(set (pc)
13522 (if_then_else (match_dup 1)
13523 (label_ref (match_operand 0 "" ""))
13524 (pc)))]
13525 "TARGET_80387 || TARGET_SSE_MATH"
13526 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13527
13528 (define_expand "bungt"
13529 [(set (pc)
13530 (if_then_else (match_dup 1)
13531 (label_ref (match_operand 0 "" ""))
13532 (pc)))]
13533 "TARGET_80387 || TARGET_SSE_MATH"
13534 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13535
13536 (define_expand "bunle"
13537 [(set (pc)
13538 (if_then_else (match_dup 1)
13539 (label_ref (match_operand 0 "" ""))
13540 (pc)))]
13541 "TARGET_80387 || TARGET_SSE_MATH"
13542 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13543
13544 (define_expand "bunlt"
13545 [(set (pc)
13546 (if_then_else (match_dup 1)
13547 (label_ref (match_operand 0 "" ""))
13548 (pc)))]
13549 "TARGET_80387 || TARGET_SSE_MATH"
13550 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13551
13552 (define_expand "bltgt"
13553 [(set (pc)
13554 (if_then_else (match_dup 1)
13555 (label_ref (match_operand 0 "" ""))
13556 (pc)))]
13557 "TARGET_80387 || TARGET_SSE_MATH"
13558 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13559
13560 (define_insn "*jcc_1"
13561 [(set (pc)
13562 (if_then_else (match_operator 1 "ix86_comparison_operator"
13563 [(reg FLAGS_REG) (const_int 0)])
13564 (label_ref (match_operand 0 "" ""))
13565 (pc)))]
13566 ""
13567 "%+j%C1\t%l0"
13568 [(set_attr "type" "ibr")
13569 (set_attr "modrm" "0")
13570 (set (attr "length")
13571 (if_then_else (and (ge (minus (match_dup 0) (pc))
13572 (const_int -126))
13573 (lt (minus (match_dup 0) (pc))
13574 (const_int 128)))
13575 (const_int 2)
13576 (const_int 6)))])
13577
13578 (define_insn "*jcc_2"
13579 [(set (pc)
13580 (if_then_else (match_operator 1 "ix86_comparison_operator"
13581 [(reg FLAGS_REG) (const_int 0)])
13582 (pc)
13583 (label_ref (match_operand 0 "" ""))))]
13584 ""
13585 "%+j%c1\t%l0"
13586 [(set_attr "type" "ibr")
13587 (set_attr "modrm" "0")
13588 (set (attr "length")
13589 (if_then_else (and (ge (minus (match_dup 0) (pc))
13590 (const_int -126))
13591 (lt (minus (match_dup 0) (pc))
13592 (const_int 128)))
13593 (const_int 2)
13594 (const_int 6)))])
13595
13596 ;; In general it is not safe to assume too much about CCmode registers,
13597 ;; so simplify-rtx stops when it sees a second one. Under certain
13598 ;; conditions this is safe on x86, so help combine not create
13599 ;;
13600 ;; seta %al
13601 ;; testb %al, %al
13602 ;; je Lfoo
13603
13604 (define_split
13605 [(set (pc)
13606 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13607 [(reg FLAGS_REG) (const_int 0)])
13608 (const_int 0))
13609 (label_ref (match_operand 1 "" ""))
13610 (pc)))]
13611 ""
13612 [(set (pc)
13613 (if_then_else (match_dup 0)
13614 (label_ref (match_dup 1))
13615 (pc)))]
13616 {
13617 PUT_MODE (operands[0], VOIDmode);
13618 })
13619
13620 (define_split
13621 [(set (pc)
13622 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13623 [(reg FLAGS_REG) (const_int 0)])
13624 (const_int 0))
13625 (label_ref (match_operand 1 "" ""))
13626 (pc)))]
13627 ""
13628 [(set (pc)
13629 (if_then_else (match_dup 0)
13630 (label_ref (match_dup 1))
13631 (pc)))]
13632 {
13633 rtx new_op0 = copy_rtx (operands[0]);
13634 operands[0] = new_op0;
13635 PUT_MODE (new_op0, VOIDmode);
13636 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13637 GET_MODE (XEXP (new_op0, 0))));
13638
13639 /* Make sure that (a) the CCmode we have for the flags is strong
13640 enough for the reversed compare or (b) we have a valid FP compare. */
13641 if (! ix86_comparison_operator (new_op0, VOIDmode))
13642 FAIL;
13643 })
13644
13645 ;; Define combination compare-and-branch fp compare instructions to use
13646 ;; during early optimization. Splitting the operation apart early makes
13647 ;; for bad code when we want to reverse the operation.
13648
13649 (define_insn "*fp_jcc_1_mixed"
13650 [(set (pc)
13651 (if_then_else (match_operator 0 "comparison_operator"
13652 [(match_operand 1 "register_operand" "f,x")
13653 (match_operand 2 "nonimmediate_operand" "f,xm")])
13654 (label_ref (match_operand 3 "" ""))
13655 (pc)))
13656 (clobber (reg:CCFP FPSR_REG))
13657 (clobber (reg:CCFP FLAGS_REG))]
13658 "TARGET_MIX_SSE_I387
13659 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13660 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13661 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13662 "#")
13663
13664 (define_insn "*fp_jcc_1_sse"
13665 [(set (pc)
13666 (if_then_else (match_operator 0 "comparison_operator"
13667 [(match_operand 1 "register_operand" "x")
13668 (match_operand 2 "nonimmediate_operand" "xm")])
13669 (label_ref (match_operand 3 "" ""))
13670 (pc)))
13671 (clobber (reg:CCFP FPSR_REG))
13672 (clobber (reg:CCFP FLAGS_REG))]
13673 "TARGET_SSE_MATH
13674 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13675 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13676 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13677 "#")
13678
13679 (define_insn "*fp_jcc_1_387"
13680 [(set (pc)
13681 (if_then_else (match_operator 0 "comparison_operator"
13682 [(match_operand 1 "register_operand" "f")
13683 (match_operand 2 "register_operand" "f")])
13684 (label_ref (match_operand 3 "" ""))
13685 (pc)))
13686 (clobber (reg:CCFP FPSR_REG))
13687 (clobber (reg:CCFP FLAGS_REG))]
13688 "TARGET_CMOVE && TARGET_80387
13689 && FLOAT_MODE_P (GET_MODE (operands[1]))
13690 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13691 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13692 "#")
13693
13694 (define_insn "*fp_jcc_2_mixed"
13695 [(set (pc)
13696 (if_then_else (match_operator 0 "comparison_operator"
13697 [(match_operand 1 "register_operand" "f,x")
13698 (match_operand 2 "nonimmediate_operand" "f,xm")])
13699 (pc)
13700 (label_ref (match_operand 3 "" ""))))
13701 (clobber (reg:CCFP FPSR_REG))
13702 (clobber (reg:CCFP FLAGS_REG))]
13703 "TARGET_MIX_SSE_I387
13704 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13705 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13706 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13707 "#")
13708
13709 (define_insn "*fp_jcc_2_sse"
13710 [(set (pc)
13711 (if_then_else (match_operator 0 "comparison_operator"
13712 [(match_operand 1 "register_operand" "x")
13713 (match_operand 2 "nonimmediate_operand" "xm")])
13714 (pc)
13715 (label_ref (match_operand 3 "" ""))))
13716 (clobber (reg:CCFP FPSR_REG))
13717 (clobber (reg:CCFP FLAGS_REG))]
13718 "TARGET_SSE_MATH
13719 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13720 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13721 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13722 "#")
13723
13724 (define_insn "*fp_jcc_2_387"
13725 [(set (pc)
13726 (if_then_else (match_operator 0 "comparison_operator"
13727 [(match_operand 1 "register_operand" "f")
13728 (match_operand 2 "register_operand" "f")])
13729 (pc)
13730 (label_ref (match_operand 3 "" ""))))
13731 (clobber (reg:CCFP FPSR_REG))
13732 (clobber (reg:CCFP FLAGS_REG))]
13733 "TARGET_CMOVE && TARGET_80387
13734 && FLOAT_MODE_P (GET_MODE (operands[1]))
13735 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13736 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13737 "#")
13738
13739 (define_insn "*fp_jcc_3_387"
13740 [(set (pc)
13741 (if_then_else (match_operator 0 "comparison_operator"
13742 [(match_operand 1 "register_operand" "f")
13743 (match_operand 2 "nonimmediate_operand" "fm")])
13744 (label_ref (match_operand 3 "" ""))
13745 (pc)))
13746 (clobber (reg:CCFP FPSR_REG))
13747 (clobber (reg:CCFP FLAGS_REG))
13748 (clobber (match_scratch:HI 4 "=a"))]
13749 "TARGET_80387
13750 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13751 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13752 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13753 && SELECT_CC_MODE (GET_CODE (operands[0]),
13754 operands[1], operands[2]) == CCFPmode
13755 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13756 "#")
13757
13758 (define_insn "*fp_jcc_4_387"
13759 [(set (pc)
13760 (if_then_else (match_operator 0 "comparison_operator"
13761 [(match_operand 1 "register_operand" "f")
13762 (match_operand 2 "nonimmediate_operand" "fm")])
13763 (pc)
13764 (label_ref (match_operand 3 "" ""))))
13765 (clobber (reg:CCFP FPSR_REG))
13766 (clobber (reg:CCFP FLAGS_REG))
13767 (clobber (match_scratch:HI 4 "=a"))]
13768 "TARGET_80387
13769 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13772 && SELECT_CC_MODE (GET_CODE (operands[0]),
13773 operands[1], operands[2]) == CCFPmode
13774 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13775 "#")
13776
13777 (define_insn "*fp_jcc_5_387"
13778 [(set (pc)
13779 (if_then_else (match_operator 0 "comparison_operator"
13780 [(match_operand 1 "register_operand" "f")
13781 (match_operand 2 "register_operand" "f")])
13782 (label_ref (match_operand 3 "" ""))
13783 (pc)))
13784 (clobber (reg:CCFP FPSR_REG))
13785 (clobber (reg:CCFP FLAGS_REG))
13786 (clobber (match_scratch:HI 4 "=a"))]
13787 "TARGET_80387
13788 && FLOAT_MODE_P (GET_MODE (operands[1]))
13789 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13790 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13791 "#")
13792
13793 (define_insn "*fp_jcc_6_387"
13794 [(set (pc)
13795 (if_then_else (match_operator 0 "comparison_operator"
13796 [(match_operand 1 "register_operand" "f")
13797 (match_operand 2 "register_operand" "f")])
13798 (pc)
13799 (label_ref (match_operand 3 "" ""))))
13800 (clobber (reg:CCFP FPSR_REG))
13801 (clobber (reg:CCFP FLAGS_REG))
13802 (clobber (match_scratch:HI 4 "=a"))]
13803 "TARGET_80387
13804 && FLOAT_MODE_P (GET_MODE (operands[1]))
13805 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13806 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13807 "#")
13808
13809 (define_insn "*fp_jcc_7_387"
13810 [(set (pc)
13811 (if_then_else (match_operator 0 "comparison_operator"
13812 [(match_operand 1 "register_operand" "f")
13813 (match_operand 2 "const0_operand" "X")])
13814 (label_ref (match_operand 3 "" ""))
13815 (pc)))
13816 (clobber (reg:CCFP FPSR_REG))
13817 (clobber (reg:CCFP FLAGS_REG))
13818 (clobber (match_scratch:HI 4 "=a"))]
13819 "TARGET_80387
13820 && FLOAT_MODE_P (GET_MODE (operands[1]))
13821 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13822 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13823 && SELECT_CC_MODE (GET_CODE (operands[0]),
13824 operands[1], operands[2]) == CCFPmode
13825 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13826 "#")
13827
13828 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13829 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13830 ;; with a precedence over other operators and is always put in the first
13831 ;; place. Swap condition and operands to match ficom instruction.
13832
13833 (define_insn "*fp_jcc_8<mode>_387"
13834 [(set (pc)
13835 (if_then_else (match_operator 0 "comparison_operator"
13836 [(match_operator 1 "float_operator"
13837 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13838 (match_operand 3 "register_operand" "f,f")])
13839 (label_ref (match_operand 4 "" ""))
13840 (pc)))
13841 (clobber (reg:CCFP FPSR_REG))
13842 (clobber (reg:CCFP FLAGS_REG))
13843 (clobber (match_scratch:HI 5 "=a,a"))]
13844 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13845 && FLOAT_MODE_P (GET_MODE (operands[3]))
13846 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13847 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13848 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13849 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13850 "#")
13851
13852 (define_split
13853 [(set (pc)
13854 (if_then_else (match_operator 0 "comparison_operator"
13855 [(match_operand 1 "register_operand" "")
13856 (match_operand 2 "nonimmediate_operand" "")])
13857 (match_operand 3 "" "")
13858 (match_operand 4 "" "")))
13859 (clobber (reg:CCFP FPSR_REG))
13860 (clobber (reg:CCFP FLAGS_REG))]
13861 "reload_completed"
13862 [(const_int 0)]
13863 {
13864 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13865 operands[3], operands[4], NULL_RTX, NULL_RTX);
13866 DONE;
13867 })
13868
13869 (define_split
13870 [(set (pc)
13871 (if_then_else (match_operator 0 "comparison_operator"
13872 [(match_operand 1 "register_operand" "")
13873 (match_operand 2 "general_operand" "")])
13874 (match_operand 3 "" "")
13875 (match_operand 4 "" "")))
13876 (clobber (reg:CCFP FPSR_REG))
13877 (clobber (reg:CCFP FLAGS_REG))
13878 (clobber (match_scratch:HI 5 "=a"))]
13879 "reload_completed"
13880 [(const_int 0)]
13881 {
13882 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13883 operands[3], operands[4], operands[5], NULL_RTX);
13884 DONE;
13885 })
13886
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 "memory_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] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13902 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13903 operands[3], operands[7],
13904 operands[4], operands[5], operands[6], NULL_RTX);
13905 DONE;
13906 })
13907
13908 ;; %%% Kill this when reload knows how to do it.
13909 (define_split
13910 [(set (pc)
13911 (if_then_else (match_operator 0 "comparison_operator"
13912 [(match_operator 1 "float_operator"
13913 [(match_operand:X87MODEI12 2 "register_operand" "")])
13914 (match_operand 3 "register_operand" "")])
13915 (match_operand 4 "" "")
13916 (match_operand 5 "" "")))
13917 (clobber (reg:CCFP FPSR_REG))
13918 (clobber (reg:CCFP FLAGS_REG))
13919 (clobber (match_scratch:HI 6 "=a"))]
13920 "reload_completed"
13921 [(const_int 0)]
13922 {
13923 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13924 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13925 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13926 operands[3], operands[7],
13927 operands[4], operands[5], operands[6], operands[2]);
13928 DONE;
13929 })
13930 \f
13931 ;; Unconditional and other jump instructions
13932
13933 (define_insn "jump"
13934 [(set (pc)
13935 (label_ref (match_operand 0 "" "")))]
13936 ""
13937 "jmp\t%l0"
13938 [(set_attr "type" "ibr")
13939 (set (attr "length")
13940 (if_then_else (and (ge (minus (match_dup 0) (pc))
13941 (const_int -126))
13942 (lt (minus (match_dup 0) (pc))
13943 (const_int 128)))
13944 (const_int 2)
13945 (const_int 5)))
13946 (set_attr "modrm" "0")])
13947
13948 (define_expand "indirect_jump"
13949 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13950 ""
13951 "")
13952
13953 (define_insn "*indirect_jump"
13954 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13955 "!TARGET_64BIT"
13956 "jmp\t%A0"
13957 [(set_attr "type" "ibr")
13958 (set_attr "length_immediate" "0")])
13959
13960 (define_insn "*indirect_jump_rtx64"
13961 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13962 "TARGET_64BIT"
13963 "jmp\t%A0"
13964 [(set_attr "type" "ibr")
13965 (set_attr "length_immediate" "0")])
13966
13967 (define_expand "tablejump"
13968 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13969 (use (label_ref (match_operand 1 "" "")))])]
13970 ""
13971 {
13972 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13973 relative. Convert the relative address to an absolute address. */
13974 if (flag_pic)
13975 {
13976 rtx op0, op1;
13977 enum rtx_code code;
13978
13979 if (TARGET_64BIT)
13980 {
13981 code = PLUS;
13982 op0 = operands[0];
13983 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13984 }
13985 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13986 {
13987 code = PLUS;
13988 op0 = operands[0];
13989 op1 = pic_offset_table_rtx;
13990 }
13991 else
13992 {
13993 code = MINUS;
13994 op0 = pic_offset_table_rtx;
13995 op1 = operands[0];
13996 }
13997
13998 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13999 OPTAB_DIRECT);
14000 }
14001 })
14002
14003 (define_insn "*tablejump_1"
14004 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14005 (use (label_ref (match_operand 1 "" "")))]
14006 "!TARGET_64BIT"
14007 "jmp\t%A0"
14008 [(set_attr "type" "ibr")
14009 (set_attr "length_immediate" "0")])
14010
14011 (define_insn "*tablejump_1_rtx64"
14012 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14013 (use (label_ref (match_operand 1 "" "")))]
14014 "TARGET_64BIT"
14015 "jmp\t%A0"
14016 [(set_attr "type" "ibr")
14017 (set_attr "length_immediate" "0")])
14018 \f
14019 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14020
14021 (define_peephole2
14022 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14023 (set (match_operand:QI 1 "register_operand" "")
14024 (match_operator:QI 2 "ix86_comparison_operator"
14025 [(reg FLAGS_REG) (const_int 0)]))
14026 (set (match_operand 3 "q_regs_operand" "")
14027 (zero_extend (match_dup 1)))]
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
14040 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14041
14042 (define_peephole2
14043 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14044 (set (match_operand:QI 1 "register_operand" "")
14045 (match_operator:QI 2 "ix86_comparison_operator"
14046 [(reg FLAGS_REG) (const_int 0)]))
14047 (parallel [(set (match_operand 3 "q_regs_operand" "")
14048 (zero_extend (match_dup 1)))
14049 (clobber (reg:CC FLAGS_REG))])]
14050 "(peep2_reg_dead_p (3, operands[1])
14051 || operands_match_p (operands[1], operands[3]))
14052 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14053 [(set (match_dup 4) (match_dup 0))
14054 (set (strict_low_part (match_dup 5))
14055 (match_dup 2))]
14056 {
14057 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14058 operands[5] = gen_lowpart (QImode, operands[3]);
14059 ix86_expand_clear (operands[3]);
14060 })
14061 \f
14062 ;; Call instructions.
14063
14064 ;; The predicates normally associated with named expanders are not properly
14065 ;; checked for calls. This is a bug in the generic code, but it isn't that
14066 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14067
14068 ;; Call subroutine returning no value.
14069
14070 (define_expand "call_pop"
14071 [(parallel [(call (match_operand:QI 0 "" "")
14072 (match_operand:SI 1 "" ""))
14073 (set (reg:SI SP_REG)
14074 (plus:SI (reg:SI SP_REG)
14075 (match_operand:SI 3 "" "")))])]
14076 "!TARGET_64BIT"
14077 {
14078 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14079 DONE;
14080 })
14081
14082 (define_insn "*call_pop_0"
14083 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14084 (match_operand:SI 1 "" ""))
14085 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14086 (match_operand:SI 2 "immediate_operand" "")))]
14087 "!TARGET_64BIT"
14088 {
14089 if (SIBLING_CALL_P (insn))
14090 return "jmp\t%P0";
14091 else
14092 return "call\t%P0";
14093 }
14094 [(set_attr "type" "call")])
14095
14096 (define_insn "*call_pop_1"
14097 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14098 (match_operand:SI 1 "" ""))
14099 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14100 (match_operand:SI 2 "immediate_operand" "i")))]
14101 "!TARGET_64BIT"
14102 {
14103 if (constant_call_address_operand (operands[0], Pmode))
14104 {
14105 if (SIBLING_CALL_P (insn))
14106 return "jmp\t%P0";
14107 else
14108 return "call\t%P0";
14109 }
14110 if (SIBLING_CALL_P (insn))
14111 return "jmp\t%A0";
14112 else
14113 return "call\t%A0";
14114 }
14115 [(set_attr "type" "call")])
14116
14117 (define_expand "call"
14118 [(call (match_operand:QI 0 "" "")
14119 (match_operand 1 "" ""))
14120 (use (match_operand 2 "" ""))]
14121 ""
14122 {
14123 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14124 DONE;
14125 })
14126
14127 (define_expand "sibcall"
14128 [(call (match_operand:QI 0 "" "")
14129 (match_operand 1 "" ""))
14130 (use (match_operand 2 "" ""))]
14131 ""
14132 {
14133 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14134 DONE;
14135 })
14136
14137 (define_insn "*call_0"
14138 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14139 (match_operand 1 "" ""))]
14140 ""
14141 {
14142 if (SIBLING_CALL_P (insn))
14143 return "jmp\t%P0";
14144 else
14145 return "call\t%P0";
14146 }
14147 [(set_attr "type" "call")])
14148
14149 (define_insn "*call_1"
14150 [(call (mem:QI (match_operand:SI 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"
14161 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14162 (match_operand 1 "" ""))]
14163 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14164 {
14165 if (constant_call_address_operand (operands[0], Pmode))
14166 return "jmp\t%P0";
14167 return "jmp\t%A0";
14168 }
14169 [(set_attr "type" "call")])
14170
14171 (define_insn "*call_1_rex64"
14172 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14173 (match_operand 1 "" ""))]
14174 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14175 {
14176 if (constant_call_address_operand (operands[0], Pmode))
14177 return "call\t%P0";
14178 return "call\t%A0";
14179 }
14180 [(set_attr "type" "call")])
14181
14182 (define_insn "*sibcall_1_rex64"
14183 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14184 (match_operand 1 "" ""))]
14185 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14186 "jmp\t%P0"
14187 [(set_attr "type" "call")])
14188
14189 (define_insn "*sibcall_1_rex64_v"
14190 [(call (mem:QI (reg:DI R11_REG))
14191 (match_operand 0 "" ""))]
14192 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14193 "jmp\t*%%r11"
14194 [(set_attr "type" "call")])
14195
14196
14197 ;; Call subroutine, returning value in operand 0
14198
14199 (define_expand "call_value_pop"
14200 [(parallel [(set (match_operand 0 "" "")
14201 (call (match_operand:QI 1 "" "")
14202 (match_operand:SI 2 "" "")))
14203 (set (reg:SI SP_REG)
14204 (plus:SI (reg:SI SP_REG)
14205 (match_operand:SI 4 "" "")))])]
14206 "!TARGET_64BIT"
14207 {
14208 ix86_expand_call (operands[0], operands[1], operands[2],
14209 operands[3], operands[4], 0);
14210 DONE;
14211 })
14212
14213 (define_expand "call_value"
14214 [(set (match_operand 0 "" "")
14215 (call (match_operand:QI 1 "" "")
14216 (match_operand:SI 2 "" "")))
14217 (use (match_operand:SI 3 "" ""))]
14218 ;; Operand 2 not used on the i386.
14219 ""
14220 {
14221 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14222 DONE;
14223 })
14224
14225 (define_expand "sibcall_value"
14226 [(set (match_operand 0 "" "")
14227 (call (match_operand:QI 1 "" "")
14228 (match_operand:SI 2 "" "")))
14229 (use (match_operand:SI 3 "" ""))]
14230 ;; Operand 2 not used on the i386.
14231 ""
14232 {
14233 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14234 DONE;
14235 })
14236
14237 ;; Call subroutine returning any type.
14238
14239 (define_expand "untyped_call"
14240 [(parallel [(call (match_operand 0 "" "")
14241 (const_int 0))
14242 (match_operand 1 "" "")
14243 (match_operand 2 "" "")])]
14244 ""
14245 {
14246 int i;
14247
14248 /* In order to give reg-stack an easier job in validating two
14249 coprocessor registers as containing a possible return value,
14250 simply pretend the untyped call returns a complex long double
14251 value. */
14252
14253 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14254 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14255 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14256 NULL, 0);
14257
14258 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14259 {
14260 rtx set = XVECEXP (operands[2], 0, i);
14261 emit_move_insn (SET_DEST (set), SET_SRC (set));
14262 }
14263
14264 /* The optimizer does not know that the call sets the function value
14265 registers we stored in the result block. We avoid problems by
14266 claiming that all hard registers are used and clobbered at this
14267 point. */
14268 emit_insn (gen_blockage (const0_rtx));
14269
14270 DONE;
14271 })
14272 \f
14273 ;; Prologue and epilogue instructions
14274
14275 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14276 ;; all of memory. This blocks insns from being moved across this point.
14277
14278 (define_insn "blockage"
14279 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14280 ""
14281 ""
14282 [(set_attr "length" "0")])
14283
14284 ;; Insn emitted into the body of a function to return from a function.
14285 ;; This is only done if the function's epilogue is known to be simple.
14286 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14287
14288 (define_expand "return"
14289 [(return)]
14290 "ix86_can_use_return_insn_p ()"
14291 {
14292 if (current_function_pops_args)
14293 {
14294 rtx popc = GEN_INT (current_function_pops_args);
14295 emit_jump_insn (gen_return_pop_internal (popc));
14296 DONE;
14297 }
14298 })
14299
14300 (define_insn "return_internal"
14301 [(return)]
14302 "reload_completed"
14303 "ret"
14304 [(set_attr "length" "1")
14305 (set_attr "length_immediate" "0")
14306 (set_attr "modrm" "0")])
14307
14308 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14309 ;; instruction Athlon and K8 have.
14310
14311 (define_insn "return_internal_long"
14312 [(return)
14313 (unspec [(const_int 0)] UNSPEC_REP)]
14314 "reload_completed"
14315 "rep {;} ret"
14316 [(set_attr "length" "1")
14317 (set_attr "length_immediate" "0")
14318 (set_attr "prefix_rep" "1")
14319 (set_attr "modrm" "0")])
14320
14321 (define_insn "return_pop_internal"
14322 [(return)
14323 (use (match_operand:SI 0 "const_int_operand" ""))]
14324 "reload_completed"
14325 "ret\t%0"
14326 [(set_attr "length" "3")
14327 (set_attr "length_immediate" "2")
14328 (set_attr "modrm" "0")])
14329
14330 (define_insn "return_indirect_internal"
14331 [(return)
14332 (use (match_operand:SI 0 "register_operand" "r"))]
14333 "reload_completed"
14334 "jmp\t%A0"
14335 [(set_attr "type" "ibr")
14336 (set_attr "length_immediate" "0")])
14337
14338 (define_insn "nop"
14339 [(const_int 0)]
14340 ""
14341 "nop"
14342 [(set_attr "length" "1")
14343 (set_attr "length_immediate" "0")
14344 (set_attr "modrm" "0")])
14345
14346 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14347 ;; branch prediction penalty for the third jump in a 16-byte
14348 ;; block on K8.
14349
14350 (define_insn "align"
14351 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14352 ""
14353 {
14354 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14355 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14356 #else
14357 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14358 The align insn is used to avoid 3 jump instructions in the row to improve
14359 branch prediction and the benefits hardly outweigh the cost of extra 8
14360 nops on the average inserted by full alignment pseudo operation. */
14361 #endif
14362 return "";
14363 }
14364 [(set_attr "length" "16")])
14365
14366 (define_expand "prologue"
14367 [(const_int 1)]
14368 ""
14369 "ix86_expand_prologue (); DONE;")
14370
14371 (define_insn "set_got"
14372 [(set (match_operand:SI 0 "register_operand" "=r")
14373 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14374 (clobber (reg:CC FLAGS_REG))]
14375 "!TARGET_64BIT"
14376 { return output_set_got (operands[0], NULL_RTX); }
14377 [(set_attr "type" "multi")
14378 (set_attr "length" "12")])
14379
14380 (define_insn "set_got_labelled"
14381 [(set (match_operand:SI 0 "register_operand" "=r")
14382 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14383 UNSPEC_SET_GOT))
14384 (clobber (reg:CC FLAGS_REG))]
14385 "!TARGET_64BIT"
14386 { return output_set_got (operands[0], operands[1]); }
14387 [(set_attr "type" "multi")
14388 (set_attr "length" "12")])
14389
14390 (define_insn "set_got_rex64"
14391 [(set (match_operand:DI 0 "register_operand" "=r")
14392 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14393 "TARGET_64BIT"
14394 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14395 [(set_attr "type" "lea")
14396 (set_attr "length" "6")])
14397
14398 (define_expand "epilogue"
14399 [(const_int 1)]
14400 ""
14401 "ix86_expand_epilogue (1); DONE;")
14402
14403 (define_expand "sibcall_epilogue"
14404 [(const_int 1)]
14405 ""
14406 "ix86_expand_epilogue (0); DONE;")
14407
14408 (define_expand "eh_return"
14409 [(use (match_operand 0 "register_operand" ""))]
14410 ""
14411 {
14412 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14413
14414 /* Tricky bit: we write the address of the handler to which we will
14415 be returning into someone else's stack frame, one word below the
14416 stack address we wish to restore. */
14417 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14418 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14419 tmp = gen_rtx_MEM (Pmode, tmp);
14420 emit_move_insn (tmp, ra);
14421
14422 if (Pmode == SImode)
14423 emit_jump_insn (gen_eh_return_si (sa));
14424 else
14425 emit_jump_insn (gen_eh_return_di (sa));
14426 emit_barrier ();
14427 DONE;
14428 })
14429
14430 (define_insn_and_split "eh_return_si"
14431 [(set (pc)
14432 (unspec [(match_operand:SI 0 "register_operand" "c")]
14433 UNSPEC_EH_RETURN))]
14434 "!TARGET_64BIT"
14435 "#"
14436 "reload_completed"
14437 [(const_int 1)]
14438 "ix86_expand_epilogue (2); DONE;")
14439
14440 (define_insn_and_split "eh_return_di"
14441 [(set (pc)
14442 (unspec [(match_operand:DI 0 "register_operand" "c")]
14443 UNSPEC_EH_RETURN))]
14444 "TARGET_64BIT"
14445 "#"
14446 "reload_completed"
14447 [(const_int 1)]
14448 "ix86_expand_epilogue (2); DONE;")
14449
14450 (define_insn "leave"
14451 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14452 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14453 (clobber (mem:BLK (scratch)))]
14454 "!TARGET_64BIT"
14455 "leave"
14456 [(set_attr "type" "leave")])
14457
14458 (define_insn "leave_rex64"
14459 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14460 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14461 (clobber (mem:BLK (scratch)))]
14462 "TARGET_64BIT"
14463 "leave"
14464 [(set_attr "type" "leave")])
14465 \f
14466 (define_expand "ffssi2"
14467 [(parallel
14468 [(set (match_operand:SI 0 "register_operand" "")
14469 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14470 (clobber (match_scratch:SI 2 ""))
14471 (clobber (reg:CC FLAGS_REG))])]
14472 ""
14473 "")
14474
14475 (define_insn_and_split "*ffs_cmove"
14476 [(set (match_operand:SI 0 "register_operand" "=r")
14477 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14478 (clobber (match_scratch:SI 2 "=&r"))
14479 (clobber (reg:CC FLAGS_REG))]
14480 "TARGET_CMOVE"
14481 "#"
14482 "&& reload_completed"
14483 [(set (match_dup 2) (const_int -1))
14484 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14485 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14486 (set (match_dup 0) (if_then_else:SI
14487 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14488 (match_dup 2)
14489 (match_dup 0)))
14490 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14491 (clobber (reg:CC FLAGS_REG))])]
14492 "")
14493
14494 (define_insn_and_split "*ffs_no_cmove"
14495 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14496 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14497 (clobber (match_scratch:SI 2 "=&q"))
14498 (clobber (reg:CC FLAGS_REG))]
14499 ""
14500 "#"
14501 "reload_completed"
14502 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14503 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14504 (set (strict_low_part (match_dup 3))
14505 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14506 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14507 (clobber (reg:CC FLAGS_REG))])
14508 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14509 (clobber (reg:CC FLAGS_REG))])
14510 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14511 (clobber (reg:CC FLAGS_REG))])]
14512 {
14513 operands[3] = gen_lowpart (QImode, operands[2]);
14514 ix86_expand_clear (operands[2]);
14515 })
14516
14517 (define_insn "*ffssi_1"
14518 [(set (reg:CCZ FLAGS_REG)
14519 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14520 (const_int 0)))
14521 (set (match_operand:SI 0 "register_operand" "=r")
14522 (ctz:SI (match_dup 1)))]
14523 ""
14524 "bsf{l}\t{%1, %0|%0, %1}"
14525 [(set_attr "prefix_0f" "1")])
14526
14527 (define_expand "ffsdi2"
14528 [(parallel
14529 [(set (match_operand:DI 0 "register_operand" "")
14530 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14531 (clobber (match_scratch:DI 2 ""))
14532 (clobber (reg:CC FLAGS_REG))])]
14533 "TARGET_64BIT && TARGET_CMOVE"
14534 "")
14535
14536 (define_insn_and_split "*ffs_rex64"
14537 [(set (match_operand:DI 0 "register_operand" "=r")
14538 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14539 (clobber (match_scratch:DI 2 "=&r"))
14540 (clobber (reg:CC FLAGS_REG))]
14541 "TARGET_64BIT && TARGET_CMOVE"
14542 "#"
14543 "&& reload_completed"
14544 [(set (match_dup 2) (const_int -1))
14545 (parallel [(set (reg:CCZ FLAGS_REG)
14546 (compare:CCZ (match_dup 1) (const_int 0)))
14547 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14548 (set (match_dup 0) (if_then_else:DI
14549 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14550 (match_dup 2)
14551 (match_dup 0)))
14552 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14553 (clobber (reg:CC FLAGS_REG))])]
14554 "")
14555
14556 (define_insn "*ffsdi_1"
14557 [(set (reg:CCZ FLAGS_REG)
14558 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14559 (const_int 0)))
14560 (set (match_operand:DI 0 "register_operand" "=r")
14561 (ctz:DI (match_dup 1)))]
14562 "TARGET_64BIT"
14563 "bsf{q}\t{%1, %0|%0, %1}"
14564 [(set_attr "prefix_0f" "1")])
14565
14566 (define_insn "ctzsi2"
14567 [(set (match_operand:SI 0 "register_operand" "=r")
14568 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14569 (clobber (reg:CC FLAGS_REG))]
14570 ""
14571 "bsf{l}\t{%1, %0|%0, %1}"
14572 [(set_attr "prefix_0f" "1")])
14573
14574 (define_insn "ctzdi2"
14575 [(set (match_operand:DI 0 "register_operand" "=r")
14576 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14577 (clobber (reg:CC FLAGS_REG))]
14578 "TARGET_64BIT"
14579 "bsf{q}\t{%1, %0|%0, %1}"
14580 [(set_attr "prefix_0f" "1")])
14581
14582 (define_expand "clzsi2"
14583 [(parallel
14584 [(set (match_operand:SI 0 "register_operand" "")
14585 (minus:SI (const_int 31)
14586 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14587 (clobber (reg:CC FLAGS_REG))])
14588 (parallel
14589 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14590 (clobber (reg:CC FLAGS_REG))])]
14591 ""
14592 "")
14593
14594 (define_insn "*bsr"
14595 [(set (match_operand:SI 0 "register_operand" "=r")
14596 (minus:SI (const_int 31)
14597 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14598 (clobber (reg:CC FLAGS_REG))]
14599 ""
14600 "bsr{l}\t{%1, %0|%0, %1}"
14601 [(set_attr "prefix_0f" "1")])
14602
14603 (define_insn "bswapsi2"
14604 [(set (match_operand:SI 0 "register_operand" "=r")
14605 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14606 (clobber (reg:CC FLAGS_REG))]
14607 "TARGET_BSWAP"
14608 "bswap\t%k0"
14609 [(set_attr "prefix_0f" "1")
14610 (set_attr "length" "2")])
14611
14612 (define_insn "bswapdi2"
14613 [(set (match_operand:DI 0 "register_operand" "=r")
14614 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14615 (clobber (reg:CC FLAGS_REG))]
14616 "TARGET_64BIT && TARGET_BSWAP"
14617 "bswap\t%0"
14618 [(set_attr "prefix_0f" "1")
14619 (set_attr "length" "3")])
14620
14621 (define_expand "clzdi2"
14622 [(parallel
14623 [(set (match_operand:DI 0 "register_operand" "")
14624 (minus:DI (const_int 63)
14625 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14626 (clobber (reg:CC FLAGS_REG))])
14627 (parallel
14628 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14629 (clobber (reg:CC FLAGS_REG))])]
14630 "TARGET_64BIT"
14631 "")
14632
14633 (define_insn "*bsr_rex64"
14634 [(set (match_operand:DI 0 "register_operand" "=r")
14635 (minus:DI (const_int 63)
14636 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14637 (clobber (reg:CC FLAGS_REG))]
14638 "TARGET_64BIT"
14639 "bsr{q}\t{%1, %0|%0, %1}"
14640 [(set_attr "prefix_0f" "1")])
14641 \f
14642 ;; Thread-local storage patterns for ELF.
14643 ;;
14644 ;; Note that these code sequences must appear exactly as shown
14645 ;; in order to allow linker relaxation.
14646
14647 (define_insn "*tls_global_dynamic_32_gnu"
14648 [(set (match_operand:SI 0 "register_operand" "=a")
14649 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14650 (match_operand:SI 2 "tls_symbolic_operand" "")
14651 (match_operand:SI 3 "call_insn_operand" "")]
14652 UNSPEC_TLS_GD))
14653 (clobber (match_scratch:SI 4 "=d"))
14654 (clobber (match_scratch:SI 5 "=c"))
14655 (clobber (reg:CC FLAGS_REG))]
14656 "!TARGET_64BIT && TARGET_GNU_TLS"
14657 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14658 [(set_attr "type" "multi")
14659 (set_attr "length" "12")])
14660
14661 (define_insn "*tls_global_dynamic_32_sun"
14662 [(set (match_operand:SI 0 "register_operand" "=a")
14663 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14664 (match_operand:SI 2 "tls_symbolic_operand" "")
14665 (match_operand:SI 3 "call_insn_operand" "")]
14666 UNSPEC_TLS_GD))
14667 (clobber (match_scratch:SI 4 "=d"))
14668 (clobber (match_scratch:SI 5 "=c"))
14669 (clobber (reg:CC FLAGS_REG))]
14670 "!TARGET_64BIT && TARGET_SUN_TLS"
14671 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14672 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14673 [(set_attr "type" "multi")
14674 (set_attr "length" "14")])
14675
14676 (define_expand "tls_global_dynamic_32"
14677 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14678 (unspec:SI
14679 [(match_dup 2)
14680 (match_operand:SI 1 "tls_symbolic_operand" "")
14681 (match_dup 3)]
14682 UNSPEC_TLS_GD))
14683 (clobber (match_scratch:SI 4 ""))
14684 (clobber (match_scratch:SI 5 ""))
14685 (clobber (reg:CC FLAGS_REG))])]
14686 ""
14687 {
14688 if (flag_pic)
14689 operands[2] = pic_offset_table_rtx;
14690 else
14691 {
14692 operands[2] = gen_reg_rtx (Pmode);
14693 emit_insn (gen_set_got (operands[2]));
14694 }
14695 if (TARGET_GNU2_TLS)
14696 {
14697 emit_insn (gen_tls_dynamic_gnu2_32
14698 (operands[0], operands[1], operands[2]));
14699 DONE;
14700 }
14701 operands[3] = ix86_tls_get_addr ();
14702 })
14703
14704 (define_insn "*tls_global_dynamic_64"
14705 [(set (match_operand:DI 0 "register_operand" "=a")
14706 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14707 (match_operand:DI 3 "" "")))
14708 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14709 UNSPEC_TLS_GD)]
14710 "TARGET_64BIT"
14711 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14712 [(set_attr "type" "multi")
14713 (set_attr "length" "16")])
14714
14715 (define_expand "tls_global_dynamic_64"
14716 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14717 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14718 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14719 UNSPEC_TLS_GD)])]
14720 ""
14721 {
14722 if (TARGET_GNU2_TLS)
14723 {
14724 emit_insn (gen_tls_dynamic_gnu2_64
14725 (operands[0], operands[1]));
14726 DONE;
14727 }
14728 operands[2] = ix86_tls_get_addr ();
14729 })
14730
14731 (define_insn "*tls_local_dynamic_base_32_gnu"
14732 [(set (match_operand:SI 0 "register_operand" "=a")
14733 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14734 (match_operand:SI 2 "call_insn_operand" "")]
14735 UNSPEC_TLS_LD_BASE))
14736 (clobber (match_scratch:SI 3 "=d"))
14737 (clobber (match_scratch:SI 4 "=c"))
14738 (clobber (reg:CC FLAGS_REG))]
14739 "!TARGET_64BIT && TARGET_GNU_TLS"
14740 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14741 [(set_attr "type" "multi")
14742 (set_attr "length" "11")])
14743
14744 (define_insn "*tls_local_dynamic_base_32_sun"
14745 [(set (match_operand:SI 0 "register_operand" "=a")
14746 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14747 (match_operand:SI 2 "call_insn_operand" "")]
14748 UNSPEC_TLS_LD_BASE))
14749 (clobber (match_scratch:SI 3 "=d"))
14750 (clobber (match_scratch:SI 4 "=c"))
14751 (clobber (reg:CC FLAGS_REG))]
14752 "!TARGET_64BIT && TARGET_SUN_TLS"
14753 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14754 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14755 [(set_attr "type" "multi")
14756 (set_attr "length" "13")])
14757
14758 (define_expand "tls_local_dynamic_base_32"
14759 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14760 (unspec:SI [(match_dup 1) (match_dup 2)]
14761 UNSPEC_TLS_LD_BASE))
14762 (clobber (match_scratch:SI 3 ""))
14763 (clobber (match_scratch:SI 4 ""))
14764 (clobber (reg:CC FLAGS_REG))])]
14765 ""
14766 {
14767 if (flag_pic)
14768 operands[1] = pic_offset_table_rtx;
14769 else
14770 {
14771 operands[1] = gen_reg_rtx (Pmode);
14772 emit_insn (gen_set_got (operands[1]));
14773 }
14774 if (TARGET_GNU2_TLS)
14775 {
14776 emit_insn (gen_tls_dynamic_gnu2_32
14777 (operands[0], ix86_tls_module_base (), operands[1]));
14778 DONE;
14779 }
14780 operands[2] = ix86_tls_get_addr ();
14781 })
14782
14783 (define_insn "*tls_local_dynamic_base_64"
14784 [(set (match_operand:DI 0 "register_operand" "=a")
14785 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14786 (match_operand:DI 2 "" "")))
14787 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14788 "TARGET_64BIT"
14789 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14790 [(set_attr "type" "multi")
14791 (set_attr "length" "12")])
14792
14793 (define_expand "tls_local_dynamic_base_64"
14794 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14795 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14796 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14797 ""
14798 {
14799 if (TARGET_GNU2_TLS)
14800 {
14801 emit_insn (gen_tls_dynamic_gnu2_64
14802 (operands[0], ix86_tls_module_base ()));
14803 DONE;
14804 }
14805 operands[1] = ix86_tls_get_addr ();
14806 })
14807
14808 ;; Local dynamic of a single variable is a lose. Show combine how
14809 ;; to convert that back to global dynamic.
14810
14811 (define_insn_and_split "*tls_local_dynamic_32_once"
14812 [(set (match_operand:SI 0 "register_operand" "=a")
14813 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14814 (match_operand:SI 2 "call_insn_operand" "")]
14815 UNSPEC_TLS_LD_BASE)
14816 (const:SI (unspec:SI
14817 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14818 UNSPEC_DTPOFF))))
14819 (clobber (match_scratch:SI 4 "=d"))
14820 (clobber (match_scratch:SI 5 "=c"))
14821 (clobber (reg:CC FLAGS_REG))]
14822 ""
14823 "#"
14824 ""
14825 [(parallel [(set (match_dup 0)
14826 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14827 UNSPEC_TLS_GD))
14828 (clobber (match_dup 4))
14829 (clobber (match_dup 5))
14830 (clobber (reg:CC FLAGS_REG))])]
14831 "")
14832
14833 ;; Load and add the thread base pointer from %gs:0.
14834
14835 (define_insn "*load_tp_si"
14836 [(set (match_operand:SI 0 "register_operand" "=r")
14837 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14838 "!TARGET_64BIT"
14839 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14840 [(set_attr "type" "imov")
14841 (set_attr "modrm" "0")
14842 (set_attr "length" "7")
14843 (set_attr "memory" "load")
14844 (set_attr "imm_disp" "false")])
14845
14846 (define_insn "*add_tp_si"
14847 [(set (match_operand:SI 0 "register_operand" "=r")
14848 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14849 (match_operand:SI 1 "register_operand" "0")))
14850 (clobber (reg:CC FLAGS_REG))]
14851 "!TARGET_64BIT"
14852 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14853 [(set_attr "type" "alu")
14854 (set_attr "modrm" "0")
14855 (set_attr "length" "7")
14856 (set_attr "memory" "load")
14857 (set_attr "imm_disp" "false")])
14858
14859 (define_insn "*load_tp_di"
14860 [(set (match_operand:DI 0 "register_operand" "=r")
14861 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14862 "TARGET_64BIT"
14863 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14864 [(set_attr "type" "imov")
14865 (set_attr "modrm" "0")
14866 (set_attr "length" "7")
14867 (set_attr "memory" "load")
14868 (set_attr "imm_disp" "false")])
14869
14870 (define_insn "*add_tp_di"
14871 [(set (match_operand:DI 0 "register_operand" "=r")
14872 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14873 (match_operand:DI 1 "register_operand" "0")))
14874 (clobber (reg:CC FLAGS_REG))]
14875 "TARGET_64BIT"
14876 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14877 [(set_attr "type" "alu")
14878 (set_attr "modrm" "0")
14879 (set_attr "length" "7")
14880 (set_attr "memory" "load")
14881 (set_attr "imm_disp" "false")])
14882
14883 ;; GNU2 TLS patterns can be split.
14884
14885 (define_expand "tls_dynamic_gnu2_32"
14886 [(set (match_dup 3)
14887 (plus:SI (match_operand:SI 2 "register_operand" "")
14888 (const:SI
14889 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14890 UNSPEC_TLSDESC))))
14891 (parallel
14892 [(set (match_operand:SI 0 "register_operand" "")
14893 (unspec:SI [(match_dup 1) (match_dup 3)
14894 (match_dup 2) (reg:SI SP_REG)]
14895 UNSPEC_TLSDESC))
14896 (clobber (reg:CC FLAGS_REG))])]
14897 "!TARGET_64BIT && TARGET_GNU2_TLS"
14898 {
14899 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14900 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14901 })
14902
14903 (define_insn "*tls_dynamic_lea_32"
14904 [(set (match_operand:SI 0 "register_operand" "=r")
14905 (plus:SI (match_operand:SI 1 "register_operand" "b")
14906 (const:SI
14907 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14908 UNSPEC_TLSDESC))))]
14909 "!TARGET_64BIT && TARGET_GNU2_TLS"
14910 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14911 [(set_attr "type" "lea")
14912 (set_attr "mode" "SI")
14913 (set_attr "length" "6")
14914 (set_attr "length_address" "4")])
14915
14916 (define_insn "*tls_dynamic_call_32"
14917 [(set (match_operand:SI 0 "register_operand" "=a")
14918 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14919 (match_operand:SI 2 "register_operand" "0")
14920 ;; we have to make sure %ebx still points to the GOT
14921 (match_operand:SI 3 "register_operand" "b")
14922 (reg:SI SP_REG)]
14923 UNSPEC_TLSDESC))
14924 (clobber (reg:CC FLAGS_REG))]
14925 "!TARGET_64BIT && TARGET_GNU2_TLS"
14926 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14927 [(set_attr "type" "call")
14928 (set_attr "length" "2")
14929 (set_attr "length_address" "0")])
14930
14931 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14932 [(set (match_operand:SI 0 "register_operand" "=&a")
14933 (plus:SI
14934 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14935 (match_operand:SI 4 "" "")
14936 (match_operand:SI 2 "register_operand" "b")
14937 (reg:SI SP_REG)]
14938 UNSPEC_TLSDESC)
14939 (const:SI (unspec:SI
14940 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14941 UNSPEC_DTPOFF))))
14942 (clobber (reg:CC FLAGS_REG))]
14943 "!TARGET_64BIT && TARGET_GNU2_TLS"
14944 "#"
14945 ""
14946 [(set (match_dup 0) (match_dup 5))]
14947 {
14948 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14949 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14950 })
14951
14952 (define_expand "tls_dynamic_gnu2_64"
14953 [(set (match_dup 2)
14954 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14955 UNSPEC_TLSDESC))
14956 (parallel
14957 [(set (match_operand:DI 0 "register_operand" "")
14958 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14959 UNSPEC_TLSDESC))
14960 (clobber (reg:CC FLAGS_REG))])]
14961 "TARGET_64BIT && TARGET_GNU2_TLS"
14962 {
14963 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14964 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14965 })
14966
14967 (define_insn "*tls_dynamic_lea_64"
14968 [(set (match_operand:DI 0 "register_operand" "=r")
14969 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14970 UNSPEC_TLSDESC))]
14971 "TARGET_64BIT && TARGET_GNU2_TLS"
14972 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14973 [(set_attr "type" "lea")
14974 (set_attr "mode" "DI")
14975 (set_attr "length" "7")
14976 (set_attr "length_address" "4")])
14977
14978 (define_insn "*tls_dynamic_call_64"
14979 [(set (match_operand:DI 0 "register_operand" "=a")
14980 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14981 (match_operand:DI 2 "register_operand" "0")
14982 (reg:DI SP_REG)]
14983 UNSPEC_TLSDESC))
14984 (clobber (reg:CC FLAGS_REG))]
14985 "TARGET_64BIT && TARGET_GNU2_TLS"
14986 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14987 [(set_attr "type" "call")
14988 (set_attr "length" "2")
14989 (set_attr "length_address" "0")])
14990
14991 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14992 [(set (match_operand:DI 0 "register_operand" "=&a")
14993 (plus:DI
14994 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14995 (match_operand:DI 3 "" "")
14996 (reg:DI SP_REG)]
14997 UNSPEC_TLSDESC)
14998 (const:DI (unspec:DI
14999 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15000 UNSPEC_DTPOFF))))
15001 (clobber (reg:CC FLAGS_REG))]
15002 "TARGET_64BIT && TARGET_GNU2_TLS"
15003 "#"
15004 ""
15005 [(set (match_dup 0) (match_dup 4))]
15006 {
15007 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15008 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15009 })
15010
15011 ;;
15012 \f
15013 ;; These patterns match the binary 387 instructions for addM3, subM3,
15014 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15015 ;; SFmode. The first is the normal insn, the second the same insn but
15016 ;; with one operand a conversion, and the third the same insn but with
15017 ;; the other operand a conversion. The conversion may be SFmode or
15018 ;; SImode if the target mode DFmode, but only SImode if the target mode
15019 ;; is SFmode.
15020
15021 ;; Gcc is slightly more smart about handling normal two address instructions
15022 ;; so use special patterns for add and mull.
15023
15024 (define_insn "*fop_sf_comm_mixed"
15025 [(set (match_operand:SF 0 "register_operand" "=f,x")
15026 (match_operator:SF 3 "binary_fp_operator"
15027 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15028 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15029 "TARGET_MIX_SSE_I387
15030 && COMMUTATIVE_ARITH_P (operands[3])
15031 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15032 "* return output_387_binary_op (insn, operands);"
15033 [(set (attr "type")
15034 (if_then_else (eq_attr "alternative" "1")
15035 (if_then_else (match_operand:SF 3 "mult_operator" "")
15036 (const_string "ssemul")
15037 (const_string "sseadd"))
15038 (if_then_else (match_operand:SF 3 "mult_operator" "")
15039 (const_string "fmul")
15040 (const_string "fop"))))
15041 (set_attr "mode" "SF")])
15042
15043 (define_insn "*fop_sf_comm_sse"
15044 [(set (match_operand:SF 0 "register_operand" "=x")
15045 (match_operator:SF 3 "binary_fp_operator"
15046 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15047 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15048 "TARGET_SSE_MATH
15049 && COMMUTATIVE_ARITH_P (operands[3])
15050 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15051 "* return output_387_binary_op (insn, operands);"
15052 [(set (attr "type")
15053 (if_then_else (match_operand:SF 3 "mult_operator" "")
15054 (const_string "ssemul")
15055 (const_string "sseadd")))
15056 (set_attr "mode" "SF")])
15057
15058 (define_insn "*fop_sf_comm_i387"
15059 [(set (match_operand:SF 0 "register_operand" "=f")
15060 (match_operator:SF 3 "binary_fp_operator"
15061 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15062 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15063 "TARGET_80387
15064 && COMMUTATIVE_ARITH_P (operands[3])
15065 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15066 "* return output_387_binary_op (insn, operands);"
15067 [(set (attr "type")
15068 (if_then_else (match_operand:SF 3 "mult_operator" "")
15069 (const_string "fmul")
15070 (const_string "fop")))
15071 (set_attr "mode" "SF")])
15072
15073 (define_insn "*fop_sf_1_mixed"
15074 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15075 (match_operator:SF 3 "binary_fp_operator"
15076 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15077 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15078 "TARGET_MIX_SSE_I387
15079 && !COMMUTATIVE_ARITH_P (operands[3])
15080 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15081 "* return output_387_binary_op (insn, operands);"
15082 [(set (attr "type")
15083 (cond [(and (eq_attr "alternative" "2")
15084 (match_operand:SF 3 "mult_operator" ""))
15085 (const_string "ssemul")
15086 (and (eq_attr "alternative" "2")
15087 (match_operand:SF 3 "div_operator" ""))
15088 (const_string "ssediv")
15089 (eq_attr "alternative" "2")
15090 (const_string "sseadd")
15091 (match_operand:SF 3 "mult_operator" "")
15092 (const_string "fmul")
15093 (match_operand:SF 3 "div_operator" "")
15094 (const_string "fdiv")
15095 ]
15096 (const_string "fop")))
15097 (set_attr "mode" "SF")])
15098
15099 (define_insn "*fop_sf_1_sse"
15100 [(set (match_operand:SF 0 "register_operand" "=x")
15101 (match_operator:SF 3 "binary_fp_operator"
15102 [(match_operand:SF 1 "register_operand" "0")
15103 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15104 "TARGET_SSE_MATH
15105 && !COMMUTATIVE_ARITH_P (operands[3])"
15106 "* return output_387_binary_op (insn, operands);"
15107 [(set (attr "type")
15108 (cond [(match_operand:SF 3 "mult_operator" "")
15109 (const_string "ssemul")
15110 (match_operand:SF 3 "div_operator" "")
15111 (const_string "ssediv")
15112 ]
15113 (const_string "sseadd")))
15114 (set_attr "mode" "SF")])
15115
15116 ;; This pattern is not fully shadowed by the pattern above.
15117 (define_insn "*fop_sf_1_i387"
15118 [(set (match_operand:SF 0 "register_operand" "=f,f")
15119 (match_operator:SF 3 "binary_fp_operator"
15120 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15121 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15122 "TARGET_80387 && !TARGET_SSE_MATH
15123 && !COMMUTATIVE_ARITH_P (operands[3])
15124 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15125 "* return output_387_binary_op (insn, operands);"
15126 [(set (attr "type")
15127 (cond [(match_operand:SF 3 "mult_operator" "")
15128 (const_string "fmul")
15129 (match_operand:SF 3 "div_operator" "")
15130 (const_string "fdiv")
15131 ]
15132 (const_string "fop")))
15133 (set_attr "mode" "SF")])
15134
15135 ;; ??? Add SSE splitters for these!
15136 (define_insn "*fop_sf_2<mode>_i387"
15137 [(set (match_operand:SF 0 "register_operand" "=f,f")
15138 (match_operator:SF 3 "binary_fp_operator"
15139 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15140 (match_operand:SF 2 "register_operand" "0,0")]))]
15141 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15142 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15143 [(set (attr "type")
15144 (cond [(match_operand:SF 3 "mult_operator" "")
15145 (const_string "fmul")
15146 (match_operand:SF 3 "div_operator" "")
15147 (const_string "fdiv")
15148 ]
15149 (const_string "fop")))
15150 (set_attr "fp_int_src" "true")
15151 (set_attr "mode" "<MODE>")])
15152
15153 (define_insn "*fop_sf_3<mode>_i387"
15154 [(set (match_operand:SF 0 "register_operand" "=f,f")
15155 (match_operator:SF 3 "binary_fp_operator"
15156 [(match_operand:SF 1 "register_operand" "0,0")
15157 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15158 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15159 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15160 [(set (attr "type")
15161 (cond [(match_operand:SF 3 "mult_operator" "")
15162 (const_string "fmul")
15163 (match_operand:SF 3 "div_operator" "")
15164 (const_string "fdiv")
15165 ]
15166 (const_string "fop")))
15167 (set_attr "fp_int_src" "true")
15168 (set_attr "mode" "<MODE>")])
15169
15170 (define_insn "*fop_df_comm_mixed"
15171 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15172 (match_operator:DF 3 "binary_fp_operator"
15173 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15174 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15175 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15176 && COMMUTATIVE_ARITH_P (operands[3])
15177 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15178 "* return output_387_binary_op (insn, operands);"
15179 [(set (attr "type")
15180 (if_then_else (eq_attr "alternative" "1")
15181 (if_then_else (match_operand:DF 3 "mult_operator" "")
15182 (const_string "ssemul")
15183 (const_string "sseadd"))
15184 (if_then_else (match_operand:DF 3 "mult_operator" "")
15185 (const_string "fmul")
15186 (const_string "fop"))))
15187 (set_attr "mode" "DF")])
15188
15189 (define_insn "*fop_df_comm_sse"
15190 [(set (match_operand:DF 0 "register_operand" "=Y")
15191 (match_operator:DF 3 "binary_fp_operator"
15192 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15193 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15194 "TARGET_SSE2 && TARGET_SSE_MATH
15195 && COMMUTATIVE_ARITH_P (operands[3])
15196 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15197 "* return output_387_binary_op (insn, operands);"
15198 [(set (attr "type")
15199 (if_then_else (match_operand:DF 3 "mult_operator" "")
15200 (const_string "ssemul")
15201 (const_string "sseadd")))
15202 (set_attr "mode" "DF")])
15203
15204 (define_insn "*fop_df_comm_i387"
15205 [(set (match_operand:DF 0 "register_operand" "=f")
15206 (match_operator:DF 3 "binary_fp_operator"
15207 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15208 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15209 "TARGET_80387
15210 && COMMUTATIVE_ARITH_P (operands[3])
15211 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15212 "* return output_387_binary_op (insn, operands);"
15213 [(set (attr "type")
15214 (if_then_else (match_operand:DF 3 "mult_operator" "")
15215 (const_string "fmul")
15216 (const_string "fop")))
15217 (set_attr "mode" "DF")])
15218
15219 (define_insn "*fop_df_1_mixed"
15220 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15221 (match_operator:DF 3 "binary_fp_operator"
15222 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15223 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15224 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15225 && !COMMUTATIVE_ARITH_P (operands[3])
15226 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15227 "* return output_387_binary_op (insn, operands);"
15228 [(set (attr "type")
15229 (cond [(and (eq_attr "alternative" "2")
15230 (match_operand:DF 3 "mult_operator" ""))
15231 (const_string "ssemul")
15232 (and (eq_attr "alternative" "2")
15233 (match_operand:DF 3 "div_operator" ""))
15234 (const_string "ssediv")
15235 (eq_attr "alternative" "2")
15236 (const_string "sseadd")
15237 (match_operand:DF 3 "mult_operator" "")
15238 (const_string "fmul")
15239 (match_operand:DF 3 "div_operator" "")
15240 (const_string "fdiv")
15241 ]
15242 (const_string "fop")))
15243 (set_attr "mode" "DF")])
15244
15245 (define_insn "*fop_df_1_sse"
15246 [(set (match_operand:DF 0 "register_operand" "=Y")
15247 (match_operator:DF 3 "binary_fp_operator"
15248 [(match_operand:DF 1 "register_operand" "0")
15249 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15250 "TARGET_SSE2 && TARGET_SSE_MATH
15251 && !COMMUTATIVE_ARITH_P (operands[3])"
15252 "* return output_387_binary_op (insn, operands);"
15253 [(set_attr "mode" "DF")
15254 (set (attr "type")
15255 (cond [(match_operand:DF 3 "mult_operator" "")
15256 (const_string "ssemul")
15257 (match_operand:DF 3 "div_operator" "")
15258 (const_string "ssediv")
15259 ]
15260 (const_string "sseadd")))])
15261
15262 ;; This pattern is not fully shadowed by the pattern above.
15263 (define_insn "*fop_df_1_i387"
15264 [(set (match_operand:DF 0 "register_operand" "=f,f")
15265 (match_operator:DF 3 "binary_fp_operator"
15266 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15267 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15268 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15269 && !COMMUTATIVE_ARITH_P (operands[3])
15270 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15271 "* return output_387_binary_op (insn, operands);"
15272 [(set (attr "type")
15273 (cond [(match_operand:DF 3 "mult_operator" "")
15274 (const_string "fmul")
15275 (match_operand:DF 3 "div_operator" "")
15276 (const_string "fdiv")
15277 ]
15278 (const_string "fop")))
15279 (set_attr "mode" "DF")])
15280
15281 ;; ??? Add SSE splitters for these!
15282 (define_insn "*fop_df_2<mode>_i387"
15283 [(set (match_operand:DF 0 "register_operand" "=f,f")
15284 (match_operator:DF 3 "binary_fp_operator"
15285 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15286 (match_operand:DF 2 "register_operand" "0,0")]))]
15287 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15288 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15289 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15290 [(set (attr "type")
15291 (cond [(match_operand:DF 3 "mult_operator" "")
15292 (const_string "fmul")
15293 (match_operand:DF 3 "div_operator" "")
15294 (const_string "fdiv")
15295 ]
15296 (const_string "fop")))
15297 (set_attr "fp_int_src" "true")
15298 (set_attr "mode" "<MODE>")])
15299
15300 (define_insn "*fop_df_3<mode>_i387"
15301 [(set (match_operand:DF 0 "register_operand" "=f,f")
15302 (match_operator:DF 3 "binary_fp_operator"
15303 [(match_operand:DF 1 "register_operand" "0,0")
15304 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15305 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15306 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15307 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15308 [(set (attr "type")
15309 (cond [(match_operand:DF 3 "mult_operator" "")
15310 (const_string "fmul")
15311 (match_operand:DF 3 "div_operator" "")
15312 (const_string "fdiv")
15313 ]
15314 (const_string "fop")))
15315 (set_attr "fp_int_src" "true")
15316 (set_attr "mode" "<MODE>")])
15317
15318 (define_insn "*fop_df_4_i387"
15319 [(set (match_operand:DF 0 "register_operand" "=f,f")
15320 (match_operator:DF 3 "binary_fp_operator"
15321 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15322 (match_operand:DF 2 "register_operand" "0,f")]))]
15323 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15324 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15325 "* return output_387_binary_op (insn, operands);"
15326 [(set (attr "type")
15327 (cond [(match_operand:DF 3 "mult_operator" "")
15328 (const_string "fmul")
15329 (match_operand:DF 3 "div_operator" "")
15330 (const_string "fdiv")
15331 ]
15332 (const_string "fop")))
15333 (set_attr "mode" "SF")])
15334
15335 (define_insn "*fop_df_5_i387"
15336 [(set (match_operand:DF 0 "register_operand" "=f,f")
15337 (match_operator:DF 3 "binary_fp_operator"
15338 [(match_operand:DF 1 "register_operand" "0,f")
15339 (float_extend:DF
15340 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15341 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15342 "* return output_387_binary_op (insn, operands);"
15343 [(set (attr "type")
15344 (cond [(match_operand:DF 3 "mult_operator" "")
15345 (const_string "fmul")
15346 (match_operand:DF 3 "div_operator" "")
15347 (const_string "fdiv")
15348 ]
15349 (const_string "fop")))
15350 (set_attr "mode" "SF")])
15351
15352 (define_insn "*fop_df_6_i387"
15353 [(set (match_operand:DF 0 "register_operand" "=f,f")
15354 (match_operator:DF 3 "binary_fp_operator"
15355 [(float_extend:DF
15356 (match_operand:SF 1 "register_operand" "0,f"))
15357 (float_extend:DF
15358 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15359 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15360 "* return output_387_binary_op (insn, operands);"
15361 [(set (attr "type")
15362 (cond [(match_operand:DF 3 "mult_operator" "")
15363 (const_string "fmul")
15364 (match_operand:DF 3 "div_operator" "")
15365 (const_string "fdiv")
15366 ]
15367 (const_string "fop")))
15368 (set_attr "mode" "SF")])
15369
15370 (define_insn "*fop_xf_comm_i387"
15371 [(set (match_operand:XF 0 "register_operand" "=f")
15372 (match_operator:XF 3 "binary_fp_operator"
15373 [(match_operand:XF 1 "register_operand" "%0")
15374 (match_operand:XF 2 "register_operand" "f")]))]
15375 "TARGET_80387
15376 && COMMUTATIVE_ARITH_P (operands[3])"
15377 "* return output_387_binary_op (insn, operands);"
15378 [(set (attr "type")
15379 (if_then_else (match_operand:XF 3 "mult_operator" "")
15380 (const_string "fmul")
15381 (const_string "fop")))
15382 (set_attr "mode" "XF")])
15383
15384 (define_insn "*fop_xf_1_i387"
15385 [(set (match_operand:XF 0 "register_operand" "=f,f")
15386 (match_operator:XF 3 "binary_fp_operator"
15387 [(match_operand:XF 1 "register_operand" "0,f")
15388 (match_operand:XF 2 "register_operand" "f,0")]))]
15389 "TARGET_80387
15390 && !COMMUTATIVE_ARITH_P (operands[3])"
15391 "* return output_387_binary_op (insn, operands);"
15392 [(set (attr "type")
15393 (cond [(match_operand:XF 3 "mult_operator" "")
15394 (const_string "fmul")
15395 (match_operand:XF 3 "div_operator" "")
15396 (const_string "fdiv")
15397 ]
15398 (const_string "fop")))
15399 (set_attr "mode" "XF")])
15400
15401 (define_insn "*fop_xf_2<mode>_i387"
15402 [(set (match_operand:XF 0 "register_operand" "=f,f")
15403 (match_operator:XF 3 "binary_fp_operator"
15404 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15405 (match_operand:XF 2 "register_operand" "0,0")]))]
15406 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15407 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15408 [(set (attr "type")
15409 (cond [(match_operand:XF 3 "mult_operator" "")
15410 (const_string "fmul")
15411 (match_operand:XF 3 "div_operator" "")
15412 (const_string "fdiv")
15413 ]
15414 (const_string "fop")))
15415 (set_attr "fp_int_src" "true")
15416 (set_attr "mode" "<MODE>")])
15417
15418 (define_insn "*fop_xf_3<mode>_i387"
15419 [(set (match_operand:XF 0 "register_operand" "=f,f")
15420 (match_operator:XF 3 "binary_fp_operator"
15421 [(match_operand:XF 1 "register_operand" "0,0")
15422 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15423 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15424 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15425 [(set (attr "type")
15426 (cond [(match_operand:XF 3 "mult_operator" "")
15427 (const_string "fmul")
15428 (match_operand:XF 3 "div_operator" "")
15429 (const_string "fdiv")
15430 ]
15431 (const_string "fop")))
15432 (set_attr "fp_int_src" "true")
15433 (set_attr "mode" "<MODE>")])
15434
15435 (define_insn "*fop_xf_4_i387"
15436 [(set (match_operand:XF 0 "register_operand" "=f,f")
15437 (match_operator:XF 3 "binary_fp_operator"
15438 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15439 (match_operand:XF 2 "register_operand" "0,f")]))]
15440 "TARGET_80387"
15441 "* return output_387_binary_op (insn, operands);"
15442 [(set (attr "type")
15443 (cond [(match_operand:XF 3 "mult_operator" "")
15444 (const_string "fmul")
15445 (match_operand:XF 3 "div_operator" "")
15446 (const_string "fdiv")
15447 ]
15448 (const_string "fop")))
15449 (set_attr "mode" "SF")])
15450
15451 (define_insn "*fop_xf_5_i387"
15452 [(set (match_operand:XF 0 "register_operand" "=f,f")
15453 (match_operator:XF 3 "binary_fp_operator"
15454 [(match_operand:XF 1 "register_operand" "0,f")
15455 (float_extend:XF
15456 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15457 "TARGET_80387"
15458 "* return output_387_binary_op (insn, operands);"
15459 [(set (attr "type")
15460 (cond [(match_operand:XF 3 "mult_operator" "")
15461 (const_string "fmul")
15462 (match_operand:XF 3 "div_operator" "")
15463 (const_string "fdiv")
15464 ]
15465 (const_string "fop")))
15466 (set_attr "mode" "SF")])
15467
15468 (define_insn "*fop_xf_6_i387"
15469 [(set (match_operand:XF 0 "register_operand" "=f,f")
15470 (match_operator:XF 3 "binary_fp_operator"
15471 [(float_extend:XF
15472 (match_operand 1 "register_operand" "0,f"))
15473 (float_extend:XF
15474 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15475 "TARGET_80387"
15476 "* return output_387_binary_op (insn, operands);"
15477 [(set (attr "type")
15478 (cond [(match_operand:XF 3 "mult_operator" "")
15479 (const_string "fmul")
15480 (match_operand:XF 3 "div_operator" "")
15481 (const_string "fdiv")
15482 ]
15483 (const_string "fop")))
15484 (set_attr "mode" "SF")])
15485
15486 (define_split
15487 [(set (match_operand 0 "register_operand" "")
15488 (match_operator 3 "binary_fp_operator"
15489 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15490 (match_operand 2 "register_operand" "")]))]
15491 "TARGET_80387 && reload_completed
15492 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15493 [(const_int 0)]
15494 {
15495 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15496 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15497 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15498 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15499 GET_MODE (operands[3]),
15500 operands[4],
15501 operands[2])));
15502 ix86_free_from_memory (GET_MODE (operands[1]));
15503 DONE;
15504 })
15505
15506 (define_split
15507 [(set (match_operand 0 "register_operand" "")
15508 (match_operator 3 "binary_fp_operator"
15509 [(match_operand 1 "register_operand" "")
15510 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15511 "TARGET_80387 && reload_completed
15512 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15513 [(const_int 0)]
15514 {
15515 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15516 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15517 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15518 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15519 GET_MODE (operands[3]),
15520 operands[1],
15521 operands[4])));
15522 ix86_free_from_memory (GET_MODE (operands[2]));
15523 DONE;
15524 })
15525 \f
15526 ;; FPU special functions.
15527
15528 (define_expand "sqrtsf2"
15529 [(set (match_operand:SF 0 "register_operand" "")
15530 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15531 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15532 {
15533 if (!TARGET_SSE_MATH)
15534 operands[1] = force_reg (SFmode, operands[1]);
15535 })
15536
15537 (define_insn "*sqrtsf2_mixed"
15538 [(set (match_operand:SF 0 "register_operand" "=f,x")
15539 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15540 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15541 "@
15542 fsqrt
15543 sqrtss\t{%1, %0|%0, %1}"
15544 [(set_attr "type" "fpspc,sse")
15545 (set_attr "mode" "SF,SF")
15546 (set_attr "athlon_decode" "direct,*")])
15547
15548 (define_insn "*sqrtsf2_sse"
15549 [(set (match_operand:SF 0 "register_operand" "=x")
15550 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15551 "TARGET_SSE_MATH"
15552 "sqrtss\t{%1, %0|%0, %1}"
15553 [(set_attr "type" "sse")
15554 (set_attr "mode" "SF")
15555 (set_attr "athlon_decode" "*")])
15556
15557 (define_insn "*sqrtsf2_i387"
15558 [(set (match_operand:SF 0 "register_operand" "=f")
15559 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15560 "TARGET_USE_FANCY_MATH_387"
15561 "fsqrt"
15562 [(set_attr "type" "fpspc")
15563 (set_attr "mode" "SF")
15564 (set_attr "athlon_decode" "direct")])
15565
15566 (define_expand "sqrtdf2"
15567 [(set (match_operand:DF 0 "register_operand" "")
15568 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15569 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15570 {
15571 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15572 operands[1] = force_reg (DFmode, operands[1]);
15573 })
15574
15575 (define_insn "*sqrtdf2_mixed"
15576 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15577 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15578 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15579 "@
15580 fsqrt
15581 sqrtsd\t{%1, %0|%0, %1}"
15582 [(set_attr "type" "fpspc,sse")
15583 (set_attr "mode" "DF,DF")
15584 (set_attr "athlon_decode" "direct,*")])
15585
15586 (define_insn "*sqrtdf2_sse"
15587 [(set (match_operand:DF 0 "register_operand" "=Y")
15588 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15589 "TARGET_SSE2 && TARGET_SSE_MATH"
15590 "sqrtsd\t{%1, %0|%0, %1}"
15591 [(set_attr "type" "sse")
15592 (set_attr "mode" "DF")
15593 (set_attr "athlon_decode" "*")])
15594
15595 (define_insn "*sqrtdf2_i387"
15596 [(set (match_operand:DF 0 "register_operand" "=f")
15597 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15598 "TARGET_USE_FANCY_MATH_387"
15599 "fsqrt"
15600 [(set_attr "type" "fpspc")
15601 (set_attr "mode" "DF")
15602 (set_attr "athlon_decode" "direct")])
15603
15604 (define_insn "*sqrtextendsfdf2_i387"
15605 [(set (match_operand:DF 0 "register_operand" "=f")
15606 (sqrt:DF (float_extend:DF
15607 (match_operand:SF 1 "register_operand" "0"))))]
15608 "TARGET_USE_FANCY_MATH_387
15609 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15610 "fsqrt"
15611 [(set_attr "type" "fpspc")
15612 (set_attr "mode" "DF")
15613 (set_attr "athlon_decode" "direct")])
15614
15615 (define_insn "sqrtxf2"
15616 [(set (match_operand:XF 0 "register_operand" "=f")
15617 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15618 "TARGET_USE_FANCY_MATH_387"
15619 "fsqrt"
15620 [(set_attr "type" "fpspc")
15621 (set_attr "mode" "XF")
15622 (set_attr "athlon_decode" "direct")])
15623
15624 (define_insn "*sqrtextendsfxf2_i387"
15625 [(set (match_operand:XF 0 "register_operand" "=f")
15626 (sqrt:XF (float_extend:XF
15627 (match_operand:SF 1 "register_operand" "0"))))]
15628 "TARGET_USE_FANCY_MATH_387"
15629 "fsqrt"
15630 [(set_attr "type" "fpspc")
15631 (set_attr "mode" "XF")
15632 (set_attr "athlon_decode" "direct")])
15633
15634 (define_insn "*sqrtextenddfxf2_i387"
15635 [(set (match_operand:XF 0 "register_operand" "=f")
15636 (sqrt:XF (float_extend:XF
15637 (match_operand:DF 1 "register_operand" "0"))))]
15638 "TARGET_USE_FANCY_MATH_387"
15639 "fsqrt"
15640 [(set_attr "type" "fpspc")
15641 (set_attr "mode" "XF")
15642 (set_attr "athlon_decode" "direct")])
15643
15644 (define_insn "fpremxf4"
15645 [(set (match_operand:XF 0 "register_operand" "=f")
15646 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15647 (match_operand:XF 3 "register_operand" "1")]
15648 UNSPEC_FPREM_F))
15649 (set (match_operand:XF 1 "register_operand" "=u")
15650 (unspec:XF [(match_dup 2) (match_dup 3)]
15651 UNSPEC_FPREM_U))
15652 (set (reg:CCFP FPSR_REG)
15653 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15654 "TARGET_USE_FANCY_MATH_387"
15655 "fprem"
15656 [(set_attr "type" "fpspc")
15657 (set_attr "mode" "XF")])
15658
15659 (define_expand "fmodsf3"
15660 [(use (match_operand:SF 0 "register_operand" ""))
15661 (use (match_operand:SF 1 "register_operand" ""))
15662 (use (match_operand:SF 2 "register_operand" ""))]
15663 "TARGET_USE_FANCY_MATH_387
15664 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15665 {
15666 rtx label = gen_label_rtx ();
15667
15668 rtx op1 = gen_reg_rtx (XFmode);
15669 rtx op2 = gen_reg_rtx (XFmode);
15670
15671 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15672 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15673
15674 emit_label (label);
15675
15676 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15677 ix86_emit_fp_unordered_jump (label);
15678
15679 emit_insn (gen_truncxfsf2 (operands[0], op1));
15680 DONE;
15681 })
15682
15683 (define_expand "fmoddf3"
15684 [(use (match_operand:DF 0 "register_operand" ""))
15685 (use (match_operand:DF 1 "register_operand" ""))
15686 (use (match_operand:DF 2 "register_operand" ""))]
15687 "TARGET_USE_FANCY_MATH_387
15688 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15689 {
15690 rtx label = gen_label_rtx ();
15691
15692 rtx op1 = gen_reg_rtx (XFmode);
15693 rtx op2 = gen_reg_rtx (XFmode);
15694
15695 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15696 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15697
15698 emit_label (label);
15699
15700 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15701 ix86_emit_fp_unordered_jump (label);
15702
15703 emit_insn (gen_truncxfdf2 (operands[0], op1));
15704 DONE;
15705 })
15706
15707 (define_expand "fmodxf3"
15708 [(use (match_operand:XF 0 "register_operand" ""))
15709 (use (match_operand:XF 1 "register_operand" ""))
15710 (use (match_operand:XF 2 "register_operand" ""))]
15711 "TARGET_USE_FANCY_MATH_387"
15712 {
15713 rtx label = gen_label_rtx ();
15714
15715 emit_label (label);
15716
15717 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15718 operands[1], operands[2]));
15719 ix86_emit_fp_unordered_jump (label);
15720
15721 emit_move_insn (operands[0], operands[1]);
15722 DONE;
15723 })
15724
15725 (define_insn "fprem1xf4"
15726 [(set (match_operand:XF 0 "register_operand" "=f")
15727 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15728 (match_operand:XF 3 "register_operand" "1")]
15729 UNSPEC_FPREM1_F))
15730 (set (match_operand:XF 1 "register_operand" "=u")
15731 (unspec:XF [(match_dup 2) (match_dup 3)]
15732 UNSPEC_FPREM1_U))
15733 (set (reg:CCFP FPSR_REG)
15734 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15735 "TARGET_USE_FANCY_MATH_387"
15736 "fprem1"
15737 [(set_attr "type" "fpspc")
15738 (set_attr "mode" "XF")])
15739
15740 (define_expand "remaindersf3"
15741 [(use (match_operand:SF 0 "register_operand" ""))
15742 (use (match_operand:SF 1 "register_operand" ""))
15743 (use (match_operand:SF 2 "register_operand" ""))]
15744 "TARGET_USE_FANCY_MATH_387
15745 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15746 {
15747 rtx label = gen_label_rtx ();
15748
15749 rtx op1 = gen_reg_rtx (XFmode);
15750 rtx op2 = gen_reg_rtx (XFmode);
15751
15752 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15753 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15754
15755 emit_label (label);
15756
15757 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15758 ix86_emit_fp_unordered_jump (label);
15759
15760 emit_insn (gen_truncxfsf2 (operands[0], op1));
15761 DONE;
15762 })
15763
15764 (define_expand "remainderdf3"
15765 [(use (match_operand:DF 0 "register_operand" ""))
15766 (use (match_operand:DF 1 "register_operand" ""))
15767 (use (match_operand:DF 2 "register_operand" ""))]
15768 "TARGET_USE_FANCY_MATH_387
15769 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15770 {
15771 rtx label = gen_label_rtx ();
15772
15773 rtx op1 = gen_reg_rtx (XFmode);
15774 rtx op2 = gen_reg_rtx (XFmode);
15775
15776 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15777 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15778
15779 emit_label (label);
15780
15781 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15782 ix86_emit_fp_unordered_jump (label);
15783
15784 emit_insn (gen_truncxfdf2 (operands[0], op1));
15785 DONE;
15786 })
15787
15788 (define_expand "remainderxf3"
15789 [(use (match_operand:XF 0 "register_operand" ""))
15790 (use (match_operand:XF 1 "register_operand" ""))
15791 (use (match_operand:XF 2 "register_operand" ""))]
15792 "TARGET_USE_FANCY_MATH_387"
15793 {
15794 rtx label = gen_label_rtx ();
15795
15796 emit_label (label);
15797
15798 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15799 operands[1], operands[2]));
15800 ix86_emit_fp_unordered_jump (label);
15801
15802 emit_move_insn (operands[0], operands[1]);
15803 DONE;
15804 })
15805
15806 (define_insn "*sindf2"
15807 [(set (match_operand:DF 0 "register_operand" "=f")
15808 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15809 "TARGET_USE_FANCY_MATH_387
15810 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15811 && flag_unsafe_math_optimizations"
15812 "fsin"
15813 [(set_attr "type" "fpspc")
15814 (set_attr "mode" "DF")])
15815
15816 (define_insn "*sinsf2"
15817 [(set (match_operand:SF 0 "register_operand" "=f")
15818 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15819 "TARGET_USE_FANCY_MATH_387
15820 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15821 && flag_unsafe_math_optimizations"
15822 "fsin"
15823 [(set_attr "type" "fpspc")
15824 (set_attr "mode" "SF")])
15825
15826 (define_insn "*sinextendsfdf2"
15827 [(set (match_operand:DF 0 "register_operand" "=f")
15828 (unspec:DF [(float_extend:DF
15829 (match_operand:SF 1 "register_operand" "0"))]
15830 UNSPEC_SIN))]
15831 "TARGET_USE_FANCY_MATH_387
15832 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15833 && flag_unsafe_math_optimizations"
15834 "fsin"
15835 [(set_attr "type" "fpspc")
15836 (set_attr "mode" "DF")])
15837
15838 (define_insn "*sinxf2"
15839 [(set (match_operand:XF 0 "register_operand" "=f")
15840 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15841 "TARGET_USE_FANCY_MATH_387
15842 && flag_unsafe_math_optimizations"
15843 "fsin"
15844 [(set_attr "type" "fpspc")
15845 (set_attr "mode" "XF")])
15846
15847 (define_insn "*cosdf2"
15848 [(set (match_operand:DF 0 "register_operand" "=f")
15849 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15850 "TARGET_USE_FANCY_MATH_387
15851 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15852 && flag_unsafe_math_optimizations"
15853 "fcos"
15854 [(set_attr "type" "fpspc")
15855 (set_attr "mode" "DF")])
15856
15857 (define_insn "*cossf2"
15858 [(set (match_operand:SF 0 "register_operand" "=f")
15859 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15860 "TARGET_USE_FANCY_MATH_387
15861 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15862 && flag_unsafe_math_optimizations"
15863 "fcos"
15864 [(set_attr "type" "fpspc")
15865 (set_attr "mode" "SF")])
15866
15867 (define_insn "*cosextendsfdf2"
15868 [(set (match_operand:DF 0 "register_operand" "=f")
15869 (unspec:DF [(float_extend:DF
15870 (match_operand:SF 1 "register_operand" "0"))]
15871 UNSPEC_COS))]
15872 "TARGET_USE_FANCY_MATH_387
15873 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15874 && flag_unsafe_math_optimizations"
15875 "fcos"
15876 [(set_attr "type" "fpspc")
15877 (set_attr "mode" "DF")])
15878
15879 (define_insn "*cosxf2"
15880 [(set (match_operand:XF 0 "register_operand" "=f")
15881 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15882 "TARGET_USE_FANCY_MATH_387
15883 && flag_unsafe_math_optimizations"
15884 "fcos"
15885 [(set_attr "type" "fpspc")
15886 (set_attr "mode" "XF")])
15887
15888 ;; With sincos pattern defined, sin and cos builtin function will be
15889 ;; expanded to sincos pattern with one of its outputs left unused.
15890 ;; Cse pass will detected, if two sincos patterns can be combined,
15891 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15892 ;; depending on the unused output.
15893
15894 (define_insn "sincosdf3"
15895 [(set (match_operand:DF 0 "register_operand" "=f")
15896 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15897 UNSPEC_SINCOS_COS))
15898 (set (match_operand:DF 1 "register_operand" "=u")
15899 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15900 "TARGET_USE_FANCY_MATH_387
15901 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15902 && flag_unsafe_math_optimizations"
15903 "fsincos"
15904 [(set_attr "type" "fpspc")
15905 (set_attr "mode" "DF")])
15906
15907 (define_split
15908 [(set (match_operand:DF 0 "register_operand" "")
15909 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15910 UNSPEC_SINCOS_COS))
15911 (set (match_operand:DF 1 "register_operand" "")
15912 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15913 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15914 && !reload_completed && !reload_in_progress"
15915 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15916 "")
15917
15918 (define_split
15919 [(set (match_operand:DF 0 "register_operand" "")
15920 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15921 UNSPEC_SINCOS_COS))
15922 (set (match_operand:DF 1 "register_operand" "")
15923 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15924 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15925 && !reload_completed && !reload_in_progress"
15926 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15927 "")
15928
15929 (define_insn "sincossf3"
15930 [(set (match_operand:SF 0 "register_operand" "=f")
15931 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15932 UNSPEC_SINCOS_COS))
15933 (set (match_operand:SF 1 "register_operand" "=u")
15934 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15935 "TARGET_USE_FANCY_MATH_387
15936 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15937 && flag_unsafe_math_optimizations"
15938 "fsincos"
15939 [(set_attr "type" "fpspc")
15940 (set_attr "mode" "SF")])
15941
15942 (define_split
15943 [(set (match_operand:SF 0 "register_operand" "")
15944 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15945 UNSPEC_SINCOS_COS))
15946 (set (match_operand:SF 1 "register_operand" "")
15947 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15948 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15949 && !reload_completed && !reload_in_progress"
15950 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15951 "")
15952
15953 (define_split
15954 [(set (match_operand:SF 0 "register_operand" "")
15955 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15956 UNSPEC_SINCOS_COS))
15957 (set (match_operand:SF 1 "register_operand" "")
15958 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15959 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15960 && !reload_completed && !reload_in_progress"
15961 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15962 "")
15963
15964 (define_insn "*sincosextendsfdf3"
15965 [(set (match_operand:DF 0 "register_operand" "=f")
15966 (unspec:DF [(float_extend:DF
15967 (match_operand:SF 2 "register_operand" "0"))]
15968 UNSPEC_SINCOS_COS))
15969 (set (match_operand:DF 1 "register_operand" "=u")
15970 (unspec:DF [(float_extend:DF
15971 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15972 "TARGET_USE_FANCY_MATH_387
15973 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15974 && flag_unsafe_math_optimizations"
15975 "fsincos"
15976 [(set_attr "type" "fpspc")
15977 (set_attr "mode" "DF")])
15978
15979 (define_split
15980 [(set (match_operand:DF 0 "register_operand" "")
15981 (unspec:DF [(float_extend:DF
15982 (match_operand:SF 2 "register_operand" ""))]
15983 UNSPEC_SINCOS_COS))
15984 (set (match_operand:DF 1 "register_operand" "")
15985 (unspec:DF [(float_extend:DF
15986 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15987 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15988 && !reload_completed && !reload_in_progress"
15989 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15990 (match_dup 2))] UNSPEC_SIN))]
15991 "")
15992
15993 (define_split
15994 [(set (match_operand:DF 0 "register_operand" "")
15995 (unspec:DF [(float_extend:DF
15996 (match_operand:SF 2 "register_operand" ""))]
15997 UNSPEC_SINCOS_COS))
15998 (set (match_operand:DF 1 "register_operand" "")
15999 (unspec:DF [(float_extend:DF
16000 (match_dup 2))] UNSPEC_SINCOS_SIN))]
16001 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16002 && !reload_completed && !reload_in_progress"
16003 [(set (match_dup 0) (unspec:DF [(float_extend:DF
16004 (match_dup 2))] UNSPEC_COS))]
16005 "")
16006
16007 (define_insn "sincosxf3"
16008 [(set (match_operand:XF 0 "register_operand" "=f")
16009 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16010 UNSPEC_SINCOS_COS))
16011 (set (match_operand:XF 1 "register_operand" "=u")
16012 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16013 "TARGET_USE_FANCY_MATH_387
16014 && flag_unsafe_math_optimizations"
16015 "fsincos"
16016 [(set_attr "type" "fpspc")
16017 (set_attr "mode" "XF")])
16018
16019 (define_split
16020 [(set (match_operand:XF 0 "register_operand" "")
16021 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16022 UNSPEC_SINCOS_COS))
16023 (set (match_operand:XF 1 "register_operand" "")
16024 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16025 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16026 && !reload_completed && !reload_in_progress"
16027 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16028 "")
16029
16030 (define_split
16031 [(set (match_operand:XF 0 "register_operand" "")
16032 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16033 UNSPEC_SINCOS_COS))
16034 (set (match_operand:XF 1 "register_operand" "")
16035 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16036 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16037 && !reload_completed && !reload_in_progress"
16038 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16039 "")
16040
16041 (define_insn "*tandf3_1"
16042 [(set (match_operand:DF 0 "register_operand" "=f")
16043 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16044 UNSPEC_TAN_ONE))
16045 (set (match_operand:DF 1 "register_operand" "=u")
16046 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16047 "TARGET_USE_FANCY_MATH_387
16048 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16049 && flag_unsafe_math_optimizations"
16050 "fptan"
16051 [(set_attr "type" "fpspc")
16052 (set_attr "mode" "DF")])
16053
16054 ;; optimize sequence: fptan
16055 ;; fstp %st(0)
16056 ;; fld1
16057 ;; into fptan insn.
16058
16059 (define_peephole2
16060 [(parallel[(set (match_operand:DF 0 "register_operand" "")
16061 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16062 UNSPEC_TAN_ONE))
16063 (set (match_operand:DF 1 "register_operand" "")
16064 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16065 (set (match_dup 0)
16066 (match_operand:DF 3 "immediate_operand" ""))]
16067 "standard_80387_constant_p (operands[3]) == 2"
16068 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16069 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16070 "")
16071
16072 (define_expand "tandf2"
16073 [(parallel [(set (match_dup 2)
16074 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16075 UNSPEC_TAN_ONE))
16076 (set (match_operand:DF 0 "register_operand" "")
16077 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16078 "TARGET_USE_FANCY_MATH_387
16079 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16080 && flag_unsafe_math_optimizations"
16081 {
16082 operands[2] = gen_reg_rtx (DFmode);
16083 })
16084
16085 (define_insn "*tansf3_1"
16086 [(set (match_operand:SF 0 "register_operand" "=f")
16087 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16088 UNSPEC_TAN_ONE))
16089 (set (match_operand:SF 1 "register_operand" "=u")
16090 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16091 "TARGET_USE_FANCY_MATH_387
16092 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16093 && flag_unsafe_math_optimizations"
16094 "fptan"
16095 [(set_attr "type" "fpspc")
16096 (set_attr "mode" "SF")])
16097
16098 ;; optimize sequence: fptan
16099 ;; fstp %st(0)
16100 ;; fld1
16101 ;; into fptan insn.
16102
16103 (define_peephole2
16104 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16105 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16106 UNSPEC_TAN_ONE))
16107 (set (match_operand:SF 1 "register_operand" "")
16108 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16109 (set (match_dup 0)
16110 (match_operand:SF 3 "immediate_operand" ""))]
16111 "standard_80387_constant_p (operands[3]) == 2"
16112 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16113 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16114 "")
16115
16116 (define_expand "tansf2"
16117 [(parallel [(set (match_dup 2)
16118 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16119 UNSPEC_TAN_ONE))
16120 (set (match_operand:SF 0 "register_operand" "")
16121 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16122 "TARGET_USE_FANCY_MATH_387
16123 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16124 && flag_unsafe_math_optimizations"
16125 {
16126 operands[2] = gen_reg_rtx (SFmode);
16127 })
16128
16129 (define_insn "*tanxf3_1"
16130 [(set (match_operand:XF 0 "register_operand" "=f")
16131 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16132 UNSPEC_TAN_ONE))
16133 (set (match_operand:XF 1 "register_operand" "=u")
16134 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16135 "TARGET_USE_FANCY_MATH_387
16136 && flag_unsafe_math_optimizations"
16137 "fptan"
16138 [(set_attr "type" "fpspc")
16139 (set_attr "mode" "XF")])
16140
16141 ;; optimize sequence: fptan
16142 ;; fstp %st(0)
16143 ;; fld1
16144 ;; into fptan insn.
16145
16146 (define_peephole2
16147 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16148 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16149 UNSPEC_TAN_ONE))
16150 (set (match_operand:XF 1 "register_operand" "")
16151 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16152 (set (match_dup 0)
16153 (match_operand:XF 3 "immediate_operand" ""))]
16154 "standard_80387_constant_p (operands[3]) == 2"
16155 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16156 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16157 "")
16158
16159 (define_expand "tanxf2"
16160 [(parallel [(set (match_dup 2)
16161 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16162 UNSPEC_TAN_ONE))
16163 (set (match_operand:XF 0 "register_operand" "")
16164 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16165 "TARGET_USE_FANCY_MATH_387
16166 && flag_unsafe_math_optimizations"
16167 {
16168 operands[2] = gen_reg_rtx (XFmode);
16169 })
16170
16171 (define_insn "atan2df3_1"
16172 [(set (match_operand:DF 0 "register_operand" "=f")
16173 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16174 (match_operand:DF 1 "register_operand" "u")]
16175 UNSPEC_FPATAN))
16176 (clobber (match_scratch:DF 3 "=1"))]
16177 "TARGET_USE_FANCY_MATH_387
16178 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16179 && flag_unsafe_math_optimizations"
16180 "fpatan"
16181 [(set_attr "type" "fpspc")
16182 (set_attr "mode" "DF")])
16183
16184 (define_expand "atan2df3"
16185 [(use (match_operand:DF 0 "register_operand" ""))
16186 (use (match_operand:DF 2 "register_operand" ""))
16187 (use (match_operand:DF 1 "register_operand" ""))]
16188 "TARGET_USE_FANCY_MATH_387
16189 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16190 && flag_unsafe_math_optimizations"
16191 {
16192 rtx copy = gen_reg_rtx (DFmode);
16193 emit_move_insn (copy, operands[1]);
16194 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16195 DONE;
16196 })
16197
16198 (define_expand "atandf2"
16199 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16200 (unspec:DF [(match_dup 2)
16201 (match_operand:DF 1 "register_operand" "")]
16202 UNSPEC_FPATAN))
16203 (clobber (match_scratch:DF 3 ""))])]
16204 "TARGET_USE_FANCY_MATH_387
16205 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16206 && flag_unsafe_math_optimizations"
16207 {
16208 operands[2] = gen_reg_rtx (DFmode);
16209 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16210 })
16211
16212 (define_insn "atan2sf3_1"
16213 [(set (match_operand:SF 0 "register_operand" "=f")
16214 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16215 (match_operand:SF 1 "register_operand" "u")]
16216 UNSPEC_FPATAN))
16217 (clobber (match_scratch:SF 3 "=1"))]
16218 "TARGET_USE_FANCY_MATH_387
16219 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16220 && flag_unsafe_math_optimizations"
16221 "fpatan"
16222 [(set_attr "type" "fpspc")
16223 (set_attr "mode" "SF")])
16224
16225 (define_expand "atan2sf3"
16226 [(use (match_operand:SF 0 "register_operand" ""))
16227 (use (match_operand:SF 2 "register_operand" ""))
16228 (use (match_operand:SF 1 "register_operand" ""))]
16229 "TARGET_USE_FANCY_MATH_387
16230 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16231 && flag_unsafe_math_optimizations"
16232 {
16233 rtx copy = gen_reg_rtx (SFmode);
16234 emit_move_insn (copy, operands[1]);
16235 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16236 DONE;
16237 })
16238
16239 (define_expand "atansf2"
16240 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16241 (unspec:SF [(match_dup 2)
16242 (match_operand:SF 1 "register_operand" "")]
16243 UNSPEC_FPATAN))
16244 (clobber (match_scratch:SF 3 ""))])]
16245 "TARGET_USE_FANCY_MATH_387
16246 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16247 && flag_unsafe_math_optimizations"
16248 {
16249 operands[2] = gen_reg_rtx (SFmode);
16250 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16251 })
16252
16253 (define_insn "atan2xf3_1"
16254 [(set (match_operand:XF 0 "register_operand" "=f")
16255 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16256 (match_operand:XF 1 "register_operand" "u")]
16257 UNSPEC_FPATAN))
16258 (clobber (match_scratch:XF 3 "=1"))]
16259 "TARGET_USE_FANCY_MATH_387
16260 && flag_unsafe_math_optimizations"
16261 "fpatan"
16262 [(set_attr "type" "fpspc")
16263 (set_attr "mode" "XF")])
16264
16265 (define_expand "atan2xf3"
16266 [(use (match_operand:XF 0 "register_operand" ""))
16267 (use (match_operand:XF 2 "register_operand" ""))
16268 (use (match_operand:XF 1 "register_operand" ""))]
16269 "TARGET_USE_FANCY_MATH_387
16270 && flag_unsafe_math_optimizations"
16271 {
16272 rtx copy = gen_reg_rtx (XFmode);
16273 emit_move_insn (copy, operands[1]);
16274 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16275 DONE;
16276 })
16277
16278 (define_expand "atanxf2"
16279 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16280 (unspec:XF [(match_dup 2)
16281 (match_operand:XF 1 "register_operand" "")]
16282 UNSPEC_FPATAN))
16283 (clobber (match_scratch:XF 3 ""))])]
16284 "TARGET_USE_FANCY_MATH_387
16285 && flag_unsafe_math_optimizations"
16286 {
16287 operands[2] = gen_reg_rtx (XFmode);
16288 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16289 })
16290
16291 (define_expand "asindf2"
16292 [(set (match_dup 2)
16293 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16294 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16295 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16296 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16297 (parallel [(set (match_dup 7)
16298 (unspec:XF [(match_dup 6) (match_dup 2)]
16299 UNSPEC_FPATAN))
16300 (clobber (match_scratch:XF 8 ""))])
16301 (set (match_operand:DF 0 "register_operand" "")
16302 (float_truncate:DF (match_dup 7)))]
16303 "TARGET_USE_FANCY_MATH_387
16304 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16305 && flag_unsafe_math_optimizations && !optimize_size"
16306 {
16307 int i;
16308
16309 for (i=2; i<8; i++)
16310 operands[i] = gen_reg_rtx (XFmode);
16311
16312 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16313 })
16314
16315 (define_expand "asinsf2"
16316 [(set (match_dup 2)
16317 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16318 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16319 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16320 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16321 (parallel [(set (match_dup 7)
16322 (unspec:XF [(match_dup 6) (match_dup 2)]
16323 UNSPEC_FPATAN))
16324 (clobber (match_scratch:XF 8 ""))])
16325 (set (match_operand:SF 0 "register_operand" "")
16326 (float_truncate:SF (match_dup 7)))]
16327 "TARGET_USE_FANCY_MATH_387
16328 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16329 && flag_unsafe_math_optimizations && !optimize_size"
16330 {
16331 int i;
16332
16333 for (i=2; i<8; i++)
16334 operands[i] = gen_reg_rtx (XFmode);
16335
16336 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16337 })
16338
16339 (define_expand "asinxf2"
16340 [(set (match_dup 2)
16341 (mult:XF (match_operand:XF 1 "register_operand" "")
16342 (match_dup 1)))
16343 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16344 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16345 (parallel [(set (match_operand:XF 0 "register_operand" "")
16346 (unspec:XF [(match_dup 5) (match_dup 1)]
16347 UNSPEC_FPATAN))
16348 (clobber (match_scratch:XF 6 ""))])]
16349 "TARGET_USE_FANCY_MATH_387
16350 && flag_unsafe_math_optimizations && !optimize_size"
16351 {
16352 int i;
16353
16354 for (i=2; i<6; i++)
16355 operands[i] = gen_reg_rtx (XFmode);
16356
16357 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16358 })
16359
16360 (define_expand "acosdf2"
16361 [(set (match_dup 2)
16362 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16363 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16364 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16365 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16366 (parallel [(set (match_dup 7)
16367 (unspec:XF [(match_dup 2) (match_dup 6)]
16368 UNSPEC_FPATAN))
16369 (clobber (match_scratch:XF 8 ""))])
16370 (set (match_operand:DF 0 "register_operand" "")
16371 (float_truncate:DF (match_dup 7)))]
16372 "TARGET_USE_FANCY_MATH_387
16373 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16374 && flag_unsafe_math_optimizations && !optimize_size"
16375 {
16376 int i;
16377
16378 for (i=2; i<8; i++)
16379 operands[i] = gen_reg_rtx (XFmode);
16380
16381 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16382 })
16383
16384 (define_expand "acossf2"
16385 [(set (match_dup 2)
16386 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16387 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16388 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16389 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16390 (parallel [(set (match_dup 7)
16391 (unspec:XF [(match_dup 2) (match_dup 6)]
16392 UNSPEC_FPATAN))
16393 (clobber (match_scratch:XF 8 ""))])
16394 (set (match_operand:SF 0 "register_operand" "")
16395 (float_truncate:SF (match_dup 7)))]
16396 "TARGET_USE_FANCY_MATH_387
16397 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16398 && flag_unsafe_math_optimizations && !optimize_size"
16399 {
16400 int i;
16401
16402 for (i=2; i<8; i++)
16403 operands[i] = gen_reg_rtx (XFmode);
16404
16405 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16406 })
16407
16408 (define_expand "acosxf2"
16409 [(set (match_dup 2)
16410 (mult:XF (match_operand:XF 1 "register_operand" "")
16411 (match_dup 1)))
16412 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16413 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16414 (parallel [(set (match_operand:XF 0 "register_operand" "")
16415 (unspec:XF [(match_dup 1) (match_dup 5)]
16416 UNSPEC_FPATAN))
16417 (clobber (match_scratch:XF 6 ""))])]
16418 "TARGET_USE_FANCY_MATH_387
16419 && flag_unsafe_math_optimizations && !optimize_size"
16420 {
16421 int i;
16422
16423 for (i=2; i<6; i++)
16424 operands[i] = gen_reg_rtx (XFmode);
16425
16426 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16427 })
16428
16429 (define_insn "fyl2x_xf3"
16430 [(set (match_operand:XF 0 "register_operand" "=f")
16431 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16432 (match_operand:XF 1 "register_operand" "u")]
16433 UNSPEC_FYL2X))
16434 (clobber (match_scratch:XF 3 "=1"))]
16435 "TARGET_USE_FANCY_MATH_387
16436 && flag_unsafe_math_optimizations"
16437 "fyl2x"
16438 [(set_attr "type" "fpspc")
16439 (set_attr "mode" "XF")])
16440
16441 (define_expand "logsf2"
16442 [(set (match_dup 2)
16443 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16444 (parallel [(set (match_dup 4)
16445 (unspec:XF [(match_dup 2)
16446 (match_dup 3)] UNSPEC_FYL2X))
16447 (clobber (match_scratch:XF 5 ""))])
16448 (set (match_operand:SF 0 "register_operand" "")
16449 (float_truncate:SF (match_dup 4)))]
16450 "TARGET_USE_FANCY_MATH_387
16451 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16452 && flag_unsafe_math_optimizations"
16453 {
16454 rtx temp;
16455
16456 operands[2] = gen_reg_rtx (XFmode);
16457 operands[3] = gen_reg_rtx (XFmode);
16458 operands[4] = gen_reg_rtx (XFmode);
16459
16460 temp = standard_80387_constant_rtx (4); /* fldln2 */
16461 emit_move_insn (operands[3], temp);
16462 })
16463
16464 (define_expand "logdf2"
16465 [(set (match_dup 2)
16466 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16467 (parallel [(set (match_dup 4)
16468 (unspec:XF [(match_dup 2)
16469 (match_dup 3)] UNSPEC_FYL2X))
16470 (clobber (match_scratch:XF 5 ""))])
16471 (set (match_operand:DF 0 "register_operand" "")
16472 (float_truncate:DF (match_dup 4)))]
16473 "TARGET_USE_FANCY_MATH_387
16474 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16475 && flag_unsafe_math_optimizations"
16476 {
16477 rtx temp;
16478
16479 operands[2] = gen_reg_rtx (XFmode);
16480 operands[3] = gen_reg_rtx (XFmode);
16481 operands[4] = gen_reg_rtx (XFmode);
16482
16483 temp = standard_80387_constant_rtx (4); /* fldln2 */
16484 emit_move_insn (operands[3], temp);
16485 })
16486
16487 (define_expand "logxf2"
16488 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16489 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16490 (match_dup 2)] UNSPEC_FYL2X))
16491 (clobber (match_scratch:XF 3 ""))])]
16492 "TARGET_USE_FANCY_MATH_387
16493 && flag_unsafe_math_optimizations"
16494 {
16495 rtx temp;
16496
16497 operands[2] = gen_reg_rtx (XFmode);
16498 temp = standard_80387_constant_rtx (4); /* fldln2 */
16499 emit_move_insn (operands[2], temp);
16500 })
16501
16502 (define_expand "log10sf2"
16503 [(set (match_dup 2)
16504 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16505 (parallel [(set (match_dup 4)
16506 (unspec:XF [(match_dup 2)
16507 (match_dup 3)] UNSPEC_FYL2X))
16508 (clobber (match_scratch:XF 5 ""))])
16509 (set (match_operand:SF 0 "register_operand" "")
16510 (float_truncate:SF (match_dup 4)))]
16511 "TARGET_USE_FANCY_MATH_387
16512 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16513 && flag_unsafe_math_optimizations"
16514 {
16515 rtx temp;
16516
16517 operands[2] = gen_reg_rtx (XFmode);
16518 operands[3] = gen_reg_rtx (XFmode);
16519 operands[4] = gen_reg_rtx (XFmode);
16520
16521 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16522 emit_move_insn (operands[3], temp);
16523 })
16524
16525 (define_expand "log10df2"
16526 [(set (match_dup 2)
16527 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16528 (parallel [(set (match_dup 4)
16529 (unspec:XF [(match_dup 2)
16530 (match_dup 3)] UNSPEC_FYL2X))
16531 (clobber (match_scratch:XF 5 ""))])
16532 (set (match_operand:DF 0 "register_operand" "")
16533 (float_truncate:DF (match_dup 4)))]
16534 "TARGET_USE_FANCY_MATH_387
16535 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16536 && flag_unsafe_math_optimizations"
16537 {
16538 rtx temp;
16539
16540 operands[2] = gen_reg_rtx (XFmode);
16541 operands[3] = gen_reg_rtx (XFmode);
16542 operands[4] = gen_reg_rtx (XFmode);
16543
16544 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16545 emit_move_insn (operands[3], temp);
16546 })
16547
16548 (define_expand "log10xf2"
16549 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16550 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16551 (match_dup 2)] UNSPEC_FYL2X))
16552 (clobber (match_scratch:XF 3 ""))])]
16553 "TARGET_USE_FANCY_MATH_387
16554 && flag_unsafe_math_optimizations"
16555 {
16556 rtx temp;
16557
16558 operands[2] = gen_reg_rtx (XFmode);
16559 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16560 emit_move_insn (operands[2], temp);
16561 })
16562
16563 (define_expand "log2sf2"
16564 [(set (match_dup 2)
16565 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16566 (parallel [(set (match_dup 4)
16567 (unspec:XF [(match_dup 2)
16568 (match_dup 3)] UNSPEC_FYL2X))
16569 (clobber (match_scratch:XF 5 ""))])
16570 (set (match_operand:SF 0 "register_operand" "")
16571 (float_truncate:SF (match_dup 4)))]
16572 "TARGET_USE_FANCY_MATH_387
16573 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16574 && flag_unsafe_math_optimizations"
16575 {
16576 operands[2] = gen_reg_rtx (XFmode);
16577 operands[3] = gen_reg_rtx (XFmode);
16578 operands[4] = gen_reg_rtx (XFmode);
16579
16580 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16581 })
16582
16583 (define_expand "log2df2"
16584 [(set (match_dup 2)
16585 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16586 (parallel [(set (match_dup 4)
16587 (unspec:XF [(match_dup 2)
16588 (match_dup 3)] UNSPEC_FYL2X))
16589 (clobber (match_scratch:XF 5 ""))])
16590 (set (match_operand:DF 0 "register_operand" "")
16591 (float_truncate:DF (match_dup 4)))]
16592 "TARGET_USE_FANCY_MATH_387
16593 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16594 && flag_unsafe_math_optimizations"
16595 {
16596 operands[2] = gen_reg_rtx (XFmode);
16597 operands[3] = gen_reg_rtx (XFmode);
16598 operands[4] = gen_reg_rtx (XFmode);
16599
16600 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16601 })
16602
16603 (define_expand "log2xf2"
16604 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16605 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16606 (match_dup 2)] UNSPEC_FYL2X))
16607 (clobber (match_scratch:XF 3 ""))])]
16608 "TARGET_USE_FANCY_MATH_387
16609 && flag_unsafe_math_optimizations"
16610 {
16611 operands[2] = gen_reg_rtx (XFmode);
16612 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16613 })
16614
16615 (define_insn "fyl2xp1_xf3"
16616 [(set (match_operand:XF 0 "register_operand" "=f")
16617 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16618 (match_operand:XF 1 "register_operand" "u")]
16619 UNSPEC_FYL2XP1))
16620 (clobber (match_scratch:XF 3 "=1"))]
16621 "TARGET_USE_FANCY_MATH_387
16622 && flag_unsafe_math_optimizations"
16623 "fyl2xp1"
16624 [(set_attr "type" "fpspc")
16625 (set_attr "mode" "XF")])
16626
16627 (define_expand "log1psf2"
16628 [(use (match_operand:SF 0 "register_operand" ""))
16629 (use (match_operand:SF 1 "register_operand" ""))]
16630 "TARGET_USE_FANCY_MATH_387
16631 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16632 && flag_unsafe_math_optimizations && !optimize_size"
16633 {
16634 rtx op0 = gen_reg_rtx (XFmode);
16635 rtx op1 = gen_reg_rtx (XFmode);
16636
16637 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16638 ix86_emit_i387_log1p (op0, op1);
16639 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16640 DONE;
16641 })
16642
16643 (define_expand "log1pdf2"
16644 [(use (match_operand:DF 0 "register_operand" ""))
16645 (use (match_operand:DF 1 "register_operand" ""))]
16646 "TARGET_USE_FANCY_MATH_387
16647 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16648 && flag_unsafe_math_optimizations && !optimize_size"
16649 {
16650 rtx op0 = gen_reg_rtx (XFmode);
16651 rtx op1 = gen_reg_rtx (XFmode);
16652
16653 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16654 ix86_emit_i387_log1p (op0, op1);
16655 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16656 DONE;
16657 })
16658
16659 (define_expand "log1pxf2"
16660 [(use (match_operand:XF 0 "register_operand" ""))
16661 (use (match_operand:XF 1 "register_operand" ""))]
16662 "TARGET_USE_FANCY_MATH_387
16663 && flag_unsafe_math_optimizations && !optimize_size"
16664 {
16665 ix86_emit_i387_log1p (operands[0], operands[1]);
16666 DONE;
16667 })
16668
16669 (define_insn "*fxtractxf3"
16670 [(set (match_operand:XF 0 "register_operand" "=f")
16671 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16672 UNSPEC_XTRACT_FRACT))
16673 (set (match_operand:XF 1 "register_operand" "=u")
16674 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16675 "TARGET_USE_FANCY_MATH_387
16676 && flag_unsafe_math_optimizations"
16677 "fxtract"
16678 [(set_attr "type" "fpspc")
16679 (set_attr "mode" "XF")])
16680
16681 (define_expand "logbsf2"
16682 [(set (match_dup 2)
16683 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16684 (parallel [(set (match_dup 3)
16685 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16686 (set (match_dup 4)
16687 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16688 (set (match_operand:SF 0 "register_operand" "")
16689 (float_truncate:SF (match_dup 4)))]
16690 "TARGET_USE_FANCY_MATH_387
16691 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16692 && flag_unsafe_math_optimizations"
16693 {
16694 operands[2] = gen_reg_rtx (XFmode);
16695 operands[3] = gen_reg_rtx (XFmode);
16696 operands[4] = gen_reg_rtx (XFmode);
16697 })
16698
16699 (define_expand "logbdf2"
16700 [(set (match_dup 2)
16701 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16702 (parallel [(set (match_dup 3)
16703 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16704 (set (match_dup 4)
16705 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16706 (set (match_operand:DF 0 "register_operand" "")
16707 (float_truncate:DF (match_dup 4)))]
16708 "TARGET_USE_FANCY_MATH_387
16709 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16710 && flag_unsafe_math_optimizations"
16711 {
16712 operands[2] = gen_reg_rtx (XFmode);
16713 operands[3] = gen_reg_rtx (XFmode);
16714 operands[4] = gen_reg_rtx (XFmode);
16715 })
16716
16717 (define_expand "logbxf2"
16718 [(parallel [(set (match_dup 2)
16719 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16720 UNSPEC_XTRACT_FRACT))
16721 (set (match_operand:XF 0 "register_operand" "")
16722 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16723 "TARGET_USE_FANCY_MATH_387
16724 && flag_unsafe_math_optimizations"
16725 {
16726 operands[2] = gen_reg_rtx (XFmode);
16727 })
16728
16729 (define_expand "ilogbsi2"
16730 [(parallel [(set (match_dup 2)
16731 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16732 UNSPEC_XTRACT_FRACT))
16733 (set (match_operand:XF 3 "register_operand" "")
16734 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16735 (parallel [(set (match_operand:SI 0 "register_operand" "")
16736 (fix:SI (match_dup 3)))
16737 (clobber (reg:CC FLAGS_REG))])]
16738 "TARGET_USE_FANCY_MATH_387
16739 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16740 && flag_unsafe_math_optimizations && !optimize_size"
16741 {
16742 operands[2] = gen_reg_rtx (XFmode);
16743 operands[3] = gen_reg_rtx (XFmode);
16744 })
16745
16746 (define_insn "*f2xm1xf2"
16747 [(set (match_operand:XF 0 "register_operand" "=f")
16748 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16749 UNSPEC_F2XM1))]
16750 "TARGET_USE_FANCY_MATH_387
16751 && flag_unsafe_math_optimizations"
16752 "f2xm1"
16753 [(set_attr "type" "fpspc")
16754 (set_attr "mode" "XF")])
16755
16756 (define_insn "*fscalexf4"
16757 [(set (match_operand:XF 0 "register_operand" "=f")
16758 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16759 (match_operand:XF 3 "register_operand" "1")]
16760 UNSPEC_FSCALE_FRACT))
16761 (set (match_operand:XF 1 "register_operand" "=u")
16762 (unspec:XF [(match_dup 2) (match_dup 3)]
16763 UNSPEC_FSCALE_EXP))]
16764 "TARGET_USE_FANCY_MATH_387
16765 && flag_unsafe_math_optimizations"
16766 "fscale"
16767 [(set_attr "type" "fpspc")
16768 (set_attr "mode" "XF")])
16769
16770 (define_expand "expsf2"
16771 [(set (match_dup 2)
16772 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16773 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16774 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16775 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16776 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16777 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16778 (parallel [(set (match_dup 10)
16779 (unspec:XF [(match_dup 9) (match_dup 5)]
16780 UNSPEC_FSCALE_FRACT))
16781 (set (match_dup 11)
16782 (unspec:XF [(match_dup 9) (match_dup 5)]
16783 UNSPEC_FSCALE_EXP))])
16784 (set (match_operand:SF 0 "register_operand" "")
16785 (float_truncate:SF (match_dup 10)))]
16786 "TARGET_USE_FANCY_MATH_387
16787 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16788 && flag_unsafe_math_optimizations && !optimize_size"
16789 {
16790 rtx temp;
16791 int i;
16792
16793 for (i=2; i<12; i++)
16794 operands[i] = gen_reg_rtx (XFmode);
16795 temp = standard_80387_constant_rtx (5); /* fldl2e */
16796 emit_move_insn (operands[3], temp);
16797 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16798 })
16799
16800 (define_expand "expdf2"
16801 [(set (match_dup 2)
16802 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16803 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16804 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16805 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16806 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16807 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16808 (parallel [(set (match_dup 10)
16809 (unspec:XF [(match_dup 9) (match_dup 5)]
16810 UNSPEC_FSCALE_FRACT))
16811 (set (match_dup 11)
16812 (unspec:XF [(match_dup 9) (match_dup 5)]
16813 UNSPEC_FSCALE_EXP))])
16814 (set (match_operand:DF 0 "register_operand" "")
16815 (float_truncate:DF (match_dup 10)))]
16816 "TARGET_USE_FANCY_MATH_387
16817 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16818 && flag_unsafe_math_optimizations && !optimize_size"
16819 {
16820 rtx temp;
16821 int i;
16822
16823 for (i=2; i<12; i++)
16824 operands[i] = gen_reg_rtx (XFmode);
16825 temp = standard_80387_constant_rtx (5); /* fldl2e */
16826 emit_move_insn (operands[3], temp);
16827 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16828 })
16829
16830 (define_expand "expxf2"
16831 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16832 (match_dup 2)))
16833 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16834 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16835 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16836 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16837 (parallel [(set (match_operand:XF 0 "register_operand" "")
16838 (unspec:XF [(match_dup 8) (match_dup 4)]
16839 UNSPEC_FSCALE_FRACT))
16840 (set (match_dup 9)
16841 (unspec:XF [(match_dup 8) (match_dup 4)]
16842 UNSPEC_FSCALE_EXP))])]
16843 "TARGET_USE_FANCY_MATH_387
16844 && flag_unsafe_math_optimizations && !optimize_size"
16845 {
16846 rtx temp;
16847 int i;
16848
16849 for (i=2; i<10; i++)
16850 operands[i] = gen_reg_rtx (XFmode);
16851 temp = standard_80387_constant_rtx (5); /* fldl2e */
16852 emit_move_insn (operands[2], temp);
16853 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16854 })
16855
16856 (define_expand "exp10sf2"
16857 [(set (match_dup 2)
16858 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16859 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16860 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16861 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16862 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16863 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16864 (parallel [(set (match_dup 10)
16865 (unspec:XF [(match_dup 9) (match_dup 5)]
16866 UNSPEC_FSCALE_FRACT))
16867 (set (match_dup 11)
16868 (unspec:XF [(match_dup 9) (match_dup 5)]
16869 UNSPEC_FSCALE_EXP))])
16870 (set (match_operand:SF 0 "register_operand" "")
16871 (float_truncate:SF (match_dup 10)))]
16872 "TARGET_USE_FANCY_MATH_387
16873 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16874 && flag_unsafe_math_optimizations && !optimize_size"
16875 {
16876 rtx temp;
16877 int i;
16878
16879 for (i=2; i<12; i++)
16880 operands[i] = gen_reg_rtx (XFmode);
16881 temp = standard_80387_constant_rtx (6); /* fldl2t */
16882 emit_move_insn (operands[3], temp);
16883 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16884 })
16885
16886 (define_expand "exp10df2"
16887 [(set (match_dup 2)
16888 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16889 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16890 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16891 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16892 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16893 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16894 (parallel [(set (match_dup 10)
16895 (unspec:XF [(match_dup 9) (match_dup 5)]
16896 UNSPEC_FSCALE_FRACT))
16897 (set (match_dup 11)
16898 (unspec:XF [(match_dup 9) (match_dup 5)]
16899 UNSPEC_FSCALE_EXP))])
16900 (set (match_operand:DF 0 "register_operand" "")
16901 (float_truncate:DF (match_dup 10)))]
16902 "TARGET_USE_FANCY_MATH_387
16903 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16904 && flag_unsafe_math_optimizations && !optimize_size"
16905 {
16906 rtx temp;
16907 int i;
16908
16909 for (i=2; i<12; i++)
16910 operands[i] = gen_reg_rtx (XFmode);
16911 temp = standard_80387_constant_rtx (6); /* fldl2t */
16912 emit_move_insn (operands[3], temp);
16913 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16914 })
16915
16916 (define_expand "exp10xf2"
16917 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16918 (match_dup 2)))
16919 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16920 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16921 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16922 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16923 (parallel [(set (match_operand:XF 0 "register_operand" "")
16924 (unspec:XF [(match_dup 8) (match_dup 4)]
16925 UNSPEC_FSCALE_FRACT))
16926 (set (match_dup 9)
16927 (unspec:XF [(match_dup 8) (match_dup 4)]
16928 UNSPEC_FSCALE_EXP))])]
16929 "TARGET_USE_FANCY_MATH_387
16930 && flag_unsafe_math_optimizations && !optimize_size"
16931 {
16932 rtx temp;
16933 int i;
16934
16935 for (i=2; i<10; i++)
16936 operands[i] = gen_reg_rtx (XFmode);
16937 temp = standard_80387_constant_rtx (6); /* fldl2t */
16938 emit_move_insn (operands[2], temp);
16939 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16940 })
16941
16942 (define_expand "exp2sf2"
16943 [(set (match_dup 2)
16944 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16945 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16946 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16947 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16948 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16949 (parallel [(set (match_dup 8)
16950 (unspec:XF [(match_dup 7) (match_dup 3)]
16951 UNSPEC_FSCALE_FRACT))
16952 (set (match_dup 9)
16953 (unspec:XF [(match_dup 7) (match_dup 3)]
16954 UNSPEC_FSCALE_EXP))])
16955 (set (match_operand:SF 0 "register_operand" "")
16956 (float_truncate:SF (match_dup 8)))]
16957 "TARGET_USE_FANCY_MATH_387
16958 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16959 && flag_unsafe_math_optimizations && !optimize_size"
16960 {
16961 int i;
16962
16963 for (i=2; i<10; i++)
16964 operands[i] = gen_reg_rtx (XFmode);
16965 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16966 })
16967
16968 (define_expand "exp2df2"
16969 [(set (match_dup 2)
16970 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16971 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16972 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16973 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16974 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16975 (parallel [(set (match_dup 8)
16976 (unspec:XF [(match_dup 7) (match_dup 3)]
16977 UNSPEC_FSCALE_FRACT))
16978 (set (match_dup 9)
16979 (unspec:XF [(match_dup 7) (match_dup 3)]
16980 UNSPEC_FSCALE_EXP))])
16981 (set (match_operand:DF 0 "register_operand" "")
16982 (float_truncate:DF (match_dup 8)))]
16983 "TARGET_USE_FANCY_MATH_387
16984 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16985 && flag_unsafe_math_optimizations && !optimize_size"
16986 {
16987 int i;
16988
16989 for (i=2; i<10; i++)
16990 operands[i] = gen_reg_rtx (XFmode);
16991 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16992 })
16993
16994 (define_expand "exp2xf2"
16995 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16996 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16997 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16998 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16999 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17000 (parallel [(set (match_operand:XF 0 "register_operand" "")
17001 (unspec:XF [(match_dup 7) (match_dup 3)]
17002 UNSPEC_FSCALE_FRACT))
17003 (set (match_dup 8)
17004 (unspec:XF [(match_dup 7) (match_dup 3)]
17005 UNSPEC_FSCALE_EXP))])]
17006 "TARGET_USE_FANCY_MATH_387
17007 && flag_unsafe_math_optimizations && !optimize_size"
17008 {
17009 int i;
17010
17011 for (i=2; i<9; i++)
17012 operands[i] = gen_reg_rtx (XFmode);
17013 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
17014 })
17015
17016 (define_expand "expm1df2"
17017 [(set (match_dup 2)
17018 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17019 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17020 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17021 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17022 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17023 (parallel [(set (match_dup 8)
17024 (unspec:XF [(match_dup 7) (match_dup 5)]
17025 UNSPEC_FSCALE_FRACT))
17026 (set (match_dup 9)
17027 (unspec:XF [(match_dup 7) (match_dup 5)]
17028 UNSPEC_FSCALE_EXP))])
17029 (parallel [(set (match_dup 11)
17030 (unspec:XF [(match_dup 10) (match_dup 9)]
17031 UNSPEC_FSCALE_FRACT))
17032 (set (match_dup 12)
17033 (unspec:XF [(match_dup 10) (match_dup 9)]
17034 UNSPEC_FSCALE_EXP))])
17035 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17036 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17037 (set (match_operand:DF 0 "register_operand" "")
17038 (float_truncate:DF (match_dup 14)))]
17039 "TARGET_USE_FANCY_MATH_387
17040 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17041 && flag_unsafe_math_optimizations && !optimize_size"
17042 {
17043 rtx temp;
17044 int i;
17045
17046 for (i=2; i<15; i++)
17047 operands[i] = gen_reg_rtx (XFmode);
17048 temp = standard_80387_constant_rtx (5); /* fldl2e */
17049 emit_move_insn (operands[3], temp);
17050 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17051 })
17052
17053 (define_expand "expm1sf2"
17054 [(set (match_dup 2)
17055 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17056 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17057 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17058 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17059 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17060 (parallel [(set (match_dup 8)
17061 (unspec:XF [(match_dup 7) (match_dup 5)]
17062 UNSPEC_FSCALE_FRACT))
17063 (set (match_dup 9)
17064 (unspec:XF [(match_dup 7) (match_dup 5)]
17065 UNSPEC_FSCALE_EXP))])
17066 (parallel [(set (match_dup 11)
17067 (unspec:XF [(match_dup 10) (match_dup 9)]
17068 UNSPEC_FSCALE_FRACT))
17069 (set (match_dup 12)
17070 (unspec:XF [(match_dup 10) (match_dup 9)]
17071 UNSPEC_FSCALE_EXP))])
17072 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17073 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17074 (set (match_operand:SF 0 "register_operand" "")
17075 (float_truncate:SF (match_dup 14)))]
17076 "TARGET_USE_FANCY_MATH_387
17077 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17078 && flag_unsafe_math_optimizations && !optimize_size"
17079 {
17080 rtx temp;
17081 int i;
17082
17083 for (i=2; i<15; i++)
17084 operands[i] = gen_reg_rtx (XFmode);
17085 temp = standard_80387_constant_rtx (5); /* fldl2e */
17086 emit_move_insn (operands[3], temp);
17087 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17088 })
17089
17090 (define_expand "expm1xf2"
17091 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17092 (match_dup 2)))
17093 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17094 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17095 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17096 (parallel [(set (match_dup 7)
17097 (unspec:XF [(match_dup 6) (match_dup 4)]
17098 UNSPEC_FSCALE_FRACT))
17099 (set (match_dup 8)
17100 (unspec:XF [(match_dup 6) (match_dup 4)]
17101 UNSPEC_FSCALE_EXP))])
17102 (parallel [(set (match_dup 10)
17103 (unspec:XF [(match_dup 9) (match_dup 8)]
17104 UNSPEC_FSCALE_FRACT))
17105 (set (match_dup 11)
17106 (unspec:XF [(match_dup 9) (match_dup 8)]
17107 UNSPEC_FSCALE_EXP))])
17108 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17109 (set (match_operand:XF 0 "register_operand" "")
17110 (plus:XF (match_dup 12) (match_dup 7)))]
17111 "TARGET_USE_FANCY_MATH_387
17112 && flag_unsafe_math_optimizations && !optimize_size"
17113 {
17114 rtx temp;
17115 int i;
17116
17117 for (i=2; i<13; i++)
17118 operands[i] = gen_reg_rtx (XFmode);
17119 temp = standard_80387_constant_rtx (5); /* fldl2e */
17120 emit_move_insn (operands[2], temp);
17121 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17122 })
17123
17124 (define_expand "ldexpdf3"
17125 [(set (match_dup 3)
17126 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17127 (set (match_dup 4)
17128 (float:XF (match_operand:SI 2 "register_operand" "")))
17129 (parallel [(set (match_dup 5)
17130 (unspec:XF [(match_dup 3) (match_dup 4)]
17131 UNSPEC_FSCALE_FRACT))
17132 (set (match_dup 6)
17133 (unspec:XF [(match_dup 3) (match_dup 4)]
17134 UNSPEC_FSCALE_EXP))])
17135 (set (match_operand:DF 0 "register_operand" "")
17136 (float_truncate:DF (match_dup 5)))]
17137 "TARGET_USE_FANCY_MATH_387
17138 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17139 && flag_unsafe_math_optimizations && !optimize_size"
17140 {
17141 int i;
17142
17143 for (i=3; i<7; i++)
17144 operands[i] = gen_reg_rtx (XFmode);
17145 })
17146
17147 (define_expand "ldexpsf3"
17148 [(set (match_dup 3)
17149 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17150 (set (match_dup 4)
17151 (float:XF (match_operand:SI 2 "register_operand" "")))
17152 (parallel [(set (match_dup 5)
17153 (unspec:XF [(match_dup 3) (match_dup 4)]
17154 UNSPEC_FSCALE_FRACT))
17155 (set (match_dup 6)
17156 (unspec:XF [(match_dup 3) (match_dup 4)]
17157 UNSPEC_FSCALE_EXP))])
17158 (set (match_operand:SF 0 "register_operand" "")
17159 (float_truncate:SF (match_dup 5)))]
17160 "TARGET_USE_FANCY_MATH_387
17161 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17162 && flag_unsafe_math_optimizations && !optimize_size"
17163 {
17164 int i;
17165
17166 for (i=3; i<7; i++)
17167 operands[i] = gen_reg_rtx (XFmode);
17168 })
17169
17170 (define_expand "ldexpxf3"
17171 [(set (match_dup 3)
17172 (float:XF (match_operand:SI 2 "register_operand" "")))
17173 (parallel [(set (match_operand:XF 0 " register_operand" "")
17174 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17175 (match_dup 3)]
17176 UNSPEC_FSCALE_FRACT))
17177 (set (match_dup 4)
17178 (unspec:XF [(match_dup 1) (match_dup 3)]
17179 UNSPEC_FSCALE_EXP))])]
17180 "TARGET_USE_FANCY_MATH_387
17181 && flag_unsafe_math_optimizations && !optimize_size"
17182 {
17183 int i;
17184
17185 for (i=3; i<5; i++)
17186 operands[i] = gen_reg_rtx (XFmode);
17187 })
17188 \f
17189
17190 (define_insn "frndintxf2"
17191 [(set (match_operand:XF 0 "register_operand" "=f")
17192 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17193 UNSPEC_FRNDINT))]
17194 "TARGET_USE_FANCY_MATH_387
17195 && flag_unsafe_math_optimizations"
17196 "frndint"
17197 [(set_attr "type" "fpspc")
17198 (set_attr "mode" "XF")])
17199
17200 (define_expand "rintdf2"
17201 [(use (match_operand:DF 0 "register_operand" ""))
17202 (use (match_operand:DF 1 "register_operand" ""))]
17203 "(TARGET_USE_FANCY_MATH_387
17204 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17205 && flag_unsafe_math_optimizations)
17206 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17207 && !flag_trapping_math
17208 && !optimize_size)"
17209 {
17210 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17211 && !flag_trapping_math
17212 && !optimize_size)
17213 ix86_expand_rint (operand0, operand1);
17214 else
17215 {
17216 rtx op0 = gen_reg_rtx (XFmode);
17217 rtx op1 = gen_reg_rtx (XFmode);
17218
17219 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17220 emit_insn (gen_frndintxf2 (op0, op1));
17221
17222 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17223 }
17224 DONE;
17225 })
17226
17227 (define_expand "rintsf2"
17228 [(use (match_operand:SF 0 "register_operand" ""))
17229 (use (match_operand:SF 1 "register_operand" ""))]
17230 "(TARGET_USE_FANCY_MATH_387
17231 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17232 && flag_unsafe_math_optimizations)
17233 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17234 && !flag_trapping_math
17235 && !optimize_size)"
17236 {
17237 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17238 && !flag_trapping_math
17239 && !optimize_size)
17240 ix86_expand_rint (operand0, operand1);
17241 else
17242 {
17243 rtx op0 = gen_reg_rtx (XFmode);
17244 rtx op1 = gen_reg_rtx (XFmode);
17245
17246 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17247 emit_insn (gen_frndintxf2 (op0, op1));
17248
17249 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17250 }
17251 DONE;
17252 })
17253
17254 (define_expand "rintxf2"
17255 [(use (match_operand:XF 0 "register_operand" ""))
17256 (use (match_operand:XF 1 "register_operand" ""))]
17257 "TARGET_USE_FANCY_MATH_387
17258 && flag_unsafe_math_optimizations && !optimize_size"
17259 {
17260 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17261 DONE;
17262 })
17263
17264 (define_expand "roundsf2"
17265 [(match_operand:SF 0 "register_operand" "")
17266 (match_operand:SF 1 "nonimmediate_operand" "")]
17267 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17268 && !flag_trapping_math && !flag_rounding_math
17269 && !optimize_size"
17270 {
17271 ix86_expand_round (operand0, operand1);
17272 DONE;
17273 })
17274
17275 (define_expand "rounddf2"
17276 [(match_operand:DF 0 "register_operand" "")
17277 (match_operand:DF 1 "nonimmediate_operand" "")]
17278 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17279 && !flag_trapping_math && !flag_rounding_math
17280 && !optimize_size"
17281 {
17282 if (TARGET_64BIT)
17283 ix86_expand_round (operand0, operand1);
17284 else
17285 ix86_expand_rounddf_32 (operand0, operand1);
17286 DONE;
17287 })
17288
17289 (define_insn_and_split "*fistdi2_1"
17290 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17291 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17292 UNSPEC_FIST))]
17293 "TARGET_USE_FANCY_MATH_387
17294 && !(reload_completed || reload_in_progress)"
17295 "#"
17296 "&& 1"
17297 [(const_int 0)]
17298 {
17299 if (memory_operand (operands[0], VOIDmode))
17300 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17301 else
17302 {
17303 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17304 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17305 operands[2]));
17306 }
17307 DONE;
17308 }
17309 [(set_attr "type" "fpspc")
17310 (set_attr "mode" "DI")])
17311
17312 (define_insn "fistdi2"
17313 [(set (match_operand:DI 0 "memory_operand" "=m")
17314 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17315 UNSPEC_FIST))
17316 (clobber (match_scratch:XF 2 "=&1f"))]
17317 "TARGET_USE_FANCY_MATH_387"
17318 "* return output_fix_trunc (insn, operands, 0);"
17319 [(set_attr "type" "fpspc")
17320 (set_attr "mode" "DI")])
17321
17322 (define_insn "fistdi2_with_temp"
17323 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17324 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17325 UNSPEC_FIST))
17326 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17327 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17328 "TARGET_USE_FANCY_MATH_387"
17329 "#"
17330 [(set_attr "type" "fpspc")
17331 (set_attr "mode" "DI")])
17332
17333 (define_split
17334 [(set (match_operand:DI 0 "register_operand" "")
17335 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17336 UNSPEC_FIST))
17337 (clobber (match_operand:DI 2 "memory_operand" ""))
17338 (clobber (match_scratch 3 ""))]
17339 "reload_completed"
17340 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17341 (clobber (match_dup 3))])
17342 (set (match_dup 0) (match_dup 2))]
17343 "")
17344
17345 (define_split
17346 [(set (match_operand:DI 0 "memory_operand" "")
17347 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17348 UNSPEC_FIST))
17349 (clobber (match_operand:DI 2 "memory_operand" ""))
17350 (clobber (match_scratch 3 ""))]
17351 "reload_completed"
17352 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17353 (clobber (match_dup 3))])]
17354 "")
17355
17356 (define_insn_and_split "*fist<mode>2_1"
17357 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17358 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17359 UNSPEC_FIST))]
17360 "TARGET_USE_FANCY_MATH_387
17361 && !(reload_completed || reload_in_progress)"
17362 "#"
17363 "&& 1"
17364 [(const_int 0)]
17365 {
17366 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17367 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17368 operands[2]));
17369 DONE;
17370 }
17371 [(set_attr "type" "fpspc")
17372 (set_attr "mode" "<MODE>")])
17373
17374 (define_insn "fist<mode>2"
17375 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17376 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17377 UNSPEC_FIST))]
17378 "TARGET_USE_FANCY_MATH_387"
17379 "* return output_fix_trunc (insn, operands, 0);"
17380 [(set_attr "type" "fpspc")
17381 (set_attr "mode" "<MODE>")])
17382
17383 (define_insn "fist<mode>2_with_temp"
17384 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17385 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17386 UNSPEC_FIST))
17387 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17388 "TARGET_USE_FANCY_MATH_387"
17389 "#"
17390 [(set_attr "type" "fpspc")
17391 (set_attr "mode" "<MODE>")])
17392
17393 (define_split
17394 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17395 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17396 UNSPEC_FIST))
17397 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17398 "reload_completed"
17399 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17400 UNSPEC_FIST))
17401 (set (match_dup 0) (match_dup 2))]
17402 "")
17403
17404 (define_split
17405 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17406 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17407 UNSPEC_FIST))
17408 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17409 "reload_completed"
17410 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17411 UNSPEC_FIST))]
17412 "")
17413
17414 (define_expand "lrintxf<mode>2"
17415 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17416 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17417 UNSPEC_FIST))]
17418 "TARGET_USE_FANCY_MATH_387"
17419 "")
17420
17421 (define_expand "lrint<mode>di2"
17422 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17423 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17424 UNSPEC_FIX_NOTRUNC))]
17425 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17426 "")
17427
17428 (define_expand "lrint<mode>si2"
17429 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17430 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17431 UNSPEC_FIX_NOTRUNC))]
17432 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17433 "")
17434
17435 (define_expand "lround<mode>di2"
17436 [(match_operand:DI 0 "nonimmediate_operand" "")
17437 (match_operand:SSEMODEF 1 "register_operand" "")]
17438 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17439 && !flag_trapping_math && !flag_rounding_math
17440 && !optimize_size"
17441 {
17442 ix86_expand_lround (operand0, operand1);
17443 DONE;
17444 })
17445
17446 (define_expand "lround<mode>si2"
17447 [(match_operand:SI 0 "nonimmediate_operand" "")
17448 (match_operand:SSEMODEF 1 "register_operand" "")]
17449 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17450 && !flag_trapping_math && !flag_rounding_math
17451 && !optimize_size"
17452 {
17453 ix86_expand_lround (operand0, operand1);
17454 DONE;
17455 })
17456
17457 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17458 (define_insn_and_split "frndintxf2_floor"
17459 [(set (match_operand:XF 0 "register_operand" "=f")
17460 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17461 UNSPEC_FRNDINT_FLOOR))
17462 (clobber (reg:CC FLAGS_REG))]
17463 "TARGET_USE_FANCY_MATH_387
17464 && flag_unsafe_math_optimizations
17465 && !(reload_completed || reload_in_progress)"
17466 "#"
17467 "&& 1"
17468 [(const_int 0)]
17469 {
17470 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17471
17472 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17473 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17474
17475 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17476 operands[2], operands[3]));
17477 DONE;
17478 }
17479 [(set_attr "type" "frndint")
17480 (set_attr "i387_cw" "floor")
17481 (set_attr "mode" "XF")])
17482
17483 (define_insn "frndintxf2_floor_i387"
17484 [(set (match_operand:XF 0 "register_operand" "=f")
17485 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17486 UNSPEC_FRNDINT_FLOOR))
17487 (use (match_operand:HI 2 "memory_operand" "m"))
17488 (use (match_operand:HI 3 "memory_operand" "m"))]
17489 "TARGET_USE_FANCY_MATH_387
17490 && flag_unsafe_math_optimizations"
17491 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17492 [(set_attr "type" "frndint")
17493 (set_attr "i387_cw" "floor")
17494 (set_attr "mode" "XF")])
17495
17496 (define_expand "floorxf2"
17497 [(use (match_operand:XF 0 "register_operand" ""))
17498 (use (match_operand:XF 1 "register_operand" ""))]
17499 "TARGET_USE_FANCY_MATH_387
17500 && flag_unsafe_math_optimizations && !optimize_size"
17501 {
17502 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17503 DONE;
17504 })
17505
17506 (define_expand "floordf2"
17507 [(use (match_operand:DF 0 "register_operand" ""))
17508 (use (match_operand:DF 1 "register_operand" ""))]
17509 "((TARGET_USE_FANCY_MATH_387
17510 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17511 && flag_unsafe_math_optimizations)
17512 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17513 && !flag_trapping_math))
17514 && !optimize_size"
17515 {
17516 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17517 && !flag_trapping_math)
17518 {
17519 if (TARGET_64BIT)
17520 ix86_expand_floorceil (operand0, operand1, true);
17521 else
17522 ix86_expand_floorceildf_32 (operand0, operand1, true);
17523 }
17524 else
17525 {
17526 rtx op0 = gen_reg_rtx (XFmode);
17527 rtx op1 = gen_reg_rtx (XFmode);
17528
17529 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17530 emit_insn (gen_frndintxf2_floor (op0, op1));
17531
17532 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17533 }
17534 DONE;
17535 })
17536
17537 (define_expand "floorsf2"
17538 [(use (match_operand:SF 0 "register_operand" ""))
17539 (use (match_operand:SF 1 "register_operand" ""))]
17540 "((TARGET_USE_FANCY_MATH_387
17541 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17542 && flag_unsafe_math_optimizations)
17543 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17544 && !flag_trapping_math))
17545 && !optimize_size"
17546 {
17547 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17548 && !flag_trapping_math)
17549 ix86_expand_floorceil (operand0, operand1, true);
17550 else
17551 {
17552 rtx op0 = gen_reg_rtx (XFmode);
17553 rtx op1 = gen_reg_rtx (XFmode);
17554
17555 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17556 emit_insn (gen_frndintxf2_floor (op0, op1));
17557
17558 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17559 }
17560 DONE;
17561 })
17562
17563 (define_insn_and_split "*fist<mode>2_floor_1"
17564 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17565 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17566 UNSPEC_FIST_FLOOR))
17567 (clobber (reg:CC FLAGS_REG))]
17568 "TARGET_USE_FANCY_MATH_387
17569 && flag_unsafe_math_optimizations
17570 && !(reload_completed || reload_in_progress)"
17571 "#"
17572 "&& 1"
17573 [(const_int 0)]
17574 {
17575 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17576
17577 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17578 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17579 if (memory_operand (operands[0], VOIDmode))
17580 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17581 operands[2], operands[3]));
17582 else
17583 {
17584 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17585 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17586 operands[2], operands[3],
17587 operands[4]));
17588 }
17589 DONE;
17590 }
17591 [(set_attr "type" "fistp")
17592 (set_attr "i387_cw" "floor")
17593 (set_attr "mode" "<MODE>")])
17594
17595 (define_insn "fistdi2_floor"
17596 [(set (match_operand:DI 0 "memory_operand" "=m")
17597 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17598 UNSPEC_FIST_FLOOR))
17599 (use (match_operand:HI 2 "memory_operand" "m"))
17600 (use (match_operand:HI 3 "memory_operand" "m"))
17601 (clobber (match_scratch:XF 4 "=&1f"))]
17602 "TARGET_USE_FANCY_MATH_387
17603 && flag_unsafe_math_optimizations"
17604 "* return output_fix_trunc (insn, operands, 0);"
17605 [(set_attr "type" "fistp")
17606 (set_attr "i387_cw" "floor")
17607 (set_attr "mode" "DI")])
17608
17609 (define_insn "fistdi2_floor_with_temp"
17610 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17611 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17612 UNSPEC_FIST_FLOOR))
17613 (use (match_operand:HI 2 "memory_operand" "m,m"))
17614 (use (match_operand:HI 3 "memory_operand" "m,m"))
17615 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17616 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17617 "TARGET_USE_FANCY_MATH_387
17618 && flag_unsafe_math_optimizations"
17619 "#"
17620 [(set_attr "type" "fistp")
17621 (set_attr "i387_cw" "floor")
17622 (set_attr "mode" "DI")])
17623
17624 (define_split
17625 [(set (match_operand:DI 0 "register_operand" "")
17626 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17627 UNSPEC_FIST_FLOOR))
17628 (use (match_operand:HI 2 "memory_operand" ""))
17629 (use (match_operand:HI 3 "memory_operand" ""))
17630 (clobber (match_operand:DI 4 "memory_operand" ""))
17631 (clobber (match_scratch 5 ""))]
17632 "reload_completed"
17633 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17634 (use (match_dup 2))
17635 (use (match_dup 3))
17636 (clobber (match_dup 5))])
17637 (set (match_dup 0) (match_dup 4))]
17638 "")
17639
17640 (define_split
17641 [(set (match_operand:DI 0 "memory_operand" "")
17642 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17643 UNSPEC_FIST_FLOOR))
17644 (use (match_operand:HI 2 "memory_operand" ""))
17645 (use (match_operand:HI 3 "memory_operand" ""))
17646 (clobber (match_operand:DI 4 "memory_operand" ""))
17647 (clobber (match_scratch 5 ""))]
17648 "reload_completed"
17649 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17650 (use (match_dup 2))
17651 (use (match_dup 3))
17652 (clobber (match_dup 5))])]
17653 "")
17654
17655 (define_insn "fist<mode>2_floor"
17656 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17657 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17658 UNSPEC_FIST_FLOOR))
17659 (use (match_operand:HI 2 "memory_operand" "m"))
17660 (use (match_operand:HI 3 "memory_operand" "m"))]
17661 "TARGET_USE_FANCY_MATH_387
17662 && flag_unsafe_math_optimizations"
17663 "* return output_fix_trunc (insn, operands, 0);"
17664 [(set_attr "type" "fistp")
17665 (set_attr "i387_cw" "floor")
17666 (set_attr "mode" "<MODE>")])
17667
17668 (define_insn "fist<mode>2_floor_with_temp"
17669 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17670 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17671 UNSPEC_FIST_FLOOR))
17672 (use (match_operand:HI 2 "memory_operand" "m,m"))
17673 (use (match_operand:HI 3 "memory_operand" "m,m"))
17674 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17675 "TARGET_USE_FANCY_MATH_387
17676 && flag_unsafe_math_optimizations"
17677 "#"
17678 [(set_attr "type" "fistp")
17679 (set_attr "i387_cw" "floor")
17680 (set_attr "mode" "<MODE>")])
17681
17682 (define_split
17683 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17684 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17685 UNSPEC_FIST_FLOOR))
17686 (use (match_operand:HI 2 "memory_operand" ""))
17687 (use (match_operand:HI 3 "memory_operand" ""))
17688 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17689 "reload_completed"
17690 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17691 UNSPEC_FIST_FLOOR))
17692 (use (match_dup 2))
17693 (use (match_dup 3))])
17694 (set (match_dup 0) (match_dup 4))]
17695 "")
17696
17697 (define_split
17698 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17699 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17700 UNSPEC_FIST_FLOOR))
17701 (use (match_operand:HI 2 "memory_operand" ""))
17702 (use (match_operand:HI 3 "memory_operand" ""))
17703 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17704 "reload_completed"
17705 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17706 UNSPEC_FIST_FLOOR))
17707 (use (match_dup 2))
17708 (use (match_dup 3))])]
17709 "")
17710
17711 (define_expand "lfloorxf<mode>2"
17712 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17713 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17714 UNSPEC_FIST_FLOOR))
17715 (clobber (reg:CC FLAGS_REG))])]
17716 "TARGET_USE_FANCY_MATH_387
17717 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17718 && flag_unsafe_math_optimizations"
17719 "")
17720
17721 (define_expand "lfloor<mode>di2"
17722 [(match_operand:DI 0 "nonimmediate_operand" "")
17723 (match_operand:SSEMODEF 1 "register_operand" "")]
17724 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17725 && !flag_trapping_math
17726 && !optimize_size"
17727 {
17728 ix86_expand_lfloorceil (operand0, operand1, true);
17729 DONE;
17730 })
17731
17732 (define_expand "lfloor<mode>si2"
17733 [(match_operand:SI 0 "nonimmediate_operand" "")
17734 (match_operand:SSEMODEF 1 "register_operand" "")]
17735 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17736 && !flag_trapping_math
17737 && (!optimize_size || !TARGET_64BIT)"
17738 {
17739 ix86_expand_lfloorceil (operand0, operand1, true);
17740 DONE;
17741 })
17742
17743 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17744 (define_insn_and_split "frndintxf2_ceil"
17745 [(set (match_operand:XF 0 "register_operand" "=f")
17746 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17747 UNSPEC_FRNDINT_CEIL))
17748 (clobber (reg:CC FLAGS_REG))]
17749 "TARGET_USE_FANCY_MATH_387
17750 && flag_unsafe_math_optimizations
17751 && !(reload_completed || reload_in_progress)"
17752 "#"
17753 "&& 1"
17754 [(const_int 0)]
17755 {
17756 ix86_optimize_mode_switching[I387_CEIL] = 1;
17757
17758 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17759 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17760
17761 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17762 operands[2], operands[3]));
17763 DONE;
17764 }
17765 [(set_attr "type" "frndint")
17766 (set_attr "i387_cw" "ceil")
17767 (set_attr "mode" "XF")])
17768
17769 (define_insn "frndintxf2_ceil_i387"
17770 [(set (match_operand:XF 0 "register_operand" "=f")
17771 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17772 UNSPEC_FRNDINT_CEIL))
17773 (use (match_operand:HI 2 "memory_operand" "m"))
17774 (use (match_operand:HI 3 "memory_operand" "m"))]
17775 "TARGET_USE_FANCY_MATH_387
17776 && flag_unsafe_math_optimizations"
17777 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17778 [(set_attr "type" "frndint")
17779 (set_attr "i387_cw" "ceil")
17780 (set_attr "mode" "XF")])
17781
17782 (define_expand "ceilxf2"
17783 [(use (match_operand:XF 0 "register_operand" ""))
17784 (use (match_operand:XF 1 "register_operand" ""))]
17785 "TARGET_USE_FANCY_MATH_387
17786 && flag_unsafe_math_optimizations && !optimize_size"
17787 {
17788 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17789 DONE;
17790 })
17791
17792 (define_expand "ceildf2"
17793 [(use (match_operand:DF 0 "register_operand" ""))
17794 (use (match_operand:DF 1 "register_operand" ""))]
17795 "((TARGET_USE_FANCY_MATH_387
17796 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17797 && flag_unsafe_math_optimizations)
17798 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17799 && !flag_trapping_math))
17800 && !optimize_size"
17801 {
17802 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17803 && !flag_trapping_math)
17804 {
17805 if (TARGET_64BIT)
17806 ix86_expand_floorceil (operand0, operand1, false);
17807 else
17808 ix86_expand_floorceildf_32 (operand0, operand1, false);
17809 }
17810 else
17811 {
17812 rtx op0 = gen_reg_rtx (XFmode);
17813 rtx op1 = gen_reg_rtx (XFmode);
17814
17815 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17816 emit_insn (gen_frndintxf2_ceil (op0, op1));
17817
17818 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17819 }
17820 DONE;
17821 })
17822
17823 (define_expand "ceilsf2"
17824 [(use (match_operand:SF 0 "register_operand" ""))
17825 (use (match_operand:SF 1 "register_operand" ""))]
17826 "((TARGET_USE_FANCY_MATH_387
17827 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17828 && flag_unsafe_math_optimizations)
17829 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17830 && !flag_trapping_math))
17831 && !optimize_size"
17832 {
17833 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17834 && !flag_trapping_math)
17835 ix86_expand_floorceil (operand0, operand1, false);
17836 else
17837 {
17838 rtx op0 = gen_reg_rtx (XFmode);
17839 rtx op1 = gen_reg_rtx (XFmode);
17840
17841 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17842 emit_insn (gen_frndintxf2_ceil (op0, op1));
17843
17844 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17845 }
17846 DONE;
17847 })
17848
17849 (define_insn_and_split "*fist<mode>2_ceil_1"
17850 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17851 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17852 UNSPEC_FIST_CEIL))
17853 (clobber (reg:CC FLAGS_REG))]
17854 "TARGET_USE_FANCY_MATH_387
17855 && flag_unsafe_math_optimizations
17856 && !(reload_completed || reload_in_progress)"
17857 "#"
17858 "&& 1"
17859 [(const_int 0)]
17860 {
17861 ix86_optimize_mode_switching[I387_CEIL] = 1;
17862
17863 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17864 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17865 if (memory_operand (operands[0], VOIDmode))
17866 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17867 operands[2], operands[3]));
17868 else
17869 {
17870 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17871 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17872 operands[2], operands[3],
17873 operands[4]));
17874 }
17875 DONE;
17876 }
17877 [(set_attr "type" "fistp")
17878 (set_attr "i387_cw" "ceil")
17879 (set_attr "mode" "<MODE>")])
17880
17881 (define_insn "fistdi2_ceil"
17882 [(set (match_operand:DI 0 "memory_operand" "=m")
17883 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17884 UNSPEC_FIST_CEIL))
17885 (use (match_operand:HI 2 "memory_operand" "m"))
17886 (use (match_operand:HI 3 "memory_operand" "m"))
17887 (clobber (match_scratch:XF 4 "=&1f"))]
17888 "TARGET_USE_FANCY_MATH_387
17889 && flag_unsafe_math_optimizations"
17890 "* return output_fix_trunc (insn, operands, 0);"
17891 [(set_attr "type" "fistp")
17892 (set_attr "i387_cw" "ceil")
17893 (set_attr "mode" "DI")])
17894
17895 (define_insn "fistdi2_ceil_with_temp"
17896 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17897 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17898 UNSPEC_FIST_CEIL))
17899 (use (match_operand:HI 2 "memory_operand" "m,m"))
17900 (use (match_operand:HI 3 "memory_operand" "m,m"))
17901 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17902 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17903 "TARGET_USE_FANCY_MATH_387
17904 && flag_unsafe_math_optimizations"
17905 "#"
17906 [(set_attr "type" "fistp")
17907 (set_attr "i387_cw" "ceil")
17908 (set_attr "mode" "DI")])
17909
17910 (define_split
17911 [(set (match_operand:DI 0 "register_operand" "")
17912 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17913 UNSPEC_FIST_CEIL))
17914 (use (match_operand:HI 2 "memory_operand" ""))
17915 (use (match_operand:HI 3 "memory_operand" ""))
17916 (clobber (match_operand:DI 4 "memory_operand" ""))
17917 (clobber (match_scratch 5 ""))]
17918 "reload_completed"
17919 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17920 (use (match_dup 2))
17921 (use (match_dup 3))
17922 (clobber (match_dup 5))])
17923 (set (match_dup 0) (match_dup 4))]
17924 "")
17925
17926 (define_split
17927 [(set (match_operand:DI 0 "memory_operand" "")
17928 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17929 UNSPEC_FIST_CEIL))
17930 (use (match_operand:HI 2 "memory_operand" ""))
17931 (use (match_operand:HI 3 "memory_operand" ""))
17932 (clobber (match_operand:DI 4 "memory_operand" ""))
17933 (clobber (match_scratch 5 ""))]
17934 "reload_completed"
17935 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17936 (use (match_dup 2))
17937 (use (match_dup 3))
17938 (clobber (match_dup 5))])]
17939 "")
17940
17941 (define_insn "fist<mode>2_ceil"
17942 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17943 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17944 UNSPEC_FIST_CEIL))
17945 (use (match_operand:HI 2 "memory_operand" "m"))
17946 (use (match_operand:HI 3 "memory_operand" "m"))]
17947 "TARGET_USE_FANCY_MATH_387
17948 && flag_unsafe_math_optimizations"
17949 "* return output_fix_trunc (insn, operands, 0);"
17950 [(set_attr "type" "fistp")
17951 (set_attr "i387_cw" "ceil")
17952 (set_attr "mode" "<MODE>")])
17953
17954 (define_insn "fist<mode>2_ceil_with_temp"
17955 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17956 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17957 UNSPEC_FIST_CEIL))
17958 (use (match_operand:HI 2 "memory_operand" "m,m"))
17959 (use (match_operand:HI 3 "memory_operand" "m,m"))
17960 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17961 "TARGET_USE_FANCY_MATH_387
17962 && flag_unsafe_math_optimizations"
17963 "#"
17964 [(set_attr "type" "fistp")
17965 (set_attr "i387_cw" "ceil")
17966 (set_attr "mode" "<MODE>")])
17967
17968 (define_split
17969 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17970 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17971 UNSPEC_FIST_CEIL))
17972 (use (match_operand:HI 2 "memory_operand" ""))
17973 (use (match_operand:HI 3 "memory_operand" ""))
17974 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17975 "reload_completed"
17976 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17977 UNSPEC_FIST_CEIL))
17978 (use (match_dup 2))
17979 (use (match_dup 3))])
17980 (set (match_dup 0) (match_dup 4))]
17981 "")
17982
17983 (define_split
17984 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17985 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17986 UNSPEC_FIST_CEIL))
17987 (use (match_operand:HI 2 "memory_operand" ""))
17988 (use (match_operand:HI 3 "memory_operand" ""))
17989 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17990 "reload_completed"
17991 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17992 UNSPEC_FIST_CEIL))
17993 (use (match_dup 2))
17994 (use (match_dup 3))])]
17995 "")
17996
17997 (define_expand "lceilxf<mode>2"
17998 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17999 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18000 UNSPEC_FIST_CEIL))
18001 (clobber (reg:CC FLAGS_REG))])]
18002 "TARGET_USE_FANCY_MATH_387
18003 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18004 && flag_unsafe_math_optimizations"
18005 "")
18006
18007 (define_expand "lceil<mode>di2"
18008 [(match_operand:DI 0 "nonimmediate_operand" "")
18009 (match_operand:SSEMODEF 1 "register_operand" "")]
18010 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18011 && !flag_trapping_math"
18012 {
18013 ix86_expand_lfloorceil (operand0, operand1, false);
18014 DONE;
18015 })
18016
18017 (define_expand "lceil<mode>si2"
18018 [(match_operand:SI 0 "nonimmediate_operand" "")
18019 (match_operand:SSEMODEF 1 "register_operand" "")]
18020 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18021 && !flag_trapping_math"
18022 {
18023 ix86_expand_lfloorceil (operand0, operand1, false);
18024 DONE;
18025 })
18026
18027 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18028 (define_insn_and_split "frndintxf2_trunc"
18029 [(set (match_operand:XF 0 "register_operand" "=f")
18030 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18031 UNSPEC_FRNDINT_TRUNC))
18032 (clobber (reg:CC FLAGS_REG))]
18033 "TARGET_USE_FANCY_MATH_387
18034 && flag_unsafe_math_optimizations
18035 && !(reload_completed || reload_in_progress)"
18036 "#"
18037 "&& 1"
18038 [(const_int 0)]
18039 {
18040 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18041
18042 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18043 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18044
18045 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18046 operands[2], operands[3]));
18047 DONE;
18048 }
18049 [(set_attr "type" "frndint")
18050 (set_attr "i387_cw" "trunc")
18051 (set_attr "mode" "XF")])
18052
18053 (define_insn "frndintxf2_trunc_i387"
18054 [(set (match_operand:XF 0 "register_operand" "=f")
18055 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18056 UNSPEC_FRNDINT_TRUNC))
18057 (use (match_operand:HI 2 "memory_operand" "m"))
18058 (use (match_operand:HI 3 "memory_operand" "m"))]
18059 "TARGET_USE_FANCY_MATH_387
18060 && flag_unsafe_math_optimizations"
18061 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18062 [(set_attr "type" "frndint")
18063 (set_attr "i387_cw" "trunc")
18064 (set_attr "mode" "XF")])
18065
18066 (define_expand "btruncxf2"
18067 [(use (match_operand:XF 0 "register_operand" ""))
18068 (use (match_operand:XF 1 "register_operand" ""))]
18069 "TARGET_USE_FANCY_MATH_387
18070 && flag_unsafe_math_optimizations && !optimize_size"
18071 {
18072 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18073 DONE;
18074 })
18075
18076 (define_expand "btruncdf2"
18077 [(use (match_operand:DF 0 "register_operand" ""))
18078 (use (match_operand:DF 1 "register_operand" ""))]
18079 "((TARGET_USE_FANCY_MATH_387
18080 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18081 && flag_unsafe_math_optimizations)
18082 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18083 && !flag_trapping_math))
18084 && !optimize_size"
18085 {
18086 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18087 && !flag_trapping_math)
18088 {
18089 if (TARGET_64BIT)
18090 ix86_expand_trunc (operand0, operand1);
18091 else
18092 ix86_expand_truncdf_32 (operand0, operand1);
18093 }
18094 else
18095 {
18096 rtx op0 = gen_reg_rtx (XFmode);
18097 rtx op1 = gen_reg_rtx (XFmode);
18098
18099 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18100 emit_insn (gen_frndintxf2_trunc (op0, op1));
18101
18102 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18103 }
18104 DONE;
18105 })
18106
18107 (define_expand "btruncsf2"
18108 [(use (match_operand:SF 0 "register_operand" ""))
18109 (use (match_operand:SF 1 "register_operand" ""))]
18110 "((TARGET_USE_FANCY_MATH_387
18111 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18112 && flag_unsafe_math_optimizations)
18113 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18114 && !flag_trapping_math))
18115 && !optimize_size"
18116 {
18117 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18118 && !flag_trapping_math)
18119 ix86_expand_trunc (operand0, operand1);
18120 else
18121 {
18122 rtx op0 = gen_reg_rtx (XFmode);
18123 rtx op1 = gen_reg_rtx (XFmode);
18124
18125 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18126 emit_insn (gen_frndintxf2_trunc (op0, op1));
18127
18128 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18129 }
18130 DONE;
18131 })
18132
18133 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18134 (define_insn_and_split "frndintxf2_mask_pm"
18135 [(set (match_operand:XF 0 "register_operand" "=f")
18136 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18137 UNSPEC_FRNDINT_MASK_PM))
18138 (clobber (reg:CC FLAGS_REG))]
18139 "TARGET_USE_FANCY_MATH_387
18140 && flag_unsafe_math_optimizations
18141 && !(reload_completed || reload_in_progress)"
18142 "#"
18143 "&& 1"
18144 [(const_int 0)]
18145 {
18146 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18147
18148 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18149 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18150
18151 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18152 operands[2], operands[3]));
18153 DONE;
18154 }
18155 [(set_attr "type" "frndint")
18156 (set_attr "i387_cw" "mask_pm")
18157 (set_attr "mode" "XF")])
18158
18159 (define_insn "frndintxf2_mask_pm_i387"
18160 [(set (match_operand:XF 0 "register_operand" "=f")
18161 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18162 UNSPEC_FRNDINT_MASK_PM))
18163 (use (match_operand:HI 2 "memory_operand" "m"))
18164 (use (match_operand:HI 3 "memory_operand" "m"))]
18165 "TARGET_USE_FANCY_MATH_387
18166 && flag_unsafe_math_optimizations"
18167 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18168 [(set_attr "type" "frndint")
18169 (set_attr "i387_cw" "mask_pm")
18170 (set_attr "mode" "XF")])
18171
18172 (define_expand "nearbyintxf2"
18173 [(use (match_operand:XF 0 "register_operand" ""))
18174 (use (match_operand:XF 1 "register_operand" ""))]
18175 "TARGET_USE_FANCY_MATH_387
18176 && flag_unsafe_math_optimizations"
18177 {
18178 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18179
18180 DONE;
18181 })
18182
18183 (define_expand "nearbyintdf2"
18184 [(use (match_operand:DF 0 "register_operand" ""))
18185 (use (match_operand:DF 1 "register_operand" ""))]
18186 "TARGET_USE_FANCY_MATH_387
18187 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18188 && flag_unsafe_math_optimizations"
18189 {
18190 rtx op0 = gen_reg_rtx (XFmode);
18191 rtx op1 = gen_reg_rtx (XFmode);
18192
18193 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18194 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18195
18196 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18197 DONE;
18198 })
18199
18200 (define_expand "nearbyintsf2"
18201 [(use (match_operand:SF 0 "register_operand" ""))
18202 (use (match_operand:SF 1 "register_operand" ""))]
18203 "TARGET_USE_FANCY_MATH_387
18204 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18205 && flag_unsafe_math_optimizations"
18206 {
18207 rtx op0 = gen_reg_rtx (XFmode);
18208 rtx op1 = gen_reg_rtx (XFmode);
18209
18210 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18211 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18212
18213 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18214 DONE;
18215 })
18216
18217 \f
18218 ;; Block operation instructions
18219
18220 (define_insn "cld"
18221 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18222 ""
18223 "cld"
18224 [(set_attr "type" "cld")])
18225
18226 (define_expand "movmemsi"
18227 [(use (match_operand:BLK 0 "memory_operand" ""))
18228 (use (match_operand:BLK 1 "memory_operand" ""))
18229 (use (match_operand:SI 2 "nonmemory_operand" ""))
18230 (use (match_operand:SI 3 "const_int_operand" ""))]
18231 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18232 {
18233 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18234 DONE;
18235 else
18236 FAIL;
18237 })
18238
18239 (define_expand "movmemdi"
18240 [(use (match_operand:BLK 0 "memory_operand" ""))
18241 (use (match_operand:BLK 1 "memory_operand" ""))
18242 (use (match_operand:DI 2 "nonmemory_operand" ""))
18243 (use (match_operand:DI 3 "const_int_operand" ""))]
18244 "TARGET_64BIT"
18245 {
18246 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18247 DONE;
18248 else
18249 FAIL;
18250 })
18251
18252 ;; Most CPUs don't like single string operations
18253 ;; Handle this case here to simplify previous expander.
18254
18255 (define_expand "strmov"
18256 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18257 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18258 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18259 (clobber (reg:CC FLAGS_REG))])
18260 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18261 (clobber (reg:CC FLAGS_REG))])]
18262 ""
18263 {
18264 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18265
18266 /* If .md ever supports :P for Pmode, these can be directly
18267 in the pattern above. */
18268 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18269 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18270
18271 if (TARGET_SINGLE_STRINGOP || optimize_size)
18272 {
18273 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18274 operands[2], operands[3],
18275 operands[5], operands[6]));
18276 DONE;
18277 }
18278
18279 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18280 })
18281
18282 (define_expand "strmov_singleop"
18283 [(parallel [(set (match_operand 1 "memory_operand" "")
18284 (match_operand 3 "memory_operand" ""))
18285 (set (match_operand 0 "register_operand" "")
18286 (match_operand 4 "" ""))
18287 (set (match_operand 2 "register_operand" "")
18288 (match_operand 5 "" ""))
18289 (use (reg:SI DIRFLAG_REG))])]
18290 "TARGET_SINGLE_STRINGOP || optimize_size"
18291 "")
18292
18293 (define_insn "*strmovdi_rex_1"
18294 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18295 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18296 (set (match_operand:DI 0 "register_operand" "=D")
18297 (plus:DI (match_dup 2)
18298 (const_int 8)))
18299 (set (match_operand:DI 1 "register_operand" "=S")
18300 (plus:DI (match_dup 3)
18301 (const_int 8)))
18302 (use (reg:SI DIRFLAG_REG))]
18303 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18304 "movsq"
18305 [(set_attr "type" "str")
18306 (set_attr "mode" "DI")
18307 (set_attr "memory" "both")])
18308
18309 (define_insn "*strmovsi_1"
18310 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18311 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18312 (set (match_operand:SI 0 "register_operand" "=D")
18313 (plus:SI (match_dup 2)
18314 (const_int 4)))
18315 (set (match_operand:SI 1 "register_operand" "=S")
18316 (plus:SI (match_dup 3)
18317 (const_int 4)))
18318 (use (reg:SI DIRFLAG_REG))]
18319 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18320 "{movsl|movsd}"
18321 [(set_attr "type" "str")
18322 (set_attr "mode" "SI")
18323 (set_attr "memory" "both")])
18324
18325 (define_insn "*strmovsi_rex_1"
18326 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18327 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18328 (set (match_operand:DI 0 "register_operand" "=D")
18329 (plus:DI (match_dup 2)
18330 (const_int 4)))
18331 (set (match_operand:DI 1 "register_operand" "=S")
18332 (plus:DI (match_dup 3)
18333 (const_int 4)))
18334 (use (reg:SI DIRFLAG_REG))]
18335 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18336 "{movsl|movsd}"
18337 [(set_attr "type" "str")
18338 (set_attr "mode" "SI")
18339 (set_attr "memory" "both")])
18340
18341 (define_insn "*strmovhi_1"
18342 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18343 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18344 (set (match_operand:SI 0 "register_operand" "=D")
18345 (plus:SI (match_dup 2)
18346 (const_int 2)))
18347 (set (match_operand:SI 1 "register_operand" "=S")
18348 (plus:SI (match_dup 3)
18349 (const_int 2)))
18350 (use (reg:SI DIRFLAG_REG))]
18351 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18352 "movsw"
18353 [(set_attr "type" "str")
18354 (set_attr "memory" "both")
18355 (set_attr "mode" "HI")])
18356
18357 (define_insn "*strmovhi_rex_1"
18358 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18359 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18360 (set (match_operand:DI 0 "register_operand" "=D")
18361 (plus:DI (match_dup 2)
18362 (const_int 2)))
18363 (set (match_operand:DI 1 "register_operand" "=S")
18364 (plus:DI (match_dup 3)
18365 (const_int 2)))
18366 (use (reg:SI DIRFLAG_REG))]
18367 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18368 "movsw"
18369 [(set_attr "type" "str")
18370 (set_attr "memory" "both")
18371 (set_attr "mode" "HI")])
18372
18373 (define_insn "*strmovqi_1"
18374 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18375 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18376 (set (match_operand:SI 0 "register_operand" "=D")
18377 (plus:SI (match_dup 2)
18378 (const_int 1)))
18379 (set (match_operand:SI 1 "register_operand" "=S")
18380 (plus:SI (match_dup 3)
18381 (const_int 1)))
18382 (use (reg:SI DIRFLAG_REG))]
18383 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18384 "movsb"
18385 [(set_attr "type" "str")
18386 (set_attr "memory" "both")
18387 (set_attr "mode" "QI")])
18388
18389 (define_insn "*strmovqi_rex_1"
18390 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18391 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18392 (set (match_operand:DI 0 "register_operand" "=D")
18393 (plus:DI (match_dup 2)
18394 (const_int 1)))
18395 (set (match_operand:DI 1 "register_operand" "=S")
18396 (plus:DI (match_dup 3)
18397 (const_int 1)))
18398 (use (reg:SI DIRFLAG_REG))]
18399 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18400 "movsb"
18401 [(set_attr "type" "str")
18402 (set_attr "memory" "both")
18403 (set_attr "mode" "QI")])
18404
18405 (define_expand "rep_mov"
18406 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18407 (set (match_operand 0 "register_operand" "")
18408 (match_operand 5 "" ""))
18409 (set (match_operand 2 "register_operand" "")
18410 (match_operand 6 "" ""))
18411 (set (match_operand 1 "memory_operand" "")
18412 (match_operand 3 "memory_operand" ""))
18413 (use (match_dup 4))
18414 (use (reg:SI DIRFLAG_REG))])]
18415 ""
18416 "")
18417
18418 (define_insn "*rep_movdi_rex64"
18419 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18420 (set (match_operand:DI 0 "register_operand" "=D")
18421 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18422 (const_int 3))
18423 (match_operand:DI 3 "register_operand" "0")))
18424 (set (match_operand:DI 1 "register_operand" "=S")
18425 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18426 (match_operand:DI 4 "register_operand" "1")))
18427 (set (mem:BLK (match_dup 3))
18428 (mem:BLK (match_dup 4)))
18429 (use (match_dup 5))
18430 (use (reg:SI DIRFLAG_REG))]
18431 "TARGET_64BIT"
18432 "{rep\;movsq|rep movsq}"
18433 [(set_attr "type" "str")
18434 (set_attr "prefix_rep" "1")
18435 (set_attr "memory" "both")
18436 (set_attr "mode" "DI")])
18437
18438 (define_insn "*rep_movsi"
18439 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18440 (set (match_operand:SI 0 "register_operand" "=D")
18441 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18442 (const_int 2))
18443 (match_operand:SI 3 "register_operand" "0")))
18444 (set (match_operand:SI 1 "register_operand" "=S")
18445 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18446 (match_operand:SI 4 "register_operand" "1")))
18447 (set (mem:BLK (match_dup 3))
18448 (mem:BLK (match_dup 4)))
18449 (use (match_dup 5))
18450 (use (reg:SI DIRFLAG_REG))]
18451 "!TARGET_64BIT"
18452 "{rep\;movsl|rep movsd}"
18453 [(set_attr "type" "str")
18454 (set_attr "prefix_rep" "1")
18455 (set_attr "memory" "both")
18456 (set_attr "mode" "SI")])
18457
18458 (define_insn "*rep_movsi_rex64"
18459 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18460 (set (match_operand:DI 0 "register_operand" "=D")
18461 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18462 (const_int 2))
18463 (match_operand:DI 3 "register_operand" "0")))
18464 (set (match_operand:DI 1 "register_operand" "=S")
18465 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18466 (match_operand:DI 4 "register_operand" "1")))
18467 (set (mem:BLK (match_dup 3))
18468 (mem:BLK (match_dup 4)))
18469 (use (match_dup 5))
18470 (use (reg:SI DIRFLAG_REG))]
18471 "TARGET_64BIT"
18472 "{rep\;movsl|rep movsd}"
18473 [(set_attr "type" "str")
18474 (set_attr "prefix_rep" "1")
18475 (set_attr "memory" "both")
18476 (set_attr "mode" "SI")])
18477
18478 (define_insn "*rep_movqi"
18479 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18480 (set (match_operand:SI 0 "register_operand" "=D")
18481 (plus:SI (match_operand:SI 3 "register_operand" "0")
18482 (match_operand:SI 5 "register_operand" "2")))
18483 (set (match_operand:SI 1 "register_operand" "=S")
18484 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18485 (set (mem:BLK (match_dup 3))
18486 (mem:BLK (match_dup 4)))
18487 (use (match_dup 5))
18488 (use (reg:SI DIRFLAG_REG))]
18489 "!TARGET_64BIT"
18490 "{rep\;movsb|rep movsb}"
18491 [(set_attr "type" "str")
18492 (set_attr "prefix_rep" "1")
18493 (set_attr "memory" "both")
18494 (set_attr "mode" "SI")])
18495
18496 (define_insn "*rep_movqi_rex64"
18497 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18498 (set (match_operand:DI 0 "register_operand" "=D")
18499 (plus:DI (match_operand:DI 3 "register_operand" "0")
18500 (match_operand:DI 5 "register_operand" "2")))
18501 (set (match_operand:DI 1 "register_operand" "=S")
18502 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18503 (set (mem:BLK (match_dup 3))
18504 (mem:BLK (match_dup 4)))
18505 (use (match_dup 5))
18506 (use (reg:SI DIRFLAG_REG))]
18507 "TARGET_64BIT"
18508 "{rep\;movsb|rep movsb}"
18509 [(set_attr "type" "str")
18510 (set_attr "prefix_rep" "1")
18511 (set_attr "memory" "both")
18512 (set_attr "mode" "SI")])
18513
18514 (define_expand "setmemsi"
18515 [(use (match_operand:BLK 0 "memory_operand" ""))
18516 (use (match_operand:SI 1 "nonmemory_operand" ""))
18517 (use (match_operand 2 "const_int_operand" ""))
18518 (use (match_operand 3 "const_int_operand" ""))]
18519 ""
18520 {
18521 /* If value to set is not zero, use the library routine. */
18522 if (operands[2] != const0_rtx)
18523 FAIL;
18524
18525 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18526 DONE;
18527 else
18528 FAIL;
18529 })
18530
18531 (define_expand "setmemdi"
18532 [(use (match_operand:BLK 0 "memory_operand" ""))
18533 (use (match_operand:DI 1 "nonmemory_operand" ""))
18534 (use (match_operand 2 "const_int_operand" ""))
18535 (use (match_operand 3 "const_int_operand" ""))]
18536 "TARGET_64BIT"
18537 {
18538 /* If value to set is not zero, use the library routine. */
18539 if (operands[2] != const0_rtx)
18540 FAIL;
18541
18542 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18543 DONE;
18544 else
18545 FAIL;
18546 })
18547
18548 ;; Most CPUs don't like single string operations
18549 ;; Handle this case here to simplify previous expander.
18550
18551 (define_expand "strset"
18552 [(set (match_operand 1 "memory_operand" "")
18553 (match_operand 2 "register_operand" ""))
18554 (parallel [(set (match_operand 0 "register_operand" "")
18555 (match_dup 3))
18556 (clobber (reg:CC FLAGS_REG))])]
18557 ""
18558 {
18559 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18560 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18561
18562 /* If .md ever supports :P for Pmode, this can be directly
18563 in the pattern above. */
18564 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18565 GEN_INT (GET_MODE_SIZE (GET_MODE
18566 (operands[2]))));
18567 if (TARGET_SINGLE_STRINGOP || optimize_size)
18568 {
18569 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18570 operands[3]));
18571 DONE;
18572 }
18573 })
18574
18575 (define_expand "strset_singleop"
18576 [(parallel [(set (match_operand 1 "memory_operand" "")
18577 (match_operand 2 "register_operand" ""))
18578 (set (match_operand 0 "register_operand" "")
18579 (match_operand 3 "" ""))
18580 (use (reg:SI DIRFLAG_REG))])]
18581 "TARGET_SINGLE_STRINGOP || optimize_size"
18582 "")
18583
18584 (define_insn "*strsetdi_rex_1"
18585 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18586 (match_operand:DI 2 "register_operand" "a"))
18587 (set (match_operand:DI 0 "register_operand" "=D")
18588 (plus:DI (match_dup 1)
18589 (const_int 8)))
18590 (use (reg:SI DIRFLAG_REG))]
18591 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18592 "stosq"
18593 [(set_attr "type" "str")
18594 (set_attr "memory" "store")
18595 (set_attr "mode" "DI")])
18596
18597 (define_insn "*strsetsi_1"
18598 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18599 (match_operand:SI 2 "register_operand" "a"))
18600 (set (match_operand:SI 0 "register_operand" "=D")
18601 (plus:SI (match_dup 1)
18602 (const_int 4)))
18603 (use (reg:SI DIRFLAG_REG))]
18604 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18605 "{stosl|stosd}"
18606 [(set_attr "type" "str")
18607 (set_attr "memory" "store")
18608 (set_attr "mode" "SI")])
18609
18610 (define_insn "*strsetsi_rex_1"
18611 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18612 (match_operand:SI 2 "register_operand" "a"))
18613 (set (match_operand:DI 0 "register_operand" "=D")
18614 (plus:DI (match_dup 1)
18615 (const_int 4)))
18616 (use (reg:SI DIRFLAG_REG))]
18617 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18618 "{stosl|stosd}"
18619 [(set_attr "type" "str")
18620 (set_attr "memory" "store")
18621 (set_attr "mode" "SI")])
18622
18623 (define_insn "*strsethi_1"
18624 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18625 (match_operand:HI 2 "register_operand" "a"))
18626 (set (match_operand:SI 0 "register_operand" "=D")
18627 (plus:SI (match_dup 1)
18628 (const_int 2)))
18629 (use (reg:SI DIRFLAG_REG))]
18630 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18631 "stosw"
18632 [(set_attr "type" "str")
18633 (set_attr "memory" "store")
18634 (set_attr "mode" "HI")])
18635
18636 (define_insn "*strsethi_rex_1"
18637 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18638 (match_operand:HI 2 "register_operand" "a"))
18639 (set (match_operand:DI 0 "register_operand" "=D")
18640 (plus:DI (match_dup 1)
18641 (const_int 2)))
18642 (use (reg:SI DIRFLAG_REG))]
18643 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18644 "stosw"
18645 [(set_attr "type" "str")
18646 (set_attr "memory" "store")
18647 (set_attr "mode" "HI")])
18648
18649 (define_insn "*strsetqi_1"
18650 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18651 (match_operand:QI 2 "register_operand" "a"))
18652 (set (match_operand:SI 0 "register_operand" "=D")
18653 (plus:SI (match_dup 1)
18654 (const_int 1)))
18655 (use (reg:SI DIRFLAG_REG))]
18656 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18657 "stosb"
18658 [(set_attr "type" "str")
18659 (set_attr "memory" "store")
18660 (set_attr "mode" "QI")])
18661
18662 (define_insn "*strsetqi_rex_1"
18663 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18664 (match_operand:QI 2 "register_operand" "a"))
18665 (set (match_operand:DI 0 "register_operand" "=D")
18666 (plus:DI (match_dup 1)
18667 (const_int 1)))
18668 (use (reg:SI DIRFLAG_REG))]
18669 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18670 "stosb"
18671 [(set_attr "type" "str")
18672 (set_attr "memory" "store")
18673 (set_attr "mode" "QI")])
18674
18675 (define_expand "rep_stos"
18676 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18677 (set (match_operand 0 "register_operand" "")
18678 (match_operand 4 "" ""))
18679 (set (match_operand 2 "memory_operand" "") (const_int 0))
18680 (use (match_operand 3 "register_operand" ""))
18681 (use (match_dup 1))
18682 (use (reg:SI DIRFLAG_REG))])]
18683 ""
18684 "")
18685
18686 (define_insn "*rep_stosdi_rex64"
18687 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18688 (set (match_operand:DI 0 "register_operand" "=D")
18689 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18690 (const_int 3))
18691 (match_operand:DI 3 "register_operand" "0")))
18692 (set (mem:BLK (match_dup 3))
18693 (const_int 0))
18694 (use (match_operand:DI 2 "register_operand" "a"))
18695 (use (match_dup 4))
18696 (use (reg:SI DIRFLAG_REG))]
18697 "TARGET_64BIT"
18698 "{rep\;stosq|rep stosq}"
18699 [(set_attr "type" "str")
18700 (set_attr "prefix_rep" "1")
18701 (set_attr "memory" "store")
18702 (set_attr "mode" "DI")])
18703
18704 (define_insn "*rep_stossi"
18705 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18706 (set (match_operand:SI 0 "register_operand" "=D")
18707 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18708 (const_int 2))
18709 (match_operand:SI 3 "register_operand" "0")))
18710 (set (mem:BLK (match_dup 3))
18711 (const_int 0))
18712 (use (match_operand:SI 2 "register_operand" "a"))
18713 (use (match_dup 4))
18714 (use (reg:SI DIRFLAG_REG))]
18715 "!TARGET_64BIT"
18716 "{rep\;stosl|rep stosd}"
18717 [(set_attr "type" "str")
18718 (set_attr "prefix_rep" "1")
18719 (set_attr "memory" "store")
18720 (set_attr "mode" "SI")])
18721
18722 (define_insn "*rep_stossi_rex64"
18723 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18724 (set (match_operand:DI 0 "register_operand" "=D")
18725 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18726 (const_int 2))
18727 (match_operand:DI 3 "register_operand" "0")))
18728 (set (mem:BLK (match_dup 3))
18729 (const_int 0))
18730 (use (match_operand:SI 2 "register_operand" "a"))
18731 (use (match_dup 4))
18732 (use (reg:SI DIRFLAG_REG))]
18733 "TARGET_64BIT"
18734 "{rep\;stosl|rep stosd}"
18735 [(set_attr "type" "str")
18736 (set_attr "prefix_rep" "1")
18737 (set_attr "memory" "store")
18738 (set_attr "mode" "SI")])
18739
18740 (define_insn "*rep_stosqi"
18741 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18742 (set (match_operand:SI 0 "register_operand" "=D")
18743 (plus:SI (match_operand:SI 3 "register_operand" "0")
18744 (match_operand:SI 4 "register_operand" "1")))
18745 (set (mem:BLK (match_dup 3))
18746 (const_int 0))
18747 (use (match_operand:QI 2 "register_operand" "a"))
18748 (use (match_dup 4))
18749 (use (reg:SI DIRFLAG_REG))]
18750 "!TARGET_64BIT"
18751 "{rep\;stosb|rep stosb}"
18752 [(set_attr "type" "str")
18753 (set_attr "prefix_rep" "1")
18754 (set_attr "memory" "store")
18755 (set_attr "mode" "QI")])
18756
18757 (define_insn "*rep_stosqi_rex64"
18758 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18759 (set (match_operand:DI 0 "register_operand" "=D")
18760 (plus:DI (match_operand:DI 3 "register_operand" "0")
18761 (match_operand:DI 4 "register_operand" "1")))
18762 (set (mem:BLK (match_dup 3))
18763 (const_int 0))
18764 (use (match_operand:QI 2 "register_operand" "a"))
18765 (use (match_dup 4))
18766 (use (reg:SI DIRFLAG_REG))]
18767 "TARGET_64BIT"
18768 "{rep\;stosb|rep stosb}"
18769 [(set_attr "type" "str")
18770 (set_attr "prefix_rep" "1")
18771 (set_attr "memory" "store")
18772 (set_attr "mode" "QI")])
18773
18774 (define_expand "cmpstrnsi"
18775 [(set (match_operand:SI 0 "register_operand" "")
18776 (compare:SI (match_operand:BLK 1 "general_operand" "")
18777 (match_operand:BLK 2 "general_operand" "")))
18778 (use (match_operand 3 "general_operand" ""))
18779 (use (match_operand 4 "immediate_operand" ""))]
18780 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18781 {
18782 rtx addr1, addr2, out, outlow, count, countreg, align;
18783
18784 /* Can't use this if the user has appropriated esi or edi. */
18785 if (global_regs[4] || global_regs[5])
18786 FAIL;
18787
18788 out = operands[0];
18789 if (GET_CODE (out) != REG)
18790 out = gen_reg_rtx (SImode);
18791
18792 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18793 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18794 if (addr1 != XEXP (operands[1], 0))
18795 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18796 if (addr2 != XEXP (operands[2], 0))
18797 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18798
18799 count = operands[3];
18800 countreg = ix86_zero_extend_to_Pmode (count);
18801
18802 /* %%% Iff we are testing strict equality, we can use known alignment
18803 to good advantage. This may be possible with combine, particularly
18804 once cc0 is dead. */
18805 align = operands[4];
18806
18807 emit_insn (gen_cld ());
18808 if (GET_CODE (count) == CONST_INT)
18809 {
18810 if (INTVAL (count) == 0)
18811 {
18812 emit_move_insn (operands[0], const0_rtx);
18813 DONE;
18814 }
18815 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18816 operands[1], operands[2]));
18817 }
18818 else
18819 {
18820 if (TARGET_64BIT)
18821 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18822 else
18823 emit_insn (gen_cmpsi_1 (countreg, countreg));
18824 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18825 operands[1], operands[2]));
18826 }
18827
18828 outlow = gen_lowpart (QImode, out);
18829 emit_insn (gen_cmpintqi (outlow));
18830 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18831
18832 if (operands[0] != out)
18833 emit_move_insn (operands[0], out);
18834
18835 DONE;
18836 })
18837
18838 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18839
18840 (define_expand "cmpintqi"
18841 [(set (match_dup 1)
18842 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18843 (set (match_dup 2)
18844 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18845 (parallel [(set (match_operand:QI 0 "register_operand" "")
18846 (minus:QI (match_dup 1)
18847 (match_dup 2)))
18848 (clobber (reg:CC FLAGS_REG))])]
18849 ""
18850 "operands[1] = gen_reg_rtx (QImode);
18851 operands[2] = gen_reg_rtx (QImode);")
18852
18853 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18854 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18855
18856 (define_expand "cmpstrnqi_nz_1"
18857 [(parallel [(set (reg:CC FLAGS_REG)
18858 (compare:CC (match_operand 4 "memory_operand" "")
18859 (match_operand 5 "memory_operand" "")))
18860 (use (match_operand 2 "register_operand" ""))
18861 (use (match_operand:SI 3 "immediate_operand" ""))
18862 (use (reg:SI DIRFLAG_REG))
18863 (clobber (match_operand 0 "register_operand" ""))
18864 (clobber (match_operand 1 "register_operand" ""))
18865 (clobber (match_dup 2))])]
18866 ""
18867 "")
18868
18869 (define_insn "*cmpstrnqi_nz_1"
18870 [(set (reg:CC FLAGS_REG)
18871 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18872 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18873 (use (match_operand:SI 6 "register_operand" "2"))
18874 (use (match_operand:SI 3 "immediate_operand" "i"))
18875 (use (reg:SI DIRFLAG_REG))
18876 (clobber (match_operand:SI 0 "register_operand" "=S"))
18877 (clobber (match_operand:SI 1 "register_operand" "=D"))
18878 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18879 "!TARGET_64BIT"
18880 "repz{\;| }cmpsb"
18881 [(set_attr "type" "str")
18882 (set_attr "mode" "QI")
18883 (set_attr "prefix_rep" "1")])
18884
18885 (define_insn "*cmpstrnqi_nz_rex_1"
18886 [(set (reg:CC FLAGS_REG)
18887 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18888 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18889 (use (match_operand:DI 6 "register_operand" "2"))
18890 (use (match_operand:SI 3 "immediate_operand" "i"))
18891 (use (reg:SI DIRFLAG_REG))
18892 (clobber (match_operand:DI 0 "register_operand" "=S"))
18893 (clobber (match_operand:DI 1 "register_operand" "=D"))
18894 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18895 "TARGET_64BIT"
18896 "repz{\;| }cmpsb"
18897 [(set_attr "type" "str")
18898 (set_attr "mode" "QI")
18899 (set_attr "prefix_rep" "1")])
18900
18901 ;; The same, but the count is not known to not be zero.
18902
18903 (define_expand "cmpstrnqi_1"
18904 [(parallel [(set (reg:CC FLAGS_REG)
18905 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18906 (const_int 0))
18907 (compare:CC (match_operand 4 "memory_operand" "")
18908 (match_operand 5 "memory_operand" ""))
18909 (const_int 0)))
18910 (use (match_operand:SI 3 "immediate_operand" ""))
18911 (use (reg:CC FLAGS_REG))
18912 (use (reg:SI DIRFLAG_REG))
18913 (clobber (match_operand 0 "register_operand" ""))
18914 (clobber (match_operand 1 "register_operand" ""))
18915 (clobber (match_dup 2))])]
18916 ""
18917 "")
18918
18919 (define_insn "*cmpstrnqi_1"
18920 [(set (reg:CC FLAGS_REG)
18921 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18922 (const_int 0))
18923 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18924 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18925 (const_int 0)))
18926 (use (match_operand:SI 3 "immediate_operand" "i"))
18927 (use (reg:CC FLAGS_REG))
18928 (use (reg:SI DIRFLAG_REG))
18929 (clobber (match_operand:SI 0 "register_operand" "=S"))
18930 (clobber (match_operand:SI 1 "register_operand" "=D"))
18931 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18932 "!TARGET_64BIT"
18933 "repz{\;| }cmpsb"
18934 [(set_attr "type" "str")
18935 (set_attr "mode" "QI")
18936 (set_attr "prefix_rep" "1")])
18937
18938 (define_insn "*cmpstrnqi_rex_1"
18939 [(set (reg:CC FLAGS_REG)
18940 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18941 (const_int 0))
18942 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18943 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18944 (const_int 0)))
18945 (use (match_operand:SI 3 "immediate_operand" "i"))
18946 (use (reg:CC FLAGS_REG))
18947 (use (reg:SI DIRFLAG_REG))
18948 (clobber (match_operand:DI 0 "register_operand" "=S"))
18949 (clobber (match_operand:DI 1 "register_operand" "=D"))
18950 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18951 "TARGET_64BIT"
18952 "repz{\;| }cmpsb"
18953 [(set_attr "type" "str")
18954 (set_attr "mode" "QI")
18955 (set_attr "prefix_rep" "1")])
18956
18957 (define_expand "strlensi"
18958 [(set (match_operand:SI 0 "register_operand" "")
18959 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18960 (match_operand:QI 2 "immediate_operand" "")
18961 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18962 ""
18963 {
18964 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18965 DONE;
18966 else
18967 FAIL;
18968 })
18969
18970 (define_expand "strlendi"
18971 [(set (match_operand:DI 0 "register_operand" "")
18972 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18973 (match_operand:QI 2 "immediate_operand" "")
18974 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18975 ""
18976 {
18977 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18978 DONE;
18979 else
18980 FAIL;
18981 })
18982
18983 (define_expand "strlenqi_1"
18984 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18985 (use (reg:SI DIRFLAG_REG))
18986 (clobber (match_operand 1 "register_operand" ""))
18987 (clobber (reg:CC FLAGS_REG))])]
18988 ""
18989 "")
18990
18991 (define_insn "*strlenqi_1"
18992 [(set (match_operand:SI 0 "register_operand" "=&c")
18993 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18994 (match_operand:QI 2 "register_operand" "a")
18995 (match_operand:SI 3 "immediate_operand" "i")
18996 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18997 (use (reg:SI DIRFLAG_REG))
18998 (clobber (match_operand:SI 1 "register_operand" "=D"))
18999 (clobber (reg:CC FLAGS_REG))]
19000 "!TARGET_64BIT"
19001 "repnz{\;| }scasb"
19002 [(set_attr "type" "str")
19003 (set_attr "mode" "QI")
19004 (set_attr "prefix_rep" "1")])
19005
19006 (define_insn "*strlenqi_rex_1"
19007 [(set (match_operand:DI 0 "register_operand" "=&c")
19008 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19009 (match_operand:QI 2 "register_operand" "a")
19010 (match_operand:DI 3 "immediate_operand" "i")
19011 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19012 (use (reg:SI DIRFLAG_REG))
19013 (clobber (match_operand:DI 1 "register_operand" "=D"))
19014 (clobber (reg:CC FLAGS_REG))]
19015 "TARGET_64BIT"
19016 "repnz{\;| }scasb"
19017 [(set_attr "type" "str")
19018 (set_attr "mode" "QI")
19019 (set_attr "prefix_rep" "1")])
19020
19021 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19022 ;; handled in combine, but it is not currently up to the task.
19023 ;; When used for their truth value, the cmpstrn* expanders generate
19024 ;; code like this:
19025 ;;
19026 ;; repz cmpsb
19027 ;; seta %al
19028 ;; setb %dl
19029 ;; cmpb %al, %dl
19030 ;; jcc label
19031 ;;
19032 ;; The intermediate three instructions are unnecessary.
19033
19034 ;; This one handles cmpstrn*_nz_1...
19035 (define_peephole2
19036 [(parallel[
19037 (set (reg:CC FLAGS_REG)
19038 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19039 (mem:BLK (match_operand 5 "register_operand" ""))))
19040 (use (match_operand 6 "register_operand" ""))
19041 (use (match_operand:SI 3 "immediate_operand" ""))
19042 (use (reg:SI DIRFLAG_REG))
19043 (clobber (match_operand 0 "register_operand" ""))
19044 (clobber (match_operand 1 "register_operand" ""))
19045 (clobber (match_operand 2 "register_operand" ""))])
19046 (set (match_operand:QI 7 "register_operand" "")
19047 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19048 (set (match_operand:QI 8 "register_operand" "")
19049 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19050 (set (reg FLAGS_REG)
19051 (compare (match_dup 7) (match_dup 8)))
19052 ]
19053 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19054 [(parallel[
19055 (set (reg:CC FLAGS_REG)
19056 (compare:CC (mem:BLK (match_dup 4))
19057 (mem:BLK (match_dup 5))))
19058 (use (match_dup 6))
19059 (use (match_dup 3))
19060 (use (reg:SI DIRFLAG_REG))
19061 (clobber (match_dup 0))
19062 (clobber (match_dup 1))
19063 (clobber (match_dup 2))])]
19064 "")
19065
19066 ;; ...and this one handles cmpstrn*_1.
19067 (define_peephole2
19068 [(parallel[
19069 (set (reg:CC FLAGS_REG)
19070 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19071 (const_int 0))
19072 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19073 (mem:BLK (match_operand 5 "register_operand" "")))
19074 (const_int 0)))
19075 (use (match_operand:SI 3 "immediate_operand" ""))
19076 (use (reg:CC FLAGS_REG))
19077 (use (reg:SI DIRFLAG_REG))
19078 (clobber (match_operand 0 "register_operand" ""))
19079 (clobber (match_operand 1 "register_operand" ""))
19080 (clobber (match_operand 2 "register_operand" ""))])
19081 (set (match_operand:QI 7 "register_operand" "")
19082 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19083 (set (match_operand:QI 8 "register_operand" "")
19084 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19085 (set (reg FLAGS_REG)
19086 (compare (match_dup 7) (match_dup 8)))
19087 ]
19088 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19089 [(parallel[
19090 (set (reg:CC FLAGS_REG)
19091 (if_then_else:CC (ne (match_dup 6)
19092 (const_int 0))
19093 (compare:CC (mem:BLK (match_dup 4))
19094 (mem:BLK (match_dup 5)))
19095 (const_int 0)))
19096 (use (match_dup 3))
19097 (use (reg:CC FLAGS_REG))
19098 (use (reg:SI DIRFLAG_REG))
19099 (clobber (match_dup 0))
19100 (clobber (match_dup 1))
19101 (clobber (match_dup 2))])]
19102 "")
19103
19104
19105 \f
19106 ;; Conditional move instructions.
19107
19108 (define_expand "movdicc"
19109 [(set (match_operand:DI 0 "register_operand" "")
19110 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19111 (match_operand:DI 2 "general_operand" "")
19112 (match_operand:DI 3 "general_operand" "")))]
19113 "TARGET_64BIT"
19114 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19115
19116 (define_insn "x86_movdicc_0_m1_rex64"
19117 [(set (match_operand:DI 0 "register_operand" "=r")
19118 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19119 (const_int -1)
19120 (const_int 0)))
19121 (clobber (reg:CC FLAGS_REG))]
19122 "TARGET_64BIT"
19123 "sbb{q}\t%0, %0"
19124 ; Since we don't have the proper number of operands for an alu insn,
19125 ; fill in all the blanks.
19126 [(set_attr "type" "alu")
19127 (set_attr "pent_pair" "pu")
19128 (set_attr "memory" "none")
19129 (set_attr "imm_disp" "false")
19130 (set_attr "mode" "DI")
19131 (set_attr "length_immediate" "0")])
19132
19133 (define_insn "*movdicc_c_rex64"
19134 [(set (match_operand:DI 0 "register_operand" "=r,r")
19135 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19136 [(reg FLAGS_REG) (const_int 0)])
19137 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19138 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19139 "TARGET_64BIT && TARGET_CMOVE
19140 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19141 "@
19142 cmov%O2%C1\t{%2, %0|%0, %2}
19143 cmov%O2%c1\t{%3, %0|%0, %3}"
19144 [(set_attr "type" "icmov")
19145 (set_attr "mode" "DI")])
19146
19147 (define_expand "movsicc"
19148 [(set (match_operand:SI 0 "register_operand" "")
19149 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19150 (match_operand:SI 2 "general_operand" "")
19151 (match_operand:SI 3 "general_operand" "")))]
19152 ""
19153 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19154
19155 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19156 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19157 ;; So just document what we're doing explicitly.
19158
19159 (define_insn "x86_movsicc_0_m1"
19160 [(set (match_operand:SI 0 "register_operand" "=r")
19161 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19162 (const_int -1)
19163 (const_int 0)))
19164 (clobber (reg:CC FLAGS_REG))]
19165 ""
19166 "sbb{l}\t%0, %0"
19167 ; Since we don't have the proper number of operands for an alu insn,
19168 ; fill in all the blanks.
19169 [(set_attr "type" "alu")
19170 (set_attr "pent_pair" "pu")
19171 (set_attr "memory" "none")
19172 (set_attr "imm_disp" "false")
19173 (set_attr "mode" "SI")
19174 (set_attr "length_immediate" "0")])
19175
19176 (define_insn "*movsicc_noc"
19177 [(set (match_operand:SI 0 "register_operand" "=r,r")
19178 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19179 [(reg FLAGS_REG) (const_int 0)])
19180 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19181 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19182 "TARGET_CMOVE
19183 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19184 "@
19185 cmov%O2%C1\t{%2, %0|%0, %2}
19186 cmov%O2%c1\t{%3, %0|%0, %3}"
19187 [(set_attr "type" "icmov")
19188 (set_attr "mode" "SI")])
19189
19190 (define_expand "movhicc"
19191 [(set (match_operand:HI 0 "register_operand" "")
19192 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19193 (match_operand:HI 2 "general_operand" "")
19194 (match_operand:HI 3 "general_operand" "")))]
19195 "TARGET_HIMODE_MATH"
19196 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19197
19198 (define_insn "*movhicc_noc"
19199 [(set (match_operand:HI 0 "register_operand" "=r,r")
19200 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19201 [(reg FLAGS_REG) (const_int 0)])
19202 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19203 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19204 "TARGET_CMOVE
19205 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19206 "@
19207 cmov%O2%C1\t{%2, %0|%0, %2}
19208 cmov%O2%c1\t{%3, %0|%0, %3}"
19209 [(set_attr "type" "icmov")
19210 (set_attr "mode" "HI")])
19211
19212 (define_expand "movqicc"
19213 [(set (match_operand:QI 0 "register_operand" "")
19214 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19215 (match_operand:QI 2 "general_operand" "")
19216 (match_operand:QI 3 "general_operand" "")))]
19217 "TARGET_QIMODE_MATH"
19218 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19219
19220 (define_insn_and_split "*movqicc_noc"
19221 [(set (match_operand:QI 0 "register_operand" "=r,r")
19222 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19223 [(match_operand 4 "flags_reg_operand" "")
19224 (const_int 0)])
19225 (match_operand:QI 2 "register_operand" "r,0")
19226 (match_operand:QI 3 "register_operand" "0,r")))]
19227 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19228 "#"
19229 "&& reload_completed"
19230 [(set (match_dup 0)
19231 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19232 (match_dup 2)
19233 (match_dup 3)))]
19234 "operands[0] = gen_lowpart (SImode, operands[0]);
19235 operands[2] = gen_lowpart (SImode, operands[2]);
19236 operands[3] = gen_lowpart (SImode, operands[3]);"
19237 [(set_attr "type" "icmov")
19238 (set_attr "mode" "SI")])
19239
19240 (define_expand "movsfcc"
19241 [(set (match_operand:SF 0 "register_operand" "")
19242 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19243 (match_operand:SF 2 "register_operand" "")
19244 (match_operand:SF 3 "register_operand" "")))]
19245 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19246 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19247
19248 (define_insn "*movsfcc_1_387"
19249 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19250 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19251 [(reg FLAGS_REG) (const_int 0)])
19252 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19253 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19254 "TARGET_80387 && TARGET_CMOVE
19255 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19256 "@
19257 fcmov%F1\t{%2, %0|%0, %2}
19258 fcmov%f1\t{%3, %0|%0, %3}
19259 cmov%O2%C1\t{%2, %0|%0, %2}
19260 cmov%O2%c1\t{%3, %0|%0, %3}"
19261 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19262 (set_attr "mode" "SF,SF,SI,SI")])
19263
19264 (define_expand "movdfcc"
19265 [(set (match_operand:DF 0 "register_operand" "")
19266 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19267 (match_operand:DF 2 "register_operand" "")
19268 (match_operand:DF 3 "register_operand" "")))]
19269 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19270 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19271
19272 (define_insn "*movdfcc_1"
19273 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19274 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19275 [(reg FLAGS_REG) (const_int 0)])
19276 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19277 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19278 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19279 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19280 "@
19281 fcmov%F1\t{%2, %0|%0, %2}
19282 fcmov%f1\t{%3, %0|%0, %3}
19283 #
19284 #"
19285 [(set_attr "type" "fcmov,fcmov,multi,multi")
19286 (set_attr "mode" "DF")])
19287
19288 (define_insn "*movdfcc_1_rex64"
19289 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19290 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19291 [(reg FLAGS_REG) (const_int 0)])
19292 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19293 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19294 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19295 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19296 "@
19297 fcmov%F1\t{%2, %0|%0, %2}
19298 fcmov%f1\t{%3, %0|%0, %3}
19299 cmov%O2%C1\t{%2, %0|%0, %2}
19300 cmov%O2%c1\t{%3, %0|%0, %3}"
19301 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19302 (set_attr "mode" "DF")])
19303
19304 (define_split
19305 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19306 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19307 [(match_operand 4 "flags_reg_operand" "")
19308 (const_int 0)])
19309 (match_operand:DF 2 "nonimmediate_operand" "")
19310 (match_operand:DF 3 "nonimmediate_operand" "")))]
19311 "!TARGET_64BIT && reload_completed"
19312 [(set (match_dup 2)
19313 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19314 (match_dup 5)
19315 (match_dup 7)))
19316 (set (match_dup 3)
19317 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19318 (match_dup 6)
19319 (match_dup 8)))]
19320 "split_di (operands+2, 1, operands+5, operands+6);
19321 split_di (operands+3, 1, operands+7, operands+8);
19322 split_di (operands, 1, operands+2, operands+3);")
19323
19324 (define_expand "movxfcc"
19325 [(set (match_operand:XF 0 "register_operand" "")
19326 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19327 (match_operand:XF 2 "register_operand" "")
19328 (match_operand:XF 3 "register_operand" "")))]
19329 "TARGET_80387 && TARGET_CMOVE"
19330 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19331
19332 (define_insn "*movxfcc_1"
19333 [(set (match_operand:XF 0 "register_operand" "=f,f")
19334 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19335 [(reg FLAGS_REG) (const_int 0)])
19336 (match_operand:XF 2 "register_operand" "f,0")
19337 (match_operand:XF 3 "register_operand" "0,f")))]
19338 "TARGET_80387 && TARGET_CMOVE"
19339 "@
19340 fcmov%F1\t{%2, %0|%0, %2}
19341 fcmov%f1\t{%3, %0|%0, %3}"
19342 [(set_attr "type" "fcmov")
19343 (set_attr "mode" "XF")])
19344
19345 ;; These versions of the min/max patterns are intentionally ignorant of
19346 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19347 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19348 ;; are undefined in this condition, we're certain this is correct.
19349
19350 (define_insn "sminsf3"
19351 [(set (match_operand:SF 0 "register_operand" "=x")
19352 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19353 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19354 "TARGET_SSE_MATH"
19355 "minss\t{%2, %0|%0, %2}"
19356 [(set_attr "type" "sseadd")
19357 (set_attr "mode" "SF")])
19358
19359 (define_insn "smaxsf3"
19360 [(set (match_operand:SF 0 "register_operand" "=x")
19361 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19362 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19363 "TARGET_SSE_MATH"
19364 "maxss\t{%2, %0|%0, %2}"
19365 [(set_attr "type" "sseadd")
19366 (set_attr "mode" "SF")])
19367
19368 (define_insn "smindf3"
19369 [(set (match_operand:DF 0 "register_operand" "=x")
19370 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19371 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19372 "TARGET_SSE2 && TARGET_SSE_MATH"
19373 "minsd\t{%2, %0|%0, %2}"
19374 [(set_attr "type" "sseadd")
19375 (set_attr "mode" "DF")])
19376
19377 (define_insn "smaxdf3"
19378 [(set (match_operand:DF 0 "register_operand" "=x")
19379 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19380 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19381 "TARGET_SSE2 && TARGET_SSE_MATH"
19382 "maxsd\t{%2, %0|%0, %2}"
19383 [(set_attr "type" "sseadd")
19384 (set_attr "mode" "DF")])
19385
19386 ;; These versions of the min/max patterns implement exactly the operations
19387 ;; min = (op1 < op2 ? op1 : op2)
19388 ;; max = (!(op1 < op2) ? op1 : op2)
19389 ;; Their operands are not commutative, and thus they may be used in the
19390 ;; presence of -0.0 and NaN.
19391
19392 (define_insn "*ieee_sminsf3"
19393 [(set (match_operand:SF 0 "register_operand" "=x")
19394 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19395 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19396 UNSPEC_IEEE_MIN))]
19397 "TARGET_SSE_MATH"
19398 "minss\t{%2, %0|%0, %2}"
19399 [(set_attr "type" "sseadd")
19400 (set_attr "mode" "SF")])
19401
19402 (define_insn "*ieee_smaxsf3"
19403 [(set (match_operand:SF 0 "register_operand" "=x")
19404 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19405 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19406 UNSPEC_IEEE_MAX))]
19407 "TARGET_SSE_MATH"
19408 "maxss\t{%2, %0|%0, %2}"
19409 [(set_attr "type" "sseadd")
19410 (set_attr "mode" "SF")])
19411
19412 (define_insn "*ieee_smindf3"
19413 [(set (match_operand:DF 0 "register_operand" "=x")
19414 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19415 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19416 UNSPEC_IEEE_MIN))]
19417 "TARGET_SSE2 && TARGET_SSE_MATH"
19418 "minsd\t{%2, %0|%0, %2}"
19419 [(set_attr "type" "sseadd")
19420 (set_attr "mode" "DF")])
19421
19422 (define_insn "*ieee_smaxdf3"
19423 [(set (match_operand:DF 0 "register_operand" "=x")
19424 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19425 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19426 UNSPEC_IEEE_MAX))]
19427 "TARGET_SSE2 && TARGET_SSE_MATH"
19428 "maxsd\t{%2, %0|%0, %2}"
19429 [(set_attr "type" "sseadd")
19430 (set_attr "mode" "DF")])
19431
19432 ;; Make two stack loads independent:
19433 ;; fld aa fld aa
19434 ;; fld %st(0) -> fld bb
19435 ;; fmul bb fmul %st(1), %st
19436 ;;
19437 ;; Actually we only match the last two instructions for simplicity.
19438 (define_peephole2
19439 [(set (match_operand 0 "fp_register_operand" "")
19440 (match_operand 1 "fp_register_operand" ""))
19441 (set (match_dup 0)
19442 (match_operator 2 "binary_fp_operator"
19443 [(match_dup 0)
19444 (match_operand 3 "memory_operand" "")]))]
19445 "REGNO (operands[0]) != REGNO (operands[1])"
19446 [(set (match_dup 0) (match_dup 3))
19447 (set (match_dup 0) (match_dup 4))]
19448
19449 ;; The % modifier is not operational anymore in peephole2's, so we have to
19450 ;; swap the operands manually in the case of addition and multiplication.
19451 "if (COMMUTATIVE_ARITH_P (operands[2]))
19452 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19453 operands[0], operands[1]);
19454 else
19455 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19456 operands[1], operands[0]);")
19457
19458 ;; Conditional addition patterns
19459 (define_expand "addqicc"
19460 [(match_operand:QI 0 "register_operand" "")
19461 (match_operand 1 "comparison_operator" "")
19462 (match_operand:QI 2 "register_operand" "")
19463 (match_operand:QI 3 "const_int_operand" "")]
19464 ""
19465 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19466
19467 (define_expand "addhicc"
19468 [(match_operand:HI 0 "register_operand" "")
19469 (match_operand 1 "comparison_operator" "")
19470 (match_operand:HI 2 "register_operand" "")
19471 (match_operand:HI 3 "const_int_operand" "")]
19472 ""
19473 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19474
19475 (define_expand "addsicc"
19476 [(match_operand:SI 0 "register_operand" "")
19477 (match_operand 1 "comparison_operator" "")
19478 (match_operand:SI 2 "register_operand" "")
19479 (match_operand:SI 3 "const_int_operand" "")]
19480 ""
19481 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19482
19483 (define_expand "adddicc"
19484 [(match_operand:DI 0 "register_operand" "")
19485 (match_operand 1 "comparison_operator" "")
19486 (match_operand:DI 2 "register_operand" "")
19487 (match_operand:DI 3 "const_int_operand" "")]
19488 "TARGET_64BIT"
19489 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19490
19491 \f
19492 ;; Misc patterns (?)
19493
19494 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19495 ;; Otherwise there will be nothing to keep
19496 ;;
19497 ;; [(set (reg ebp) (reg esp))]
19498 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19499 ;; (clobber (eflags)]
19500 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19501 ;;
19502 ;; in proper program order.
19503 (define_insn "pro_epilogue_adjust_stack_1"
19504 [(set (match_operand:SI 0 "register_operand" "=r,r")
19505 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19506 (match_operand:SI 2 "immediate_operand" "i,i")))
19507 (clobber (reg:CC FLAGS_REG))
19508 (clobber (mem:BLK (scratch)))]
19509 "!TARGET_64BIT"
19510 {
19511 switch (get_attr_type (insn))
19512 {
19513 case TYPE_IMOV:
19514 return "mov{l}\t{%1, %0|%0, %1}";
19515
19516 case TYPE_ALU:
19517 if (GET_CODE (operands[2]) == CONST_INT
19518 && (INTVAL (operands[2]) == 128
19519 || (INTVAL (operands[2]) < 0
19520 && INTVAL (operands[2]) != -128)))
19521 {
19522 operands[2] = GEN_INT (-INTVAL (operands[2]));
19523 return "sub{l}\t{%2, %0|%0, %2}";
19524 }
19525 return "add{l}\t{%2, %0|%0, %2}";
19526
19527 case TYPE_LEA:
19528 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19529 return "lea{l}\t{%a2, %0|%0, %a2}";
19530
19531 default:
19532 gcc_unreachable ();
19533 }
19534 }
19535 [(set (attr "type")
19536 (cond [(eq_attr "alternative" "0")
19537 (const_string "alu")
19538 (match_operand:SI 2 "const0_operand" "")
19539 (const_string "imov")
19540 ]
19541 (const_string "lea")))
19542 (set_attr "mode" "SI")])
19543
19544 (define_insn "pro_epilogue_adjust_stack_rex64"
19545 [(set (match_operand:DI 0 "register_operand" "=r,r")
19546 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19547 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19548 (clobber (reg:CC FLAGS_REG))
19549 (clobber (mem:BLK (scratch)))]
19550 "TARGET_64BIT"
19551 {
19552 switch (get_attr_type (insn))
19553 {
19554 case TYPE_IMOV:
19555 return "mov{q}\t{%1, %0|%0, %1}";
19556
19557 case TYPE_ALU:
19558 if (GET_CODE (operands[2]) == CONST_INT
19559 /* Avoid overflows. */
19560 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19561 && (INTVAL (operands[2]) == 128
19562 || (INTVAL (operands[2]) < 0
19563 && INTVAL (operands[2]) != -128)))
19564 {
19565 operands[2] = GEN_INT (-INTVAL (operands[2]));
19566 return "sub{q}\t{%2, %0|%0, %2}";
19567 }
19568 return "add{q}\t{%2, %0|%0, %2}";
19569
19570 case TYPE_LEA:
19571 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19572 return "lea{q}\t{%a2, %0|%0, %a2}";
19573
19574 default:
19575 gcc_unreachable ();
19576 }
19577 }
19578 [(set (attr "type")
19579 (cond [(eq_attr "alternative" "0")
19580 (const_string "alu")
19581 (match_operand:DI 2 "const0_operand" "")
19582 (const_string "imov")
19583 ]
19584 (const_string "lea")))
19585 (set_attr "mode" "DI")])
19586
19587 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19588 [(set (match_operand:DI 0 "register_operand" "=r,r")
19589 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19590 (match_operand:DI 3 "immediate_operand" "i,i")))
19591 (use (match_operand:DI 2 "register_operand" "r,r"))
19592 (clobber (reg:CC FLAGS_REG))
19593 (clobber (mem:BLK (scratch)))]
19594 "TARGET_64BIT"
19595 {
19596 switch (get_attr_type (insn))
19597 {
19598 case TYPE_ALU:
19599 return "add{q}\t{%2, %0|%0, %2}";
19600
19601 case TYPE_LEA:
19602 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19603 return "lea{q}\t{%a2, %0|%0, %a2}";
19604
19605 default:
19606 gcc_unreachable ();
19607 }
19608 }
19609 [(set_attr "type" "alu,lea")
19610 (set_attr "mode" "DI")])
19611
19612 (define_expand "allocate_stack_worker"
19613 [(match_operand:SI 0 "register_operand" "")]
19614 "TARGET_STACK_PROBE"
19615 {
19616 if (reload_completed)
19617 {
19618 if (TARGET_64BIT)
19619 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19620 else
19621 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19622 }
19623 else
19624 {
19625 if (TARGET_64BIT)
19626 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19627 else
19628 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19629 }
19630 DONE;
19631 })
19632
19633 (define_insn "allocate_stack_worker_1"
19634 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19635 UNSPECV_STACK_PROBE)
19636 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19637 (clobber (match_scratch:SI 1 "=0"))
19638 (clobber (reg:CC FLAGS_REG))]
19639 "!TARGET_64BIT && TARGET_STACK_PROBE"
19640 "call\t__alloca"
19641 [(set_attr "type" "multi")
19642 (set_attr "length" "5")])
19643
19644 (define_expand "allocate_stack_worker_postreload"
19645 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19646 UNSPECV_STACK_PROBE)
19647 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19648 (clobber (match_dup 0))
19649 (clobber (reg:CC FLAGS_REG))])]
19650 ""
19651 "")
19652
19653 (define_insn "allocate_stack_worker_rex64"
19654 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19655 UNSPECV_STACK_PROBE)
19656 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19657 (clobber (match_scratch:DI 1 "=0"))
19658 (clobber (reg:CC FLAGS_REG))]
19659 "TARGET_64BIT && TARGET_STACK_PROBE"
19660 "call\t__alloca"
19661 [(set_attr "type" "multi")
19662 (set_attr "length" "5")])
19663
19664 (define_expand "allocate_stack_worker_rex64_postreload"
19665 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19666 UNSPECV_STACK_PROBE)
19667 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19668 (clobber (match_dup 0))
19669 (clobber (reg:CC FLAGS_REG))])]
19670 ""
19671 "")
19672
19673 (define_expand "allocate_stack"
19674 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19675 (minus:SI (reg:SI SP_REG)
19676 (match_operand:SI 1 "general_operand" "")))
19677 (clobber (reg:CC FLAGS_REG))])
19678 (parallel [(set (reg:SI SP_REG)
19679 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19680 (clobber (reg:CC FLAGS_REG))])]
19681 "TARGET_STACK_PROBE"
19682 {
19683 #ifdef CHECK_STACK_LIMIT
19684 if (GET_CODE (operands[1]) == CONST_INT
19685 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19686 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19687 operands[1]));
19688 else
19689 #endif
19690 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19691 operands[1])));
19692
19693 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19694 DONE;
19695 })
19696
19697 (define_expand "builtin_setjmp_receiver"
19698 [(label_ref (match_operand 0 "" ""))]
19699 "!TARGET_64BIT && flag_pic"
19700 {
19701 if (TARGET_MACHO)
19702 {
19703 rtx xops[3];
19704 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19705 rtx label_rtx = gen_label_rtx ();
19706 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19707 xops[0] = xops[1] = picreg;
19708 xops[2] = gen_rtx_CONST (SImode,
19709 gen_rtx_MINUS (SImode,
19710 gen_rtx_LABEL_REF (SImode, label_rtx),
19711 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19712 ix86_expand_binary_operator (MINUS, SImode, xops);
19713 }
19714 else
19715 emit_insn (gen_set_got (pic_offset_table_rtx));
19716 DONE;
19717 })
19718 \f
19719 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19720
19721 (define_split
19722 [(set (match_operand 0 "register_operand" "")
19723 (match_operator 3 "promotable_binary_operator"
19724 [(match_operand 1 "register_operand" "")
19725 (match_operand 2 "aligned_operand" "")]))
19726 (clobber (reg:CC FLAGS_REG))]
19727 "! TARGET_PARTIAL_REG_STALL && reload_completed
19728 && ((GET_MODE (operands[0]) == HImode
19729 && ((!optimize_size && !TARGET_FAST_PREFIX)
19730 /* ??? next two lines just !satisfies_constraint_K (...) */
19731 || GET_CODE (operands[2]) != CONST_INT
19732 || satisfies_constraint_K (operands[2])))
19733 || (GET_MODE (operands[0]) == QImode
19734 && (TARGET_PROMOTE_QImode || optimize_size)))"
19735 [(parallel [(set (match_dup 0)
19736 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19737 (clobber (reg:CC FLAGS_REG))])]
19738 "operands[0] = gen_lowpart (SImode, operands[0]);
19739 operands[1] = gen_lowpart (SImode, operands[1]);
19740 if (GET_CODE (operands[3]) != ASHIFT)
19741 operands[2] = gen_lowpart (SImode, operands[2]);
19742 PUT_MODE (operands[3], SImode);")
19743
19744 ; Promote the QImode tests, as i386 has encoding of the AND
19745 ; instruction with 32-bit sign-extended immediate and thus the
19746 ; instruction size is unchanged, except in the %eax case for
19747 ; which it is increased by one byte, hence the ! optimize_size.
19748 (define_split
19749 [(set (match_operand 0 "flags_reg_operand" "")
19750 (match_operator 2 "compare_operator"
19751 [(and (match_operand 3 "aligned_operand" "")
19752 (match_operand 4 "const_int_operand" ""))
19753 (const_int 0)]))
19754 (set (match_operand 1 "register_operand" "")
19755 (and (match_dup 3) (match_dup 4)))]
19756 "! TARGET_PARTIAL_REG_STALL && reload_completed
19757 /* Ensure that the operand will remain sign-extended immediate. */
19758 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19759 && ! optimize_size
19760 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19761 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19762 [(parallel [(set (match_dup 0)
19763 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19764 (const_int 0)]))
19765 (set (match_dup 1)
19766 (and:SI (match_dup 3) (match_dup 4)))])]
19767 {
19768 operands[4]
19769 = gen_int_mode (INTVAL (operands[4])
19770 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19771 operands[1] = gen_lowpart (SImode, operands[1]);
19772 operands[3] = gen_lowpart (SImode, operands[3]);
19773 })
19774
19775 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19776 ; the TEST instruction with 32-bit sign-extended immediate and thus
19777 ; the instruction size would at least double, which is not what we
19778 ; want even with ! optimize_size.
19779 (define_split
19780 [(set (match_operand 0 "flags_reg_operand" "")
19781 (match_operator 1 "compare_operator"
19782 [(and (match_operand:HI 2 "aligned_operand" "")
19783 (match_operand:HI 3 "const_int_operand" ""))
19784 (const_int 0)]))]
19785 "! TARGET_PARTIAL_REG_STALL && reload_completed
19786 /* Ensure that the operand will remain sign-extended immediate. */
19787 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19788 && ! TARGET_FAST_PREFIX
19789 && ! optimize_size"
19790 [(set (match_dup 0)
19791 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19792 (const_int 0)]))]
19793 {
19794 operands[3]
19795 = gen_int_mode (INTVAL (operands[3])
19796 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19797 operands[2] = gen_lowpart (SImode, operands[2]);
19798 })
19799
19800 (define_split
19801 [(set (match_operand 0 "register_operand" "")
19802 (neg (match_operand 1 "register_operand" "")))
19803 (clobber (reg:CC FLAGS_REG))]
19804 "! TARGET_PARTIAL_REG_STALL && reload_completed
19805 && (GET_MODE (operands[0]) == HImode
19806 || (GET_MODE (operands[0]) == QImode
19807 && (TARGET_PROMOTE_QImode || optimize_size)))"
19808 [(parallel [(set (match_dup 0)
19809 (neg:SI (match_dup 1)))
19810 (clobber (reg:CC FLAGS_REG))])]
19811 "operands[0] = gen_lowpart (SImode, operands[0]);
19812 operands[1] = gen_lowpart (SImode, operands[1]);")
19813
19814 (define_split
19815 [(set (match_operand 0 "register_operand" "")
19816 (not (match_operand 1 "register_operand" "")))]
19817 "! TARGET_PARTIAL_REG_STALL && reload_completed
19818 && (GET_MODE (operands[0]) == HImode
19819 || (GET_MODE (operands[0]) == QImode
19820 && (TARGET_PROMOTE_QImode || optimize_size)))"
19821 [(set (match_dup 0)
19822 (not:SI (match_dup 1)))]
19823 "operands[0] = gen_lowpart (SImode, operands[0]);
19824 operands[1] = gen_lowpart (SImode, operands[1]);")
19825
19826 (define_split
19827 [(set (match_operand 0 "register_operand" "")
19828 (if_then_else (match_operator 1 "comparison_operator"
19829 [(reg FLAGS_REG) (const_int 0)])
19830 (match_operand 2 "register_operand" "")
19831 (match_operand 3 "register_operand" "")))]
19832 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19833 && (GET_MODE (operands[0]) == HImode
19834 || (GET_MODE (operands[0]) == QImode
19835 && (TARGET_PROMOTE_QImode || optimize_size)))"
19836 [(set (match_dup 0)
19837 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19838 "operands[0] = gen_lowpart (SImode, operands[0]);
19839 operands[2] = gen_lowpart (SImode, operands[2]);
19840 operands[3] = gen_lowpart (SImode, operands[3]);")
19841
19842 \f
19843 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19844 ;; transform a complex memory operation into two memory to register operations.
19845
19846 ;; Don't push memory operands
19847 (define_peephole2
19848 [(set (match_operand:SI 0 "push_operand" "")
19849 (match_operand:SI 1 "memory_operand" ""))
19850 (match_scratch:SI 2 "r")]
19851 "!optimize_size && !TARGET_PUSH_MEMORY
19852 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19853 [(set (match_dup 2) (match_dup 1))
19854 (set (match_dup 0) (match_dup 2))]
19855 "")
19856
19857 (define_peephole2
19858 [(set (match_operand:DI 0 "push_operand" "")
19859 (match_operand:DI 1 "memory_operand" ""))
19860 (match_scratch:DI 2 "r")]
19861 "!optimize_size && !TARGET_PUSH_MEMORY
19862 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19863 [(set (match_dup 2) (match_dup 1))
19864 (set (match_dup 0) (match_dup 2))]
19865 "")
19866
19867 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19868 ;; SImode pushes.
19869 (define_peephole2
19870 [(set (match_operand:SF 0 "push_operand" "")
19871 (match_operand:SF 1 "memory_operand" ""))
19872 (match_scratch:SF 2 "r")]
19873 "!optimize_size && !TARGET_PUSH_MEMORY
19874 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19875 [(set (match_dup 2) (match_dup 1))
19876 (set (match_dup 0) (match_dup 2))]
19877 "")
19878
19879 (define_peephole2
19880 [(set (match_operand:HI 0 "push_operand" "")
19881 (match_operand:HI 1 "memory_operand" ""))
19882 (match_scratch:HI 2 "r")]
19883 "!optimize_size && !TARGET_PUSH_MEMORY
19884 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19885 [(set (match_dup 2) (match_dup 1))
19886 (set (match_dup 0) (match_dup 2))]
19887 "")
19888
19889 (define_peephole2
19890 [(set (match_operand:QI 0 "push_operand" "")
19891 (match_operand:QI 1 "memory_operand" ""))
19892 (match_scratch:QI 2 "q")]
19893 "!optimize_size && !TARGET_PUSH_MEMORY
19894 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19895 [(set (match_dup 2) (match_dup 1))
19896 (set (match_dup 0) (match_dup 2))]
19897 "")
19898
19899 ;; Don't move an immediate directly to memory when the instruction
19900 ;; gets too big.
19901 (define_peephole2
19902 [(match_scratch:SI 1 "r")
19903 (set (match_operand:SI 0 "memory_operand" "")
19904 (const_int 0))]
19905 "! optimize_size
19906 && ! TARGET_USE_MOV0
19907 && TARGET_SPLIT_LONG_MOVES
19908 && get_attr_length (insn) >= ix86_cost->large_insn
19909 && peep2_regno_dead_p (0, FLAGS_REG)"
19910 [(parallel [(set (match_dup 1) (const_int 0))
19911 (clobber (reg:CC FLAGS_REG))])
19912 (set (match_dup 0) (match_dup 1))]
19913 "")
19914
19915 (define_peephole2
19916 [(match_scratch:HI 1 "r")
19917 (set (match_operand:HI 0 "memory_operand" "")
19918 (const_int 0))]
19919 "! optimize_size
19920 && ! TARGET_USE_MOV0
19921 && TARGET_SPLIT_LONG_MOVES
19922 && get_attr_length (insn) >= ix86_cost->large_insn
19923 && peep2_regno_dead_p (0, FLAGS_REG)"
19924 [(parallel [(set (match_dup 2) (const_int 0))
19925 (clobber (reg:CC FLAGS_REG))])
19926 (set (match_dup 0) (match_dup 1))]
19927 "operands[2] = gen_lowpart (SImode, operands[1]);")
19928
19929 (define_peephole2
19930 [(match_scratch:QI 1 "q")
19931 (set (match_operand:QI 0 "memory_operand" "")
19932 (const_int 0))]
19933 "! optimize_size
19934 && ! TARGET_USE_MOV0
19935 && TARGET_SPLIT_LONG_MOVES
19936 && get_attr_length (insn) >= ix86_cost->large_insn
19937 && peep2_regno_dead_p (0, FLAGS_REG)"
19938 [(parallel [(set (match_dup 2) (const_int 0))
19939 (clobber (reg:CC FLAGS_REG))])
19940 (set (match_dup 0) (match_dup 1))]
19941 "operands[2] = gen_lowpart (SImode, operands[1]);")
19942
19943 (define_peephole2
19944 [(match_scratch:SI 2 "r")
19945 (set (match_operand:SI 0 "memory_operand" "")
19946 (match_operand:SI 1 "immediate_operand" ""))]
19947 "! optimize_size
19948 && get_attr_length (insn) >= ix86_cost->large_insn
19949 && TARGET_SPLIT_LONG_MOVES"
19950 [(set (match_dup 2) (match_dup 1))
19951 (set (match_dup 0) (match_dup 2))]
19952 "")
19953
19954 (define_peephole2
19955 [(match_scratch:HI 2 "r")
19956 (set (match_operand:HI 0 "memory_operand" "")
19957 (match_operand:HI 1 "immediate_operand" ""))]
19958 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19959 && TARGET_SPLIT_LONG_MOVES"
19960 [(set (match_dup 2) (match_dup 1))
19961 (set (match_dup 0) (match_dup 2))]
19962 "")
19963
19964 (define_peephole2
19965 [(match_scratch:QI 2 "q")
19966 (set (match_operand:QI 0 "memory_operand" "")
19967 (match_operand:QI 1 "immediate_operand" ""))]
19968 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19969 && TARGET_SPLIT_LONG_MOVES"
19970 [(set (match_dup 2) (match_dup 1))
19971 (set (match_dup 0) (match_dup 2))]
19972 "")
19973
19974 ;; Don't compare memory with zero, load and use a test instead.
19975 (define_peephole2
19976 [(set (match_operand 0 "flags_reg_operand" "")
19977 (match_operator 1 "compare_operator"
19978 [(match_operand:SI 2 "memory_operand" "")
19979 (const_int 0)]))
19980 (match_scratch:SI 3 "r")]
19981 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19982 [(set (match_dup 3) (match_dup 2))
19983 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19984 "")
19985
19986 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19987 ;; Don't split NOTs with a displacement operand, because resulting XOR
19988 ;; will not be pairable anyway.
19989 ;;
19990 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19991 ;; represented using a modRM byte. The XOR replacement is long decoded,
19992 ;; so this split helps here as well.
19993 ;;
19994 ;; Note: Can't do this as a regular split because we can't get proper
19995 ;; lifetime information then.
19996
19997 (define_peephole2
19998 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19999 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20000 "!optimize_size
20001 && peep2_regno_dead_p (0, FLAGS_REG)
20002 && ((TARGET_PENTIUM
20003 && (GET_CODE (operands[0]) != MEM
20004 || !memory_displacement_operand (operands[0], SImode)))
20005 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20006 [(parallel [(set (match_dup 0)
20007 (xor:SI (match_dup 1) (const_int -1)))
20008 (clobber (reg:CC FLAGS_REG))])]
20009 "")
20010
20011 (define_peephole2
20012 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20013 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20014 "!optimize_size
20015 && peep2_regno_dead_p (0, FLAGS_REG)
20016 && ((TARGET_PENTIUM
20017 && (GET_CODE (operands[0]) != MEM
20018 || !memory_displacement_operand (operands[0], HImode)))
20019 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20020 [(parallel [(set (match_dup 0)
20021 (xor:HI (match_dup 1) (const_int -1)))
20022 (clobber (reg:CC FLAGS_REG))])]
20023 "")
20024
20025 (define_peephole2
20026 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20027 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20028 "!optimize_size
20029 && peep2_regno_dead_p (0, FLAGS_REG)
20030 && ((TARGET_PENTIUM
20031 && (GET_CODE (operands[0]) != MEM
20032 || !memory_displacement_operand (operands[0], QImode)))
20033 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20034 [(parallel [(set (match_dup 0)
20035 (xor:QI (match_dup 1) (const_int -1)))
20036 (clobber (reg:CC FLAGS_REG))])]
20037 "")
20038
20039 ;; Non pairable "test imm, reg" instructions can be translated to
20040 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20041 ;; byte opcode instead of two, have a short form for byte operands),
20042 ;; so do it for other CPUs as well. Given that the value was dead,
20043 ;; this should not create any new dependencies. Pass on the sub-word
20044 ;; versions if we're concerned about partial register stalls.
20045
20046 (define_peephole2
20047 [(set (match_operand 0 "flags_reg_operand" "")
20048 (match_operator 1 "compare_operator"
20049 [(and:SI (match_operand:SI 2 "register_operand" "")
20050 (match_operand:SI 3 "immediate_operand" ""))
20051 (const_int 0)]))]
20052 "ix86_match_ccmode (insn, CCNOmode)
20053 && (true_regnum (operands[2]) != 0
20054 || satisfies_constraint_K (operands[3]))
20055 && peep2_reg_dead_p (1, operands[2])"
20056 [(parallel
20057 [(set (match_dup 0)
20058 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20059 (const_int 0)]))
20060 (set (match_dup 2)
20061 (and:SI (match_dup 2) (match_dup 3)))])]
20062 "")
20063
20064 ;; We don't need to handle HImode case, because it will be promoted to SImode
20065 ;; on ! TARGET_PARTIAL_REG_STALL
20066
20067 (define_peephole2
20068 [(set (match_operand 0 "flags_reg_operand" "")
20069 (match_operator 1 "compare_operator"
20070 [(and:QI (match_operand:QI 2 "register_operand" "")
20071 (match_operand:QI 3 "immediate_operand" ""))
20072 (const_int 0)]))]
20073 "! TARGET_PARTIAL_REG_STALL
20074 && ix86_match_ccmode (insn, CCNOmode)
20075 && true_regnum (operands[2]) != 0
20076 && peep2_reg_dead_p (1, operands[2])"
20077 [(parallel
20078 [(set (match_dup 0)
20079 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20080 (const_int 0)]))
20081 (set (match_dup 2)
20082 (and:QI (match_dup 2) (match_dup 3)))])]
20083 "")
20084
20085 (define_peephole2
20086 [(set (match_operand 0 "flags_reg_operand" "")
20087 (match_operator 1 "compare_operator"
20088 [(and:SI
20089 (zero_extract:SI
20090 (match_operand 2 "ext_register_operand" "")
20091 (const_int 8)
20092 (const_int 8))
20093 (match_operand 3 "const_int_operand" ""))
20094 (const_int 0)]))]
20095 "! TARGET_PARTIAL_REG_STALL
20096 && ix86_match_ccmode (insn, CCNOmode)
20097 && true_regnum (operands[2]) != 0
20098 && peep2_reg_dead_p (1, operands[2])"
20099 [(parallel [(set (match_dup 0)
20100 (match_op_dup 1
20101 [(and:SI
20102 (zero_extract:SI
20103 (match_dup 2)
20104 (const_int 8)
20105 (const_int 8))
20106 (match_dup 3))
20107 (const_int 0)]))
20108 (set (zero_extract:SI (match_dup 2)
20109 (const_int 8)
20110 (const_int 8))
20111 (and:SI
20112 (zero_extract:SI
20113 (match_dup 2)
20114 (const_int 8)
20115 (const_int 8))
20116 (match_dup 3)))])]
20117 "")
20118
20119 ;; Don't do logical operations with memory inputs.
20120 (define_peephole2
20121 [(match_scratch:SI 2 "r")
20122 (parallel [(set (match_operand:SI 0 "register_operand" "")
20123 (match_operator:SI 3 "arith_or_logical_operator"
20124 [(match_dup 0)
20125 (match_operand:SI 1 "memory_operand" "")]))
20126 (clobber (reg:CC FLAGS_REG))])]
20127 "! optimize_size && ! TARGET_READ_MODIFY"
20128 [(set (match_dup 2) (match_dup 1))
20129 (parallel [(set (match_dup 0)
20130 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20131 (clobber (reg:CC FLAGS_REG))])]
20132 "")
20133
20134 (define_peephole2
20135 [(match_scratch:SI 2 "r")
20136 (parallel [(set (match_operand:SI 0 "register_operand" "")
20137 (match_operator:SI 3 "arith_or_logical_operator"
20138 [(match_operand:SI 1 "memory_operand" "")
20139 (match_dup 0)]))
20140 (clobber (reg:CC FLAGS_REG))])]
20141 "! optimize_size && ! TARGET_READ_MODIFY"
20142 [(set (match_dup 2) (match_dup 1))
20143 (parallel [(set (match_dup 0)
20144 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20145 (clobber (reg:CC FLAGS_REG))])]
20146 "")
20147
20148 ; Don't do logical operations with memory outputs
20149 ;
20150 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20151 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20152 ; the same decoder scheduling characteristics as the original.
20153
20154 (define_peephole2
20155 [(match_scratch:SI 2 "r")
20156 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20157 (match_operator:SI 3 "arith_or_logical_operator"
20158 [(match_dup 0)
20159 (match_operand:SI 1 "nonmemory_operand" "")]))
20160 (clobber (reg:CC FLAGS_REG))])]
20161 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20162 [(set (match_dup 2) (match_dup 0))
20163 (parallel [(set (match_dup 2)
20164 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20165 (clobber (reg:CC FLAGS_REG))])
20166 (set (match_dup 0) (match_dup 2))]
20167 "")
20168
20169 (define_peephole2
20170 [(match_scratch:SI 2 "r")
20171 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20172 (match_operator:SI 3 "arith_or_logical_operator"
20173 [(match_operand:SI 1 "nonmemory_operand" "")
20174 (match_dup 0)]))
20175 (clobber (reg:CC FLAGS_REG))])]
20176 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20177 [(set (match_dup 2) (match_dup 0))
20178 (parallel [(set (match_dup 2)
20179 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20180 (clobber (reg:CC FLAGS_REG))])
20181 (set (match_dup 0) (match_dup 2))]
20182 "")
20183
20184 ;; Attempt to always use XOR for zeroing registers.
20185 (define_peephole2
20186 [(set (match_operand 0 "register_operand" "")
20187 (match_operand 1 "const0_operand" ""))]
20188 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20189 && (! TARGET_USE_MOV0 || optimize_size)
20190 && GENERAL_REG_P (operands[0])
20191 && peep2_regno_dead_p (0, FLAGS_REG)"
20192 [(parallel [(set (match_dup 0) (const_int 0))
20193 (clobber (reg:CC FLAGS_REG))])]
20194 {
20195 operands[0] = gen_lowpart (word_mode, operands[0]);
20196 })
20197
20198 (define_peephole2
20199 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20200 (const_int 0))]
20201 "(GET_MODE (operands[0]) == QImode
20202 || GET_MODE (operands[0]) == HImode)
20203 && (! TARGET_USE_MOV0 || optimize_size)
20204 && peep2_regno_dead_p (0, FLAGS_REG)"
20205 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20206 (clobber (reg:CC FLAGS_REG))])])
20207
20208 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20209 (define_peephole2
20210 [(set (match_operand 0 "register_operand" "")
20211 (const_int -1))]
20212 "(GET_MODE (operands[0]) == HImode
20213 || GET_MODE (operands[0]) == SImode
20214 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20215 && (optimize_size || TARGET_PENTIUM)
20216 && peep2_regno_dead_p (0, FLAGS_REG)"
20217 [(parallel [(set (match_dup 0) (const_int -1))
20218 (clobber (reg:CC FLAGS_REG))])]
20219 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20220 operands[0]);")
20221
20222 ;; Attempt to convert simple leas to adds. These can be created by
20223 ;; move expanders.
20224 (define_peephole2
20225 [(set (match_operand:SI 0 "register_operand" "")
20226 (plus:SI (match_dup 0)
20227 (match_operand:SI 1 "nonmemory_operand" "")))]
20228 "peep2_regno_dead_p (0, FLAGS_REG)"
20229 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20230 (clobber (reg:CC FLAGS_REG))])]
20231 "")
20232
20233 (define_peephole2
20234 [(set (match_operand:SI 0 "register_operand" "")
20235 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20236 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20237 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20238 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20239 (clobber (reg:CC FLAGS_REG))])]
20240 "operands[2] = gen_lowpart (SImode, operands[2]);")
20241
20242 (define_peephole2
20243 [(set (match_operand:DI 0 "register_operand" "")
20244 (plus:DI (match_dup 0)
20245 (match_operand:DI 1 "x86_64_general_operand" "")))]
20246 "peep2_regno_dead_p (0, FLAGS_REG)"
20247 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20248 (clobber (reg:CC FLAGS_REG))])]
20249 "")
20250
20251 (define_peephole2
20252 [(set (match_operand:SI 0 "register_operand" "")
20253 (mult:SI (match_dup 0)
20254 (match_operand:SI 1 "const_int_operand" "")))]
20255 "exact_log2 (INTVAL (operands[1])) >= 0
20256 && peep2_regno_dead_p (0, FLAGS_REG)"
20257 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20258 (clobber (reg:CC FLAGS_REG))])]
20259 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20260
20261 (define_peephole2
20262 [(set (match_operand:DI 0 "register_operand" "")
20263 (mult:DI (match_dup 0)
20264 (match_operand:DI 1 "const_int_operand" "")))]
20265 "exact_log2 (INTVAL (operands[1])) >= 0
20266 && peep2_regno_dead_p (0, FLAGS_REG)"
20267 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20268 (clobber (reg:CC FLAGS_REG))])]
20269 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20270
20271 (define_peephole2
20272 [(set (match_operand:SI 0 "register_operand" "")
20273 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20274 (match_operand:DI 2 "const_int_operand" "")) 0))]
20275 "exact_log2 (INTVAL (operands[2])) >= 0
20276 && REGNO (operands[0]) == REGNO (operands[1])
20277 && peep2_regno_dead_p (0, FLAGS_REG)"
20278 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20279 (clobber (reg:CC FLAGS_REG))])]
20280 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20281
20282 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20283 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20284 ;; many CPUs it is also faster, since special hardware to avoid esp
20285 ;; dependencies is present.
20286
20287 ;; While some of these conversions may be done using splitters, we use peepholes
20288 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20289
20290 ;; Convert prologue esp subtractions to push.
20291 ;; We need register to push. In order to keep verify_flow_info happy we have
20292 ;; two choices
20293 ;; - use scratch and clobber it in order to avoid dependencies
20294 ;; - use already live register
20295 ;; We can't use the second way right now, since there is no reliable way how to
20296 ;; verify that given register is live. First choice will also most likely in
20297 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20298 ;; call clobbered registers are dead. We may want to use base pointer as an
20299 ;; alternative when no register is available later.
20300
20301 (define_peephole2
20302 [(match_scratch:SI 0 "r")
20303 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20304 (clobber (reg:CC FLAGS_REG))
20305 (clobber (mem:BLK (scratch)))])]
20306 "optimize_size || !TARGET_SUB_ESP_4"
20307 [(clobber (match_dup 0))
20308 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20309 (clobber (mem:BLK (scratch)))])])
20310
20311 (define_peephole2
20312 [(match_scratch:SI 0 "r")
20313 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20314 (clobber (reg:CC FLAGS_REG))
20315 (clobber (mem:BLK (scratch)))])]
20316 "optimize_size || !TARGET_SUB_ESP_8"
20317 [(clobber (match_dup 0))
20318 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20319 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20320 (clobber (mem:BLK (scratch)))])])
20321
20322 ;; Convert esp subtractions to push.
20323 (define_peephole2
20324 [(match_scratch:SI 0 "r")
20325 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20326 (clobber (reg:CC FLAGS_REG))])]
20327 "optimize_size || !TARGET_SUB_ESP_4"
20328 [(clobber (match_dup 0))
20329 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20330
20331 (define_peephole2
20332 [(match_scratch:SI 0 "r")
20333 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20334 (clobber (reg:CC FLAGS_REG))])]
20335 "optimize_size || !TARGET_SUB_ESP_8"
20336 [(clobber (match_dup 0))
20337 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20338 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20339
20340 ;; Convert epilogue deallocator to pop.
20341 (define_peephole2
20342 [(match_scratch:SI 0 "r")
20343 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20344 (clobber (reg:CC FLAGS_REG))
20345 (clobber (mem:BLK (scratch)))])]
20346 "optimize_size || !TARGET_ADD_ESP_4"
20347 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20348 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20349 (clobber (mem:BLK (scratch)))])]
20350 "")
20351
20352 ;; Two pops case is tricky, since pop causes dependency on destination register.
20353 ;; We use two registers if available.
20354 (define_peephole2
20355 [(match_scratch:SI 0 "r")
20356 (match_scratch:SI 1 "r")
20357 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20358 (clobber (reg:CC FLAGS_REG))
20359 (clobber (mem:BLK (scratch)))])]
20360 "optimize_size || !TARGET_ADD_ESP_8"
20361 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20362 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20363 (clobber (mem:BLK (scratch)))])
20364 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20365 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20366 "")
20367
20368 (define_peephole2
20369 [(match_scratch:SI 0 "r")
20370 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20371 (clobber (reg:CC FLAGS_REG))
20372 (clobber (mem:BLK (scratch)))])]
20373 "optimize_size"
20374 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20375 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20376 (clobber (mem:BLK (scratch)))])
20377 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20378 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20379 "")
20380
20381 ;; Convert esp additions to pop.
20382 (define_peephole2
20383 [(match_scratch:SI 0 "r")
20384 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20385 (clobber (reg:CC FLAGS_REG))])]
20386 ""
20387 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20388 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20389 "")
20390
20391 ;; Two pops case is tricky, since pop causes dependency on destination register.
20392 ;; We use two registers if available.
20393 (define_peephole2
20394 [(match_scratch:SI 0 "r")
20395 (match_scratch:SI 1 "r")
20396 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20397 (clobber (reg:CC FLAGS_REG))])]
20398 ""
20399 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20400 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20401 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20402 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20403 "")
20404
20405 (define_peephole2
20406 [(match_scratch:SI 0 "r")
20407 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20408 (clobber (reg:CC FLAGS_REG))])]
20409 "optimize_size"
20410 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20411 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20412 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20413 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20414 "")
20415 \f
20416 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20417 ;; required and register dies. Similarly for 128 to plus -128.
20418 (define_peephole2
20419 [(set (match_operand 0 "flags_reg_operand" "")
20420 (match_operator 1 "compare_operator"
20421 [(match_operand 2 "register_operand" "")
20422 (match_operand 3 "const_int_operand" "")]))]
20423 "(INTVAL (operands[3]) == -1
20424 || INTVAL (operands[3]) == 1
20425 || INTVAL (operands[3]) == 128)
20426 && ix86_match_ccmode (insn, CCGCmode)
20427 && peep2_reg_dead_p (1, operands[2])"
20428 [(parallel [(set (match_dup 0)
20429 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20430 (clobber (match_dup 2))])]
20431 "")
20432 \f
20433 (define_peephole2
20434 [(match_scratch:DI 0 "r")
20435 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20436 (clobber (reg:CC FLAGS_REG))
20437 (clobber (mem:BLK (scratch)))])]
20438 "optimize_size || !TARGET_SUB_ESP_4"
20439 [(clobber (match_dup 0))
20440 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20441 (clobber (mem:BLK (scratch)))])])
20442
20443 (define_peephole2
20444 [(match_scratch:DI 0 "r")
20445 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20446 (clobber (reg:CC FLAGS_REG))
20447 (clobber (mem:BLK (scratch)))])]
20448 "optimize_size || !TARGET_SUB_ESP_8"
20449 [(clobber (match_dup 0))
20450 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20451 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20452 (clobber (mem:BLK (scratch)))])])
20453
20454 ;; Convert esp subtractions to push.
20455 (define_peephole2
20456 [(match_scratch:DI 0 "r")
20457 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20458 (clobber (reg:CC FLAGS_REG))])]
20459 "optimize_size || !TARGET_SUB_ESP_4"
20460 [(clobber (match_dup 0))
20461 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20462
20463 (define_peephole2
20464 [(match_scratch:DI 0 "r")
20465 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20466 (clobber (reg:CC FLAGS_REG))])]
20467 "optimize_size || !TARGET_SUB_ESP_8"
20468 [(clobber (match_dup 0))
20469 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20470 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20471
20472 ;; Convert epilogue deallocator to pop.
20473 (define_peephole2
20474 [(match_scratch:DI 0 "r")
20475 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20476 (clobber (reg:CC FLAGS_REG))
20477 (clobber (mem:BLK (scratch)))])]
20478 "optimize_size || !TARGET_ADD_ESP_4"
20479 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20480 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20481 (clobber (mem:BLK (scratch)))])]
20482 "")
20483
20484 ;; Two pops case is tricky, since pop causes dependency on destination register.
20485 ;; We use two registers if available.
20486 (define_peephole2
20487 [(match_scratch:DI 0 "r")
20488 (match_scratch:DI 1 "r")
20489 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20490 (clobber (reg:CC FLAGS_REG))
20491 (clobber (mem:BLK (scratch)))])]
20492 "optimize_size || !TARGET_ADD_ESP_8"
20493 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20494 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20495 (clobber (mem:BLK (scratch)))])
20496 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20497 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20498 "")
20499
20500 (define_peephole2
20501 [(match_scratch:DI 0 "r")
20502 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20503 (clobber (reg:CC FLAGS_REG))
20504 (clobber (mem:BLK (scratch)))])]
20505 "optimize_size"
20506 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20507 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20508 (clobber (mem:BLK (scratch)))])
20509 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20510 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20511 "")
20512
20513 ;; Convert esp additions to pop.
20514 (define_peephole2
20515 [(match_scratch:DI 0 "r")
20516 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20517 (clobber (reg:CC FLAGS_REG))])]
20518 ""
20519 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20520 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20521 "")
20522
20523 ;; Two pops case is tricky, since pop causes dependency on destination register.
20524 ;; We use two registers if available.
20525 (define_peephole2
20526 [(match_scratch:DI 0 "r")
20527 (match_scratch:DI 1 "r")
20528 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20529 (clobber (reg:CC FLAGS_REG))])]
20530 ""
20531 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20532 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20533 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20534 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20535 "")
20536
20537 (define_peephole2
20538 [(match_scratch:DI 0 "r")
20539 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20540 (clobber (reg:CC FLAGS_REG))])]
20541 "optimize_size"
20542 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20543 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20544 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20545 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20546 "")
20547 \f
20548 ;; Convert imul by three, five and nine into lea
20549 (define_peephole2
20550 [(parallel
20551 [(set (match_operand:SI 0 "register_operand" "")
20552 (mult:SI (match_operand:SI 1 "register_operand" "")
20553 (match_operand:SI 2 "const_int_operand" "")))
20554 (clobber (reg:CC FLAGS_REG))])]
20555 "INTVAL (operands[2]) == 3
20556 || INTVAL (operands[2]) == 5
20557 || INTVAL (operands[2]) == 9"
20558 [(set (match_dup 0)
20559 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20560 (match_dup 1)))]
20561 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20562
20563 (define_peephole2
20564 [(parallel
20565 [(set (match_operand:SI 0 "register_operand" "")
20566 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20567 (match_operand:SI 2 "const_int_operand" "")))
20568 (clobber (reg:CC FLAGS_REG))])]
20569 "!optimize_size
20570 && (INTVAL (operands[2]) == 3
20571 || INTVAL (operands[2]) == 5
20572 || INTVAL (operands[2]) == 9)"
20573 [(set (match_dup 0) (match_dup 1))
20574 (set (match_dup 0)
20575 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20576 (match_dup 0)))]
20577 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20578
20579 (define_peephole2
20580 [(parallel
20581 [(set (match_operand:DI 0 "register_operand" "")
20582 (mult:DI (match_operand:DI 1 "register_operand" "")
20583 (match_operand:DI 2 "const_int_operand" "")))
20584 (clobber (reg:CC FLAGS_REG))])]
20585 "TARGET_64BIT
20586 && (INTVAL (operands[2]) == 3
20587 || INTVAL (operands[2]) == 5
20588 || INTVAL (operands[2]) == 9)"
20589 [(set (match_dup 0)
20590 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20591 (match_dup 1)))]
20592 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20593
20594 (define_peephole2
20595 [(parallel
20596 [(set (match_operand:DI 0 "register_operand" "")
20597 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20598 (match_operand:DI 2 "const_int_operand" "")))
20599 (clobber (reg:CC FLAGS_REG))])]
20600 "TARGET_64BIT
20601 && !optimize_size
20602 && (INTVAL (operands[2]) == 3
20603 || INTVAL (operands[2]) == 5
20604 || INTVAL (operands[2]) == 9)"
20605 [(set (match_dup 0) (match_dup 1))
20606 (set (match_dup 0)
20607 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20608 (match_dup 0)))]
20609 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20610
20611 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20612 ;; imul $32bit_imm, reg, reg is direct decoded.
20613 (define_peephole2
20614 [(match_scratch:DI 3 "r")
20615 (parallel [(set (match_operand:DI 0 "register_operand" "")
20616 (mult:DI (match_operand:DI 1 "memory_operand" "")
20617 (match_operand:DI 2 "immediate_operand" "")))
20618 (clobber (reg:CC FLAGS_REG))])]
20619 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20620 && !satisfies_constraint_K (operands[2])"
20621 [(set (match_dup 3) (match_dup 1))
20622 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20623 (clobber (reg:CC FLAGS_REG))])]
20624 "")
20625
20626 (define_peephole2
20627 [(match_scratch:SI 3 "r")
20628 (parallel [(set (match_operand:SI 0 "register_operand" "")
20629 (mult:SI (match_operand:SI 1 "memory_operand" "")
20630 (match_operand:SI 2 "immediate_operand" "")))
20631 (clobber (reg:CC FLAGS_REG))])]
20632 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20633 && !satisfies_constraint_K (operands[2])"
20634 [(set (match_dup 3) (match_dup 1))
20635 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20636 (clobber (reg:CC FLAGS_REG))])]
20637 "")
20638
20639 (define_peephole2
20640 [(match_scratch:SI 3 "r")
20641 (parallel [(set (match_operand:DI 0 "register_operand" "")
20642 (zero_extend:DI
20643 (mult:SI (match_operand:SI 1 "memory_operand" "")
20644 (match_operand:SI 2 "immediate_operand" ""))))
20645 (clobber (reg:CC FLAGS_REG))])]
20646 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20647 && !satisfies_constraint_K (operands[2])"
20648 [(set (match_dup 3) (match_dup 1))
20649 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20650 (clobber (reg:CC FLAGS_REG))])]
20651 "")
20652
20653 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20654 ;; Convert it into imul reg, reg
20655 ;; It would be better to force assembler to encode instruction using long
20656 ;; immediate, but there is apparently no way to do so.
20657 (define_peephole2
20658 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20659 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20660 (match_operand:DI 2 "const_int_operand" "")))
20661 (clobber (reg:CC FLAGS_REG))])
20662 (match_scratch:DI 3 "r")]
20663 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20664 && satisfies_constraint_K (operands[2])"
20665 [(set (match_dup 3) (match_dup 2))
20666 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20667 (clobber (reg:CC FLAGS_REG))])]
20668 {
20669 if (!rtx_equal_p (operands[0], operands[1]))
20670 emit_move_insn (operands[0], operands[1]);
20671 })
20672
20673 (define_peephole2
20674 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20675 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20676 (match_operand:SI 2 "const_int_operand" "")))
20677 (clobber (reg:CC FLAGS_REG))])
20678 (match_scratch:SI 3 "r")]
20679 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20680 && satisfies_constraint_K (operands[2])"
20681 [(set (match_dup 3) (match_dup 2))
20682 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20683 (clobber (reg:CC FLAGS_REG))])]
20684 {
20685 if (!rtx_equal_p (operands[0], operands[1]))
20686 emit_move_insn (operands[0], operands[1]);
20687 })
20688
20689 (define_peephole2
20690 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20691 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20692 (match_operand:HI 2 "immediate_operand" "")))
20693 (clobber (reg:CC FLAGS_REG))])
20694 (match_scratch:HI 3 "r")]
20695 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20696 [(set (match_dup 3) (match_dup 2))
20697 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20698 (clobber (reg:CC FLAGS_REG))])]
20699 {
20700 if (!rtx_equal_p (operands[0], operands[1]))
20701 emit_move_insn (operands[0], operands[1]);
20702 })
20703
20704 ;; After splitting up read-modify operations, array accesses with memory
20705 ;; operands might end up in form:
20706 ;; sall $2, %eax
20707 ;; movl 4(%esp), %edx
20708 ;; addl %edx, %eax
20709 ;; instead of pre-splitting:
20710 ;; sall $2, %eax
20711 ;; addl 4(%esp), %eax
20712 ;; Turn it into:
20713 ;; movl 4(%esp), %edx
20714 ;; leal (%edx,%eax,4), %eax
20715
20716 (define_peephole2
20717 [(parallel [(set (match_operand 0 "register_operand" "")
20718 (ashift (match_operand 1 "register_operand" "")
20719 (match_operand 2 "const_int_operand" "")))
20720 (clobber (reg:CC FLAGS_REG))])
20721 (set (match_operand 3 "register_operand")
20722 (match_operand 4 "x86_64_general_operand" ""))
20723 (parallel [(set (match_operand 5 "register_operand" "")
20724 (plus (match_operand 6 "register_operand" "")
20725 (match_operand 7 "register_operand" "")))
20726 (clobber (reg:CC FLAGS_REG))])]
20727 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20728 /* Validate MODE for lea. */
20729 && ((!TARGET_PARTIAL_REG_STALL
20730 && (GET_MODE (operands[0]) == QImode
20731 || GET_MODE (operands[0]) == HImode))
20732 || GET_MODE (operands[0]) == SImode
20733 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20734 /* We reorder load and the shift. */
20735 && !rtx_equal_p (operands[1], operands[3])
20736 && !reg_overlap_mentioned_p (operands[0], operands[4])
20737 /* Last PLUS must consist of operand 0 and 3. */
20738 && !rtx_equal_p (operands[0], operands[3])
20739 && (rtx_equal_p (operands[3], operands[6])
20740 || rtx_equal_p (operands[3], operands[7]))
20741 && (rtx_equal_p (operands[0], operands[6])
20742 || rtx_equal_p (operands[0], operands[7]))
20743 /* The intermediate operand 0 must die or be same as output. */
20744 && (rtx_equal_p (operands[0], operands[5])
20745 || peep2_reg_dead_p (3, operands[0]))"
20746 [(set (match_dup 3) (match_dup 4))
20747 (set (match_dup 0) (match_dup 1))]
20748 {
20749 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20750 int scale = 1 << INTVAL (operands[2]);
20751 rtx index = gen_lowpart (Pmode, operands[1]);
20752 rtx base = gen_lowpart (Pmode, operands[3]);
20753 rtx dest = gen_lowpart (mode, operands[5]);
20754
20755 operands[1] = gen_rtx_PLUS (Pmode, base,
20756 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20757 if (mode != Pmode)
20758 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20759 operands[0] = dest;
20760 })
20761 \f
20762 ;; Call-value patterns last so that the wildcard operand does not
20763 ;; disrupt insn-recog's switch tables.
20764
20765 (define_insn "*call_value_pop_0"
20766 [(set (match_operand 0 "" "")
20767 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20768 (match_operand:SI 2 "" "")))
20769 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20770 (match_operand:SI 3 "immediate_operand" "")))]
20771 "!TARGET_64BIT"
20772 {
20773 if (SIBLING_CALL_P (insn))
20774 return "jmp\t%P1";
20775 else
20776 return "call\t%P1";
20777 }
20778 [(set_attr "type" "callv")])
20779
20780 (define_insn "*call_value_pop_1"
20781 [(set (match_operand 0 "" "")
20782 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20783 (match_operand:SI 2 "" "")))
20784 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20785 (match_operand:SI 3 "immediate_operand" "i")))]
20786 "!TARGET_64BIT"
20787 {
20788 if (constant_call_address_operand (operands[1], Pmode))
20789 {
20790 if (SIBLING_CALL_P (insn))
20791 return "jmp\t%P1";
20792 else
20793 return "call\t%P1";
20794 }
20795 if (SIBLING_CALL_P (insn))
20796 return "jmp\t%A1";
20797 else
20798 return "call\t%A1";
20799 }
20800 [(set_attr "type" "callv")])
20801
20802 (define_insn "*call_value_0"
20803 [(set (match_operand 0 "" "")
20804 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20805 (match_operand:SI 2 "" "")))]
20806 "!TARGET_64BIT"
20807 {
20808 if (SIBLING_CALL_P (insn))
20809 return "jmp\t%P1";
20810 else
20811 return "call\t%P1";
20812 }
20813 [(set_attr "type" "callv")])
20814
20815 (define_insn "*call_value_0_rex64"
20816 [(set (match_operand 0 "" "")
20817 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20818 (match_operand:DI 2 "const_int_operand" "")))]
20819 "TARGET_64BIT"
20820 {
20821 if (SIBLING_CALL_P (insn))
20822 return "jmp\t%P1";
20823 else
20824 return "call\t%P1";
20825 }
20826 [(set_attr "type" "callv")])
20827
20828 (define_insn "*call_value_1"
20829 [(set (match_operand 0 "" "")
20830 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20831 (match_operand:SI 2 "" "")))]
20832 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20833 {
20834 if (constant_call_address_operand (operands[1], Pmode))
20835 return "call\t%P1";
20836 return "call\t%A1";
20837 }
20838 [(set_attr "type" "callv")])
20839
20840 (define_insn "*sibcall_value_1"
20841 [(set (match_operand 0 "" "")
20842 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20843 (match_operand:SI 2 "" "")))]
20844 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20845 {
20846 if (constant_call_address_operand (operands[1], Pmode))
20847 return "jmp\t%P1";
20848 return "jmp\t%A1";
20849 }
20850 [(set_attr "type" "callv")])
20851
20852 (define_insn "*call_value_1_rex64"
20853 [(set (match_operand 0 "" "")
20854 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20855 (match_operand:DI 2 "" "")))]
20856 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20857 {
20858 if (constant_call_address_operand (operands[1], Pmode))
20859 return "call\t%P1";
20860 return "call\t%A1";
20861 }
20862 [(set_attr "type" "callv")])
20863
20864 (define_insn "*sibcall_value_1_rex64"
20865 [(set (match_operand 0 "" "")
20866 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20867 (match_operand:DI 2 "" "")))]
20868 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20869 "jmp\t%P1"
20870 [(set_attr "type" "callv")])
20871
20872 (define_insn "*sibcall_value_1_rex64_v"
20873 [(set (match_operand 0 "" "")
20874 (call (mem:QI (reg:DI R11_REG))
20875 (match_operand:DI 1 "" "")))]
20876 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20877 "jmp\t*%%r11"
20878 [(set_attr "type" "callv")])
20879 \f
20880 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20881 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20882 ;; caught for use by garbage collectors and the like. Using an insn that
20883 ;; maps to SIGILL makes it more likely the program will rightfully die.
20884 ;; Keeping with tradition, "6" is in honor of #UD.
20885 (define_insn "trap"
20886 [(trap_if (const_int 1) (const_int 6))]
20887 ""
20888 { return ASM_SHORT "0x0b0f"; }
20889 [(set_attr "length" "2")])
20890
20891 (define_expand "sse_prologue_save"
20892 [(parallel [(set (match_operand:BLK 0 "" "")
20893 (unspec:BLK [(reg:DI 22)
20894 (reg:DI 23)
20895 (reg:DI 24)
20896 (reg:DI 25)
20897 (reg:DI 26)
20898 (reg:DI 27)
20899 (reg:DI 28)
20900 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20901 (use (match_operand:DI 1 "register_operand" ""))
20902 (use (match_operand:DI 2 "immediate_operand" ""))
20903 (use (label_ref:DI (match_operand 3 "" "")))])]
20904 "TARGET_64BIT"
20905 "")
20906
20907 (define_insn "*sse_prologue_save_insn"
20908 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20909 (match_operand:DI 4 "const_int_operand" "n")))
20910 (unspec:BLK [(reg:DI 22)
20911 (reg:DI 23)
20912 (reg:DI 24)
20913 (reg:DI 25)
20914 (reg:DI 26)
20915 (reg:DI 27)
20916 (reg:DI 28)
20917 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20918 (use (match_operand:DI 1 "register_operand" "r"))
20919 (use (match_operand:DI 2 "const_int_operand" "i"))
20920 (use (label_ref:DI (match_operand 3 "" "X")))]
20921 "TARGET_64BIT
20922 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20923 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20924 "*
20925 {
20926 int i;
20927 operands[0] = gen_rtx_MEM (Pmode,
20928 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20929 output_asm_insn (\"jmp\\t%A1\", operands);
20930 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20931 {
20932 operands[4] = adjust_address (operands[0], DImode, i*16);
20933 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20934 PUT_MODE (operands[4], TImode);
20935 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20936 output_asm_insn (\"rex\", operands);
20937 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20938 }
20939 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20940 CODE_LABEL_NUMBER (operands[3]));
20941 RET;
20942 }
20943 "
20944 [(set_attr "type" "other")
20945 (set_attr "length_immediate" "0")
20946 (set_attr "length_address" "0")
20947 (set_attr "length" "135")
20948 (set_attr "memory" "store")
20949 (set_attr "modrm" "0")
20950 (set_attr "mode" "DI")])
20951
20952 (define_expand "prefetch"
20953 [(prefetch (match_operand 0 "address_operand" "")
20954 (match_operand:SI 1 "const_int_operand" "")
20955 (match_operand:SI 2 "const_int_operand" ""))]
20956 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20957 {
20958 int rw = INTVAL (operands[1]);
20959 int locality = INTVAL (operands[2]);
20960
20961 gcc_assert (rw == 0 || rw == 1);
20962 gcc_assert (locality >= 0 && locality <= 3);
20963 gcc_assert (GET_MODE (operands[0]) == Pmode
20964 || GET_MODE (operands[0]) == VOIDmode);
20965
20966 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20967 supported by SSE counterpart or the SSE prefetch is not available
20968 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20969 of locality. */
20970 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20971 operands[2] = GEN_INT (3);
20972 else
20973 operands[1] = const0_rtx;
20974 })
20975
20976 (define_insn "*prefetch_sse"
20977 [(prefetch (match_operand:SI 0 "address_operand" "p")
20978 (const_int 0)
20979 (match_operand:SI 1 "const_int_operand" ""))]
20980 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20981 {
20982 static const char * const patterns[4] = {
20983 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20984 };
20985
20986 int locality = INTVAL (operands[1]);
20987 gcc_assert (locality >= 0 && locality <= 3);
20988
20989 return patterns[locality];
20990 }
20991 [(set_attr "type" "sse")
20992 (set_attr "memory" "none")])
20993
20994 (define_insn "*prefetch_sse_rex"
20995 [(prefetch (match_operand:DI 0 "address_operand" "p")
20996 (const_int 0)
20997 (match_operand:SI 1 "const_int_operand" ""))]
20998 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20999 {
21000 static const char * const patterns[4] = {
21001 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21002 };
21003
21004 int locality = INTVAL (operands[1]);
21005 gcc_assert (locality >= 0 && locality <= 3);
21006
21007 return patterns[locality];
21008 }
21009 [(set_attr "type" "sse")
21010 (set_attr "memory" "none")])
21011
21012 (define_insn "*prefetch_3dnow"
21013 [(prefetch (match_operand:SI 0 "address_operand" "p")
21014 (match_operand:SI 1 "const_int_operand" "n")
21015 (const_int 3))]
21016 "TARGET_3DNOW && !TARGET_64BIT"
21017 {
21018 if (INTVAL (operands[1]) == 0)
21019 return "prefetch\t%a0";
21020 else
21021 return "prefetchw\t%a0";
21022 }
21023 [(set_attr "type" "mmx")
21024 (set_attr "memory" "none")])
21025
21026 (define_insn "*prefetch_3dnow_rex"
21027 [(prefetch (match_operand:DI 0 "address_operand" "p")
21028 (match_operand:SI 1 "const_int_operand" "n")
21029 (const_int 3))]
21030 "TARGET_3DNOW && TARGET_64BIT"
21031 {
21032 if (INTVAL (operands[1]) == 0)
21033 return "prefetch\t%a0";
21034 else
21035 return "prefetchw\t%a0";
21036 }
21037 [(set_attr "type" "mmx")
21038 (set_attr "memory" "none")])
21039
21040 (define_expand "stack_protect_set"
21041 [(match_operand 0 "memory_operand" "")
21042 (match_operand 1 "memory_operand" "")]
21043 ""
21044 {
21045 #ifdef TARGET_THREAD_SSP_OFFSET
21046 if (TARGET_64BIT)
21047 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21048 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21049 else
21050 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21051 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21052 #else
21053 if (TARGET_64BIT)
21054 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21055 else
21056 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21057 #endif
21058 DONE;
21059 })
21060
21061 (define_insn "stack_protect_set_si"
21062 [(set (match_operand:SI 0 "memory_operand" "=m")
21063 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21064 (set (match_scratch:SI 2 "=&r") (const_int 0))
21065 (clobber (reg:CC FLAGS_REG))]
21066 ""
21067 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21068 [(set_attr "type" "multi")])
21069
21070 (define_insn "stack_protect_set_di"
21071 [(set (match_operand:DI 0 "memory_operand" "=m")
21072 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21073 (set (match_scratch:DI 2 "=&r") (const_int 0))
21074 (clobber (reg:CC FLAGS_REG))]
21075 "TARGET_64BIT"
21076 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21077 [(set_attr "type" "multi")])
21078
21079 (define_insn "stack_tls_protect_set_si"
21080 [(set (match_operand:SI 0 "memory_operand" "=m")
21081 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21082 (set (match_scratch:SI 2 "=&r") (const_int 0))
21083 (clobber (reg:CC FLAGS_REG))]
21084 ""
21085 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21086 [(set_attr "type" "multi")])
21087
21088 (define_insn "stack_tls_protect_set_di"
21089 [(set (match_operand:DI 0 "memory_operand" "=m")
21090 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21091 (set (match_scratch:DI 2 "=&r") (const_int 0))
21092 (clobber (reg:CC FLAGS_REG))]
21093 "TARGET_64BIT"
21094 {
21095 /* The kernel uses a different segment register for performance reasons; a
21096 system call would not have to trash the userspace segment register,
21097 which would be expensive */
21098 if (ix86_cmodel != CM_KERNEL)
21099 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21100 else
21101 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21102 }
21103 [(set_attr "type" "multi")])
21104
21105 (define_expand "stack_protect_test"
21106 [(match_operand 0 "memory_operand" "")
21107 (match_operand 1 "memory_operand" "")
21108 (match_operand 2 "" "")]
21109 ""
21110 {
21111 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21112 ix86_compare_op0 = operands[0];
21113 ix86_compare_op1 = operands[1];
21114 ix86_compare_emitted = flags;
21115
21116 #ifdef TARGET_THREAD_SSP_OFFSET
21117 if (TARGET_64BIT)
21118 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21119 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21120 else
21121 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21122 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21123 #else
21124 if (TARGET_64BIT)
21125 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21126 else
21127 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21128 #endif
21129 emit_jump_insn (gen_beq (operands[2]));
21130 DONE;
21131 })
21132
21133 (define_insn "stack_protect_test_si"
21134 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21135 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21136 (match_operand:SI 2 "memory_operand" "m")]
21137 UNSPEC_SP_TEST))
21138 (clobber (match_scratch:SI 3 "=&r"))]
21139 ""
21140 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21141 [(set_attr "type" "multi")])
21142
21143 (define_insn "stack_protect_test_di"
21144 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21145 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21146 (match_operand:DI 2 "memory_operand" "m")]
21147 UNSPEC_SP_TEST))
21148 (clobber (match_scratch:DI 3 "=&r"))]
21149 "TARGET_64BIT"
21150 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21151 [(set_attr "type" "multi")])
21152
21153 (define_insn "stack_tls_protect_test_si"
21154 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21155 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21156 (match_operand:SI 2 "const_int_operand" "i")]
21157 UNSPEC_SP_TLS_TEST))
21158 (clobber (match_scratch:SI 3 "=r"))]
21159 ""
21160 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21161 [(set_attr "type" "multi")])
21162
21163 (define_insn "stack_tls_protect_test_di"
21164 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21165 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21166 (match_operand:DI 2 "const_int_operand" "i")]
21167 UNSPEC_SP_TLS_TEST))
21168 (clobber (match_scratch:DI 3 "=r"))]
21169 "TARGET_64BIT"
21170 {
21171 /* The kernel uses a different segment register for performance reasons; a
21172 system call would not have to trash the userspace segment register,
21173 which would be expensive */
21174 if (ix86_cmodel != CM_KERNEL)
21175 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21176 else
21177 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21178 }
21179 [(set_attr "type" "multi")])
21180
21181 (include "mmx.md")
21182 (include "sse.md")
21183 (include "sync.md")