i386.md (trap): Use "".word/t0x0b0f" instead of ud2.
[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
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
70 ; TLS support
71 (UNSPEC_TP 15)
72 (UNSPEC_TLS_GD 16)
73 (UNSPEC_TLS_LD_BASE 17)
74
75 ; Other random patterns
76 (UNSPEC_SCAS 20)
77 (UNSPEC_FNSTSW 21)
78 (UNSPEC_SAHF 22)
79 (UNSPEC_FSTCW 23)
80 (UNSPEC_ADD_CARRY 24)
81 (UNSPEC_FLDCW 25)
82 (UNSPEC_REP 26)
83 (UNSPEC_EH_RETURN 27)
84
85 ; For SSE/MMX support:
86 (UNSPEC_FIX_NOTRUNC 30)
87 (UNSPEC_MASKMOV 31)
88 (UNSPEC_MOVMSK 32)
89 (UNSPEC_MOVNT 33)
90 (UNSPEC_MOVU 34)
91 (UNSPEC_RCP 35)
92 (UNSPEC_RSQRT 36)
93 (UNSPEC_SFENCE 37)
94 (UNSPEC_NOP 38) ; prevents combiner cleverness
95 (UNSPEC_PFRCP 39)
96 (UNSPEC_PFRCPIT1 40)
97 (UNSPEC_PFRCPIT2 41)
98 (UNSPEC_PFRSQRT 42)
99 (UNSPEC_PFRSQIT1 43)
100 (UNSPEC_MFENCE 44)
101 (UNSPEC_LFENCE 45)
102 (UNSPEC_PSADBW 46)
103 (UNSPEC_LDQQU 47)
104
105 ; Generic math support
106 (UNSPEC_COPYSIGN 50)
107 (UNSPEC_IEEE_MIN 51) ; not commutative
108 (UNSPEC_IEEE_MAX 52) ; not commutative
109
110 ; x87 Floating point
111 (UNSPEC_SIN 60)
112 (UNSPEC_COS 61)
113 (UNSPEC_FPATAN 62)
114 (UNSPEC_FYL2X 63)
115 (UNSPEC_FYL2XP1 64)
116 (UNSPEC_FRNDINT 65)
117 (UNSPEC_FIST 66)
118 (UNSPEC_F2XM1 67)
119
120 ; x87 Rounding
121 (UNSPEC_FRNDINT_FLOOR 70)
122 (UNSPEC_FRNDINT_CEIL 71)
123 (UNSPEC_FRNDINT_TRUNC 72)
124 (UNSPEC_FRNDINT_MASK_PM 73)
125 (UNSPEC_FIST_FLOOR 74)
126 (UNSPEC_FIST_CEIL 75)
127
128 ; x87 Double output FP
129 (UNSPEC_SINCOS_COS 80)
130 (UNSPEC_SINCOS_SIN 81)
131 (UNSPEC_TAN_ONE 82)
132 (UNSPEC_TAN_TAN 83)
133 (UNSPEC_XTRACT_FRACT 84)
134 (UNSPEC_XTRACT_EXP 85)
135 (UNSPEC_FSCALE_FRACT 86)
136 (UNSPEC_FSCALE_EXP 87)
137 (UNSPEC_FPREM_F 88)
138 (UNSPEC_FPREM_U 89)
139 (UNSPEC_FPREM1_F 90)
140 (UNSPEC_FPREM1_U 91)
141
142 ; SSP patterns
143 (UNSPEC_SP_SET 100)
144 (UNSPEC_SP_TEST 101)
145 (UNSPEC_SP_TLS_SET 102)
146 (UNSPEC_SP_TLS_TEST 103)
147 ])
148
149 (define_constants
150 [(UNSPECV_BLOCKAGE 0)
151 (UNSPECV_STACK_PROBE 1)
152 (UNSPECV_EMMS 2)
153 (UNSPECV_LDMXCSR 3)
154 (UNSPECV_STMXCSR 4)
155 (UNSPECV_FEMMS 5)
156 (UNSPECV_CLFLUSH 6)
157 (UNSPECV_ALIGN 7)
158 (UNSPECV_MONITOR 8)
159 (UNSPECV_MWAIT 9)
160 (UNSPECV_CMPXCHG_1 10)
161 (UNSPECV_CMPXCHG_2 11)
162 (UNSPECV_XCHG 12)
163 (UNSPECV_LOCK 13)
164 ])
165
166 ;; Registers by name.
167 (define_constants
168 [(BP_REG 6)
169 (SP_REG 7)
170 (FLAGS_REG 17)
171 (FPSR_REG 18)
172 (DIRFLAG_REG 19)
173 ])
174
175 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
176 ;; from i386.c.
177
178 ;; In C guard expressions, put expressions which may be compile-time
179 ;; constants first. This allows for better optimization. For
180 ;; example, write "TARGET_64BIT && reload_completed", not
181 ;; "reload_completed && TARGET_64BIT".
182
183 \f
184 ;; Processor type. This attribute must exactly match the processor_type
185 ;; enumeration in i386.h.
186 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
187 (const (symbol_ref "ix86_tune")))
188
189 ;; A basic instruction type. Refinements due to arguments to be
190 ;; provided in other attributes.
191 (define_attr "type"
192 "other,multi,
193 alu,alu1,negnot,imov,imovx,lea,
194 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
195 icmp,test,ibr,setcc,icmov,
196 push,pop,call,callv,leave,
197 str,cld,
198 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
199 sselog,sselog1,sseiadd,sseishft,sseimul,
200 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
201 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
202 (const_string "other"))
203
204 ;; Main data type used by the insn
205 (define_attr "mode"
206 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
207 (const_string "unknown"))
208
209 ;; The CPU unit operations uses.
210 (define_attr "unit" "integer,i387,sse,mmx,unknown"
211 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
212 (const_string "i387")
213 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
214 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
215 (const_string "sse")
216 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
217 (const_string "mmx")
218 (eq_attr "type" "other")
219 (const_string "unknown")]
220 (const_string "integer")))
221
222 ;; The (bounding maximum) length of an instruction immediate.
223 (define_attr "length_immediate" ""
224 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
225 (const_int 0)
226 (eq_attr "unit" "i387,sse,mmx")
227 (const_int 0)
228 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
229 imul,icmp,push,pop")
230 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
231 (eq_attr "type" "imov,test")
232 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
233 (eq_attr "type" "call")
234 (if_then_else (match_operand 0 "constant_call_address_operand" "")
235 (const_int 4)
236 (const_int 0))
237 (eq_attr "type" "callv")
238 (if_then_else (match_operand 1 "constant_call_address_operand" "")
239 (const_int 4)
240 (const_int 0))
241 ;; We don't know the size before shorten_branches. Expect
242 ;; the instruction to fit for better scheduling.
243 (eq_attr "type" "ibr")
244 (const_int 1)
245 ]
246 (symbol_ref "/* Update immediate_length and other attributes! */
247 gcc_unreachable (),1")))
248
249 ;; The (bounding maximum) length of an instruction address.
250 (define_attr "length_address" ""
251 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
252 (const_int 0)
253 (and (eq_attr "type" "call")
254 (match_operand 0 "constant_call_address_operand" ""))
255 (const_int 0)
256 (and (eq_attr "type" "callv")
257 (match_operand 1 "constant_call_address_operand" ""))
258 (const_int 0)
259 ]
260 (symbol_ref "ix86_attr_length_address_default (insn)")))
261
262 ;; Set when length prefix is used.
263 (define_attr "prefix_data16" ""
264 (if_then_else (ior (eq_attr "mode" "HI")
265 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
266 (const_int 1)
267 (const_int 0)))
268
269 ;; Set when string REP prefix is used.
270 (define_attr "prefix_rep" ""
271 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
272 (const_int 1)
273 (const_int 0)))
274
275 ;; Set when 0f opcode prefix is used.
276 (define_attr "prefix_0f" ""
277 (if_then_else
278 (ior (eq_attr "type" "imovx,setcc,icmov")
279 (eq_attr "unit" "sse,mmx"))
280 (const_int 1)
281 (const_int 0)))
282
283 ;; Set when REX opcode prefix is used.
284 (define_attr "prefix_rex" ""
285 (cond [(and (eq_attr "mode" "DI")
286 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
287 (const_int 1)
288 (and (eq_attr "mode" "QI")
289 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
290 (const_int 0)))
291 (const_int 1)
292 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
293 (const_int 0))
294 (const_int 1)
295 ]
296 (const_int 0)))
297
298 ;; Set when modrm byte is used.
299 (define_attr "modrm" ""
300 (cond [(eq_attr "type" "str,cld,leave")
301 (const_int 0)
302 (eq_attr "unit" "i387")
303 (const_int 0)
304 (and (eq_attr "type" "incdec")
305 (ior (match_operand:SI 1 "register_operand" "")
306 (match_operand:HI 1 "register_operand" "")))
307 (const_int 0)
308 (and (eq_attr "type" "push")
309 (not (match_operand 1 "memory_operand" "")))
310 (const_int 0)
311 (and (eq_attr "type" "pop")
312 (not (match_operand 0 "memory_operand" "")))
313 (const_int 0)
314 (and (eq_attr "type" "imov")
315 (and (match_operand 0 "register_operand" "")
316 (match_operand 1 "immediate_operand" "")))
317 (const_int 0)
318 (and (eq_attr "type" "call")
319 (match_operand 0 "constant_call_address_operand" ""))
320 (const_int 0)
321 (and (eq_attr "type" "callv")
322 (match_operand 1 "constant_call_address_operand" ""))
323 (const_int 0)
324 ]
325 (const_int 1)))
326
327 ;; The (bounding maximum) length of an instruction in bytes.
328 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
329 ;; Later we may want to split them and compute proper length as for
330 ;; other insns.
331 (define_attr "length" ""
332 (cond [(eq_attr "type" "other,multi,fistp,frndint")
333 (const_int 16)
334 (eq_attr "type" "fcmp")
335 (const_int 4)
336 (eq_attr "unit" "i387")
337 (plus (const_int 2)
338 (plus (attr "prefix_data16")
339 (attr "length_address")))]
340 (plus (plus (attr "modrm")
341 (plus (attr "prefix_0f")
342 (plus (attr "prefix_rex")
343 (const_int 1))))
344 (plus (attr "prefix_rep")
345 (plus (attr "prefix_data16")
346 (plus (attr "length_immediate")
347 (attr "length_address")))))))
348
349 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
350 ;; `store' if there is a simple memory reference therein, or `unknown'
351 ;; if the instruction is complex.
352
353 (define_attr "memory" "none,load,store,both,unknown"
354 (cond [(eq_attr "type" "other,multi,str")
355 (const_string "unknown")
356 (eq_attr "type" "lea,fcmov,fpspc,cld")
357 (const_string "none")
358 (eq_attr "type" "fistp,leave")
359 (const_string "both")
360 (eq_attr "type" "frndint")
361 (const_string "load")
362 (eq_attr "type" "push")
363 (if_then_else (match_operand 1 "memory_operand" "")
364 (const_string "both")
365 (const_string "store"))
366 (eq_attr "type" "pop")
367 (if_then_else (match_operand 0 "memory_operand" "")
368 (const_string "both")
369 (const_string "load"))
370 (eq_attr "type" "setcc")
371 (if_then_else (match_operand 0 "memory_operand" "")
372 (const_string "store")
373 (const_string "none"))
374 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
375 (if_then_else (ior (match_operand 0 "memory_operand" "")
376 (match_operand 1 "memory_operand" ""))
377 (const_string "load")
378 (const_string "none"))
379 (eq_attr "type" "ibr")
380 (if_then_else (match_operand 0 "memory_operand" "")
381 (const_string "load")
382 (const_string "none"))
383 (eq_attr "type" "call")
384 (if_then_else (match_operand 0 "constant_call_address_operand" "")
385 (const_string "none")
386 (const_string "load"))
387 (eq_attr "type" "callv")
388 (if_then_else (match_operand 1 "constant_call_address_operand" "")
389 (const_string "none")
390 (const_string "load"))
391 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
392 (match_operand 1 "memory_operand" ""))
393 (const_string "both")
394 (and (match_operand 0 "memory_operand" "")
395 (match_operand 1 "memory_operand" ""))
396 (const_string "both")
397 (match_operand 0 "memory_operand" "")
398 (const_string "store")
399 (match_operand 1 "memory_operand" "")
400 (const_string "load")
401 (and (eq_attr "type"
402 "!alu1,negnot,ishift1,
403 imov,imovx,icmp,test,
404 fmov,fcmp,fsgn,
405 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
406 mmx,mmxmov,mmxcmp,mmxcvt")
407 (match_operand 2 "memory_operand" ""))
408 (const_string "load")
409 (and (eq_attr "type" "icmov")
410 (match_operand 3 "memory_operand" ""))
411 (const_string "load")
412 ]
413 (const_string "none")))
414
415 ;; Indicates if an instruction has both an immediate and a displacement.
416
417 (define_attr "imm_disp" "false,true,unknown"
418 (cond [(eq_attr "type" "other,multi")
419 (const_string "unknown")
420 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
421 (and (match_operand 0 "memory_displacement_operand" "")
422 (match_operand 1 "immediate_operand" "")))
423 (const_string "true")
424 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
425 (and (match_operand 0 "memory_displacement_operand" "")
426 (match_operand 2 "immediate_operand" "")))
427 (const_string "true")
428 ]
429 (const_string "false")))
430
431 ;; Indicates if an FP operation has an integer source.
432
433 (define_attr "fp_int_src" "false,true"
434 (const_string "false"))
435
436 ;; Defines rounding mode of an FP operation.
437
438 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
439 (const_string "any"))
440
441 ;; Describe a user's asm statement.
442 (define_asm_attributes
443 [(set_attr "length" "128")
444 (set_attr "type" "multi")])
445
446 ;; All x87 floating point modes
447 (define_mode_macro X87MODEF [SF DF XF])
448
449 ;; All integer modes handled by x87 fisttp operator.
450 (define_mode_macro X87MODEI [HI SI DI])
451
452 ;; All integer modes handled by integer x87 operators.
453 (define_mode_macro X87MODEI12 [HI SI])
454
455 ;; All SSE floating point modes
456 (define_mode_macro SSEMODEF [SF DF])
457
458 ;; All integer modes handled by SSE cvtts?2si* operators.
459 (define_mode_macro SSEMODEI24 [SI DI])
460
461 \f
462 ;; Scheduling descriptions
463
464 (include "pentium.md")
465 (include "ppro.md")
466 (include "k6.md")
467 (include "athlon.md")
468
469 \f
470 ;; Operand and operator predicates
471
472 (include "predicates.md")
473
474 \f
475 ;; Compare instructions.
476
477 ;; All compare insns have expanders that save the operands away without
478 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
479 ;; after the cmp) will actually emit the cmpM.
480
481 (define_expand "cmpti"
482 [(set (reg:CC FLAGS_REG)
483 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
484 (match_operand:TI 1 "x86_64_general_operand" "")))]
485 "TARGET_64BIT"
486 {
487 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
488 operands[0] = force_reg (TImode, operands[0]);
489 ix86_compare_op0 = operands[0];
490 ix86_compare_op1 = operands[1];
491 DONE;
492 })
493
494 (define_expand "cmpdi"
495 [(set (reg:CC FLAGS_REG)
496 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
497 (match_operand:DI 1 "x86_64_general_operand" "")))]
498 ""
499 {
500 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
501 operands[0] = force_reg (DImode, operands[0]);
502 ix86_compare_op0 = operands[0];
503 ix86_compare_op1 = operands[1];
504 DONE;
505 })
506
507 (define_expand "cmpsi"
508 [(set (reg:CC FLAGS_REG)
509 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
510 (match_operand:SI 1 "general_operand" "")))]
511 ""
512 {
513 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
514 operands[0] = force_reg (SImode, operands[0]);
515 ix86_compare_op0 = operands[0];
516 ix86_compare_op1 = operands[1];
517 DONE;
518 })
519
520 (define_expand "cmphi"
521 [(set (reg:CC FLAGS_REG)
522 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
523 (match_operand:HI 1 "general_operand" "")))]
524 ""
525 {
526 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
527 operands[0] = force_reg (HImode, operands[0]);
528 ix86_compare_op0 = operands[0];
529 ix86_compare_op1 = operands[1];
530 DONE;
531 })
532
533 (define_expand "cmpqi"
534 [(set (reg:CC FLAGS_REG)
535 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
536 (match_operand:QI 1 "general_operand" "")))]
537 "TARGET_QIMODE_MATH"
538 {
539 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
540 operands[0] = force_reg (QImode, operands[0]);
541 ix86_compare_op0 = operands[0];
542 ix86_compare_op1 = operands[1];
543 DONE;
544 })
545
546 (define_insn "cmpdi_ccno_1_rex64"
547 [(set (reg FLAGS_REG)
548 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
549 (match_operand:DI 1 "const0_operand" "n,n")))]
550 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
551 "@
552 test{q}\t{%0, %0|%0, %0}
553 cmp{q}\t{%1, %0|%0, %1}"
554 [(set_attr "type" "test,icmp")
555 (set_attr "length_immediate" "0,1")
556 (set_attr "mode" "DI")])
557
558 (define_insn "*cmpdi_minus_1_rex64"
559 [(set (reg FLAGS_REG)
560 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
561 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
562 (const_int 0)))]
563 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
564 "cmp{q}\t{%1, %0|%0, %1}"
565 [(set_attr "type" "icmp")
566 (set_attr "mode" "DI")])
567
568 (define_expand "cmpdi_1_rex64"
569 [(set (reg:CC FLAGS_REG)
570 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
571 (match_operand:DI 1 "general_operand" "")))]
572 "TARGET_64BIT"
573 "")
574
575 (define_insn "cmpdi_1_insn_rex64"
576 [(set (reg FLAGS_REG)
577 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
578 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
579 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
580 "cmp{q}\t{%1, %0|%0, %1}"
581 [(set_attr "type" "icmp")
582 (set_attr "mode" "DI")])
583
584
585 (define_insn "*cmpsi_ccno_1"
586 [(set (reg FLAGS_REG)
587 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
588 (match_operand:SI 1 "const0_operand" "n,n")))]
589 "ix86_match_ccmode (insn, CCNOmode)"
590 "@
591 test{l}\t{%0, %0|%0, %0}
592 cmp{l}\t{%1, %0|%0, %1}"
593 [(set_attr "type" "test,icmp")
594 (set_attr "length_immediate" "0,1")
595 (set_attr "mode" "SI")])
596
597 (define_insn "*cmpsi_minus_1"
598 [(set (reg FLAGS_REG)
599 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
600 (match_operand:SI 1 "general_operand" "ri,mr"))
601 (const_int 0)))]
602 "ix86_match_ccmode (insn, CCGOCmode)"
603 "cmp{l}\t{%1, %0|%0, %1}"
604 [(set_attr "type" "icmp")
605 (set_attr "mode" "SI")])
606
607 (define_expand "cmpsi_1"
608 [(set (reg:CC FLAGS_REG)
609 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
610 (match_operand:SI 1 "general_operand" "ri,mr")))]
611 ""
612 "")
613
614 (define_insn "*cmpsi_1_insn"
615 [(set (reg FLAGS_REG)
616 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
617 (match_operand:SI 1 "general_operand" "ri,mr")))]
618 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
619 && ix86_match_ccmode (insn, CCmode)"
620 "cmp{l}\t{%1, %0|%0, %1}"
621 [(set_attr "type" "icmp")
622 (set_attr "mode" "SI")])
623
624 (define_insn "*cmphi_ccno_1"
625 [(set (reg FLAGS_REG)
626 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
627 (match_operand:HI 1 "const0_operand" "n,n")))]
628 "ix86_match_ccmode (insn, CCNOmode)"
629 "@
630 test{w}\t{%0, %0|%0, %0}
631 cmp{w}\t{%1, %0|%0, %1}"
632 [(set_attr "type" "test,icmp")
633 (set_attr "length_immediate" "0,1")
634 (set_attr "mode" "HI")])
635
636 (define_insn "*cmphi_minus_1"
637 [(set (reg FLAGS_REG)
638 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
639 (match_operand:HI 1 "general_operand" "ri,mr"))
640 (const_int 0)))]
641 "ix86_match_ccmode (insn, CCGOCmode)"
642 "cmp{w}\t{%1, %0|%0, %1}"
643 [(set_attr "type" "icmp")
644 (set_attr "mode" "HI")])
645
646 (define_insn "*cmphi_1"
647 [(set (reg FLAGS_REG)
648 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
649 (match_operand:HI 1 "general_operand" "ri,mr")))]
650 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
651 && ix86_match_ccmode (insn, CCmode)"
652 "cmp{w}\t{%1, %0|%0, %1}"
653 [(set_attr "type" "icmp")
654 (set_attr "mode" "HI")])
655
656 (define_insn "*cmpqi_ccno_1"
657 [(set (reg FLAGS_REG)
658 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
659 (match_operand:QI 1 "const0_operand" "n,n")))]
660 "ix86_match_ccmode (insn, CCNOmode)"
661 "@
662 test{b}\t{%0, %0|%0, %0}
663 cmp{b}\t{$0, %0|%0, 0}"
664 [(set_attr "type" "test,icmp")
665 (set_attr "length_immediate" "0,1")
666 (set_attr "mode" "QI")])
667
668 (define_insn "*cmpqi_1"
669 [(set (reg FLAGS_REG)
670 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
671 (match_operand:QI 1 "general_operand" "qi,mq")))]
672 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
673 && ix86_match_ccmode (insn, CCmode)"
674 "cmp{b}\t{%1, %0|%0, %1}"
675 [(set_attr "type" "icmp")
676 (set_attr "mode" "QI")])
677
678 (define_insn "*cmpqi_minus_1"
679 [(set (reg FLAGS_REG)
680 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
681 (match_operand:QI 1 "general_operand" "qi,mq"))
682 (const_int 0)))]
683 "ix86_match_ccmode (insn, CCGOCmode)"
684 "cmp{b}\t{%1, %0|%0, %1}"
685 [(set_attr "type" "icmp")
686 (set_attr "mode" "QI")])
687
688 (define_insn "*cmpqi_ext_1"
689 [(set (reg FLAGS_REG)
690 (compare
691 (match_operand:QI 0 "general_operand" "Qm")
692 (subreg:QI
693 (zero_extract:SI
694 (match_operand 1 "ext_register_operand" "Q")
695 (const_int 8)
696 (const_int 8)) 0)))]
697 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
698 "cmp{b}\t{%h1, %0|%0, %h1}"
699 [(set_attr "type" "icmp")
700 (set_attr "mode" "QI")])
701
702 (define_insn "*cmpqi_ext_1_rex64"
703 [(set (reg FLAGS_REG)
704 (compare
705 (match_operand:QI 0 "register_operand" "Q")
706 (subreg:QI
707 (zero_extract:SI
708 (match_operand 1 "ext_register_operand" "Q")
709 (const_int 8)
710 (const_int 8)) 0)))]
711 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
712 "cmp{b}\t{%h1, %0|%0, %h1}"
713 [(set_attr "type" "icmp")
714 (set_attr "mode" "QI")])
715
716 (define_insn "*cmpqi_ext_2"
717 [(set (reg FLAGS_REG)
718 (compare
719 (subreg:QI
720 (zero_extract:SI
721 (match_operand 0 "ext_register_operand" "Q")
722 (const_int 8)
723 (const_int 8)) 0)
724 (match_operand:QI 1 "const0_operand" "n")))]
725 "ix86_match_ccmode (insn, CCNOmode)"
726 "test{b}\t%h0, %h0"
727 [(set_attr "type" "test")
728 (set_attr "length_immediate" "0")
729 (set_attr "mode" "QI")])
730
731 (define_expand "cmpqi_ext_3"
732 [(set (reg:CC FLAGS_REG)
733 (compare:CC
734 (subreg:QI
735 (zero_extract:SI
736 (match_operand 0 "ext_register_operand" "")
737 (const_int 8)
738 (const_int 8)) 0)
739 (match_operand:QI 1 "general_operand" "")))]
740 ""
741 "")
742
743 (define_insn "cmpqi_ext_3_insn"
744 [(set (reg FLAGS_REG)
745 (compare
746 (subreg:QI
747 (zero_extract:SI
748 (match_operand 0 "ext_register_operand" "Q")
749 (const_int 8)
750 (const_int 8)) 0)
751 (match_operand:QI 1 "general_operand" "Qmn")))]
752 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
753 "cmp{b}\t{%1, %h0|%h0, %1}"
754 [(set_attr "type" "icmp")
755 (set_attr "mode" "QI")])
756
757 (define_insn "cmpqi_ext_3_insn_rex64"
758 [(set (reg FLAGS_REG)
759 (compare
760 (subreg:QI
761 (zero_extract:SI
762 (match_operand 0 "ext_register_operand" "Q")
763 (const_int 8)
764 (const_int 8)) 0)
765 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
766 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
767 "cmp{b}\t{%1, %h0|%h0, %1}"
768 [(set_attr "type" "icmp")
769 (set_attr "mode" "QI")])
770
771 (define_insn "*cmpqi_ext_4"
772 [(set (reg FLAGS_REG)
773 (compare
774 (subreg:QI
775 (zero_extract:SI
776 (match_operand 0 "ext_register_operand" "Q")
777 (const_int 8)
778 (const_int 8)) 0)
779 (subreg:QI
780 (zero_extract:SI
781 (match_operand 1 "ext_register_operand" "Q")
782 (const_int 8)
783 (const_int 8)) 0)))]
784 "ix86_match_ccmode (insn, CCmode)"
785 "cmp{b}\t{%h1, %h0|%h0, %h1}"
786 [(set_attr "type" "icmp")
787 (set_attr "mode" "QI")])
788
789 ;; These implement float point compares.
790 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
791 ;; which would allow mix and match FP modes on the compares. Which is what
792 ;; the old patterns did, but with many more of them.
793
794 (define_expand "cmpxf"
795 [(set (reg:CC FLAGS_REG)
796 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
797 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
798 "TARGET_80387"
799 {
800 ix86_compare_op0 = operands[0];
801 ix86_compare_op1 = operands[1];
802 DONE;
803 })
804
805 (define_expand "cmpdf"
806 [(set (reg:CC FLAGS_REG)
807 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
808 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
809 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
810 {
811 ix86_compare_op0 = operands[0];
812 ix86_compare_op1 = operands[1];
813 DONE;
814 })
815
816 (define_expand "cmpsf"
817 [(set (reg:CC FLAGS_REG)
818 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
819 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
820 "TARGET_80387 || TARGET_SSE_MATH"
821 {
822 ix86_compare_op0 = operands[0];
823 ix86_compare_op1 = operands[1];
824 DONE;
825 })
826
827 ;; FP compares, step 1:
828 ;; Set the FP condition codes.
829 ;;
830 ;; CCFPmode compare with exceptions
831 ;; CCFPUmode compare with no exceptions
832
833 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
834 ;; used to manage the reg stack popping would not be preserved.
835
836 (define_insn "*cmpfp_0"
837 [(set (match_operand:HI 0 "register_operand" "=a")
838 (unspec:HI
839 [(compare:CCFP
840 (match_operand 1 "register_operand" "f")
841 (match_operand 2 "const0_operand" "X"))]
842 UNSPEC_FNSTSW))]
843 "TARGET_80387
844 && FLOAT_MODE_P (GET_MODE (operands[1]))
845 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
846 "* return output_fp_compare (insn, operands, 0, 0);"
847 [(set_attr "type" "multi")
848 (set_attr "unit" "i387")
849 (set (attr "mode")
850 (cond [(match_operand:SF 1 "" "")
851 (const_string "SF")
852 (match_operand:DF 1 "" "")
853 (const_string "DF")
854 ]
855 (const_string "XF")))])
856
857 (define_insn "*cmpfp_sf"
858 [(set (match_operand:HI 0 "register_operand" "=a")
859 (unspec:HI
860 [(compare:CCFP
861 (match_operand:SF 1 "register_operand" "f")
862 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
863 UNSPEC_FNSTSW))]
864 "TARGET_80387"
865 "* return output_fp_compare (insn, operands, 0, 0);"
866 [(set_attr "type" "multi")
867 (set_attr "unit" "i387")
868 (set_attr "mode" "SF")])
869
870 (define_insn "*cmpfp_df"
871 [(set (match_operand:HI 0 "register_operand" "=a")
872 (unspec:HI
873 [(compare:CCFP
874 (match_operand:DF 1 "register_operand" "f")
875 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
876 UNSPEC_FNSTSW))]
877 "TARGET_80387"
878 "* return output_fp_compare (insn, operands, 0, 0);"
879 [(set_attr "type" "multi")
880 (set_attr "unit" "i387")
881 (set_attr "mode" "DF")])
882
883 (define_insn "*cmpfp_xf"
884 [(set (match_operand:HI 0 "register_operand" "=a")
885 (unspec:HI
886 [(compare:CCFP
887 (match_operand:XF 1 "register_operand" "f")
888 (match_operand:XF 2 "register_operand" "f"))]
889 UNSPEC_FNSTSW))]
890 "TARGET_80387"
891 "* return output_fp_compare (insn, operands, 0, 0);"
892 [(set_attr "type" "multi")
893 (set_attr "unit" "i387")
894 (set_attr "mode" "XF")])
895
896 (define_insn "*cmpfp_u"
897 [(set (match_operand:HI 0 "register_operand" "=a")
898 (unspec:HI
899 [(compare:CCFPU
900 (match_operand 1 "register_operand" "f")
901 (match_operand 2 "register_operand" "f"))]
902 UNSPEC_FNSTSW))]
903 "TARGET_80387
904 && FLOAT_MODE_P (GET_MODE (operands[1]))
905 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
906 "* return output_fp_compare (insn, operands, 0, 1);"
907 [(set_attr "type" "multi")
908 (set_attr "unit" "i387")
909 (set (attr "mode")
910 (cond [(match_operand:SF 1 "" "")
911 (const_string "SF")
912 (match_operand:DF 1 "" "")
913 (const_string "DF")
914 ]
915 (const_string "XF")))])
916
917 (define_insn "*cmpfp_<mode>"
918 [(set (match_operand:HI 0 "register_operand" "=a")
919 (unspec:HI
920 [(compare:CCFP
921 (match_operand 1 "register_operand" "f")
922 (match_operator 3 "float_operator"
923 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
924 UNSPEC_FNSTSW))]
925 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
926 && FLOAT_MODE_P (GET_MODE (operands[1]))
927 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
928 "* return output_fp_compare (insn, operands, 0, 0);"
929 [(set_attr "type" "multi")
930 (set_attr "unit" "i387")
931 (set_attr "fp_int_src" "true")
932 (set_attr "mode" "<MODE>")])
933
934 ;; FP compares, step 2
935 ;; Move the fpsw to ax.
936
937 (define_insn "x86_fnstsw_1"
938 [(set (match_operand:HI 0 "register_operand" "=a")
939 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
940 "TARGET_80387"
941 "fnstsw\t%0"
942 [(set_attr "length" "2")
943 (set_attr "mode" "SI")
944 (set_attr "unit" "i387")])
945
946 ;; FP compares, step 3
947 ;; Get ax into flags, general case.
948
949 (define_insn "x86_sahf_1"
950 [(set (reg:CC FLAGS_REG)
951 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
952 "!TARGET_64BIT"
953 "sahf"
954 [(set_attr "length" "1")
955 (set_attr "athlon_decode" "vector")
956 (set_attr "mode" "SI")])
957
958 ;; Pentium Pro can do steps 1 through 3 in one go.
959
960 (define_insn "*cmpfp_i_mixed"
961 [(set (reg:CCFP FLAGS_REG)
962 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
963 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
964 "TARGET_MIX_SSE_I387
965 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
966 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
967 "* return output_fp_compare (insn, operands, 1, 0);"
968 [(set_attr "type" "fcmp,ssecomi")
969 (set (attr "mode")
970 (if_then_else (match_operand:SF 1 "" "")
971 (const_string "SF")
972 (const_string "DF")))
973 (set_attr "athlon_decode" "vector")])
974
975 (define_insn "*cmpfp_i_sse"
976 [(set (reg:CCFP FLAGS_REG)
977 (compare:CCFP (match_operand 0 "register_operand" "x")
978 (match_operand 1 "nonimmediate_operand" "xm")))]
979 "TARGET_SSE_MATH
980 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
981 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
982 "* return output_fp_compare (insn, operands, 1, 0);"
983 [(set_attr "type" "ssecomi")
984 (set (attr "mode")
985 (if_then_else (match_operand:SF 1 "" "")
986 (const_string "SF")
987 (const_string "DF")))
988 (set_attr "athlon_decode" "vector")])
989
990 (define_insn "*cmpfp_i_i387"
991 [(set (reg:CCFP FLAGS_REG)
992 (compare:CCFP (match_operand 0 "register_operand" "f")
993 (match_operand 1 "register_operand" "f")))]
994 "TARGET_80387 && TARGET_CMOVE
995 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
996 && FLOAT_MODE_P (GET_MODE (operands[0]))
997 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
998 "* return output_fp_compare (insn, operands, 1, 0);"
999 [(set_attr "type" "fcmp")
1000 (set (attr "mode")
1001 (cond [(match_operand:SF 1 "" "")
1002 (const_string "SF")
1003 (match_operand:DF 1 "" "")
1004 (const_string "DF")
1005 ]
1006 (const_string "XF")))
1007 (set_attr "athlon_decode" "vector")])
1008
1009 (define_insn "*cmpfp_iu_mixed"
1010 [(set (reg:CCFPU FLAGS_REG)
1011 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1012 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1013 "TARGET_MIX_SSE_I387
1014 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016 "* return output_fp_compare (insn, operands, 1, 1);"
1017 [(set_attr "type" "fcmp,ssecomi")
1018 (set (attr "mode")
1019 (if_then_else (match_operand:SF 1 "" "")
1020 (const_string "SF")
1021 (const_string "DF")))
1022 (set_attr "athlon_decode" "vector")])
1023
1024 (define_insn "*cmpfp_iu_sse"
1025 [(set (reg:CCFPU FLAGS_REG)
1026 (compare:CCFPU (match_operand 0 "register_operand" "x")
1027 (match_operand 1 "nonimmediate_operand" "xm")))]
1028 "TARGET_SSE_MATH
1029 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1030 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1031 "* return output_fp_compare (insn, operands, 1, 1);"
1032 [(set_attr "type" "ssecomi")
1033 (set (attr "mode")
1034 (if_then_else (match_operand:SF 1 "" "")
1035 (const_string "SF")
1036 (const_string "DF")))
1037 (set_attr "athlon_decode" "vector")])
1038
1039 (define_insn "*cmpfp_iu_387"
1040 [(set (reg:CCFPU FLAGS_REG)
1041 (compare:CCFPU (match_operand 0 "register_operand" "f")
1042 (match_operand 1 "register_operand" "f")))]
1043 "TARGET_80387 && TARGET_CMOVE
1044 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1045 && FLOAT_MODE_P (GET_MODE (operands[0]))
1046 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1047 "* return output_fp_compare (insn, operands, 1, 1);"
1048 [(set_attr "type" "fcmp")
1049 (set (attr "mode")
1050 (cond [(match_operand:SF 1 "" "")
1051 (const_string "SF")
1052 (match_operand:DF 1 "" "")
1053 (const_string "DF")
1054 ]
1055 (const_string "XF")))
1056 (set_attr "athlon_decode" "vector")])
1057 \f
1058 ;; Move instructions.
1059
1060 ;; General case of fullword move.
1061
1062 (define_expand "movsi"
1063 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1064 (match_operand:SI 1 "general_operand" ""))]
1065 ""
1066 "ix86_expand_move (SImode, operands); DONE;")
1067
1068 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1069 ;; general_operand.
1070 ;;
1071 ;; %%% We don't use a post-inc memory reference because x86 is not a
1072 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1073 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1074 ;; targets without our curiosities, and it is just as easy to represent
1075 ;; this differently.
1076
1077 (define_insn "*pushsi2"
1078 [(set (match_operand:SI 0 "push_operand" "=<")
1079 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1080 "!TARGET_64BIT"
1081 "push{l}\t%1"
1082 [(set_attr "type" "push")
1083 (set_attr "mode" "SI")])
1084
1085 ;; For 64BIT abi we always round up to 8 bytes.
1086 (define_insn "*pushsi2_rex64"
1087 [(set (match_operand:SI 0 "push_operand" "=X")
1088 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1089 "TARGET_64BIT"
1090 "push{q}\t%q1"
1091 [(set_attr "type" "push")
1092 (set_attr "mode" "SI")])
1093
1094 (define_insn "*pushsi2_prologue"
1095 [(set (match_operand:SI 0 "push_operand" "=<")
1096 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1097 (clobber (mem:BLK (scratch)))]
1098 "!TARGET_64BIT"
1099 "push{l}\t%1"
1100 [(set_attr "type" "push")
1101 (set_attr "mode" "SI")])
1102
1103 (define_insn "*popsi1_epilogue"
1104 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1105 (mem:SI (reg:SI SP_REG)))
1106 (set (reg:SI SP_REG)
1107 (plus:SI (reg:SI SP_REG) (const_int 4)))
1108 (clobber (mem:BLK (scratch)))]
1109 "!TARGET_64BIT"
1110 "pop{l}\t%0"
1111 [(set_attr "type" "pop")
1112 (set_attr "mode" "SI")])
1113
1114 (define_insn "popsi1"
1115 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1116 (mem:SI (reg:SI SP_REG)))
1117 (set (reg:SI SP_REG)
1118 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1119 "!TARGET_64BIT"
1120 "pop{l}\t%0"
1121 [(set_attr "type" "pop")
1122 (set_attr "mode" "SI")])
1123
1124 (define_insn "*movsi_xor"
1125 [(set (match_operand:SI 0 "register_operand" "=r")
1126 (match_operand:SI 1 "const0_operand" "i"))
1127 (clobber (reg:CC FLAGS_REG))]
1128 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1129 "xor{l}\t{%0, %0|%0, %0}"
1130 [(set_attr "type" "alu1")
1131 (set_attr "mode" "SI")
1132 (set_attr "length_immediate" "0")])
1133
1134 (define_insn "*movsi_or"
1135 [(set (match_operand:SI 0 "register_operand" "=r")
1136 (match_operand:SI 1 "immediate_operand" "i"))
1137 (clobber (reg:CC FLAGS_REG))]
1138 "reload_completed
1139 && operands[1] == constm1_rtx
1140 && (TARGET_PENTIUM || optimize_size)"
1141 {
1142 operands[1] = constm1_rtx;
1143 return "or{l}\t{%1, %0|%0, %1}";
1144 }
1145 [(set_attr "type" "alu1")
1146 (set_attr "mode" "SI")
1147 (set_attr "length_immediate" "1")])
1148
1149 (define_insn "*movsi_1"
1150 [(set (match_operand:SI 0 "nonimmediate_operand"
1151 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1152 (match_operand:SI 1 "general_operand"
1153 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1154 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1155 {
1156 switch (get_attr_type (insn))
1157 {
1158 case TYPE_SSELOG1:
1159 if (get_attr_mode (insn) == MODE_TI)
1160 return "pxor\t%0, %0";
1161 return "xorps\t%0, %0";
1162
1163 case TYPE_SSEMOV:
1164 switch (get_attr_mode (insn))
1165 {
1166 case MODE_TI:
1167 return "movdqa\t{%1, %0|%0, %1}";
1168 case MODE_V4SF:
1169 return "movaps\t{%1, %0|%0, %1}";
1170 case MODE_SI:
1171 return "movd\t{%1, %0|%0, %1}";
1172 case MODE_SF:
1173 return "movss\t{%1, %0|%0, %1}";
1174 default:
1175 gcc_unreachable ();
1176 }
1177
1178 case TYPE_MMXADD:
1179 return "pxor\t%0, %0";
1180
1181 case TYPE_MMXMOV:
1182 if (get_attr_mode (insn) == MODE_DI)
1183 return "movq\t{%1, %0|%0, %1}";
1184 return "movd\t{%1, %0|%0, %1}";
1185
1186 case TYPE_LEA:
1187 return "lea{l}\t{%1, %0|%0, %1}";
1188
1189 default:
1190 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1191 return "mov{l}\t{%1, %0|%0, %1}";
1192 }
1193 }
1194 [(set (attr "type")
1195 (cond [(eq_attr "alternative" "2")
1196 (const_string "mmx")
1197 (eq_attr "alternative" "3,4,5")
1198 (const_string "mmxmov")
1199 (eq_attr "alternative" "6")
1200 (const_string "sselog1")
1201 (eq_attr "alternative" "7,8,9,10,11")
1202 (const_string "ssemov")
1203 (and (ne (symbol_ref "flag_pic") (const_int 0))
1204 (match_operand:SI 1 "symbolic_operand" ""))
1205 (const_string "lea")
1206 ]
1207 (const_string "imov")))
1208 (set (attr "mode")
1209 (cond [(eq_attr "alternative" "2,3")
1210 (const_string "DI")
1211 (eq_attr "alternative" "6,7")
1212 (if_then_else
1213 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1214 (const_string "V4SF")
1215 (const_string "TI"))
1216 (and (eq_attr "alternative" "8,9,10,11")
1217 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1218 (const_string "SF")
1219 ]
1220 (const_string "SI")))])
1221
1222 ;; Stores and loads of ax to arbitrary constant address.
1223 ;; We fake an second form of instruction to force reload to load address
1224 ;; into register when rax is not available
1225 (define_insn "*movabssi_1_rex64"
1226 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1227 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1228 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1229 "@
1230 movabs{l}\t{%1, %P0|%P0, %1}
1231 mov{l}\t{%1, %a0|%a0, %1}"
1232 [(set_attr "type" "imov")
1233 (set_attr "modrm" "0,*")
1234 (set_attr "length_address" "8,0")
1235 (set_attr "length_immediate" "0,*")
1236 (set_attr "memory" "store")
1237 (set_attr "mode" "SI")])
1238
1239 (define_insn "*movabssi_2_rex64"
1240 [(set (match_operand:SI 0 "register_operand" "=a,r")
1241 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1242 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1243 "@
1244 movabs{l}\t{%P1, %0|%0, %P1}
1245 mov{l}\t{%a1, %0|%0, %a1}"
1246 [(set_attr "type" "imov")
1247 (set_attr "modrm" "0,*")
1248 (set_attr "length_address" "8,0")
1249 (set_attr "length_immediate" "0")
1250 (set_attr "memory" "load")
1251 (set_attr "mode" "SI")])
1252
1253 (define_insn "*swapsi"
1254 [(set (match_operand:SI 0 "register_operand" "+r")
1255 (match_operand:SI 1 "register_operand" "+r"))
1256 (set (match_dup 1)
1257 (match_dup 0))]
1258 ""
1259 "xchg{l}\t%1, %0"
1260 [(set_attr "type" "imov")
1261 (set_attr "mode" "SI")
1262 (set_attr "pent_pair" "np")
1263 (set_attr "athlon_decode" "vector")])
1264
1265 (define_expand "movhi"
1266 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1267 (match_operand:HI 1 "general_operand" ""))]
1268 ""
1269 "ix86_expand_move (HImode, operands); DONE;")
1270
1271 (define_insn "*pushhi2"
1272 [(set (match_operand:HI 0 "push_operand" "=<,<")
1273 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1274 "!TARGET_64BIT"
1275 "@
1276 push{w}\t{|WORD PTR }%1
1277 push{w}\t%1"
1278 [(set_attr "type" "push")
1279 (set_attr "mode" "HI")])
1280
1281 ;; For 64BIT abi we always round up to 8 bytes.
1282 (define_insn "*pushhi2_rex64"
1283 [(set (match_operand:HI 0 "push_operand" "=X")
1284 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1285 "TARGET_64BIT"
1286 "push{q}\t%q1"
1287 [(set_attr "type" "push")
1288 (set_attr "mode" "QI")])
1289
1290 (define_insn "*movhi_1"
1291 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1292 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1293 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1294 {
1295 switch (get_attr_type (insn))
1296 {
1297 case TYPE_IMOVX:
1298 /* movzwl is faster than movw on p2 due to partial word stalls,
1299 though not as fast as an aligned movl. */
1300 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1301 default:
1302 if (get_attr_mode (insn) == MODE_SI)
1303 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1304 else
1305 return "mov{w}\t{%1, %0|%0, %1}";
1306 }
1307 }
1308 [(set (attr "type")
1309 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1310 (const_string "imov")
1311 (and (eq_attr "alternative" "0")
1312 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1313 (const_int 0))
1314 (eq (symbol_ref "TARGET_HIMODE_MATH")
1315 (const_int 0))))
1316 (const_string "imov")
1317 (and (eq_attr "alternative" "1,2")
1318 (match_operand:HI 1 "aligned_operand" ""))
1319 (const_string "imov")
1320 (and (ne (symbol_ref "TARGET_MOVX")
1321 (const_int 0))
1322 (eq_attr "alternative" "0,2"))
1323 (const_string "imovx")
1324 ]
1325 (const_string "imov")))
1326 (set (attr "mode")
1327 (cond [(eq_attr "type" "imovx")
1328 (const_string "SI")
1329 (and (eq_attr "alternative" "1,2")
1330 (match_operand:HI 1 "aligned_operand" ""))
1331 (const_string "SI")
1332 (and (eq_attr "alternative" "0")
1333 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1334 (const_int 0))
1335 (eq (symbol_ref "TARGET_HIMODE_MATH")
1336 (const_int 0))))
1337 (const_string "SI")
1338 ]
1339 (const_string "HI")))])
1340
1341 ;; Stores and loads of ax to arbitrary constant address.
1342 ;; We fake an second form of instruction to force reload to load address
1343 ;; into register when rax is not available
1344 (define_insn "*movabshi_1_rex64"
1345 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1346 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1347 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1348 "@
1349 movabs{w}\t{%1, %P0|%P0, %1}
1350 mov{w}\t{%1, %a0|%a0, %1}"
1351 [(set_attr "type" "imov")
1352 (set_attr "modrm" "0,*")
1353 (set_attr "length_address" "8,0")
1354 (set_attr "length_immediate" "0,*")
1355 (set_attr "memory" "store")
1356 (set_attr "mode" "HI")])
1357
1358 (define_insn "*movabshi_2_rex64"
1359 [(set (match_operand:HI 0 "register_operand" "=a,r")
1360 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1361 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1362 "@
1363 movabs{w}\t{%P1, %0|%0, %P1}
1364 mov{w}\t{%a1, %0|%0, %a1}"
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" "load")
1370 (set_attr "mode" "HI")])
1371
1372 (define_insn "*swaphi_1"
1373 [(set (match_operand:HI 0 "register_operand" "+r")
1374 (match_operand:HI 1 "register_operand" "+r"))
1375 (set (match_dup 1)
1376 (match_dup 0))]
1377 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1378 "xchg{l}\t%k1, %k0"
1379 [(set_attr "type" "imov")
1380 (set_attr "mode" "SI")
1381 (set_attr "pent_pair" "np")
1382 (set_attr "athlon_decode" "vector")])
1383
1384 (define_insn "*swaphi_2"
1385 [(set (match_operand:HI 0 "register_operand" "+r")
1386 (match_operand:HI 1 "register_operand" "+r"))
1387 (set (match_dup 1)
1388 (match_dup 0))]
1389 "TARGET_PARTIAL_REG_STALL"
1390 "xchg{w}\t%1, %0"
1391 [(set_attr "type" "imov")
1392 (set_attr "mode" "HI")
1393 (set_attr "pent_pair" "np")
1394 (set_attr "athlon_decode" "vector")])
1395
1396 (define_expand "movstricthi"
1397 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1398 (match_operand:HI 1 "general_operand" ""))]
1399 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1400 {
1401 /* Don't generate memory->memory moves, go through a register */
1402 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1403 operands[1] = force_reg (HImode, operands[1]);
1404 })
1405
1406 (define_insn "*movstricthi_1"
1407 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1408 (match_operand:HI 1 "general_operand" "rn,m"))]
1409 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1410 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1411 "mov{w}\t{%1, %0|%0, %1}"
1412 [(set_attr "type" "imov")
1413 (set_attr "mode" "HI")])
1414
1415 (define_insn "*movstricthi_xor"
1416 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1417 (match_operand:HI 1 "const0_operand" "i"))
1418 (clobber (reg:CC FLAGS_REG))]
1419 "reload_completed
1420 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1421 "xor{w}\t{%0, %0|%0, %0}"
1422 [(set_attr "type" "alu1")
1423 (set_attr "mode" "HI")
1424 (set_attr "length_immediate" "0")])
1425
1426 (define_expand "movqi"
1427 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1428 (match_operand:QI 1 "general_operand" ""))]
1429 ""
1430 "ix86_expand_move (QImode, operands); DONE;")
1431
1432 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1433 ;; "push a byte". But actually we use pushw, which has the effect
1434 ;; of rounding the amount pushed up to a halfword.
1435
1436 (define_insn "*pushqi2"
1437 [(set (match_operand:QI 0 "push_operand" "=X,X")
1438 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1439 "!TARGET_64BIT"
1440 "@
1441 push{w}\t{|word ptr }%1
1442 push{w}\t%w1"
1443 [(set_attr "type" "push")
1444 (set_attr "mode" "HI")])
1445
1446 ;; For 64BIT abi we always round up to 8 bytes.
1447 (define_insn "*pushqi2_rex64"
1448 [(set (match_operand:QI 0 "push_operand" "=X")
1449 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1450 "TARGET_64BIT"
1451 "push{q}\t%q1"
1452 [(set_attr "type" "push")
1453 (set_attr "mode" "QI")])
1454
1455 ;; Situation is quite tricky about when to choose full sized (SImode) move
1456 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1457 ;; partial register dependency machines (such as AMD Athlon), where QImode
1458 ;; moves issue extra dependency and for partial register stalls machines
1459 ;; that don't use QImode patterns (and QImode move cause stall on the next
1460 ;; instruction).
1461 ;;
1462 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1463 ;; register stall machines with, where we use QImode instructions, since
1464 ;; partial register stall can be caused there. Then we use movzx.
1465 (define_insn "*movqi_1"
1466 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1467 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,m ,qn"))]
1468 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1469 {
1470 switch (get_attr_type (insn))
1471 {
1472 case TYPE_IMOVX:
1473 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1474 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1475 default:
1476 if (get_attr_mode (insn) == MODE_SI)
1477 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1478 else
1479 return "mov{b}\t{%1, %0|%0, %1}";
1480 }
1481 }
1482 [(set (attr "type")
1483 (cond [(eq_attr "alternative" "5")
1484 (const_string "imovx")
1485 (ne (symbol_ref "optimize_size") (const_int 0))
1486 (const_string "imov")
1487 (and (eq_attr "alternative" "3")
1488 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1489 (const_int 0))
1490 (eq (symbol_ref "TARGET_QIMODE_MATH")
1491 (const_int 0))))
1492 (const_string "imov")
1493 (eq_attr "alternative" "3")
1494 (const_string "imovx")
1495 (and (ne (symbol_ref "TARGET_MOVX")
1496 (const_int 0))
1497 (eq_attr "alternative" "2"))
1498 (const_string "imovx")
1499 ]
1500 (const_string "imov")))
1501 (set (attr "mode")
1502 (cond [(eq_attr "alternative" "3,4,5")
1503 (const_string "SI")
1504 (eq_attr "alternative" "6")
1505 (const_string "QI")
1506 (eq_attr "type" "imovx")
1507 (const_string "SI")
1508 (and (eq_attr "type" "imov")
1509 (and (eq_attr "alternative" "0,1")
1510 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1511 (const_int 0))))
1512 (const_string "SI")
1513 ;; Avoid partial register stalls when not using QImode arithmetic
1514 (and (eq_attr "type" "imov")
1515 (and (eq_attr "alternative" "0,1")
1516 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1517 (const_int 0))
1518 (eq (symbol_ref "TARGET_QIMODE_MATH")
1519 (const_int 0)))))
1520 (const_string "SI")
1521 ]
1522 (const_string "QI")))])
1523
1524 (define_expand "reload_outqi"
1525 [(parallel [(match_operand:QI 0 "" "=m")
1526 (match_operand:QI 1 "register_operand" "r")
1527 (match_operand:QI 2 "register_operand" "=&q")])]
1528 ""
1529 {
1530 rtx op0, op1, op2;
1531 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1532
1533 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1534 if (! q_regs_operand (op1, QImode))
1535 {
1536 emit_insn (gen_movqi (op2, op1));
1537 op1 = op2;
1538 }
1539 emit_insn (gen_movqi (op0, op1));
1540 DONE;
1541 })
1542
1543 (define_insn "*swapqi_1"
1544 [(set (match_operand:QI 0 "register_operand" "+r")
1545 (match_operand:QI 1 "register_operand" "+r"))
1546 (set (match_dup 1)
1547 (match_dup 0))]
1548 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1549 "xchg{l}\t%k1, %k0"
1550 [(set_attr "type" "imov")
1551 (set_attr "mode" "SI")
1552 (set_attr "pent_pair" "np")
1553 (set_attr "athlon_decode" "vector")])
1554
1555 (define_insn "*swapqi_2"
1556 [(set (match_operand:QI 0 "register_operand" "+q")
1557 (match_operand:QI 1 "register_operand" "+q"))
1558 (set (match_dup 1)
1559 (match_dup 0))]
1560 "TARGET_PARTIAL_REG_STALL"
1561 "xchg{b}\t%1, %0"
1562 [(set_attr "type" "imov")
1563 (set_attr "mode" "QI")
1564 (set_attr "pent_pair" "np")
1565 (set_attr "athlon_decode" "vector")])
1566
1567 (define_expand "movstrictqi"
1568 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1569 (match_operand:QI 1 "general_operand" ""))]
1570 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1571 {
1572 /* Don't generate memory->memory moves, go through a register. */
1573 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1574 operands[1] = force_reg (QImode, operands[1]);
1575 })
1576
1577 (define_insn "*movstrictqi_1"
1578 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1579 (match_operand:QI 1 "general_operand" "*qn,m"))]
1580 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1581 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1582 "mov{b}\t{%1, %0|%0, %1}"
1583 [(set_attr "type" "imov")
1584 (set_attr "mode" "QI")])
1585
1586 (define_insn "*movstrictqi_xor"
1587 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1588 (match_operand:QI 1 "const0_operand" "i"))
1589 (clobber (reg:CC FLAGS_REG))]
1590 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1591 "xor{b}\t{%0, %0|%0, %0}"
1592 [(set_attr "type" "alu1")
1593 (set_attr "mode" "QI")
1594 (set_attr "length_immediate" "0")])
1595
1596 (define_insn "*movsi_extv_1"
1597 [(set (match_operand:SI 0 "register_operand" "=R")
1598 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1599 (const_int 8)
1600 (const_int 8)))]
1601 ""
1602 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1603 [(set_attr "type" "imovx")
1604 (set_attr "mode" "SI")])
1605
1606 (define_insn "*movhi_extv_1"
1607 [(set (match_operand:HI 0 "register_operand" "=R")
1608 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1609 (const_int 8)
1610 (const_int 8)))]
1611 ""
1612 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1613 [(set_attr "type" "imovx")
1614 (set_attr "mode" "SI")])
1615
1616 (define_insn "*movqi_extv_1"
1617 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1618 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1619 (const_int 8)
1620 (const_int 8)))]
1621 "!TARGET_64BIT"
1622 {
1623 switch (get_attr_type (insn))
1624 {
1625 case TYPE_IMOVX:
1626 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1627 default:
1628 return "mov{b}\t{%h1, %0|%0, %h1}";
1629 }
1630 }
1631 [(set (attr "type")
1632 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1633 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1634 (ne (symbol_ref "TARGET_MOVX")
1635 (const_int 0))))
1636 (const_string "imovx")
1637 (const_string "imov")))
1638 (set (attr "mode")
1639 (if_then_else (eq_attr "type" "imovx")
1640 (const_string "SI")
1641 (const_string "QI")))])
1642
1643 (define_insn "*movqi_extv_1_rex64"
1644 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1645 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1646 (const_int 8)
1647 (const_int 8)))]
1648 "TARGET_64BIT"
1649 {
1650 switch (get_attr_type (insn))
1651 {
1652 case TYPE_IMOVX:
1653 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1654 default:
1655 return "mov{b}\t{%h1, %0|%0, %h1}";
1656 }
1657 }
1658 [(set (attr "type")
1659 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1660 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1661 (ne (symbol_ref "TARGET_MOVX")
1662 (const_int 0))))
1663 (const_string "imovx")
1664 (const_string "imov")))
1665 (set (attr "mode")
1666 (if_then_else (eq_attr "type" "imovx")
1667 (const_string "SI")
1668 (const_string "QI")))])
1669
1670 ;; Stores and loads of ax to arbitrary constant address.
1671 ;; We fake an second form of instruction to force reload to load address
1672 ;; into register when rax is not available
1673 (define_insn "*movabsqi_1_rex64"
1674 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1675 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1676 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1677 "@
1678 movabs{b}\t{%1, %P0|%P0, %1}
1679 mov{b}\t{%1, %a0|%a0, %1}"
1680 [(set_attr "type" "imov")
1681 (set_attr "modrm" "0,*")
1682 (set_attr "length_address" "8,0")
1683 (set_attr "length_immediate" "0,*")
1684 (set_attr "memory" "store")
1685 (set_attr "mode" "QI")])
1686
1687 (define_insn "*movabsqi_2_rex64"
1688 [(set (match_operand:QI 0 "register_operand" "=a,r")
1689 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1690 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1691 "@
1692 movabs{b}\t{%P1, %0|%0, %P1}
1693 mov{b}\t{%a1, %0|%0, %a1}"
1694 [(set_attr "type" "imov")
1695 (set_attr "modrm" "0,*")
1696 (set_attr "length_address" "8,0")
1697 (set_attr "length_immediate" "0")
1698 (set_attr "memory" "load")
1699 (set_attr "mode" "QI")])
1700
1701 (define_insn "*movdi_extzv_1"
1702 [(set (match_operand:DI 0 "register_operand" "=R")
1703 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1704 (const_int 8)
1705 (const_int 8)))]
1706 "TARGET_64BIT"
1707 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1708 [(set_attr "type" "imovx")
1709 (set_attr "mode" "DI")])
1710
1711 (define_insn "*movsi_extzv_1"
1712 [(set (match_operand:SI 0 "register_operand" "=R")
1713 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1714 (const_int 8)
1715 (const_int 8)))]
1716 ""
1717 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1718 [(set_attr "type" "imovx")
1719 (set_attr "mode" "SI")])
1720
1721 (define_insn "*movqi_extzv_2"
1722 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1723 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1724 (const_int 8)
1725 (const_int 8)) 0))]
1726 "!TARGET_64BIT"
1727 {
1728 switch (get_attr_type (insn))
1729 {
1730 case TYPE_IMOVX:
1731 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1732 default:
1733 return "mov{b}\t{%h1, %0|%0, %h1}";
1734 }
1735 }
1736 [(set (attr "type")
1737 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1738 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1739 (ne (symbol_ref "TARGET_MOVX")
1740 (const_int 0))))
1741 (const_string "imovx")
1742 (const_string "imov")))
1743 (set (attr "mode")
1744 (if_then_else (eq_attr "type" "imovx")
1745 (const_string "SI")
1746 (const_string "QI")))])
1747
1748 (define_insn "*movqi_extzv_2_rex64"
1749 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1750 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1751 (const_int 8)
1752 (const_int 8)) 0))]
1753 "TARGET_64BIT"
1754 {
1755 switch (get_attr_type (insn))
1756 {
1757 case TYPE_IMOVX:
1758 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1759 default:
1760 return "mov{b}\t{%h1, %0|%0, %h1}";
1761 }
1762 }
1763 [(set (attr "type")
1764 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1765 (ne (symbol_ref "TARGET_MOVX")
1766 (const_int 0)))
1767 (const_string "imovx")
1768 (const_string "imov")))
1769 (set (attr "mode")
1770 (if_then_else (eq_attr "type" "imovx")
1771 (const_string "SI")
1772 (const_string "QI")))])
1773
1774 (define_insn "movsi_insv_1"
1775 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1776 (const_int 8)
1777 (const_int 8))
1778 (match_operand:SI 1 "general_operand" "Qmn"))]
1779 "!TARGET_64BIT"
1780 "mov{b}\t{%b1, %h0|%h0, %b1}"
1781 [(set_attr "type" "imov")
1782 (set_attr "mode" "QI")])
1783
1784 (define_insn "movdi_insv_1_rex64"
1785 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1786 (const_int 8)
1787 (const_int 8))
1788 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1789 "TARGET_64BIT"
1790 "mov{b}\t{%b1, %h0|%h0, %b1}"
1791 [(set_attr "type" "imov")
1792 (set_attr "mode" "QI")])
1793
1794 (define_insn "*movqi_insv_2"
1795 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1796 (const_int 8)
1797 (const_int 8))
1798 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1799 (const_int 8)))]
1800 ""
1801 "mov{b}\t{%h1, %h0|%h0, %h1}"
1802 [(set_attr "type" "imov")
1803 (set_attr "mode" "QI")])
1804
1805 (define_expand "movdi"
1806 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1807 (match_operand:DI 1 "general_operand" ""))]
1808 ""
1809 "ix86_expand_move (DImode, operands); DONE;")
1810
1811 (define_insn "*pushdi"
1812 [(set (match_operand:DI 0 "push_operand" "=<")
1813 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1814 "!TARGET_64BIT"
1815 "#")
1816
1817 (define_insn "*pushdi2_rex64"
1818 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1819 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1820 "TARGET_64BIT"
1821 "@
1822 push{q}\t%1
1823 #"
1824 [(set_attr "type" "push,multi")
1825 (set_attr "mode" "DI")])
1826
1827 ;; Convert impossible pushes of immediate to existing instructions.
1828 ;; First try to get scratch register and go through it. In case this
1829 ;; fails, push sign extended lower part first and then overwrite
1830 ;; upper part by 32bit move.
1831 (define_peephole2
1832 [(match_scratch:DI 2 "r")
1833 (set (match_operand:DI 0 "push_operand" "")
1834 (match_operand:DI 1 "immediate_operand" ""))]
1835 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1836 && !x86_64_immediate_operand (operands[1], DImode)"
1837 [(set (match_dup 2) (match_dup 1))
1838 (set (match_dup 0) (match_dup 2))]
1839 "")
1840
1841 ;; We need to define this as both peepholer and splitter for case
1842 ;; peephole2 pass is not run.
1843 ;; "&& 1" is needed to keep it from matching the previous pattern.
1844 (define_peephole2
1845 [(set (match_operand:DI 0 "push_operand" "")
1846 (match_operand:DI 1 "immediate_operand" ""))]
1847 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1848 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1849 [(set (match_dup 0) (match_dup 1))
1850 (set (match_dup 2) (match_dup 3))]
1851 "split_di (operands + 1, 1, operands + 2, operands + 3);
1852 operands[1] = gen_lowpart (DImode, operands[2]);
1853 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1854 GEN_INT (4)));
1855 ")
1856
1857 (define_split
1858 [(set (match_operand:DI 0 "push_operand" "")
1859 (match_operand:DI 1 "immediate_operand" ""))]
1860 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1861 && !symbolic_operand (operands[1], DImode)
1862 && !x86_64_immediate_operand (operands[1], DImode)"
1863 [(set (match_dup 0) (match_dup 1))
1864 (set (match_dup 2) (match_dup 3))]
1865 "split_di (operands + 1, 1, operands + 2, operands + 3);
1866 operands[1] = gen_lowpart (DImode, operands[2]);
1867 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1868 GEN_INT (4)));
1869 ")
1870
1871 (define_insn "*pushdi2_prologue_rex64"
1872 [(set (match_operand:DI 0 "push_operand" "=<")
1873 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1874 (clobber (mem:BLK (scratch)))]
1875 "TARGET_64BIT"
1876 "push{q}\t%1"
1877 [(set_attr "type" "push")
1878 (set_attr "mode" "DI")])
1879
1880 (define_insn "*popdi1_epilogue_rex64"
1881 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1882 (mem:DI (reg:DI SP_REG)))
1883 (set (reg:DI SP_REG)
1884 (plus:DI (reg:DI SP_REG) (const_int 8)))
1885 (clobber (mem:BLK (scratch)))]
1886 "TARGET_64BIT"
1887 "pop{q}\t%0"
1888 [(set_attr "type" "pop")
1889 (set_attr "mode" "DI")])
1890
1891 (define_insn "popdi1"
1892 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1893 (mem:DI (reg:DI SP_REG)))
1894 (set (reg:DI SP_REG)
1895 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1896 "TARGET_64BIT"
1897 "pop{q}\t%0"
1898 [(set_attr "type" "pop")
1899 (set_attr "mode" "DI")])
1900
1901 (define_insn "*movdi_xor_rex64"
1902 [(set (match_operand:DI 0 "register_operand" "=r")
1903 (match_operand:DI 1 "const0_operand" "i"))
1904 (clobber (reg:CC FLAGS_REG))]
1905 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1906 && reload_completed"
1907 "xor{l}\t{%k0, %k0|%k0, %k0}"
1908 [(set_attr "type" "alu1")
1909 (set_attr "mode" "SI")
1910 (set_attr "length_immediate" "0")])
1911
1912 (define_insn "*movdi_or_rex64"
1913 [(set (match_operand:DI 0 "register_operand" "=r")
1914 (match_operand:DI 1 "const_int_operand" "i"))
1915 (clobber (reg:CC FLAGS_REG))]
1916 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1917 && reload_completed
1918 && operands[1] == constm1_rtx"
1919 {
1920 operands[1] = constm1_rtx;
1921 return "or{q}\t{%1, %0|%0, %1}";
1922 }
1923 [(set_attr "type" "alu1")
1924 (set_attr "mode" "DI")
1925 (set_attr "length_immediate" "1")])
1926
1927 (define_insn "*movdi_2"
1928 [(set (match_operand:DI 0 "nonimmediate_operand"
1929 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1930 (match_operand:DI 1 "general_operand"
1931 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1932 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1933 "@
1934 #
1935 #
1936 pxor\t%0, %0
1937 movq\t{%1, %0|%0, %1}
1938 movq\t{%1, %0|%0, %1}
1939 pxor\t%0, %0
1940 movq\t{%1, %0|%0, %1}
1941 movdqa\t{%1, %0|%0, %1}
1942 movq\t{%1, %0|%0, %1}
1943 xorps\t%0, %0
1944 movlps\t{%1, %0|%0, %1}
1945 movaps\t{%1, %0|%0, %1}
1946 movlps\t{%1, %0|%0, %1}"
1947 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1948 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1949
1950 (define_split
1951 [(set (match_operand:DI 0 "push_operand" "")
1952 (match_operand:DI 1 "general_operand" ""))]
1953 "!TARGET_64BIT && reload_completed
1954 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1955 [(const_int 0)]
1956 "ix86_split_long_move (operands); DONE;")
1957
1958 ;; %%% This multiword shite has got to go.
1959 (define_split
1960 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1961 (match_operand:DI 1 "general_operand" ""))]
1962 "!TARGET_64BIT && reload_completed
1963 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1964 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1965 [(const_int 0)]
1966 "ix86_split_long_move (operands); DONE;")
1967
1968 (define_insn "*movdi_1_rex64"
1969 [(set (match_operand:DI 0 "nonimmediate_operand"
1970 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1971 (match_operand:DI 1 "general_operand"
1972 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1973 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1974 {
1975 switch (get_attr_type (insn))
1976 {
1977 case TYPE_SSECVT:
1978 if (which_alternative == 13)
1979 return "movq2dq\t{%1, %0|%0, %1}";
1980 else
1981 return "movdq2q\t{%1, %0|%0, %1}";
1982 case TYPE_SSEMOV:
1983 if (get_attr_mode (insn) == MODE_TI)
1984 return "movdqa\t{%1, %0|%0, %1}";
1985 /* FALLTHRU */
1986 case TYPE_MMXMOV:
1987 /* Moves from and into integer register is done using movd opcode with
1988 REX prefix. */
1989 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1990 return "movd\t{%1, %0|%0, %1}";
1991 return "movq\t{%1, %0|%0, %1}";
1992 case TYPE_SSELOG1:
1993 case TYPE_MMXADD:
1994 return "pxor\t%0, %0";
1995 case TYPE_MULTI:
1996 return "#";
1997 case TYPE_LEA:
1998 return "lea{q}\t{%a1, %0|%0, %a1}";
1999 default:
2000 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2001 if (get_attr_mode (insn) == MODE_SI)
2002 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2003 else if (which_alternative == 2)
2004 return "movabs{q}\t{%1, %0|%0, %1}";
2005 else
2006 return "mov{q}\t{%1, %0|%0, %1}";
2007 }
2008 }
2009 [(set (attr "type")
2010 (cond [(eq_attr "alternative" "5")
2011 (const_string "mmx")
2012 (eq_attr "alternative" "6,7,8")
2013 (const_string "mmxmov")
2014 (eq_attr "alternative" "9")
2015 (const_string "sselog1")
2016 (eq_attr "alternative" "10,11,12")
2017 (const_string "ssemov")
2018 (eq_attr "alternative" "13,14")
2019 (const_string "ssecvt")
2020 (eq_attr "alternative" "4")
2021 (const_string "multi")
2022 (and (ne (symbol_ref "flag_pic") (const_int 0))
2023 (match_operand:DI 1 "symbolic_operand" ""))
2024 (const_string "lea")
2025 ]
2026 (const_string "imov")))
2027 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2028 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2029 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2030
2031 ;; Stores and loads of ax to arbitrary constant address.
2032 ;; We fake an second form of instruction to force reload to load address
2033 ;; into register when rax is not available
2034 (define_insn "*movabsdi_1_rex64"
2035 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2036 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2037 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2038 "@
2039 movabs{q}\t{%1, %P0|%P0, %1}
2040 mov{q}\t{%1, %a0|%a0, %1}"
2041 [(set_attr "type" "imov")
2042 (set_attr "modrm" "0,*")
2043 (set_attr "length_address" "8,0")
2044 (set_attr "length_immediate" "0,*")
2045 (set_attr "memory" "store")
2046 (set_attr "mode" "DI")])
2047
2048 (define_insn "*movabsdi_2_rex64"
2049 [(set (match_operand:DI 0 "register_operand" "=a,r")
2050 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2051 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2052 "@
2053 movabs{q}\t{%P1, %0|%0, %P1}
2054 mov{q}\t{%a1, %0|%0, %a1}"
2055 [(set_attr "type" "imov")
2056 (set_attr "modrm" "0,*")
2057 (set_attr "length_address" "8,0")
2058 (set_attr "length_immediate" "0")
2059 (set_attr "memory" "load")
2060 (set_attr "mode" "DI")])
2061
2062 ;; Convert impossible stores of immediate to existing instructions.
2063 ;; First try to get scratch register and go through it. In case this
2064 ;; fails, move by 32bit parts.
2065 (define_peephole2
2066 [(match_scratch:DI 2 "r")
2067 (set (match_operand:DI 0 "memory_operand" "")
2068 (match_operand:DI 1 "immediate_operand" ""))]
2069 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2070 && !x86_64_immediate_operand (operands[1], DImode)"
2071 [(set (match_dup 2) (match_dup 1))
2072 (set (match_dup 0) (match_dup 2))]
2073 "")
2074
2075 ;; We need to define this as both peepholer and splitter for case
2076 ;; peephole2 pass is not run.
2077 ;; "&& 1" is needed to keep it from matching the previous pattern.
2078 (define_peephole2
2079 [(set (match_operand:DI 0 "memory_operand" "")
2080 (match_operand:DI 1 "immediate_operand" ""))]
2081 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2082 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2083 [(set (match_dup 2) (match_dup 3))
2084 (set (match_dup 4) (match_dup 5))]
2085 "split_di (operands, 2, operands + 2, operands + 4);")
2086
2087 (define_split
2088 [(set (match_operand:DI 0 "memory_operand" "")
2089 (match_operand:DI 1 "immediate_operand" ""))]
2090 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2091 && !symbolic_operand (operands[1], DImode)
2092 && !x86_64_immediate_operand (operands[1], DImode)"
2093 [(set (match_dup 2) (match_dup 3))
2094 (set (match_dup 4) (match_dup 5))]
2095 "split_di (operands, 2, operands + 2, operands + 4);")
2096
2097 (define_insn "*swapdi_rex64"
2098 [(set (match_operand:DI 0 "register_operand" "+r")
2099 (match_operand:DI 1 "register_operand" "+r"))
2100 (set (match_dup 1)
2101 (match_dup 0))]
2102 "TARGET_64BIT"
2103 "xchg{q}\t%1, %0"
2104 [(set_attr "type" "imov")
2105 (set_attr "mode" "DI")
2106 (set_attr "pent_pair" "np")
2107 (set_attr "athlon_decode" "vector")])
2108
2109 (define_expand "movti"
2110 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2111 (match_operand:TI 1 "nonimmediate_operand" ""))]
2112 "TARGET_SSE || TARGET_64BIT"
2113 {
2114 if (TARGET_64BIT)
2115 ix86_expand_move (TImode, operands);
2116 else
2117 ix86_expand_vector_move (TImode, operands);
2118 DONE;
2119 })
2120
2121 (define_insn "*movti_internal"
2122 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2123 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2124 "TARGET_SSE && !TARGET_64BIT
2125 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2126 {
2127 switch (which_alternative)
2128 {
2129 case 0:
2130 if (get_attr_mode (insn) == MODE_V4SF)
2131 return "xorps\t%0, %0";
2132 else
2133 return "pxor\t%0, %0";
2134 case 1:
2135 case 2:
2136 if (get_attr_mode (insn) == MODE_V4SF)
2137 return "movaps\t{%1, %0|%0, %1}";
2138 else
2139 return "movdqa\t{%1, %0|%0, %1}";
2140 default:
2141 gcc_unreachable ();
2142 }
2143 }
2144 [(set_attr "type" "ssemov,ssemov,ssemov")
2145 (set (attr "mode")
2146 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2147 (const_string "V4SF")
2148
2149 (eq_attr "alternative" "0,1")
2150 (if_then_else
2151 (ne (symbol_ref "optimize_size")
2152 (const_int 0))
2153 (const_string "V4SF")
2154 (const_string "TI"))
2155 (eq_attr "alternative" "2")
2156 (if_then_else
2157 (ne (symbol_ref "optimize_size")
2158 (const_int 0))
2159 (const_string "V4SF")
2160 (const_string "TI"))]
2161 (const_string "TI")))])
2162
2163 (define_insn "*movti_rex64"
2164 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2165 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2166 "TARGET_64BIT
2167 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2168 {
2169 switch (which_alternative)
2170 {
2171 case 0:
2172 case 1:
2173 return "#";
2174 case 2:
2175 if (get_attr_mode (insn) == MODE_V4SF)
2176 return "xorps\t%0, %0";
2177 else
2178 return "pxor\t%0, %0";
2179 case 3:
2180 case 4:
2181 if (get_attr_mode (insn) == MODE_V4SF)
2182 return "movaps\t{%1, %0|%0, %1}";
2183 else
2184 return "movdqa\t{%1, %0|%0, %1}";
2185 default:
2186 gcc_unreachable ();
2187 }
2188 }
2189 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2190 (set (attr "mode")
2191 (cond [(eq_attr "alternative" "2,3")
2192 (if_then_else
2193 (ne (symbol_ref "optimize_size")
2194 (const_int 0))
2195 (const_string "V4SF")
2196 (const_string "TI"))
2197 (eq_attr "alternative" "4")
2198 (if_then_else
2199 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2200 (const_int 0))
2201 (ne (symbol_ref "optimize_size")
2202 (const_int 0)))
2203 (const_string "V4SF")
2204 (const_string "TI"))]
2205 (const_string "DI")))])
2206
2207 (define_split
2208 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2209 (match_operand:TI 1 "general_operand" ""))]
2210 "reload_completed && !SSE_REG_P (operands[0])
2211 && !SSE_REG_P (operands[1])"
2212 [(const_int 0)]
2213 "ix86_split_long_move (operands); DONE;")
2214
2215 (define_expand "movsf"
2216 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2217 (match_operand:SF 1 "general_operand" ""))]
2218 ""
2219 "ix86_expand_move (SFmode, operands); DONE;")
2220
2221 (define_insn "*pushsf"
2222 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2223 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2224 "!TARGET_64BIT"
2225 {
2226 /* Anything else should be already split before reg-stack. */
2227 gcc_assert (which_alternative == 1);
2228 return "push{l}\t%1";
2229 }
2230 [(set_attr "type" "multi,push,multi")
2231 (set_attr "unit" "i387,*,*")
2232 (set_attr "mode" "SF,SI,SF")])
2233
2234 (define_insn "*pushsf_rex64"
2235 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2236 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2237 "TARGET_64BIT"
2238 {
2239 /* Anything else should be already split before reg-stack. */
2240 gcc_assert (which_alternative == 1);
2241 return "push{q}\t%q1";
2242 }
2243 [(set_attr "type" "multi,push,multi")
2244 (set_attr "unit" "i387,*,*")
2245 (set_attr "mode" "SF,DI,SF")])
2246
2247 (define_split
2248 [(set (match_operand:SF 0 "push_operand" "")
2249 (match_operand:SF 1 "memory_operand" ""))]
2250 "reload_completed
2251 && GET_CODE (operands[1]) == MEM
2252 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2253 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2254 [(set (match_dup 0)
2255 (match_dup 1))]
2256 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2257
2258
2259 ;; %%% Kill this when call knows how to work this out.
2260 (define_split
2261 [(set (match_operand:SF 0 "push_operand" "")
2262 (match_operand:SF 1 "any_fp_register_operand" ""))]
2263 "!TARGET_64BIT"
2264 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2265 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2266
2267 (define_split
2268 [(set (match_operand:SF 0 "push_operand" "")
2269 (match_operand:SF 1 "any_fp_register_operand" ""))]
2270 "TARGET_64BIT"
2271 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2272 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2273
2274 (define_insn "*movsf_1"
2275 [(set (match_operand:SF 0 "nonimmediate_operand"
2276 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2277 (match_operand:SF 1 "general_operand"
2278 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2279 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2280 && (reload_in_progress || reload_completed
2281 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2282 || GET_CODE (operands[1]) != CONST_DOUBLE
2283 || memory_operand (operands[0], SFmode))"
2284 {
2285 switch (which_alternative)
2286 {
2287 case 0:
2288 return output_387_reg_move (insn, operands);
2289
2290 case 1:
2291 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2292 return "fstp%z0\t%y0";
2293 else
2294 return "fst%z0\t%y0";
2295
2296 case 2:
2297 return standard_80387_constant_opcode (operands[1]);
2298
2299 case 3:
2300 case 4:
2301 return "mov{l}\t{%1, %0|%0, %1}";
2302 case 5:
2303 if (get_attr_mode (insn) == MODE_TI)
2304 return "pxor\t%0, %0";
2305 else
2306 return "xorps\t%0, %0";
2307 case 6:
2308 if (get_attr_mode (insn) == MODE_V4SF)
2309 return "movaps\t{%1, %0|%0, %1}";
2310 else
2311 return "movss\t{%1, %0|%0, %1}";
2312 case 7:
2313 case 8:
2314 return "movss\t{%1, %0|%0, %1}";
2315
2316 case 9:
2317 case 10:
2318 return "movd\t{%1, %0|%0, %1}";
2319
2320 case 11:
2321 return "movq\t{%1, %0|%0, %1}";
2322
2323 default:
2324 gcc_unreachable ();
2325 }
2326 }
2327 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2328 (set (attr "mode")
2329 (cond [(eq_attr "alternative" "3,4,9,10")
2330 (const_string "SI")
2331 (eq_attr "alternative" "5")
2332 (if_then_else
2333 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2334 (const_int 0))
2335 (ne (symbol_ref "TARGET_SSE2")
2336 (const_int 0)))
2337 (eq (symbol_ref "optimize_size")
2338 (const_int 0)))
2339 (const_string "TI")
2340 (const_string "V4SF"))
2341 /* For architectures resolving dependencies on
2342 whole SSE registers use APS move to break dependency
2343 chains, otherwise use short move to avoid extra work.
2344
2345 Do the same for architectures resolving dependencies on
2346 the parts. While in DF mode it is better to always handle
2347 just register parts, the SF mode is different due to lack
2348 of instructions to load just part of the register. It is
2349 better to maintain the whole registers in single format
2350 to avoid problems on using packed logical operations. */
2351 (eq_attr "alternative" "6")
2352 (if_then_else
2353 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2354 (const_int 0))
2355 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2356 (const_int 0)))
2357 (const_string "V4SF")
2358 (const_string "SF"))
2359 (eq_attr "alternative" "11")
2360 (const_string "DI")]
2361 (const_string "SF")))])
2362
2363 (define_insn "*swapsf"
2364 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2365 (match_operand:SF 1 "fp_register_operand" "+f"))
2366 (set (match_dup 1)
2367 (match_dup 0))]
2368 "reload_completed || TARGET_80387"
2369 {
2370 if (STACK_TOP_P (operands[0]))
2371 return "fxch\t%1";
2372 else
2373 return "fxch\t%0";
2374 }
2375 [(set_attr "type" "fxch")
2376 (set_attr "mode" "SF")])
2377
2378 (define_expand "movdf"
2379 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2380 (match_operand:DF 1 "general_operand" ""))]
2381 ""
2382 "ix86_expand_move (DFmode, operands); DONE;")
2383
2384 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2385 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2386 ;; On the average, pushdf using integers can be still shorter. Allow this
2387 ;; pattern for optimize_size too.
2388
2389 (define_insn "*pushdf_nointeger"
2390 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2391 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2392 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2393 {
2394 /* This insn should be already split before reg-stack. */
2395 gcc_unreachable ();
2396 }
2397 [(set_attr "type" "multi")
2398 (set_attr "unit" "i387,*,*,*")
2399 (set_attr "mode" "DF,SI,SI,DF")])
2400
2401 (define_insn "*pushdf_integer"
2402 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2403 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2404 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2405 {
2406 /* This insn should be already split before reg-stack. */
2407 gcc_unreachable ();
2408 }
2409 [(set_attr "type" "multi")
2410 (set_attr "unit" "i387,*,*")
2411 (set_attr "mode" "DF,SI,DF")])
2412
2413 ;; %%% Kill this when call knows how to work this out.
2414 (define_split
2415 [(set (match_operand:DF 0 "push_operand" "")
2416 (match_operand:DF 1 "any_fp_register_operand" ""))]
2417 "!TARGET_64BIT && reload_completed"
2418 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2419 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2420 "")
2421
2422 (define_split
2423 [(set (match_operand:DF 0 "push_operand" "")
2424 (match_operand:DF 1 "any_fp_register_operand" ""))]
2425 "TARGET_64BIT && reload_completed"
2426 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2427 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2428 "")
2429
2430 (define_split
2431 [(set (match_operand:DF 0 "push_operand" "")
2432 (match_operand:DF 1 "general_operand" ""))]
2433 "reload_completed"
2434 [(const_int 0)]
2435 "ix86_split_long_move (operands); DONE;")
2436
2437 ;; Moving is usually shorter when only FP registers are used. This separate
2438 ;; movdf pattern avoids the use of integer registers for FP operations
2439 ;; when optimizing for size.
2440
2441 (define_insn "*movdf_nointeger"
2442 [(set (match_operand:DF 0 "nonimmediate_operand"
2443 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2444 (match_operand:DF 1 "general_operand"
2445 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2446 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2447 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2448 && (reload_in_progress || reload_completed
2449 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2450 || GET_CODE (operands[1]) != CONST_DOUBLE
2451 || memory_operand (operands[0], DFmode))"
2452 {
2453 switch (which_alternative)
2454 {
2455 case 0:
2456 return output_387_reg_move (insn, operands);
2457
2458 case 1:
2459 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2460 return "fstp%z0\t%y0";
2461 else
2462 return "fst%z0\t%y0";
2463
2464 case 2:
2465 return standard_80387_constant_opcode (operands[1]);
2466
2467 case 3:
2468 case 4:
2469 return "#";
2470 case 5:
2471 switch (get_attr_mode (insn))
2472 {
2473 case MODE_V4SF:
2474 return "xorps\t%0, %0";
2475 case MODE_V2DF:
2476 return "xorpd\t%0, %0";
2477 case MODE_TI:
2478 return "pxor\t%0, %0";
2479 default:
2480 gcc_unreachable ();
2481 }
2482 case 6:
2483 case 7:
2484 case 8:
2485 switch (get_attr_mode (insn))
2486 {
2487 case MODE_V4SF:
2488 return "movaps\t{%1, %0|%0, %1}";
2489 case MODE_V2DF:
2490 return "movapd\t{%1, %0|%0, %1}";
2491 case MODE_TI:
2492 return "movdqa\t{%1, %0|%0, %1}";
2493 case MODE_DI:
2494 return "movq\t{%1, %0|%0, %1}";
2495 case MODE_DF:
2496 return "movsd\t{%1, %0|%0, %1}";
2497 case MODE_V1DF:
2498 return "movlpd\t{%1, %0|%0, %1}";
2499 case MODE_V2SF:
2500 return "movlps\t{%1, %0|%0, %1}";
2501 default:
2502 gcc_unreachable ();
2503 }
2504
2505 default:
2506 gcc_unreachable ();
2507 }
2508 }
2509 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2510 (set (attr "mode")
2511 (cond [(eq_attr "alternative" "0,1,2")
2512 (const_string "DF")
2513 (eq_attr "alternative" "3,4")
2514 (const_string "SI")
2515
2516 /* For SSE1, we have many fewer alternatives. */
2517 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518 (cond [(eq_attr "alternative" "5,6")
2519 (const_string "V4SF")
2520 ]
2521 (const_string "V2SF"))
2522
2523 /* xorps is one byte shorter. */
2524 (eq_attr "alternative" "5")
2525 (cond [(ne (symbol_ref "optimize_size")
2526 (const_int 0))
2527 (const_string "V4SF")
2528 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2529 (const_int 0))
2530 (const_string "TI")
2531 ]
2532 (const_string "V2DF"))
2533
2534 /* For architectures resolving dependencies on
2535 whole SSE registers use APD move to break dependency
2536 chains, otherwise use short move to avoid extra work.
2537
2538 movaps encodes one byte shorter. */
2539 (eq_attr "alternative" "6")
2540 (cond
2541 [(ne (symbol_ref "optimize_size")
2542 (const_int 0))
2543 (const_string "V4SF")
2544 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2545 (const_int 0))
2546 (const_string "V2DF")
2547 ]
2548 (const_string "DF"))
2549 /* For architectures resolving dependencies on register
2550 parts we may avoid extra work to zero out upper part
2551 of register. */
2552 (eq_attr "alternative" "7")
2553 (if_then_else
2554 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2555 (const_int 0))
2556 (const_string "V1DF")
2557 (const_string "DF"))
2558 ]
2559 (const_string "DF")))])
2560
2561 (define_insn "*movdf_integer"
2562 [(set (match_operand:DF 0 "nonimmediate_operand"
2563 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2564 (match_operand:DF 1 "general_operand"
2565 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2566 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2567 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2568 && (reload_in_progress || reload_completed
2569 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2570 || GET_CODE (operands[1]) != CONST_DOUBLE
2571 || memory_operand (operands[0], DFmode))"
2572 {
2573 switch (which_alternative)
2574 {
2575 case 0:
2576 return output_387_reg_move (insn, operands);
2577
2578 case 1:
2579 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2580 return "fstp%z0\t%y0";
2581 else
2582 return "fst%z0\t%y0";
2583
2584 case 2:
2585 return standard_80387_constant_opcode (operands[1]);
2586
2587 case 3:
2588 case 4:
2589 return "#";
2590
2591 case 5:
2592 switch (get_attr_mode (insn))
2593 {
2594 case MODE_V4SF:
2595 return "xorps\t%0, %0";
2596 case MODE_V2DF:
2597 return "xorpd\t%0, %0";
2598 case MODE_TI:
2599 return "pxor\t%0, %0";
2600 default:
2601 gcc_unreachable ();
2602 }
2603 case 6:
2604 case 7:
2605 case 8:
2606 switch (get_attr_mode (insn))
2607 {
2608 case MODE_V4SF:
2609 return "movaps\t{%1, %0|%0, %1}";
2610 case MODE_V2DF:
2611 return "movapd\t{%1, %0|%0, %1}";
2612 case MODE_TI:
2613 return "movdqa\t{%1, %0|%0, %1}";
2614 case MODE_DI:
2615 return "movq\t{%1, %0|%0, %1}";
2616 case MODE_DF:
2617 return "movsd\t{%1, %0|%0, %1}";
2618 case MODE_V1DF:
2619 return "movlpd\t{%1, %0|%0, %1}";
2620 case MODE_V2SF:
2621 return "movlps\t{%1, %0|%0, %1}";
2622 default:
2623 gcc_unreachable ();
2624 }
2625
2626 default:
2627 gcc_unreachable();
2628 }
2629 }
2630 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2631 (set (attr "mode")
2632 (cond [(eq_attr "alternative" "0,1,2")
2633 (const_string "DF")
2634 (eq_attr "alternative" "3,4")
2635 (const_string "SI")
2636
2637 /* For SSE1, we have many fewer alternatives. */
2638 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2639 (cond [(eq_attr "alternative" "5,6")
2640 (const_string "V4SF")
2641 ]
2642 (const_string "V2SF"))
2643
2644 /* xorps is one byte shorter. */
2645 (eq_attr "alternative" "5")
2646 (cond [(ne (symbol_ref "optimize_size")
2647 (const_int 0))
2648 (const_string "V4SF")
2649 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2650 (const_int 0))
2651 (const_string "TI")
2652 ]
2653 (const_string "V2DF"))
2654
2655 /* For architectures resolving dependencies on
2656 whole SSE registers use APD move to break dependency
2657 chains, otherwise use short move to avoid extra work.
2658
2659 movaps encodes one byte shorter. */
2660 (eq_attr "alternative" "6")
2661 (cond
2662 [(ne (symbol_ref "optimize_size")
2663 (const_int 0))
2664 (const_string "V4SF")
2665 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2666 (const_int 0))
2667 (const_string "V2DF")
2668 ]
2669 (const_string "DF"))
2670 /* For architectures resolving dependencies on register
2671 parts we may avoid extra work to zero out upper part
2672 of register. */
2673 (eq_attr "alternative" "7")
2674 (if_then_else
2675 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2676 (const_int 0))
2677 (const_string "V1DF")
2678 (const_string "DF"))
2679 ]
2680 (const_string "DF")))])
2681
2682 (define_split
2683 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2684 (match_operand:DF 1 "general_operand" ""))]
2685 "reload_completed
2686 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2687 && ! (ANY_FP_REG_P (operands[0]) ||
2688 (GET_CODE (operands[0]) == SUBREG
2689 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2690 && ! (ANY_FP_REG_P (operands[1]) ||
2691 (GET_CODE (operands[1]) == SUBREG
2692 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2693 [(const_int 0)]
2694 "ix86_split_long_move (operands); DONE;")
2695
2696 (define_insn "*swapdf"
2697 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2698 (match_operand:DF 1 "fp_register_operand" "+f"))
2699 (set (match_dup 1)
2700 (match_dup 0))]
2701 "reload_completed || TARGET_80387"
2702 {
2703 if (STACK_TOP_P (operands[0]))
2704 return "fxch\t%1";
2705 else
2706 return "fxch\t%0";
2707 }
2708 [(set_attr "type" "fxch")
2709 (set_attr "mode" "DF")])
2710
2711 (define_expand "movxf"
2712 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2713 (match_operand:XF 1 "general_operand" ""))]
2714 ""
2715 "ix86_expand_move (XFmode, operands); DONE;")
2716
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2719 ;; Pushing using integer instructions is longer except for constants
2720 ;; and direct memory references.
2721 ;; (assuming that any given constant is pushed only once, but this ought to be
2722 ;; handled elsewhere).
2723
2724 (define_insn "*pushxf_nointeger"
2725 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2726 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2727 "optimize_size"
2728 {
2729 /* This insn should be already split before reg-stack. */
2730 gcc_unreachable ();
2731 }
2732 [(set_attr "type" "multi")
2733 (set_attr "unit" "i387,*,*")
2734 (set_attr "mode" "XF,SI,SI")])
2735
2736 (define_insn "*pushxf_integer"
2737 [(set (match_operand:XF 0 "push_operand" "=<,<")
2738 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2739 "!optimize_size"
2740 {
2741 /* This insn should be already split before reg-stack. */
2742 gcc_unreachable ();
2743 }
2744 [(set_attr "type" "multi")
2745 (set_attr "unit" "i387,*")
2746 (set_attr "mode" "XF,SI")])
2747
2748 (define_split
2749 [(set (match_operand 0 "push_operand" "")
2750 (match_operand 1 "general_operand" ""))]
2751 "reload_completed
2752 && (GET_MODE (operands[0]) == XFmode
2753 || GET_MODE (operands[0]) == DFmode)
2754 && !ANY_FP_REG_P (operands[1])"
2755 [(const_int 0)]
2756 "ix86_split_long_move (operands); DONE;")
2757
2758 (define_split
2759 [(set (match_operand:XF 0 "push_operand" "")
2760 (match_operand:XF 1 "any_fp_register_operand" ""))]
2761 "!TARGET_64BIT"
2762 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2765
2766 (define_split
2767 [(set (match_operand:XF 0 "push_operand" "")
2768 (match_operand:XF 1 "any_fp_register_operand" ""))]
2769 "TARGET_64BIT"
2770 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2778 "optimize_size
2779 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780 && (reload_in_progress || reload_completed
2781 || GET_CODE (operands[1]) != CONST_DOUBLE
2782 || memory_operand (operands[0], XFmode))"
2783 {
2784 switch (which_alternative)
2785 {
2786 case 0:
2787 return output_387_reg_move (insn, operands);
2788
2789 case 1:
2790 /* There is no non-popping store to memory for XFmode. So if
2791 we need one, follow the store with a load. */
2792 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793 return "fstp%z0\t%y0\;fld%z0\t%y0";
2794 else
2795 return "fstp%z0\t%y0";
2796
2797 case 2:
2798 return standard_80387_constant_opcode (operands[1]);
2799
2800 case 3: case 4:
2801 return "#";
2802 default:
2803 gcc_unreachable ();
2804 }
2805 }
2806 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2807 (set_attr "mode" "XF,XF,XF,SI,SI")])
2808
2809 (define_insn "*movxf_integer"
2810 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2811 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2812 "!optimize_size
2813 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2814 && (reload_in_progress || reload_completed
2815 || GET_CODE (operands[1]) != CONST_DOUBLE
2816 || memory_operand (operands[0], XFmode))"
2817 {
2818 switch (which_alternative)
2819 {
2820 case 0:
2821 return output_387_reg_move (insn, operands);
2822
2823 case 1:
2824 /* There is no non-popping store to memory for XFmode. So if
2825 we need one, follow the store with a load. */
2826 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827 return "fstp%z0\t%y0\;fld%z0\t%y0";
2828 else
2829 return "fstp%z0\t%y0";
2830
2831 case 2:
2832 return standard_80387_constant_opcode (operands[1]);
2833
2834 case 3: case 4:
2835 return "#";
2836
2837 default:
2838 gcc_unreachable ();
2839 }
2840 }
2841 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2842 (set_attr "mode" "XF,XF,XF,SI,SI")])
2843
2844 (define_split
2845 [(set (match_operand 0 "nonimmediate_operand" "")
2846 (match_operand 1 "general_operand" ""))]
2847 "reload_completed
2848 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2849 && GET_MODE (operands[0]) == XFmode
2850 && ! (ANY_FP_REG_P (operands[0]) ||
2851 (GET_CODE (operands[0]) == SUBREG
2852 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2853 && ! (ANY_FP_REG_P (operands[1]) ||
2854 (GET_CODE (operands[1]) == SUBREG
2855 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2856 [(const_int 0)]
2857 "ix86_split_long_move (operands); DONE;")
2858
2859 (define_split
2860 [(set (match_operand 0 "register_operand" "")
2861 (match_operand 1 "memory_operand" ""))]
2862 "reload_completed
2863 && GET_CODE (operands[1]) == MEM
2864 && (GET_MODE (operands[0]) == XFmode
2865 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2866 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2867 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2868 [(set (match_dup 0) (match_dup 1))]
2869 {
2870 rtx c = get_pool_constant (XEXP (operands[1], 0));
2871 rtx r = operands[0];
2872
2873 if (GET_CODE (r) == SUBREG)
2874 r = SUBREG_REG (r);
2875
2876 if (SSE_REG_P (r))
2877 {
2878 if (!standard_sse_constant_p (c))
2879 FAIL;
2880 }
2881 else if (FP_REG_P (r))
2882 {
2883 if (!standard_80387_constant_p (c))
2884 FAIL;
2885 }
2886 else if (MMX_REG_P (r))
2887 FAIL;
2888
2889 operands[1] = c;
2890 })
2891
2892 (define_insn "swapxf"
2893 [(set (match_operand:XF 0 "register_operand" "+f")
2894 (match_operand:XF 1 "register_operand" "+f"))
2895 (set (match_dup 1)
2896 (match_dup 0))]
2897 "TARGET_80387"
2898 {
2899 if (STACK_TOP_P (operands[0]))
2900 return "fxch\t%1";
2901 else
2902 return "fxch\t%0";
2903 }
2904 [(set_attr "type" "fxch")
2905 (set_attr "mode" "XF")])
2906
2907 (define_expand "movtf"
2908 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909 (match_operand:TF 1 "nonimmediate_operand" ""))]
2910 "TARGET_64BIT"
2911 {
2912 ix86_expand_move (TFmode, operands);
2913 DONE;
2914 })
2915
2916 (define_insn "*movtf_internal"
2917 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2919 "TARGET_64BIT
2920 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2921 {
2922 switch (which_alternative)
2923 {
2924 case 0:
2925 case 1:
2926 return "#";
2927 case 2:
2928 if (get_attr_mode (insn) == MODE_V4SF)
2929 return "xorps\t%0, %0";
2930 else
2931 return "pxor\t%0, %0";
2932 case 3:
2933 case 4:
2934 if (get_attr_mode (insn) == MODE_V4SF)
2935 return "movaps\t{%1, %0|%0, %1}";
2936 else
2937 return "movdqa\t{%1, %0|%0, %1}";
2938 default:
2939 gcc_unreachable ();
2940 }
2941 }
2942 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2943 (set (attr "mode")
2944 (cond [(eq_attr "alternative" "2,3")
2945 (if_then_else
2946 (ne (symbol_ref "optimize_size")
2947 (const_int 0))
2948 (const_string "V4SF")
2949 (const_string "TI"))
2950 (eq_attr "alternative" "4")
2951 (if_then_else
2952 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2953 (const_int 0))
2954 (ne (symbol_ref "optimize_size")
2955 (const_int 0)))
2956 (const_string "V4SF")
2957 (const_string "TI"))]
2958 (const_string "DI")))])
2959
2960 (define_split
2961 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962 (match_operand:TF 1 "general_operand" ""))]
2963 "reload_completed && !SSE_REG_P (operands[0])
2964 && !SSE_REG_P (operands[1])"
2965 [(const_int 0)]
2966 "ix86_split_long_move (operands); DONE;")
2967 \f
2968 ;; Zero extension instructions
2969
2970 (define_expand "zero_extendhisi2"
2971 [(set (match_operand:SI 0 "register_operand" "")
2972 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2973 ""
2974 {
2975 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2976 {
2977 operands[1] = force_reg (HImode, operands[1]);
2978 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2979 DONE;
2980 }
2981 })
2982
2983 (define_insn "zero_extendhisi2_and"
2984 [(set (match_operand:SI 0 "register_operand" "=r")
2985 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986 (clobber (reg:CC FLAGS_REG))]
2987 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2988 "#"
2989 [(set_attr "type" "alu1")
2990 (set_attr "mode" "SI")])
2991
2992 (define_split
2993 [(set (match_operand:SI 0 "register_operand" "")
2994 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995 (clobber (reg:CC FLAGS_REG))]
2996 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998 (clobber (reg:CC FLAGS_REG))])]
2999 "")
3000
3001 (define_insn "*zero_extendhisi2_movzwl"
3002 [(set (match_operand:SI 0 "register_operand" "=r")
3003 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005 "movz{wl|x}\t{%1, %0|%0, %1}"
3006 [(set_attr "type" "imovx")
3007 (set_attr "mode" "SI")])
3008
3009 (define_expand "zero_extendqihi2"
3010 [(parallel
3011 [(set (match_operand:HI 0 "register_operand" "")
3012 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013 (clobber (reg:CC FLAGS_REG))])]
3014 ""
3015 "")
3016
3017 (define_insn "*zero_extendqihi2_and"
3018 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020 (clobber (reg:CC FLAGS_REG))]
3021 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3022 "#"
3023 [(set_attr "type" "alu1")
3024 (set_attr "mode" "HI")])
3025
3026 (define_insn "*zero_extendqihi2_movzbw_and"
3027 [(set (match_operand:HI 0 "register_operand" "=r,r")
3028 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029 (clobber (reg:CC FLAGS_REG))]
3030 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3031 "#"
3032 [(set_attr "type" "imovx,alu1")
3033 (set_attr "mode" "HI")])
3034
3035 (define_insn "*zero_extendqihi2_movzbw"
3036 [(set (match_operand:HI 0 "register_operand" "=r")
3037 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3038 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3039 "movz{bw|x}\t{%1, %0|%0, %1}"
3040 [(set_attr "type" "imovx")
3041 (set_attr "mode" "HI")])
3042
3043 ;; For the movzbw case strip only the clobber
3044 (define_split
3045 [(set (match_operand:HI 0 "register_operand" "")
3046 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3047 (clobber (reg:CC FLAGS_REG))]
3048 "reload_completed
3049 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3050 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3051 [(set (match_operand:HI 0 "register_operand" "")
3052 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3053
3054 ;; When source and destination does not overlap, clear destination
3055 ;; first and then do the movb
3056 (define_split
3057 [(set (match_operand:HI 0 "register_operand" "")
3058 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3059 (clobber (reg:CC FLAGS_REG))]
3060 "reload_completed
3061 && ANY_QI_REG_P (operands[0])
3062 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3064 [(set (match_dup 0) (const_int 0))
3065 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3066 "operands[2] = gen_lowpart (QImode, operands[0]);")
3067
3068 ;; Rest is handled by single and.
3069 (define_split
3070 [(set (match_operand:HI 0 "register_operand" "")
3071 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3072 (clobber (reg:CC FLAGS_REG))]
3073 "reload_completed
3074 && true_regnum (operands[0]) == true_regnum (operands[1])"
3075 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3076 (clobber (reg:CC FLAGS_REG))])]
3077 "")
3078
3079 (define_expand "zero_extendqisi2"
3080 [(parallel
3081 [(set (match_operand:SI 0 "register_operand" "")
3082 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3083 (clobber (reg:CC FLAGS_REG))])]
3084 ""
3085 "")
3086
3087 (define_insn "*zero_extendqisi2_and"
3088 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3089 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3090 (clobber (reg:CC FLAGS_REG))]
3091 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3092 "#"
3093 [(set_attr "type" "alu1")
3094 (set_attr "mode" "SI")])
3095
3096 (define_insn "*zero_extendqisi2_movzbw_and"
3097 [(set (match_operand:SI 0 "register_operand" "=r,r")
3098 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3099 (clobber (reg:CC FLAGS_REG))]
3100 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3101 "#"
3102 [(set_attr "type" "imovx,alu1")
3103 (set_attr "mode" "SI")])
3104
3105 (define_insn "*zero_extendqisi2_movzbw"
3106 [(set (match_operand:SI 0 "register_operand" "=r")
3107 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109 "movz{bl|x}\t{%1, %0|%0, %1}"
3110 [(set_attr "type" "imovx")
3111 (set_attr "mode" "SI")])
3112
3113 ;; For the movzbl case strip only the clobber
3114 (define_split
3115 [(set (match_operand:SI 0 "register_operand" "")
3116 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3117 (clobber (reg:CC FLAGS_REG))]
3118 "reload_completed
3119 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3120 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3121 [(set (match_dup 0)
3122 (zero_extend:SI (match_dup 1)))])
3123
3124 ;; When source and destination does not overlap, clear destination
3125 ;; first and then do the movb
3126 (define_split
3127 [(set (match_operand:SI 0 "register_operand" "")
3128 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3129 (clobber (reg:CC FLAGS_REG))]
3130 "reload_completed
3131 && ANY_QI_REG_P (operands[0])
3132 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3133 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3134 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3135 [(set (match_dup 0) (const_int 0))
3136 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3137 "operands[2] = gen_lowpart (QImode, operands[0]);")
3138
3139 ;; Rest is handled by single and.
3140 (define_split
3141 [(set (match_operand:SI 0 "register_operand" "")
3142 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3143 (clobber (reg:CC FLAGS_REG))]
3144 "reload_completed
3145 && true_regnum (operands[0]) == true_regnum (operands[1])"
3146 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3147 (clobber (reg:CC FLAGS_REG))])]
3148 "")
3149
3150 ;; %%% Kill me once multi-word ops are sane.
3151 (define_expand "zero_extendsidi2"
3152 [(set (match_operand:DI 0 "register_operand" "=r")
3153 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3154 ""
3155 "if (!TARGET_64BIT)
3156 {
3157 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3158 DONE;
3159 }
3160 ")
3161
3162 (define_insn "zero_extendsidi2_32"
3163 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3164 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3165 (clobber (reg:CC FLAGS_REG))]
3166 "!TARGET_64BIT"
3167 "@
3168 #
3169 #
3170 #
3171 movd\t{%1, %0|%0, %1}
3172 movd\t{%1, %0|%0, %1}"
3173 [(set_attr "mode" "SI,SI,SI,DI,TI")
3174 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3175
3176 (define_insn "zero_extendsidi2_rex64"
3177 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3178 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3179 "TARGET_64BIT"
3180 "@
3181 mov\t{%k1, %k0|%k0, %k1}
3182 #
3183 movd\t{%1, %0|%0, %1}
3184 movd\t{%1, %0|%0, %1}"
3185 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3186 (set_attr "mode" "SI,DI,SI,SI")])
3187
3188 (define_split
3189 [(set (match_operand:DI 0 "memory_operand" "")
3190 (zero_extend:DI (match_dup 0)))]
3191 "TARGET_64BIT"
3192 [(set (match_dup 4) (const_int 0))]
3193 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3194
3195 (define_split
3196 [(set (match_operand:DI 0 "register_operand" "")
3197 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3198 (clobber (reg:CC FLAGS_REG))]
3199 "!TARGET_64BIT && reload_completed
3200 && true_regnum (operands[0]) == true_regnum (operands[1])"
3201 [(set (match_dup 4) (const_int 0))]
3202 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3203
3204 (define_split
3205 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3206 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3207 (clobber (reg:CC FLAGS_REG))]
3208 "!TARGET_64BIT && reload_completed
3209 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3210 [(set (match_dup 3) (match_dup 1))
3211 (set (match_dup 4) (const_int 0))]
3212 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3213
3214 (define_insn "zero_extendhidi2"
3215 [(set (match_operand:DI 0 "register_operand" "=r")
3216 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3217 "TARGET_64BIT"
3218 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3219 [(set_attr "type" "imovx")
3220 (set_attr "mode" "DI")])
3221
3222 (define_insn "zero_extendqidi2"
3223 [(set (match_operand:DI 0 "register_operand" "=r")
3224 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3225 "TARGET_64BIT"
3226 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3227 [(set_attr "type" "imovx")
3228 (set_attr "mode" "DI")])
3229 \f
3230 ;; Sign extension instructions
3231
3232 (define_expand "extendsidi2"
3233 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3234 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3235 (clobber (reg:CC FLAGS_REG))
3236 (clobber (match_scratch:SI 2 ""))])]
3237 ""
3238 {
3239 if (TARGET_64BIT)
3240 {
3241 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3242 DONE;
3243 }
3244 })
3245
3246 (define_insn "*extendsidi2_1"
3247 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3248 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3249 (clobber (reg:CC FLAGS_REG))
3250 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3251 "!TARGET_64BIT"
3252 "#")
3253
3254 (define_insn "extendsidi2_rex64"
3255 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3256 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3257 "TARGET_64BIT"
3258 "@
3259 {cltq|cdqe}
3260 movs{lq|x}\t{%1,%0|%0, %1}"
3261 [(set_attr "type" "imovx")
3262 (set_attr "mode" "DI")
3263 (set_attr "prefix_0f" "0")
3264 (set_attr "modrm" "0,1")])
3265
3266 (define_insn "extendhidi2"
3267 [(set (match_operand:DI 0 "register_operand" "=r")
3268 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3269 "TARGET_64BIT"
3270 "movs{wq|x}\t{%1,%0|%0, %1}"
3271 [(set_attr "type" "imovx")
3272 (set_attr "mode" "DI")])
3273
3274 (define_insn "extendqidi2"
3275 [(set (match_operand:DI 0 "register_operand" "=r")
3276 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3277 "TARGET_64BIT"
3278 "movs{bq|x}\t{%1,%0|%0, %1}"
3279 [(set_attr "type" "imovx")
3280 (set_attr "mode" "DI")])
3281
3282 ;; Extend to memory case when source register does die.
3283 (define_split
3284 [(set (match_operand:DI 0 "memory_operand" "")
3285 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286 (clobber (reg:CC FLAGS_REG))
3287 (clobber (match_operand:SI 2 "register_operand" ""))]
3288 "(reload_completed
3289 && dead_or_set_p (insn, operands[1])
3290 && !reg_mentioned_p (operands[1], operands[0]))"
3291 [(set (match_dup 3) (match_dup 1))
3292 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3293 (clobber (reg:CC FLAGS_REG))])
3294 (set (match_dup 4) (match_dup 1))]
3295 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3296
3297 ;; Extend to memory case when source register does not die.
3298 (define_split
3299 [(set (match_operand:DI 0 "memory_operand" "")
3300 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3301 (clobber (reg:CC FLAGS_REG))
3302 (clobber (match_operand:SI 2 "register_operand" ""))]
3303 "reload_completed"
3304 [(const_int 0)]
3305 {
3306 split_di (&operands[0], 1, &operands[3], &operands[4]);
3307
3308 emit_move_insn (operands[3], operands[1]);
3309
3310 /* Generate a cltd if possible and doing so it profitable. */
3311 if (true_regnum (operands[1]) == 0
3312 && true_regnum (operands[2]) == 1
3313 && (optimize_size || TARGET_USE_CLTD))
3314 {
3315 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3316 }
3317 else
3318 {
3319 emit_move_insn (operands[2], operands[1]);
3320 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3321 }
3322 emit_move_insn (operands[4], operands[2]);
3323 DONE;
3324 })
3325
3326 ;; Extend to register case. Optimize case where source and destination
3327 ;; registers match and cases where we can use cltd.
3328 (define_split
3329 [(set (match_operand:DI 0 "register_operand" "")
3330 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3331 (clobber (reg:CC FLAGS_REG))
3332 (clobber (match_scratch:SI 2 ""))]
3333 "reload_completed"
3334 [(const_int 0)]
3335 {
3336 split_di (&operands[0], 1, &operands[3], &operands[4]);
3337
3338 if (true_regnum (operands[3]) != true_regnum (operands[1]))
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[3]) == 0
3343 && (optimize_size || TARGET_USE_CLTD))
3344 {
3345 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3346 DONE;
3347 }
3348
3349 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3350 emit_move_insn (operands[4], operands[1]);
3351
3352 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3353 DONE;
3354 })
3355
3356 (define_insn "extendhisi2"
3357 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3358 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3359 ""
3360 {
3361 switch (get_attr_prefix_0f (insn))
3362 {
3363 case 0:
3364 return "{cwtl|cwde}";
3365 default:
3366 return "movs{wl|x}\t{%1,%0|%0, %1}";
3367 }
3368 }
3369 [(set_attr "type" "imovx")
3370 (set_attr "mode" "SI")
3371 (set (attr "prefix_0f")
3372 ;; movsx is short decodable while cwtl is vector decoded.
3373 (if_then_else (and (eq_attr "cpu" "!k6")
3374 (eq_attr "alternative" "0"))
3375 (const_string "0")
3376 (const_string "1")))
3377 (set (attr "modrm")
3378 (if_then_else (eq_attr "prefix_0f" "0")
3379 (const_string "0")
3380 (const_string "1")))])
3381
3382 (define_insn "*extendhisi2_zext"
3383 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3384 (zero_extend:DI
3385 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3386 "TARGET_64BIT"
3387 {
3388 switch (get_attr_prefix_0f (insn))
3389 {
3390 case 0:
3391 return "{cwtl|cwde}";
3392 default:
3393 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3394 }
3395 }
3396 [(set_attr "type" "imovx")
3397 (set_attr "mode" "SI")
3398 (set (attr "prefix_0f")
3399 ;; movsx is short decodable while cwtl is vector decoded.
3400 (if_then_else (and (eq_attr "cpu" "!k6")
3401 (eq_attr "alternative" "0"))
3402 (const_string "0")
3403 (const_string "1")))
3404 (set (attr "modrm")
3405 (if_then_else (eq_attr "prefix_0f" "0")
3406 (const_string "0")
3407 (const_string "1")))])
3408
3409 (define_insn "extendqihi2"
3410 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3411 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3412 ""
3413 {
3414 switch (get_attr_prefix_0f (insn))
3415 {
3416 case 0:
3417 return "{cbtw|cbw}";
3418 default:
3419 return "movs{bw|x}\t{%1,%0|%0, %1}";
3420 }
3421 }
3422 [(set_attr "type" "imovx")
3423 (set_attr "mode" "HI")
3424 (set (attr "prefix_0f")
3425 ;; movsx is short decodable while cwtl is vector decoded.
3426 (if_then_else (and (eq_attr "cpu" "!k6")
3427 (eq_attr "alternative" "0"))
3428 (const_string "0")
3429 (const_string "1")))
3430 (set (attr "modrm")
3431 (if_then_else (eq_attr "prefix_0f" "0")
3432 (const_string "0")
3433 (const_string "1")))])
3434
3435 (define_insn "extendqisi2"
3436 [(set (match_operand:SI 0 "register_operand" "=r")
3437 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3438 ""
3439 "movs{bl|x}\t{%1,%0|%0, %1}"
3440 [(set_attr "type" "imovx")
3441 (set_attr "mode" "SI")])
3442
3443 (define_insn "*extendqisi2_zext"
3444 [(set (match_operand:DI 0 "register_operand" "=r")
3445 (zero_extend:DI
3446 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3447 "TARGET_64BIT"
3448 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3449 [(set_attr "type" "imovx")
3450 (set_attr "mode" "SI")])
3451 \f
3452 ;; Conversions between float and double.
3453
3454 ;; These are all no-ops in the model used for the 80387. So just
3455 ;; emit moves.
3456
3457 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3458 (define_insn "*dummy_extendsfdf2"
3459 [(set (match_operand:DF 0 "push_operand" "=<")
3460 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3461 "0"
3462 "#")
3463
3464 (define_split
3465 [(set (match_operand:DF 0 "push_operand" "")
3466 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3467 "!TARGET_64BIT"
3468 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3469 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3470
3471 (define_split
3472 [(set (match_operand:DF 0 "push_operand" "")
3473 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3474 "TARGET_64BIT"
3475 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3476 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3477
3478 (define_insn "*dummy_extendsfxf2"
3479 [(set (match_operand:XF 0 "push_operand" "=<")
3480 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3481 "0"
3482 "#")
3483
3484 (define_split
3485 [(set (match_operand:XF 0 "push_operand" "")
3486 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3487 ""
3488 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3489 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3490 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3491
3492 (define_split
3493 [(set (match_operand:XF 0 "push_operand" "")
3494 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3495 "TARGET_64BIT"
3496 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3497 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3498 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3499
3500 (define_split
3501 [(set (match_operand:XF 0 "push_operand" "")
3502 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3503 ""
3504 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3505 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3506 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3507
3508 (define_split
3509 [(set (match_operand:XF 0 "push_operand" "")
3510 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3511 "TARGET_64BIT"
3512 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3513 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3514 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3515
3516 (define_expand "extendsfdf2"
3517 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3518 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3519 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3520 {
3521 /* ??? Needed for compress_float_constant since all fp constants
3522 are LEGITIMATE_CONSTANT_P. */
3523 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3524 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3525 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3526 operands[1] = force_reg (SFmode, operands[1]);
3527 })
3528
3529 (define_insn "*extendsfdf2_mixed"
3530 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3531 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3532 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3533 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3534 {
3535 switch (which_alternative)
3536 {
3537 case 0:
3538 return output_387_reg_move (insn, operands);
3539
3540 case 1:
3541 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3542 return "fstp%z0\t%y0";
3543 else
3544 return "fst%z0\t%y0";
3545
3546 case 2:
3547 return "cvtss2sd\t{%1, %0|%0, %1}";
3548
3549 default:
3550 gcc_unreachable ();
3551 }
3552 }
3553 [(set_attr "type" "fmov,fmov,ssecvt")
3554 (set_attr "mode" "SF,XF,DF")])
3555
3556 (define_insn "*extendsfdf2_sse"
3557 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3558 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3559 "TARGET_SSE2 && TARGET_SSE_MATH
3560 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3561 "cvtss2sd\t{%1, %0|%0, %1}"
3562 [(set_attr "type" "ssecvt")
3563 (set_attr "mode" "DF")])
3564
3565 (define_insn "*extendsfdf2_i387"
3566 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3567 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3568 "TARGET_80387
3569 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3570 {
3571 switch (which_alternative)
3572 {
3573 case 0:
3574 return output_387_reg_move (insn, operands);
3575
3576 case 1:
3577 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3578 return "fstp%z0\t%y0";
3579 else
3580 return "fst%z0\t%y0";
3581
3582 default:
3583 gcc_unreachable ();
3584 }
3585 }
3586 [(set_attr "type" "fmov")
3587 (set_attr "mode" "SF,XF")])
3588
3589 (define_expand "extendsfxf2"
3590 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3591 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3592 "TARGET_80387"
3593 {
3594 /* ??? Needed for compress_float_constant since all fp constants
3595 are LEGITIMATE_CONSTANT_P. */
3596 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3597 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3598 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3599 operands[1] = force_reg (SFmode, operands[1]);
3600 })
3601
3602 (define_insn "*extendsfxf2_i387"
3603 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3604 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3605 "TARGET_80387
3606 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3607 {
3608 switch (which_alternative)
3609 {
3610 case 0:
3611 return output_387_reg_move (insn, operands);
3612
3613 case 1:
3614 /* There is no non-popping store to memory for XFmode. So if
3615 we need one, follow the store with a load. */
3616 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3617 return "fstp%z0\t%y0";
3618 else
3619 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3620
3621 default:
3622 gcc_unreachable ();
3623 }
3624 }
3625 [(set_attr "type" "fmov")
3626 (set_attr "mode" "SF,XF")])
3627
3628 (define_expand "extenddfxf2"
3629 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3630 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3631 "TARGET_80387"
3632 {
3633 /* ??? Needed for compress_float_constant since all fp constants
3634 are LEGITIMATE_CONSTANT_P. */
3635 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3636 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3637 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3638 operands[1] = force_reg (DFmode, operands[1]);
3639 })
3640
3641 (define_insn "*extenddfxf2_i387"
3642 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3643 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3644 "TARGET_80387
3645 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3646 {
3647 switch (which_alternative)
3648 {
3649 case 0:
3650 return output_387_reg_move (insn, operands);
3651
3652 case 1:
3653 /* There is no non-popping store to memory for XFmode. So if
3654 we need one, follow the store with a load. */
3655 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3656 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3657 else
3658 return "fstp%z0\t%y0";
3659
3660 default:
3661 gcc_unreachable ();
3662 }
3663 }
3664 [(set_attr "type" "fmov")
3665 (set_attr "mode" "DF,XF")])
3666
3667 ;; %%% This seems bad bad news.
3668 ;; This cannot output into an f-reg because there is no way to be sure
3669 ;; of truncating in that case. Otherwise this is just like a simple move
3670 ;; insn. So we pretend we can output to a reg in order to get better
3671 ;; register preferencing, but we really use a stack slot.
3672
3673 ;; Conversion from DFmode to SFmode.
3674
3675 (define_expand "truncdfsf2"
3676 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3677 (float_truncate:SF
3678 (match_operand:DF 1 "nonimmediate_operand" "")))]
3679 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3680 {
3681 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3682 operands[1] = force_reg (DFmode, operands[1]);
3683
3684 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3685 ;
3686 else if (flag_unsafe_math_optimizations)
3687 ;
3688 else
3689 {
3690 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3691 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3692 DONE;
3693 }
3694 })
3695
3696 (define_expand "truncdfsf2_with_temp"
3697 [(parallel [(set (match_operand:SF 0 "" "")
3698 (float_truncate:SF (match_operand:DF 1 "" "")))
3699 (clobber (match_operand:SF 2 "" ""))])]
3700 "")
3701
3702 (define_insn "*truncdfsf_fast_mixed"
3703 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3704 (float_truncate:SF
3705 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3706 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3707 {
3708 switch (which_alternative)
3709 {
3710 case 0:
3711 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712 return "fstp%z0\t%y0";
3713 else
3714 return "fst%z0\t%y0";
3715 case 1:
3716 return output_387_reg_move (insn, operands);
3717 case 2:
3718 return "cvtsd2ss\t{%1, %0|%0, %1}";
3719 default:
3720 gcc_unreachable ();
3721 }
3722 }
3723 [(set_attr "type" "fmov,fmov,ssecvt")
3724 (set_attr "mode" "SF")])
3725
3726 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3727 ;; because nothing we do here is unsafe.
3728 (define_insn "*truncdfsf_fast_sse"
3729 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3730 (float_truncate:SF
3731 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3732 "TARGET_SSE2 && TARGET_SSE_MATH"
3733 "cvtsd2ss\t{%1, %0|%0, %1}"
3734 [(set_attr "type" "ssecvt")
3735 (set_attr "mode" "SF")])
3736
3737 (define_insn "*truncdfsf_fast_i387"
3738 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3739 (float_truncate:SF
3740 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3741 "TARGET_80387 && flag_unsafe_math_optimizations"
3742 "* return output_387_reg_move (insn, operands);"
3743 [(set_attr "type" "fmov")
3744 (set_attr "mode" "SF")])
3745
3746 (define_insn "*truncdfsf_mixed"
3747 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3748 (float_truncate:SF
3749 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3750 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3751 "TARGET_MIX_SSE_I387"
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 "#";
3762 case 2:
3763 return "cvtsd2ss\t{%1, %0|%0, %1}";
3764 default:
3765 gcc_unreachable ();
3766 }
3767 }
3768 [(set_attr "type" "fmov,multi,ssecvt")
3769 (set_attr "unit" "*,i387,*")
3770 (set_attr "mode" "SF")])
3771
3772 (define_insn "*truncdfsf_i387"
3773 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3774 (float_truncate:SF
3775 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3776 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3777 "TARGET_80387"
3778 {
3779 switch (which_alternative)
3780 {
3781 case 0:
3782 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3783 return "fstp%z0\t%y0";
3784 else
3785 return "fst%z0\t%y0";
3786 case 1:
3787 return "#";
3788 default:
3789 gcc_unreachable ();
3790 }
3791 }
3792 [(set_attr "type" "fmov,multi")
3793 (set_attr "unit" "*,i387")
3794 (set_attr "mode" "SF")])
3795
3796 (define_insn "*truncdfsf2_i387_1"
3797 [(set (match_operand:SF 0 "memory_operand" "=m")
3798 (float_truncate:SF
3799 (match_operand:DF 1 "register_operand" "f")))]
3800 "TARGET_80387
3801 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3802 && !TARGET_MIX_SSE_I387"
3803 {
3804 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3805 return "fstp%z0\t%y0";
3806 else
3807 return "fst%z0\t%y0";
3808 }
3809 [(set_attr "type" "fmov")
3810 (set_attr "mode" "SF")])
3811
3812 (define_split
3813 [(set (match_operand:SF 0 "register_operand" "")
3814 (float_truncate:SF
3815 (match_operand:DF 1 "fp_register_operand" "")))
3816 (clobber (match_operand 2 "" ""))]
3817 "reload_completed"
3818 [(set (match_dup 2) (match_dup 1))
3819 (set (match_dup 0) (match_dup 2))]
3820 {
3821 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3822 })
3823
3824 ;; Conversion from XFmode to SFmode.
3825
3826 (define_expand "truncxfsf2"
3827 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3828 (float_truncate:SF
3829 (match_operand:XF 1 "register_operand" "")))
3830 (clobber (match_dup 2))])]
3831 "TARGET_80387"
3832 {
3833 if (flag_unsafe_math_optimizations)
3834 {
3835 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3836 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3837 if (reg != operands[0])
3838 emit_move_insn (operands[0], reg);
3839 DONE;
3840 }
3841 else
3842 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3843 })
3844
3845 (define_insn "*truncxfsf2_mixed"
3846 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3847 (float_truncate:SF
3848 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3849 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3850 "TARGET_MIX_SSE_I387"
3851 {
3852 gcc_assert (!which_alternative);
3853 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3854 return "fstp%z0\t%y0";
3855 else
3856 return "fst%z0\t%y0";
3857 }
3858 [(set_attr "type" "fmov,multi,multi,multi")
3859 (set_attr "unit" "*,i387,i387,i387")
3860 (set_attr "mode" "SF")])
3861
3862 (define_insn "truncxfsf2_i387_noop"
3863 [(set (match_operand:SF 0 "register_operand" "=f")
3864 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3865 "TARGET_80387 && flag_unsafe_math_optimizations"
3866 {
3867 return output_387_reg_move (insn, operands);
3868 }
3869 [(set_attr "type" "fmov")
3870 (set_attr "mode" "SF")])
3871
3872 (define_insn "*truncxfsf2_i387"
3873 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3874 (float_truncate:SF
3875 (match_operand:XF 1 "register_operand" "f,f,f")))
3876 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3877 "TARGET_80387"
3878 {
3879 gcc_assert (!which_alternative);
3880 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3881 return "fstp%z0\t%y0";
3882 else
3883 return "fst%z0\t%y0";
3884 }
3885 [(set_attr "type" "fmov,multi,multi")
3886 (set_attr "unit" "*,i387,i387")
3887 (set_attr "mode" "SF")])
3888
3889 (define_insn "*truncxfsf2_i387_1"
3890 [(set (match_operand:SF 0 "memory_operand" "=m")
3891 (float_truncate:SF
3892 (match_operand:XF 1 "register_operand" "f")))]
3893 "TARGET_80387"
3894 {
3895 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3896 return "fstp%z0\t%y0";
3897 else
3898 return "fst%z0\t%y0";
3899 }
3900 [(set_attr "type" "fmov")
3901 (set_attr "mode" "SF")])
3902
3903 (define_split
3904 [(set (match_operand:SF 0 "register_operand" "")
3905 (float_truncate:SF
3906 (match_operand:XF 1 "register_operand" "")))
3907 (clobber (match_operand:SF 2 "memory_operand" ""))]
3908 "TARGET_80387 && reload_completed"
3909 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3910 (set (match_dup 0) (match_dup 2))]
3911 "")
3912
3913 (define_split
3914 [(set (match_operand:SF 0 "memory_operand" "")
3915 (float_truncate:SF
3916 (match_operand:XF 1 "register_operand" "")))
3917 (clobber (match_operand:SF 2 "memory_operand" ""))]
3918 "TARGET_80387"
3919 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3920 "")
3921
3922 ;; Conversion from XFmode to DFmode.
3923
3924 (define_expand "truncxfdf2"
3925 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3926 (float_truncate:DF
3927 (match_operand:XF 1 "register_operand" "")))
3928 (clobber (match_dup 2))])]
3929 "TARGET_80387"
3930 {
3931 if (flag_unsafe_math_optimizations)
3932 {
3933 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3934 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3935 if (reg != operands[0])
3936 emit_move_insn (operands[0], reg);
3937 DONE;
3938 }
3939 else
3940 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3941 })
3942
3943 (define_insn "*truncxfdf2_mixed"
3944 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3945 (float_truncate:DF
3946 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3947 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3948 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3949 {
3950 gcc_assert (!which_alternative);
3951 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3952 return "fstp%z0\t%y0";
3953 else
3954 return "fst%z0\t%y0";
3955 }
3956 [(set_attr "type" "fmov,multi,multi,multi")
3957 (set_attr "unit" "*,i387,i387,i387")
3958 (set_attr "mode" "DF")])
3959
3960 (define_insn "truncxfdf2_i387_noop"
3961 [(set (match_operand:DF 0 "register_operand" "=f")
3962 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3963 "TARGET_80387 && flag_unsafe_math_optimizations"
3964 {
3965 return output_387_reg_move (insn, operands);
3966 }
3967 [(set_attr "type" "fmov")
3968 (set_attr "mode" "DF")])
3969
3970 (define_insn "*truncxfdf2_i387"
3971 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3972 (float_truncate:DF
3973 (match_operand:XF 1 "register_operand" "f,f,f")))
3974 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3975 "TARGET_80387"
3976 {
3977 gcc_assert (!which_alternative);
3978 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3979 return "fstp%z0\t%y0";
3980 else
3981 return "fst%z0\t%y0";
3982 }
3983 [(set_attr "type" "fmov,multi,multi")
3984 (set_attr "unit" "*,i387,i387")
3985 (set_attr "mode" "DF")])
3986
3987 (define_insn "*truncxfdf2_i387_1"
3988 [(set (match_operand:DF 0 "memory_operand" "=m")
3989 (float_truncate:DF
3990 (match_operand:XF 1 "register_operand" "f")))]
3991 "TARGET_80387"
3992 {
3993 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3994 return "fstp%z0\t%y0";
3995 else
3996 return "fst%z0\t%y0";
3997 }
3998 [(set_attr "type" "fmov")
3999 (set_attr "mode" "DF")])
4000
4001 (define_split
4002 [(set (match_operand:DF 0 "register_operand" "")
4003 (float_truncate:DF
4004 (match_operand:XF 1 "register_operand" "")))
4005 (clobber (match_operand:DF 2 "memory_operand" ""))]
4006 "TARGET_80387 && reload_completed"
4007 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4008 (set (match_dup 0) (match_dup 2))]
4009 "")
4010
4011 (define_split
4012 [(set (match_operand:DF 0 "memory_operand" "")
4013 (float_truncate:DF
4014 (match_operand:XF 1 "register_operand" "")))
4015 (clobber (match_operand:DF 2 "memory_operand" ""))]
4016 "TARGET_80387"
4017 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4018 "")
4019 \f
4020 ;; Signed conversion to DImode.
4021
4022 (define_expand "fix_truncxfdi2"
4023 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4024 (fix:DI (match_operand:XF 1 "register_operand" "")))
4025 (clobber (reg:CC FLAGS_REG))])]
4026 "TARGET_80387"
4027 {
4028 if (TARGET_FISTTP)
4029 {
4030 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4031 DONE;
4032 }
4033 })
4034
4035 (define_expand "fix_trunc<mode>di2"
4036 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4037 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4038 (clobber (reg:CC FLAGS_REG))])]
4039 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4040 {
4041 if (TARGET_FISTTP
4042 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4043 {
4044 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4045 DONE;
4046 }
4047 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4048 {
4049 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4050 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4051 if (out != operands[0])
4052 emit_move_insn (operands[0], out);
4053 DONE;
4054 }
4055 })
4056
4057 ;; Signed conversion to SImode.
4058
4059 (define_expand "fix_truncxfsi2"
4060 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4061 (fix:SI (match_operand:XF 1 "register_operand" "")))
4062 (clobber (reg:CC FLAGS_REG))])]
4063 "TARGET_80387"
4064 {
4065 if (TARGET_FISTTP)
4066 {
4067 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4068 DONE;
4069 }
4070 })
4071
4072 (define_expand "fix_trunc<mode>si2"
4073 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4074 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4075 (clobber (reg:CC FLAGS_REG))])]
4076 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4077 {
4078 if (TARGET_FISTTP
4079 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4080 {
4081 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4082 DONE;
4083 }
4084 if (SSE_FLOAT_MODE_P (<MODE>mode))
4085 {
4086 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4087 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4088 if (out != operands[0])
4089 emit_move_insn (operands[0], out);
4090 DONE;
4091 }
4092 })
4093
4094 ;; Signed conversion to HImode.
4095
4096 (define_expand "fix_trunc<mode>hi2"
4097 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4098 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4099 (clobber (reg:CC FLAGS_REG))])]
4100 "TARGET_80387
4101 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4102 {
4103 if (TARGET_FISTTP)
4104 {
4105 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4106 DONE;
4107 }
4108 })
4109
4110 ;; When SSE is available, it is always faster to use it!
4111 (define_insn "fix_truncsfdi_sse"
4112 [(set (match_operand:DI 0 "register_operand" "=r,r")
4113 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4114 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4115 "cvttss2si{q}\t{%1, %0|%0, %1}"
4116 [(set_attr "type" "sseicvt")
4117 (set_attr "mode" "SF")
4118 (set_attr "athlon_decode" "double,vector")])
4119
4120 (define_insn "fix_truncdfdi_sse"
4121 [(set (match_operand:DI 0 "register_operand" "=r,r")
4122 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4123 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4124 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4125 [(set_attr "type" "sseicvt")
4126 (set_attr "mode" "DF")
4127 (set_attr "athlon_decode" "double,vector")])
4128
4129 (define_insn "fix_truncsfsi_sse"
4130 [(set (match_operand:SI 0 "register_operand" "=r,r")
4131 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4132 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4133 "cvttss2si\t{%1, %0|%0, %1}"
4134 [(set_attr "type" "sseicvt")
4135 (set_attr "mode" "DF")
4136 (set_attr "athlon_decode" "double,vector")])
4137
4138 (define_insn "fix_truncdfsi_sse"
4139 [(set (match_operand:SI 0 "register_operand" "=r,r")
4140 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4141 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4142 "cvttsd2si\t{%1, %0|%0, %1}"
4143 [(set_attr "type" "sseicvt")
4144 (set_attr "mode" "DF")
4145 (set_attr "athlon_decode" "double,vector")])
4146
4147 ;; Avoid vector decoded forms of the instruction.
4148 (define_peephole2
4149 [(match_scratch:DF 2 "Y")
4150 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4151 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4152 "TARGET_K8 && !optimize_size"
4153 [(set (match_dup 2) (match_dup 1))
4154 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4155 "")
4156
4157 (define_peephole2
4158 [(match_scratch:SF 2 "x")
4159 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4160 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4161 "TARGET_K8 && !optimize_size"
4162 [(set (match_dup 2) (match_dup 1))
4163 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4164 "")
4165
4166 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4167 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4168 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4169 "TARGET_80387 && TARGET_FISTTP
4170 && FLOAT_MODE_P (GET_MODE (operands[1]))
4171 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4172 && (TARGET_64BIT || <MODE>mode != DImode))
4173 && TARGET_SSE_MATH)
4174 && !(reload_completed || reload_in_progress)"
4175 "#"
4176 "&& 1"
4177 [(const_int 0)]
4178 {
4179 if (memory_operand (operands[0], VOIDmode))
4180 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4181 else
4182 {
4183 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4184 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4185 operands[1],
4186 operands[2]));
4187 }
4188 DONE;
4189 }
4190 [(set_attr "type" "fisttp")
4191 (set_attr "mode" "<MODE>")])
4192
4193 (define_insn "fix_trunc<mode>_i387_fisttp"
4194 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4195 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4196 (clobber (match_scratch:XF 2 "=&1f"))]
4197 "TARGET_80387 && TARGET_FISTTP
4198 && FLOAT_MODE_P (GET_MODE (operands[1]))
4199 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4200 && (TARGET_64BIT || <MODE>mode != DImode))
4201 && TARGET_SSE_MATH)"
4202 "* return output_fix_trunc (insn, operands, 1);"
4203 [(set_attr "type" "fisttp")
4204 (set_attr "mode" "<MODE>")])
4205
4206 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4207 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4208 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4209 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4210 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4211 "TARGET_80387 && TARGET_FISTTP
4212 && FLOAT_MODE_P (GET_MODE (operands[1]))
4213 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4214 && (TARGET_64BIT || <MODE>mode != DImode))
4215 && TARGET_SSE_MATH)"
4216 "#"
4217 [(set_attr "type" "fisttp")
4218 (set_attr "mode" "<MODE>")])
4219
4220 (define_split
4221 [(set (match_operand:X87MODEI 0 "register_operand" "")
4222 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4223 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4224 (clobber (match_scratch 3 ""))]
4225 "reload_completed"
4226 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4227 (clobber (match_dup 3))])
4228 (set (match_dup 0) (match_dup 2))]
4229 "")
4230
4231 (define_split
4232 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4233 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4234 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4235 (clobber (match_scratch 3 ""))]
4236 "reload_completed"
4237 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4238 (clobber (match_dup 3))])]
4239 "")
4240
4241 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4242 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4243 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4244 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4245 ;; function in i386.c.
4246 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4247 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4248 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4249 (clobber (reg:CC FLAGS_REG))]
4250 "TARGET_80387 && !TARGET_FISTTP
4251 && FLOAT_MODE_P (GET_MODE (operands[1]))
4252 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4253 && (TARGET_64BIT || <MODE>mode != DImode))
4254 && !(reload_completed || reload_in_progress)"
4255 "#"
4256 "&& 1"
4257 [(const_int 0)]
4258 {
4259 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4260
4261 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4262 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4263 if (memory_operand (operands[0], VOIDmode))
4264 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4265 operands[2], operands[3]));
4266 else
4267 {
4268 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4269 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4270 operands[2], operands[3],
4271 operands[4]));
4272 }
4273 DONE;
4274 }
4275 [(set_attr "type" "fistp")
4276 (set_attr "i387_cw" "trunc")
4277 (set_attr "mode" "<MODE>")])
4278
4279 (define_insn "fix_truncdi_i387"
4280 [(set (match_operand:DI 0 "memory_operand" "=m")
4281 (fix:DI (match_operand 1 "register_operand" "f")))
4282 (use (match_operand:HI 2 "memory_operand" "m"))
4283 (use (match_operand:HI 3 "memory_operand" "m"))
4284 (clobber (match_scratch:XF 4 "=&1f"))]
4285 "TARGET_80387 && !TARGET_FISTTP
4286 && FLOAT_MODE_P (GET_MODE (operands[1]))
4287 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4288 "* return output_fix_trunc (insn, operands, 0);"
4289 [(set_attr "type" "fistp")
4290 (set_attr "i387_cw" "trunc")
4291 (set_attr "mode" "DI")])
4292
4293 (define_insn "fix_truncdi_i387_with_temp"
4294 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4295 (fix:DI (match_operand 1 "register_operand" "f,f")))
4296 (use (match_operand:HI 2 "memory_operand" "m,m"))
4297 (use (match_operand:HI 3 "memory_operand" "m,m"))
4298 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4299 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4300 "TARGET_80387 && !TARGET_FISTTP
4301 && FLOAT_MODE_P (GET_MODE (operands[1]))
4302 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4303 "#"
4304 [(set_attr "type" "fistp")
4305 (set_attr "i387_cw" "trunc")
4306 (set_attr "mode" "DI")])
4307
4308 (define_split
4309 [(set (match_operand:DI 0 "register_operand" "")
4310 (fix:DI (match_operand 1 "register_operand" "")))
4311 (use (match_operand:HI 2 "memory_operand" ""))
4312 (use (match_operand:HI 3 "memory_operand" ""))
4313 (clobber (match_operand:DI 4 "memory_operand" ""))
4314 (clobber (match_scratch 5 ""))]
4315 "reload_completed"
4316 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4317 (use (match_dup 2))
4318 (use (match_dup 3))
4319 (clobber (match_dup 5))])
4320 (set (match_dup 0) (match_dup 4))]
4321 "")
4322
4323 (define_split
4324 [(set (match_operand:DI 0 "memory_operand" "")
4325 (fix:DI (match_operand 1 "register_operand" "")))
4326 (use (match_operand:HI 2 "memory_operand" ""))
4327 (use (match_operand:HI 3 "memory_operand" ""))
4328 (clobber (match_operand:DI 4 "memory_operand" ""))
4329 (clobber (match_scratch 5 ""))]
4330 "reload_completed"
4331 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4332 (use (match_dup 2))
4333 (use (match_dup 3))
4334 (clobber (match_dup 5))])]
4335 "")
4336
4337 (define_insn "fix_trunc<mode>_i387"
4338 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4339 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4340 (use (match_operand:HI 2 "memory_operand" "m"))
4341 (use (match_operand:HI 3 "memory_operand" "m"))]
4342 "TARGET_80387 && !TARGET_FISTTP
4343 && FLOAT_MODE_P (GET_MODE (operands[1]))
4344 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4345 "* return output_fix_trunc (insn, operands, 0);"
4346 [(set_attr "type" "fistp")
4347 (set_attr "i387_cw" "trunc")
4348 (set_attr "mode" "<MODE>")])
4349
4350 (define_insn "fix_trunc<mode>_i387_with_temp"
4351 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4352 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4353 (use (match_operand:HI 2 "memory_operand" "m,m"))
4354 (use (match_operand:HI 3 "memory_operand" "m,m"))
4355 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4356 "TARGET_80387 && !TARGET_FISTTP
4357 && FLOAT_MODE_P (GET_MODE (operands[1]))
4358 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4359 "#"
4360 [(set_attr "type" "fistp")
4361 (set_attr "i387_cw" "trunc")
4362 (set_attr "mode" "<MODE>")])
4363
4364 (define_split
4365 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4366 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4367 (use (match_operand:HI 2 "memory_operand" ""))
4368 (use (match_operand:HI 3 "memory_operand" ""))
4369 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4370 "reload_completed"
4371 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4372 (use (match_dup 2))
4373 (use (match_dup 3))])
4374 (set (match_dup 0) (match_dup 4))]
4375 "")
4376
4377 (define_split
4378 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4379 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4380 (use (match_operand:HI 2 "memory_operand" ""))
4381 (use (match_operand:HI 3 "memory_operand" ""))
4382 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4383 "reload_completed"
4384 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4385 (use (match_dup 2))
4386 (use (match_dup 3))])]
4387 "")
4388
4389 (define_insn "x86_fnstcw_1"
4390 [(set (match_operand:HI 0 "memory_operand" "=m")
4391 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4392 "TARGET_80387"
4393 "fnstcw\t%0"
4394 [(set_attr "length" "2")
4395 (set_attr "mode" "HI")
4396 (set_attr "unit" "i387")])
4397
4398 (define_insn "x86_fldcw_1"
4399 [(set (reg:HI FPSR_REG)
4400 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4401 "TARGET_80387"
4402 "fldcw\t%0"
4403 [(set_attr "length" "2")
4404 (set_attr "mode" "HI")
4405 (set_attr "unit" "i387")
4406 (set_attr "athlon_decode" "vector")])
4407 \f
4408 ;; Conversion between fixed point and floating point.
4409
4410 ;; Even though we only accept memory inputs, the backend _really_
4411 ;; wants to be able to do this between registers.
4412
4413 (define_expand "floathisf2"
4414 [(set (match_operand:SF 0 "register_operand" "")
4415 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4416 "TARGET_80387 || TARGET_SSE_MATH"
4417 {
4418 if (TARGET_SSE_MATH)
4419 {
4420 emit_insn (gen_floatsisf2 (operands[0],
4421 convert_to_mode (SImode, operands[1], 0)));
4422 DONE;
4423 }
4424 })
4425
4426 (define_insn "*floathisf2_i387"
4427 [(set (match_operand:SF 0 "register_operand" "=f,f")
4428 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4429 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4430 "@
4431 fild%z1\t%1
4432 #"
4433 [(set_attr "type" "fmov,multi")
4434 (set_attr "mode" "SF")
4435 (set_attr "unit" "*,i387")
4436 (set_attr "fp_int_src" "true")])
4437
4438 (define_expand "floatsisf2"
4439 [(set (match_operand:SF 0 "register_operand" "")
4440 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4441 "TARGET_80387 || TARGET_SSE_MATH"
4442 "")
4443
4444 (define_insn "*floatsisf2_mixed"
4445 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4446 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4447 "TARGET_MIX_SSE_I387"
4448 "@
4449 fild%z1\t%1
4450 #
4451 cvtsi2ss\t{%1, %0|%0, %1}
4452 cvtsi2ss\t{%1, %0|%0, %1}"
4453 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4454 (set_attr "mode" "SF")
4455 (set_attr "unit" "*,i387,*,*")
4456 (set_attr "athlon_decode" "*,*,vector,double")
4457 (set_attr "fp_int_src" "true")])
4458
4459 (define_insn "*floatsisf2_sse"
4460 [(set (match_operand:SF 0 "register_operand" "=x,x")
4461 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4462 "TARGET_SSE_MATH"
4463 "cvtsi2ss\t{%1, %0|%0, %1}"
4464 [(set_attr "type" "sseicvt")
4465 (set_attr "mode" "SF")
4466 (set_attr "athlon_decode" "vector,double")
4467 (set_attr "fp_int_src" "true")])
4468
4469 (define_insn "*floatsisf2_i387"
4470 [(set (match_operand:SF 0 "register_operand" "=f,f")
4471 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4472 "TARGET_80387"
4473 "@
4474 fild%z1\t%1
4475 #"
4476 [(set_attr "type" "fmov,multi")
4477 (set_attr "mode" "SF")
4478 (set_attr "unit" "*,i387")
4479 (set_attr "fp_int_src" "true")])
4480
4481 (define_expand "floatdisf2"
4482 [(set (match_operand:SF 0 "register_operand" "")
4483 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4484 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4485 "")
4486
4487 (define_insn "*floatdisf2_mixed"
4488 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4489 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4490 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4491 "@
4492 fild%z1\t%1
4493 #
4494 cvtsi2ss{q}\t{%1, %0|%0, %1}
4495 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4496 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4497 (set_attr "mode" "SF")
4498 (set_attr "unit" "*,i387,*,*")
4499 (set_attr "athlon_decode" "*,*,vector,double")
4500 (set_attr "fp_int_src" "true")])
4501
4502 (define_insn "*floatdisf2_sse"
4503 [(set (match_operand:SF 0 "register_operand" "=x,x")
4504 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4505 "TARGET_64BIT && TARGET_SSE_MATH"
4506 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4507 [(set_attr "type" "sseicvt")
4508 (set_attr "mode" "SF")
4509 (set_attr "athlon_decode" "vector,double")
4510 (set_attr "fp_int_src" "true")])
4511
4512 (define_insn "*floatdisf2_i387"
4513 [(set (match_operand:SF 0 "register_operand" "=f,f")
4514 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4515 "TARGET_80387"
4516 "@
4517 fild%z1\t%1
4518 #"
4519 [(set_attr "type" "fmov,multi")
4520 (set_attr "mode" "SF")
4521 (set_attr "unit" "*,i387")
4522 (set_attr "fp_int_src" "true")])
4523
4524 (define_expand "floathidf2"
4525 [(set (match_operand:DF 0 "register_operand" "")
4526 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4527 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4528 {
4529 if (TARGET_SSE2 && TARGET_SSE_MATH)
4530 {
4531 emit_insn (gen_floatsidf2 (operands[0],
4532 convert_to_mode (SImode, operands[1], 0)));
4533 DONE;
4534 }
4535 })
4536
4537 (define_insn "*floathidf2_i387"
4538 [(set (match_operand:DF 0 "register_operand" "=f,f")
4539 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4540 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4541 "@
4542 fild%z1\t%1
4543 #"
4544 [(set_attr "type" "fmov,multi")
4545 (set_attr "mode" "DF")
4546 (set_attr "unit" "*,i387")
4547 (set_attr "fp_int_src" "true")])
4548
4549 (define_expand "floatsidf2"
4550 [(set (match_operand:DF 0 "register_operand" "")
4551 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4552 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4553 "")
4554
4555 (define_insn "*floatsidf2_mixed"
4556 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4557 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4558 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4559 "@
4560 fild%z1\t%1
4561 #
4562 cvtsi2sd\t{%1, %0|%0, %1}
4563 cvtsi2sd\t{%1, %0|%0, %1}"
4564 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4565 (set_attr "mode" "DF")
4566 (set_attr "unit" "*,i387,*,*")
4567 (set_attr "athlon_decode" "*,*,double,direct")
4568 (set_attr "fp_int_src" "true")])
4569
4570 (define_insn "*floatsidf2_sse"
4571 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4572 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4573 "TARGET_SSE2 && TARGET_SSE_MATH"
4574 "cvtsi2sd\t{%1, %0|%0, %1}"
4575 [(set_attr "type" "sseicvt")
4576 (set_attr "mode" "DF")
4577 (set_attr "athlon_decode" "double,direct")
4578 (set_attr "fp_int_src" "true")])
4579
4580 (define_insn "*floatsidf2_i387"
4581 [(set (match_operand:DF 0 "register_operand" "=f,f")
4582 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4583 "TARGET_80387"
4584 "@
4585 fild%z1\t%1
4586 #"
4587 [(set_attr "type" "fmov,multi")
4588 (set_attr "mode" "DF")
4589 (set_attr "unit" "*,i387")
4590 (set_attr "fp_int_src" "true")])
4591
4592 (define_expand "floatdidf2"
4593 [(set (match_operand:DF 0 "register_operand" "")
4594 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4595 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4596 "")
4597
4598 (define_insn "*floatdidf2_mixed"
4599 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4600 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4601 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4602 "@
4603 fild%z1\t%1
4604 #
4605 cvtsi2sd{q}\t{%1, %0|%0, %1}
4606 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4607 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4608 (set_attr "mode" "DF")
4609 (set_attr "unit" "*,i387,*,*")
4610 (set_attr "athlon_decode" "*,*,double,direct")
4611 (set_attr "fp_int_src" "true")])
4612
4613 (define_insn "*floatdidf2_sse"
4614 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4615 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4616 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4617 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4618 [(set_attr "type" "sseicvt")
4619 (set_attr "mode" "DF")
4620 (set_attr "athlon_decode" "double,direct")
4621 (set_attr "fp_int_src" "true")])
4622
4623 (define_insn "*floatdidf2_i387"
4624 [(set (match_operand:DF 0 "register_operand" "=f,f")
4625 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4626 "TARGET_80387"
4627 "@
4628 fild%z1\t%1
4629 #"
4630 [(set_attr "type" "fmov,multi")
4631 (set_attr "mode" "DF")
4632 (set_attr "unit" "*,i387")
4633 (set_attr "fp_int_src" "true")])
4634
4635 (define_insn "floathixf2"
4636 [(set (match_operand:XF 0 "register_operand" "=f,f")
4637 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4638 "TARGET_80387"
4639 "@
4640 fild%z1\t%1
4641 #"
4642 [(set_attr "type" "fmov,multi")
4643 (set_attr "mode" "XF")
4644 (set_attr "unit" "*,i387")
4645 (set_attr "fp_int_src" "true")])
4646
4647 (define_insn "floatsixf2"
4648 [(set (match_operand:XF 0 "register_operand" "=f,f")
4649 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4650 "TARGET_80387"
4651 "@
4652 fild%z1\t%1
4653 #"
4654 [(set_attr "type" "fmov,multi")
4655 (set_attr "mode" "XF")
4656 (set_attr "unit" "*,i387")
4657 (set_attr "fp_int_src" "true")])
4658
4659 (define_insn "floatdixf2"
4660 [(set (match_operand:XF 0 "register_operand" "=f,f")
4661 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4662 "TARGET_80387"
4663 "@
4664 fild%z1\t%1
4665 #"
4666 [(set_attr "type" "fmov,multi")
4667 (set_attr "mode" "XF")
4668 (set_attr "unit" "*,i387")
4669 (set_attr "fp_int_src" "true")])
4670
4671 ;; %%% Kill these when reload knows how to do it.
4672 (define_split
4673 [(set (match_operand 0 "fp_register_operand" "")
4674 (float (match_operand 1 "register_operand" "")))]
4675 "reload_completed
4676 && TARGET_80387
4677 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4678 [(const_int 0)]
4679 {
4680 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4681 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4682 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4683 ix86_free_from_memory (GET_MODE (operands[1]));
4684 DONE;
4685 })
4686
4687 (define_expand "floatunssisf2"
4688 [(use (match_operand:SF 0 "register_operand" ""))
4689 (use (match_operand:SI 1 "register_operand" ""))]
4690 "!TARGET_64BIT && TARGET_SSE_MATH"
4691 "x86_emit_floatuns (operands); DONE;")
4692
4693 (define_expand "floatunsdisf2"
4694 [(use (match_operand:SF 0 "register_operand" ""))
4695 (use (match_operand:DI 1 "register_operand" ""))]
4696 "TARGET_64BIT && TARGET_SSE_MATH"
4697 "x86_emit_floatuns (operands); DONE;")
4698
4699 (define_expand "floatunsdidf2"
4700 [(use (match_operand:DF 0 "register_operand" ""))
4701 (use (match_operand:DI 1 "register_operand" ""))]
4702 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4703 "x86_emit_floatuns (operands); DONE;")
4704 \f
4705 ;; SSE extract/set expanders
4706
4707 \f
4708 ;; Add instructions
4709
4710 ;; %%% splits for addditi3
4711
4712 (define_expand "addti3"
4713 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4714 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4715 (match_operand:TI 2 "x86_64_general_operand" "")))
4716 (clobber (reg:CC FLAGS_REG))]
4717 "TARGET_64BIT"
4718 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4719
4720 (define_insn "*addti3_1"
4721 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4722 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4723 (match_operand:TI 2 "general_operand" "roiF,riF")))
4724 (clobber (reg:CC FLAGS_REG))]
4725 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4726 "#")
4727
4728 (define_split
4729 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4730 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4731 (match_operand:TI 2 "general_operand" "")))
4732 (clobber (reg:CC FLAGS_REG))]
4733 "TARGET_64BIT && reload_completed"
4734 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4735 UNSPEC_ADD_CARRY))
4736 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4737 (parallel [(set (match_dup 3)
4738 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4739 (match_dup 4))
4740 (match_dup 5)))
4741 (clobber (reg:CC FLAGS_REG))])]
4742 "split_ti (operands+0, 1, operands+0, operands+3);
4743 split_ti (operands+1, 1, operands+1, operands+4);
4744 split_ti (operands+2, 1, operands+2, operands+5);")
4745
4746 ;; %%% splits for addsidi3
4747 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4748 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4749 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4750
4751 (define_expand "adddi3"
4752 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4753 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4754 (match_operand:DI 2 "x86_64_general_operand" "")))
4755 (clobber (reg:CC FLAGS_REG))]
4756 ""
4757 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4758
4759 (define_insn "*adddi3_1"
4760 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4761 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4762 (match_operand:DI 2 "general_operand" "roiF,riF")))
4763 (clobber (reg:CC FLAGS_REG))]
4764 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4765 "#")
4766
4767 (define_split
4768 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4769 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4770 (match_operand:DI 2 "general_operand" "")))
4771 (clobber (reg:CC FLAGS_REG))]
4772 "!TARGET_64BIT && reload_completed"
4773 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4774 UNSPEC_ADD_CARRY))
4775 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4776 (parallel [(set (match_dup 3)
4777 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4778 (match_dup 4))
4779 (match_dup 5)))
4780 (clobber (reg:CC FLAGS_REG))])]
4781 "split_di (operands+0, 1, operands+0, operands+3);
4782 split_di (operands+1, 1, operands+1, operands+4);
4783 split_di (operands+2, 1, operands+2, operands+5);")
4784
4785 (define_insn "adddi3_carry_rex64"
4786 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4787 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4788 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4789 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4790 (clobber (reg:CC FLAGS_REG))]
4791 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4792 "adc{q}\t{%2, %0|%0, %2}"
4793 [(set_attr "type" "alu")
4794 (set_attr "pent_pair" "pu")
4795 (set_attr "mode" "DI")])
4796
4797 (define_insn "*adddi3_cc_rex64"
4798 [(set (reg:CC FLAGS_REG)
4799 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4800 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4801 UNSPEC_ADD_CARRY))
4802 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4803 (plus:DI (match_dup 1) (match_dup 2)))]
4804 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4805 "add{q}\t{%2, %0|%0, %2}"
4806 [(set_attr "type" "alu")
4807 (set_attr "mode" "DI")])
4808
4809 (define_insn "addqi3_carry"
4810 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4811 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4812 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4813 (match_operand:QI 2 "general_operand" "qi,qm")))
4814 (clobber (reg:CC FLAGS_REG))]
4815 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4816 "adc{b}\t{%2, %0|%0, %2}"
4817 [(set_attr "type" "alu")
4818 (set_attr "pent_pair" "pu")
4819 (set_attr "mode" "QI")])
4820
4821 (define_insn "addhi3_carry"
4822 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4823 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4824 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4825 (match_operand:HI 2 "general_operand" "ri,rm")))
4826 (clobber (reg:CC FLAGS_REG))]
4827 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4828 "adc{w}\t{%2, %0|%0, %2}"
4829 [(set_attr "type" "alu")
4830 (set_attr "pent_pair" "pu")
4831 (set_attr "mode" "HI")])
4832
4833 (define_insn "addsi3_carry"
4834 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4835 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4836 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4837 (match_operand:SI 2 "general_operand" "ri,rm")))
4838 (clobber (reg:CC FLAGS_REG))]
4839 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4840 "adc{l}\t{%2, %0|%0, %2}"
4841 [(set_attr "type" "alu")
4842 (set_attr "pent_pair" "pu")
4843 (set_attr "mode" "SI")])
4844
4845 (define_insn "*addsi3_carry_zext"
4846 [(set (match_operand:DI 0 "register_operand" "=r")
4847 (zero_extend:DI
4848 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4849 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4850 (match_operand:SI 2 "general_operand" "rim"))))
4851 (clobber (reg:CC FLAGS_REG))]
4852 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4853 "adc{l}\t{%2, %k0|%k0, %2}"
4854 [(set_attr "type" "alu")
4855 (set_attr "pent_pair" "pu")
4856 (set_attr "mode" "SI")])
4857
4858 (define_insn "*addsi3_cc"
4859 [(set (reg:CC FLAGS_REG)
4860 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4861 (match_operand:SI 2 "general_operand" "ri,rm")]
4862 UNSPEC_ADD_CARRY))
4863 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864 (plus:SI (match_dup 1) (match_dup 2)))]
4865 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4866 "add{l}\t{%2, %0|%0, %2}"
4867 [(set_attr "type" "alu")
4868 (set_attr "mode" "SI")])
4869
4870 (define_insn "addqi3_cc"
4871 [(set (reg:CC FLAGS_REG)
4872 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4873 (match_operand:QI 2 "general_operand" "qi,qm")]
4874 UNSPEC_ADD_CARRY))
4875 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4876 (plus:QI (match_dup 1) (match_dup 2)))]
4877 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4878 "add{b}\t{%2, %0|%0, %2}"
4879 [(set_attr "type" "alu")
4880 (set_attr "mode" "QI")])
4881
4882 (define_expand "addsi3"
4883 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4884 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4885 (match_operand:SI 2 "general_operand" "")))
4886 (clobber (reg:CC FLAGS_REG))])]
4887 ""
4888 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4889
4890 (define_insn "*lea_1"
4891 [(set (match_operand:SI 0 "register_operand" "=r")
4892 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4893 "!TARGET_64BIT"
4894 "lea{l}\t{%a1, %0|%0, %a1}"
4895 [(set_attr "type" "lea")
4896 (set_attr "mode" "SI")])
4897
4898 (define_insn "*lea_1_rex64"
4899 [(set (match_operand:SI 0 "register_operand" "=r")
4900 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4901 "TARGET_64BIT"
4902 "lea{l}\t{%a1, %0|%0, %a1}"
4903 [(set_attr "type" "lea")
4904 (set_attr "mode" "SI")])
4905
4906 (define_insn "*lea_1_zext"
4907 [(set (match_operand:DI 0 "register_operand" "=r")
4908 (zero_extend:DI
4909 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4910 "TARGET_64BIT"
4911 "lea{l}\t{%a1, %k0|%k0, %a1}"
4912 [(set_attr "type" "lea")
4913 (set_attr "mode" "SI")])
4914
4915 (define_insn "*lea_2_rex64"
4916 [(set (match_operand:DI 0 "register_operand" "=r")
4917 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4918 "TARGET_64BIT"
4919 "lea{q}\t{%a1, %0|%0, %a1}"
4920 [(set_attr "type" "lea")
4921 (set_attr "mode" "DI")])
4922
4923 ;; The lea patterns for non-Pmodes needs to be matched by several
4924 ;; insns converted to real lea by splitters.
4925
4926 (define_insn_and_split "*lea_general_1"
4927 [(set (match_operand 0 "register_operand" "=r")
4928 (plus (plus (match_operand 1 "index_register_operand" "l")
4929 (match_operand 2 "register_operand" "r"))
4930 (match_operand 3 "immediate_operand" "i")))]
4931 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4932 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4933 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4934 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4935 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4936 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4937 || GET_MODE (operands[3]) == VOIDmode)"
4938 "#"
4939 "&& reload_completed"
4940 [(const_int 0)]
4941 {
4942 rtx pat;
4943 operands[0] = gen_lowpart (SImode, operands[0]);
4944 operands[1] = gen_lowpart (Pmode, operands[1]);
4945 operands[2] = gen_lowpart (Pmode, operands[2]);
4946 operands[3] = gen_lowpart (Pmode, operands[3]);
4947 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4948 operands[3]);
4949 if (Pmode != SImode)
4950 pat = gen_rtx_SUBREG (SImode, pat, 0);
4951 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4952 DONE;
4953 }
4954 [(set_attr "type" "lea")
4955 (set_attr "mode" "SI")])
4956
4957 (define_insn_and_split "*lea_general_1_zext"
4958 [(set (match_operand:DI 0 "register_operand" "=r")
4959 (zero_extend:DI
4960 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4961 (match_operand:SI 2 "register_operand" "r"))
4962 (match_operand:SI 3 "immediate_operand" "i"))))]
4963 "TARGET_64BIT"
4964 "#"
4965 "&& reload_completed"
4966 [(set (match_dup 0)
4967 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4968 (match_dup 2))
4969 (match_dup 3)) 0)))]
4970 {
4971 operands[1] = gen_lowpart (Pmode, operands[1]);
4972 operands[2] = gen_lowpart (Pmode, operands[2]);
4973 operands[3] = gen_lowpart (Pmode, operands[3]);
4974 }
4975 [(set_attr "type" "lea")
4976 (set_attr "mode" "SI")])
4977
4978 (define_insn_and_split "*lea_general_2"
4979 [(set (match_operand 0 "register_operand" "=r")
4980 (plus (mult (match_operand 1 "index_register_operand" "l")
4981 (match_operand 2 "const248_operand" "i"))
4982 (match_operand 3 "nonmemory_operand" "ri")))]
4983 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4984 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4985 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4986 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4987 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4988 || GET_MODE (operands[3]) == VOIDmode)"
4989 "#"
4990 "&& reload_completed"
4991 [(const_int 0)]
4992 {
4993 rtx pat;
4994 operands[0] = gen_lowpart (SImode, operands[0]);
4995 operands[1] = gen_lowpart (Pmode, operands[1]);
4996 operands[3] = gen_lowpart (Pmode, operands[3]);
4997 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4998 operands[3]);
4999 if (Pmode != SImode)
5000 pat = gen_rtx_SUBREG (SImode, pat, 0);
5001 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5002 DONE;
5003 }
5004 [(set_attr "type" "lea")
5005 (set_attr "mode" "SI")])
5006
5007 (define_insn_and_split "*lea_general_2_zext"
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5009 (zero_extend:DI
5010 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5011 (match_operand:SI 2 "const248_operand" "n"))
5012 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5013 "TARGET_64BIT"
5014 "#"
5015 "&& reload_completed"
5016 [(set (match_dup 0)
5017 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5018 (match_dup 2))
5019 (match_dup 3)) 0)))]
5020 {
5021 operands[1] = gen_lowpart (Pmode, operands[1]);
5022 operands[3] = gen_lowpart (Pmode, operands[3]);
5023 }
5024 [(set_attr "type" "lea")
5025 (set_attr "mode" "SI")])
5026
5027 (define_insn_and_split "*lea_general_3"
5028 [(set (match_operand 0 "register_operand" "=r")
5029 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5030 (match_operand 2 "const248_operand" "i"))
5031 (match_operand 3 "register_operand" "r"))
5032 (match_operand 4 "immediate_operand" "i")))]
5033 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5034 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5035 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5036 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5037 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5038 "#"
5039 "&& reload_completed"
5040 [(const_int 0)]
5041 {
5042 rtx pat;
5043 operands[0] = gen_lowpart (SImode, operands[0]);
5044 operands[1] = gen_lowpart (Pmode, operands[1]);
5045 operands[3] = gen_lowpart (Pmode, operands[3]);
5046 operands[4] = gen_lowpart (Pmode, operands[4]);
5047 pat = gen_rtx_PLUS (Pmode,
5048 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5049 operands[2]),
5050 operands[3]),
5051 operands[4]);
5052 if (Pmode != SImode)
5053 pat = gen_rtx_SUBREG (SImode, pat, 0);
5054 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5055 DONE;
5056 }
5057 [(set_attr "type" "lea")
5058 (set_attr "mode" "SI")])
5059
5060 (define_insn_and_split "*lea_general_3_zext"
5061 [(set (match_operand:DI 0 "register_operand" "=r")
5062 (zero_extend:DI
5063 (plus:SI (plus:SI (mult:SI
5064 (match_operand:SI 1 "index_register_operand" "l")
5065 (match_operand:SI 2 "const248_operand" "n"))
5066 (match_operand:SI 3 "register_operand" "r"))
5067 (match_operand:SI 4 "immediate_operand" "i"))))]
5068 "TARGET_64BIT"
5069 "#"
5070 "&& reload_completed"
5071 [(set (match_dup 0)
5072 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5073 (match_dup 2))
5074 (match_dup 3))
5075 (match_dup 4)) 0)))]
5076 {
5077 operands[1] = gen_lowpart (Pmode, operands[1]);
5078 operands[3] = gen_lowpart (Pmode, operands[3]);
5079 operands[4] = gen_lowpart (Pmode, operands[4]);
5080 }
5081 [(set_attr "type" "lea")
5082 (set_attr "mode" "SI")])
5083
5084 (define_insn "*adddi_1_rex64"
5085 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5086 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5087 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5088 (clobber (reg:CC FLAGS_REG))]
5089 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5090 {
5091 switch (get_attr_type (insn))
5092 {
5093 case TYPE_LEA:
5094 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5095 return "lea{q}\t{%a2, %0|%0, %a2}";
5096
5097 case TYPE_INCDEC:
5098 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5099 if (operands[2] == const1_rtx)
5100 return "inc{q}\t%0";
5101 else
5102 {
5103 gcc_assert (operands[2] == constm1_rtx);
5104 return "dec{q}\t%0";
5105 }
5106
5107 default:
5108 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5109
5110 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5111 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5112 if (GET_CODE (operands[2]) == CONST_INT
5113 /* Avoid overflows. */
5114 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5115 && (INTVAL (operands[2]) == 128
5116 || (INTVAL (operands[2]) < 0
5117 && INTVAL (operands[2]) != -128)))
5118 {
5119 operands[2] = GEN_INT (-INTVAL (operands[2]));
5120 return "sub{q}\t{%2, %0|%0, %2}";
5121 }
5122 return "add{q}\t{%2, %0|%0, %2}";
5123 }
5124 }
5125 [(set (attr "type")
5126 (cond [(eq_attr "alternative" "2")
5127 (const_string "lea")
5128 ; Current assemblers are broken and do not allow @GOTOFF in
5129 ; ought but a memory context.
5130 (match_operand:DI 2 "pic_symbolic_operand" "")
5131 (const_string "lea")
5132 (match_operand:DI 2 "incdec_operand" "")
5133 (const_string "incdec")
5134 ]
5135 (const_string "alu")))
5136 (set_attr "mode" "DI")])
5137
5138 ;; Convert lea to the lea pattern to avoid flags dependency.
5139 (define_split
5140 [(set (match_operand:DI 0 "register_operand" "")
5141 (plus:DI (match_operand:DI 1 "register_operand" "")
5142 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5143 (clobber (reg:CC FLAGS_REG))]
5144 "TARGET_64BIT && reload_completed
5145 && true_regnum (operands[0]) != true_regnum (operands[1])"
5146 [(set (match_dup 0)
5147 (plus:DI (match_dup 1)
5148 (match_dup 2)))]
5149 "")
5150
5151 (define_insn "*adddi_2_rex64"
5152 [(set (reg FLAGS_REG)
5153 (compare
5154 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5155 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5156 (const_int 0)))
5157 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5158 (plus:DI (match_dup 1) (match_dup 2)))]
5159 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5160 && ix86_binary_operator_ok (PLUS, DImode, operands)
5161 /* Current assemblers are broken and do not allow @GOTOFF in
5162 ought but a memory context. */
5163 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5164 {
5165 switch (get_attr_type (insn))
5166 {
5167 case TYPE_INCDEC:
5168 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5169 if (operands[2] == const1_rtx)
5170 return "inc{q}\t%0";
5171 else
5172 {
5173 gcc_assert (operands[2] == constm1_rtx);
5174 return "dec{q}\t%0";
5175 }
5176
5177 default:
5178 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5179 /* ???? We ought to handle there the 32bit case too
5180 - do we need new constraint? */
5181 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5182 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5183 if (GET_CODE (operands[2]) == CONST_INT
5184 /* Avoid overflows. */
5185 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5186 && (INTVAL (operands[2]) == 128
5187 || (INTVAL (operands[2]) < 0
5188 && INTVAL (operands[2]) != -128)))
5189 {
5190 operands[2] = GEN_INT (-INTVAL (operands[2]));
5191 return "sub{q}\t{%2, %0|%0, %2}";
5192 }
5193 return "add{q}\t{%2, %0|%0, %2}";
5194 }
5195 }
5196 [(set (attr "type")
5197 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5198 (const_string "incdec")
5199 (const_string "alu")))
5200 (set_attr "mode" "DI")])
5201
5202 (define_insn "*adddi_3_rex64"
5203 [(set (reg FLAGS_REG)
5204 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5205 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5206 (clobber (match_scratch:DI 0 "=r"))]
5207 "TARGET_64BIT
5208 && ix86_match_ccmode (insn, CCZmode)
5209 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5210 /* Current assemblers are broken and do not allow @GOTOFF in
5211 ought but a memory context. */
5212 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5213 {
5214 switch (get_attr_type (insn))
5215 {
5216 case TYPE_INCDEC:
5217 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5218 if (operands[2] == const1_rtx)
5219 return "inc{q}\t%0";
5220 else
5221 {
5222 gcc_assert (operands[2] == constm1_rtx);
5223 return "dec{q}\t%0";
5224 }
5225
5226 default:
5227 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5228 /* ???? We ought to handle there the 32bit case too
5229 - do we need new constraint? */
5230 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5231 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5232 if (GET_CODE (operands[2]) == CONST_INT
5233 /* Avoid overflows. */
5234 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5235 && (INTVAL (operands[2]) == 128
5236 || (INTVAL (operands[2]) < 0
5237 && INTVAL (operands[2]) != -128)))
5238 {
5239 operands[2] = GEN_INT (-INTVAL (operands[2]));
5240 return "sub{q}\t{%2, %0|%0, %2}";
5241 }
5242 return "add{q}\t{%2, %0|%0, %2}";
5243 }
5244 }
5245 [(set (attr "type")
5246 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5247 (const_string "incdec")
5248 (const_string "alu")))
5249 (set_attr "mode" "DI")])
5250
5251 ; For comparisons against 1, -1 and 128, we may generate better code
5252 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5253 ; is matched then. We can't accept general immediate, because for
5254 ; case of overflows, the result is messed up.
5255 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5256 ; when negated.
5257 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5258 ; only for comparisons not depending on it.
5259 (define_insn "*adddi_4_rex64"
5260 [(set (reg FLAGS_REG)
5261 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5262 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5263 (clobber (match_scratch:DI 0 "=rm"))]
5264 "TARGET_64BIT
5265 && ix86_match_ccmode (insn, CCGCmode)"
5266 {
5267 switch (get_attr_type (insn))
5268 {
5269 case TYPE_INCDEC:
5270 if (operands[2] == constm1_rtx)
5271 return "inc{q}\t%0";
5272 else
5273 {
5274 gcc_assert (operands[2] == const1_rtx);
5275 return "dec{q}\t%0";
5276 }
5277
5278 default:
5279 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5280 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5281 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5282 if ((INTVAL (operands[2]) == -128
5283 || (INTVAL (operands[2]) > 0
5284 && INTVAL (operands[2]) != 128))
5285 /* Avoid overflows. */
5286 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5287 return "sub{q}\t{%2, %0|%0, %2}";
5288 operands[2] = GEN_INT (-INTVAL (operands[2]));
5289 return "add{q}\t{%2, %0|%0, %2}";
5290 }
5291 }
5292 [(set (attr "type")
5293 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5294 (const_string "incdec")
5295 (const_string "alu")))
5296 (set_attr "mode" "DI")])
5297
5298 (define_insn "*adddi_5_rex64"
5299 [(set (reg FLAGS_REG)
5300 (compare
5301 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5302 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5303 (const_int 0)))
5304 (clobber (match_scratch:DI 0 "=r"))]
5305 "TARGET_64BIT
5306 && ix86_match_ccmode (insn, CCGOCmode)
5307 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5308 /* Current assemblers are broken and do not allow @GOTOFF in
5309 ought but a memory context. */
5310 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5311 {
5312 switch (get_attr_type (insn))
5313 {
5314 case TYPE_INCDEC:
5315 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5316 if (operands[2] == const1_rtx)
5317 return "inc{q}\t%0";
5318 else
5319 {
5320 gcc_assert (operands[2] == constm1_rtx);
5321 return "dec{q}\t%0";
5322 }
5323
5324 default:
5325 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5326 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5327 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5328 if (GET_CODE (operands[2]) == CONST_INT
5329 /* Avoid overflows. */
5330 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5331 && (INTVAL (operands[2]) == 128
5332 || (INTVAL (operands[2]) < 0
5333 && INTVAL (operands[2]) != -128)))
5334 {
5335 operands[2] = GEN_INT (-INTVAL (operands[2]));
5336 return "sub{q}\t{%2, %0|%0, %2}";
5337 }
5338 return "add{q}\t{%2, %0|%0, %2}";
5339 }
5340 }
5341 [(set (attr "type")
5342 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5343 (const_string "incdec")
5344 (const_string "alu")))
5345 (set_attr "mode" "DI")])
5346
5347
5348 (define_insn "*addsi_1"
5349 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5350 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5351 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5352 (clobber (reg:CC FLAGS_REG))]
5353 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5354 {
5355 switch (get_attr_type (insn))
5356 {
5357 case TYPE_LEA:
5358 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5359 return "lea{l}\t{%a2, %0|%0, %a2}";
5360
5361 case TYPE_INCDEC:
5362 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5363 if (operands[2] == const1_rtx)
5364 return "inc{l}\t%0";
5365 else
5366 {
5367 gcc_assert (operands[2] == constm1_rtx);
5368 return "dec{l}\t%0";
5369 }
5370
5371 default:
5372 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5373
5374 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5375 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5376 if (GET_CODE (operands[2]) == CONST_INT
5377 && (INTVAL (operands[2]) == 128
5378 || (INTVAL (operands[2]) < 0
5379 && INTVAL (operands[2]) != -128)))
5380 {
5381 operands[2] = GEN_INT (-INTVAL (operands[2]));
5382 return "sub{l}\t{%2, %0|%0, %2}";
5383 }
5384 return "add{l}\t{%2, %0|%0, %2}";
5385 }
5386 }
5387 [(set (attr "type")
5388 (cond [(eq_attr "alternative" "2")
5389 (const_string "lea")
5390 ; Current assemblers are broken and do not allow @GOTOFF in
5391 ; ought but a memory context.
5392 (match_operand:SI 2 "pic_symbolic_operand" "")
5393 (const_string "lea")
5394 (match_operand:SI 2 "incdec_operand" "")
5395 (const_string "incdec")
5396 ]
5397 (const_string "alu")))
5398 (set_attr "mode" "SI")])
5399
5400 ;; Convert lea to the lea pattern to avoid flags dependency.
5401 (define_split
5402 [(set (match_operand 0 "register_operand" "")
5403 (plus (match_operand 1 "register_operand" "")
5404 (match_operand 2 "nonmemory_operand" "")))
5405 (clobber (reg:CC FLAGS_REG))]
5406 "reload_completed
5407 && true_regnum (operands[0]) != true_regnum (operands[1])"
5408 [(const_int 0)]
5409 {
5410 rtx pat;
5411 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5412 may confuse gen_lowpart. */
5413 if (GET_MODE (operands[0]) != Pmode)
5414 {
5415 operands[1] = gen_lowpart (Pmode, operands[1]);
5416 operands[2] = gen_lowpart (Pmode, operands[2]);
5417 }
5418 operands[0] = gen_lowpart (SImode, operands[0]);
5419 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5420 if (Pmode != SImode)
5421 pat = gen_rtx_SUBREG (SImode, pat, 0);
5422 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5423 DONE;
5424 })
5425
5426 ;; It may seem that nonimmediate operand is proper one for operand 1.
5427 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5428 ;; we take care in ix86_binary_operator_ok to not allow two memory
5429 ;; operands so proper swapping will be done in reload. This allow
5430 ;; patterns constructed from addsi_1 to match.
5431 (define_insn "addsi_1_zext"
5432 [(set (match_operand:DI 0 "register_operand" "=r,r")
5433 (zero_extend:DI
5434 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5435 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5436 (clobber (reg:CC FLAGS_REG))]
5437 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5438 {
5439 switch (get_attr_type (insn))
5440 {
5441 case TYPE_LEA:
5442 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5443 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5444
5445 case TYPE_INCDEC:
5446 if (operands[2] == const1_rtx)
5447 return "inc{l}\t%k0";
5448 else
5449 {
5450 gcc_assert (operands[2] == constm1_rtx);
5451 return "dec{l}\t%k0";
5452 }
5453
5454 default:
5455 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5456 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5457 if (GET_CODE (operands[2]) == CONST_INT
5458 && (INTVAL (operands[2]) == 128
5459 || (INTVAL (operands[2]) < 0
5460 && INTVAL (operands[2]) != -128)))
5461 {
5462 operands[2] = GEN_INT (-INTVAL (operands[2]));
5463 return "sub{l}\t{%2, %k0|%k0, %2}";
5464 }
5465 return "add{l}\t{%2, %k0|%k0, %2}";
5466 }
5467 }
5468 [(set (attr "type")
5469 (cond [(eq_attr "alternative" "1")
5470 (const_string "lea")
5471 ; Current assemblers are broken and do not allow @GOTOFF in
5472 ; ought but a memory context.
5473 (match_operand:SI 2 "pic_symbolic_operand" "")
5474 (const_string "lea")
5475 (match_operand:SI 2 "incdec_operand" "")
5476 (const_string "incdec")
5477 ]
5478 (const_string "alu")))
5479 (set_attr "mode" "SI")])
5480
5481 ;; Convert lea to the lea pattern to avoid flags dependency.
5482 (define_split
5483 [(set (match_operand:DI 0 "register_operand" "")
5484 (zero_extend:DI
5485 (plus:SI (match_operand:SI 1 "register_operand" "")
5486 (match_operand:SI 2 "nonmemory_operand" ""))))
5487 (clobber (reg:CC FLAGS_REG))]
5488 "TARGET_64BIT && reload_completed
5489 && true_regnum (operands[0]) != true_regnum (operands[1])"
5490 [(set (match_dup 0)
5491 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5492 {
5493 operands[1] = gen_lowpart (Pmode, operands[1]);
5494 operands[2] = gen_lowpart (Pmode, operands[2]);
5495 })
5496
5497 (define_insn "*addsi_2"
5498 [(set (reg FLAGS_REG)
5499 (compare
5500 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5501 (match_operand:SI 2 "general_operand" "rmni,rni"))
5502 (const_int 0)))
5503 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5504 (plus:SI (match_dup 1) (match_dup 2)))]
5505 "ix86_match_ccmode (insn, CCGOCmode)
5506 && ix86_binary_operator_ok (PLUS, SImode, operands)
5507 /* Current assemblers are broken and do not allow @GOTOFF in
5508 ought but a memory context. */
5509 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5510 {
5511 switch (get_attr_type (insn))
5512 {
5513 case TYPE_INCDEC:
5514 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515 if (operands[2] == const1_rtx)
5516 return "inc{l}\t%0";
5517 else
5518 {
5519 gcc_assert (operands[2] == constm1_rtx);
5520 return "dec{l}\t%0";
5521 }
5522
5523 default:
5524 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5525 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5526 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5527 if (GET_CODE (operands[2]) == CONST_INT
5528 && (INTVAL (operands[2]) == 128
5529 || (INTVAL (operands[2]) < 0
5530 && INTVAL (operands[2]) != -128)))
5531 {
5532 operands[2] = GEN_INT (-INTVAL (operands[2]));
5533 return "sub{l}\t{%2, %0|%0, %2}";
5534 }
5535 return "add{l}\t{%2, %0|%0, %2}";
5536 }
5537 }
5538 [(set (attr "type")
5539 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5540 (const_string "incdec")
5541 (const_string "alu")))
5542 (set_attr "mode" "SI")])
5543
5544 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5545 (define_insn "*addsi_2_zext"
5546 [(set (reg FLAGS_REG)
5547 (compare
5548 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5549 (match_operand:SI 2 "general_operand" "rmni"))
5550 (const_int 0)))
5551 (set (match_operand:DI 0 "register_operand" "=r")
5552 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5553 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5554 && ix86_binary_operator_ok (PLUS, SImode, operands)
5555 /* Current assemblers are broken and do not allow @GOTOFF in
5556 ought but a memory context. */
5557 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5558 {
5559 switch (get_attr_type (insn))
5560 {
5561 case TYPE_INCDEC:
5562 if (operands[2] == const1_rtx)
5563 return "inc{l}\t%k0";
5564 else
5565 {
5566 gcc_assert (operands[2] == constm1_rtx);
5567 return "dec{l}\t%k0";
5568 }
5569
5570 default:
5571 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5572 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5573 if (GET_CODE (operands[2]) == CONST_INT
5574 && (INTVAL (operands[2]) == 128
5575 || (INTVAL (operands[2]) < 0
5576 && INTVAL (operands[2]) != -128)))
5577 {
5578 operands[2] = GEN_INT (-INTVAL (operands[2]));
5579 return "sub{l}\t{%2, %k0|%k0, %2}";
5580 }
5581 return "add{l}\t{%2, %k0|%k0, %2}";
5582 }
5583 }
5584 [(set (attr "type")
5585 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5586 (const_string "incdec")
5587 (const_string "alu")))
5588 (set_attr "mode" "SI")])
5589
5590 (define_insn "*addsi_3"
5591 [(set (reg FLAGS_REG)
5592 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5593 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5594 (clobber (match_scratch:SI 0 "=r"))]
5595 "ix86_match_ccmode (insn, CCZmode)
5596 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5597 /* Current assemblers are broken and do not allow @GOTOFF in
5598 ought but a memory context. */
5599 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5600 {
5601 switch (get_attr_type (insn))
5602 {
5603 case TYPE_INCDEC:
5604 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5605 if (operands[2] == const1_rtx)
5606 return "inc{l}\t%0";
5607 else
5608 {
5609 gcc_assert (operands[2] == constm1_rtx);
5610 return "dec{l}\t%0";
5611 }
5612
5613 default:
5614 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5615 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5616 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5617 if (GET_CODE (operands[2]) == CONST_INT
5618 && (INTVAL (operands[2]) == 128
5619 || (INTVAL (operands[2]) < 0
5620 && INTVAL (operands[2]) != -128)))
5621 {
5622 operands[2] = GEN_INT (-INTVAL (operands[2]));
5623 return "sub{l}\t{%2, %0|%0, %2}";
5624 }
5625 return "add{l}\t{%2, %0|%0, %2}";
5626 }
5627 }
5628 [(set (attr "type")
5629 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5630 (const_string "incdec")
5631 (const_string "alu")))
5632 (set_attr "mode" "SI")])
5633
5634 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5635 (define_insn "*addsi_3_zext"
5636 [(set (reg FLAGS_REG)
5637 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5638 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5639 (set (match_operand:DI 0 "register_operand" "=r")
5640 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5641 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5642 && ix86_binary_operator_ok (PLUS, SImode, operands)
5643 /* Current assemblers are broken and do not allow @GOTOFF in
5644 ought but a memory context. */
5645 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5646 {
5647 switch (get_attr_type (insn))
5648 {
5649 case TYPE_INCDEC:
5650 if (operands[2] == const1_rtx)
5651 return "inc{l}\t%k0";
5652 else
5653 {
5654 gcc_assert (operands[2] == constm1_rtx);
5655 return "dec{l}\t%k0";
5656 }
5657
5658 default:
5659 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5660 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5661 if (GET_CODE (operands[2]) == CONST_INT
5662 && (INTVAL (operands[2]) == 128
5663 || (INTVAL (operands[2]) < 0
5664 && INTVAL (operands[2]) != -128)))
5665 {
5666 operands[2] = GEN_INT (-INTVAL (operands[2]));
5667 return "sub{l}\t{%2, %k0|%k0, %2}";
5668 }
5669 return "add{l}\t{%2, %k0|%k0, %2}";
5670 }
5671 }
5672 [(set (attr "type")
5673 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674 (const_string "incdec")
5675 (const_string "alu")))
5676 (set_attr "mode" "SI")])
5677
5678 ; For comparisons against 1, -1 and 128, we may generate better code
5679 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5680 ; is matched then. We can't accept general immediate, because for
5681 ; case of overflows, the result is messed up.
5682 ; This pattern also don't hold of 0x80000000, since the value overflows
5683 ; when negated.
5684 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5685 ; only for comparisons not depending on it.
5686 (define_insn "*addsi_4"
5687 [(set (reg FLAGS_REG)
5688 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5689 (match_operand:SI 2 "const_int_operand" "n")))
5690 (clobber (match_scratch:SI 0 "=rm"))]
5691 "ix86_match_ccmode (insn, CCGCmode)
5692 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5693 {
5694 switch (get_attr_type (insn))
5695 {
5696 case TYPE_INCDEC:
5697 if (operands[2] == constm1_rtx)
5698 return "inc{l}\t%0";
5699 else
5700 {
5701 gcc_assert (operands[2] == const1_rtx);
5702 return "dec{l}\t%0";
5703 }
5704
5705 default:
5706 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5707 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5708 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5709 if ((INTVAL (operands[2]) == -128
5710 || (INTVAL (operands[2]) > 0
5711 && INTVAL (operands[2]) != 128)))
5712 return "sub{l}\t{%2, %0|%0, %2}";
5713 operands[2] = GEN_INT (-INTVAL (operands[2]));
5714 return "add{l}\t{%2, %0|%0, %2}";
5715 }
5716 }
5717 [(set (attr "type")
5718 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5719 (const_string "incdec")
5720 (const_string "alu")))
5721 (set_attr "mode" "SI")])
5722
5723 (define_insn "*addsi_5"
5724 [(set (reg FLAGS_REG)
5725 (compare
5726 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5727 (match_operand:SI 2 "general_operand" "rmni"))
5728 (const_int 0)))
5729 (clobber (match_scratch:SI 0 "=r"))]
5730 "ix86_match_ccmode (insn, CCGOCmode)
5731 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5732 /* Current assemblers are broken and do not allow @GOTOFF in
5733 ought but a memory context. */
5734 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5735 {
5736 switch (get_attr_type (insn))
5737 {
5738 case TYPE_INCDEC:
5739 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5740 if (operands[2] == const1_rtx)
5741 return "inc{l}\t%0";
5742 else
5743 {
5744 gcc_assert (operands[2] == constm1_rtx);
5745 return "dec{l}\t%0";
5746 }
5747
5748 default:
5749 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5750 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5751 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5752 if (GET_CODE (operands[2]) == CONST_INT
5753 && (INTVAL (operands[2]) == 128
5754 || (INTVAL (operands[2]) < 0
5755 && INTVAL (operands[2]) != -128)))
5756 {
5757 operands[2] = GEN_INT (-INTVAL (operands[2]));
5758 return "sub{l}\t{%2, %0|%0, %2}";
5759 }
5760 return "add{l}\t{%2, %0|%0, %2}";
5761 }
5762 }
5763 [(set (attr "type")
5764 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5765 (const_string "incdec")
5766 (const_string "alu")))
5767 (set_attr "mode" "SI")])
5768
5769 (define_expand "addhi3"
5770 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5771 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5772 (match_operand:HI 2 "general_operand" "")))
5773 (clobber (reg:CC FLAGS_REG))])]
5774 "TARGET_HIMODE_MATH"
5775 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5776
5777 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5778 ;; type optimizations enabled by define-splits. This is not important
5779 ;; for PII, and in fact harmful because of partial register stalls.
5780
5781 (define_insn "*addhi_1_lea"
5782 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5783 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5784 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5785 (clobber (reg:CC FLAGS_REG))]
5786 "!TARGET_PARTIAL_REG_STALL
5787 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5788 {
5789 switch (get_attr_type (insn))
5790 {
5791 case TYPE_LEA:
5792 return "#";
5793 case TYPE_INCDEC:
5794 if (operands[2] == const1_rtx)
5795 return "inc{w}\t%0";
5796 else
5797 {
5798 gcc_assert (operands[2] == constm1_rtx);
5799 return "dec{w}\t%0";
5800 }
5801
5802 default:
5803 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5804 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5805 if (GET_CODE (operands[2]) == CONST_INT
5806 && (INTVAL (operands[2]) == 128
5807 || (INTVAL (operands[2]) < 0
5808 && INTVAL (operands[2]) != -128)))
5809 {
5810 operands[2] = GEN_INT (-INTVAL (operands[2]));
5811 return "sub{w}\t{%2, %0|%0, %2}";
5812 }
5813 return "add{w}\t{%2, %0|%0, %2}";
5814 }
5815 }
5816 [(set (attr "type")
5817 (if_then_else (eq_attr "alternative" "2")
5818 (const_string "lea")
5819 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5820 (const_string "incdec")
5821 (const_string "alu"))))
5822 (set_attr "mode" "HI,HI,SI")])
5823
5824 (define_insn "*addhi_1"
5825 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5826 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5827 (match_operand:HI 2 "general_operand" "ri,rm")))
5828 (clobber (reg:CC FLAGS_REG))]
5829 "TARGET_PARTIAL_REG_STALL
5830 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5831 {
5832 switch (get_attr_type (insn))
5833 {
5834 case TYPE_INCDEC:
5835 if (operands[2] == const1_rtx)
5836 return "inc{w}\t%0";
5837 else
5838 {
5839 gcc_assert (operands[2] == constm1_rtx);
5840 return "dec{w}\t%0";
5841 }
5842
5843 default:
5844 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5845 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5846 if (GET_CODE (operands[2]) == CONST_INT
5847 && (INTVAL (operands[2]) == 128
5848 || (INTVAL (operands[2]) < 0
5849 && INTVAL (operands[2]) != -128)))
5850 {
5851 operands[2] = GEN_INT (-INTVAL (operands[2]));
5852 return "sub{w}\t{%2, %0|%0, %2}";
5853 }
5854 return "add{w}\t{%2, %0|%0, %2}";
5855 }
5856 }
5857 [(set (attr "type")
5858 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5859 (const_string "incdec")
5860 (const_string "alu")))
5861 (set_attr "mode" "HI")])
5862
5863 (define_insn "*addhi_2"
5864 [(set (reg FLAGS_REG)
5865 (compare
5866 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5867 (match_operand:HI 2 "general_operand" "rmni,rni"))
5868 (const_int 0)))
5869 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5870 (plus:HI (match_dup 1) (match_dup 2)))]
5871 "ix86_match_ccmode (insn, CCGOCmode)
5872 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5873 {
5874 switch (get_attr_type (insn))
5875 {
5876 case TYPE_INCDEC:
5877 if (operands[2] == const1_rtx)
5878 return "inc{w}\t%0";
5879 else
5880 {
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{w}\t%0";
5883 }
5884
5885 default:
5886 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5888 if (GET_CODE (operands[2]) == CONST_INT
5889 && (INTVAL (operands[2]) == 128
5890 || (INTVAL (operands[2]) < 0
5891 && INTVAL (operands[2]) != -128)))
5892 {
5893 operands[2] = GEN_INT (-INTVAL (operands[2]));
5894 return "sub{w}\t{%2, %0|%0, %2}";
5895 }
5896 return "add{w}\t{%2, %0|%0, %2}";
5897 }
5898 }
5899 [(set (attr "type")
5900 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set_attr "mode" "HI")])
5904
5905 (define_insn "*addhi_3"
5906 [(set (reg FLAGS_REG)
5907 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5908 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5909 (clobber (match_scratch:HI 0 "=r"))]
5910 "ix86_match_ccmode (insn, CCZmode)
5911 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5912 {
5913 switch (get_attr_type (insn))
5914 {
5915 case TYPE_INCDEC:
5916 if (operands[2] == const1_rtx)
5917 return "inc{w}\t%0";
5918 else
5919 {
5920 gcc_assert (operands[2] == constm1_rtx);
5921 return "dec{w}\t%0";
5922 }
5923
5924 default:
5925 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5926 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5927 if (GET_CODE (operands[2]) == CONST_INT
5928 && (INTVAL (operands[2]) == 128
5929 || (INTVAL (operands[2]) < 0
5930 && INTVAL (operands[2]) != -128)))
5931 {
5932 operands[2] = GEN_INT (-INTVAL (operands[2]));
5933 return "sub{w}\t{%2, %0|%0, %2}";
5934 }
5935 return "add{w}\t{%2, %0|%0, %2}";
5936 }
5937 }
5938 [(set (attr "type")
5939 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5940 (const_string "incdec")
5941 (const_string "alu")))
5942 (set_attr "mode" "HI")])
5943
5944 ; See comments above addsi_4 for details.
5945 (define_insn "*addhi_4"
5946 [(set (reg FLAGS_REG)
5947 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5948 (match_operand:HI 2 "const_int_operand" "n")))
5949 (clobber (match_scratch:HI 0 "=rm"))]
5950 "ix86_match_ccmode (insn, CCGCmode)
5951 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5952 {
5953 switch (get_attr_type (insn))
5954 {
5955 case TYPE_INCDEC:
5956 if (operands[2] == constm1_rtx)
5957 return "inc{w}\t%0";
5958 else
5959 {
5960 gcc_assert (operands[2] == const1_rtx);
5961 return "dec{w}\t%0";
5962 }
5963
5964 default:
5965 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5966 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5967 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5968 if ((INTVAL (operands[2]) == -128
5969 || (INTVAL (operands[2]) > 0
5970 && INTVAL (operands[2]) != 128)))
5971 return "sub{w}\t{%2, %0|%0, %2}";
5972 operands[2] = GEN_INT (-INTVAL (operands[2]));
5973 return "add{w}\t{%2, %0|%0, %2}";
5974 }
5975 }
5976 [(set (attr "type")
5977 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5978 (const_string "incdec")
5979 (const_string "alu")))
5980 (set_attr "mode" "SI")])
5981
5982
5983 (define_insn "*addhi_5"
5984 [(set (reg FLAGS_REG)
5985 (compare
5986 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5987 (match_operand:HI 2 "general_operand" "rmni"))
5988 (const_int 0)))
5989 (clobber (match_scratch:HI 0 "=r"))]
5990 "ix86_match_ccmode (insn, CCGOCmode)
5991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5992 {
5993 switch (get_attr_type (insn))
5994 {
5995 case TYPE_INCDEC:
5996 if (operands[2] == const1_rtx)
5997 return "inc{w}\t%0";
5998 else
5999 {
6000 gcc_assert (operands[2] == constm1_rtx);
6001 return "dec{w}\t%0";
6002 }
6003
6004 default:
6005 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6007 if (GET_CODE (operands[2]) == CONST_INT
6008 && (INTVAL (operands[2]) == 128
6009 || (INTVAL (operands[2]) < 0
6010 && INTVAL (operands[2]) != -128)))
6011 {
6012 operands[2] = GEN_INT (-INTVAL (operands[2]));
6013 return "sub{w}\t{%2, %0|%0, %2}";
6014 }
6015 return "add{w}\t{%2, %0|%0, %2}";
6016 }
6017 }
6018 [(set (attr "type")
6019 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6020 (const_string "incdec")
6021 (const_string "alu")))
6022 (set_attr "mode" "HI")])
6023
6024 (define_expand "addqi3"
6025 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6026 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6027 (match_operand:QI 2 "general_operand" "")))
6028 (clobber (reg:CC FLAGS_REG))])]
6029 "TARGET_QIMODE_MATH"
6030 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6031
6032 ;; %%% Potential partial reg stall on alternative 2. What to do?
6033 (define_insn "*addqi_1_lea"
6034 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6035 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6036 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6037 (clobber (reg:CC FLAGS_REG))]
6038 "!TARGET_PARTIAL_REG_STALL
6039 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6040 {
6041 int widen = (which_alternative == 2);
6042 switch (get_attr_type (insn))
6043 {
6044 case TYPE_LEA:
6045 return "#";
6046 case TYPE_INCDEC:
6047 if (operands[2] == const1_rtx)
6048 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6049 else
6050 {
6051 gcc_assert (operands[2] == constm1_rtx);
6052 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6053 }
6054
6055 default:
6056 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6057 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6058 if (GET_CODE (operands[2]) == CONST_INT
6059 && (INTVAL (operands[2]) == 128
6060 || (INTVAL (operands[2]) < 0
6061 && INTVAL (operands[2]) != -128)))
6062 {
6063 operands[2] = GEN_INT (-INTVAL (operands[2]));
6064 if (widen)
6065 return "sub{l}\t{%2, %k0|%k0, %2}";
6066 else
6067 return "sub{b}\t{%2, %0|%0, %2}";
6068 }
6069 if (widen)
6070 return "add{l}\t{%k2, %k0|%k0, %k2}";
6071 else
6072 return "add{b}\t{%2, %0|%0, %2}";
6073 }
6074 }
6075 [(set (attr "type")
6076 (if_then_else (eq_attr "alternative" "3")
6077 (const_string "lea")
6078 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6079 (const_string "incdec")
6080 (const_string "alu"))))
6081 (set_attr "mode" "QI,QI,SI,SI")])
6082
6083 (define_insn "*addqi_1"
6084 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6085 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6086 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6087 (clobber (reg:CC FLAGS_REG))]
6088 "TARGET_PARTIAL_REG_STALL
6089 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6090 {
6091 int widen = (which_alternative == 2);
6092 switch (get_attr_type (insn))
6093 {
6094 case TYPE_INCDEC:
6095 if (operands[2] == const1_rtx)
6096 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6097 else
6098 {
6099 gcc_assert (operands[2] == constm1_rtx);
6100 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6101 }
6102
6103 default:
6104 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6106 if (GET_CODE (operands[2]) == CONST_INT
6107 && (INTVAL (operands[2]) == 128
6108 || (INTVAL (operands[2]) < 0
6109 && INTVAL (operands[2]) != -128)))
6110 {
6111 operands[2] = GEN_INT (-INTVAL (operands[2]));
6112 if (widen)
6113 return "sub{l}\t{%2, %k0|%k0, %2}";
6114 else
6115 return "sub{b}\t{%2, %0|%0, %2}";
6116 }
6117 if (widen)
6118 return "add{l}\t{%k2, %k0|%k0, %k2}";
6119 else
6120 return "add{b}\t{%2, %0|%0, %2}";
6121 }
6122 }
6123 [(set (attr "type")
6124 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6125 (const_string "incdec")
6126 (const_string "alu")))
6127 (set_attr "mode" "QI,QI,SI")])
6128
6129 (define_insn "*addqi_1_slp"
6130 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6131 (plus:QI (match_dup 0)
6132 (match_operand:QI 1 "general_operand" "qn,qnm")))
6133 (clobber (reg:CC FLAGS_REG))]
6134 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6135 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6136 {
6137 switch (get_attr_type (insn))
6138 {
6139 case TYPE_INCDEC:
6140 if (operands[1] == const1_rtx)
6141 return "inc{b}\t%0";
6142 else
6143 {
6144 gcc_assert (operands[1] == constm1_rtx);
6145 return "dec{b}\t%0";
6146 }
6147
6148 default:
6149 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6150 if (GET_CODE (operands[1]) == CONST_INT
6151 && INTVAL (operands[1]) < 0)
6152 {
6153 operands[1] = GEN_INT (-INTVAL (operands[1]));
6154 return "sub{b}\t{%1, %0|%0, %1}";
6155 }
6156 return "add{b}\t{%1, %0|%0, %1}";
6157 }
6158 }
6159 [(set (attr "type")
6160 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6161 (const_string "incdec")
6162 (const_string "alu1")))
6163 (set (attr "memory")
6164 (if_then_else (match_operand 1 "memory_operand" "")
6165 (const_string "load")
6166 (const_string "none")))
6167 (set_attr "mode" "QI")])
6168
6169 (define_insn "*addqi_2"
6170 [(set (reg FLAGS_REG)
6171 (compare
6172 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6173 (match_operand:QI 2 "general_operand" "qmni,qni"))
6174 (const_int 0)))
6175 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6176 (plus:QI (match_dup 1) (match_dup 2)))]
6177 "ix86_match_ccmode (insn, CCGOCmode)
6178 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6179 {
6180 switch (get_attr_type (insn))
6181 {
6182 case TYPE_INCDEC:
6183 if (operands[2] == const1_rtx)
6184 return "inc{b}\t%0";
6185 else
6186 {
6187 gcc_assert (operands[2] == constm1_rtx
6188 || (GET_CODE (operands[2]) == CONST_INT
6189 && INTVAL (operands[2]) == 255));
6190 return "dec{b}\t%0";
6191 }
6192
6193 default:
6194 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6195 if (GET_CODE (operands[2]) == CONST_INT
6196 && INTVAL (operands[2]) < 0)
6197 {
6198 operands[2] = GEN_INT (-INTVAL (operands[2]));
6199 return "sub{b}\t{%2, %0|%0, %2}";
6200 }
6201 return "add{b}\t{%2, %0|%0, %2}";
6202 }
6203 }
6204 [(set (attr "type")
6205 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6206 (const_string "incdec")
6207 (const_string "alu")))
6208 (set_attr "mode" "QI")])
6209
6210 (define_insn "*addqi_3"
6211 [(set (reg FLAGS_REG)
6212 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6213 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6214 (clobber (match_scratch:QI 0 "=q"))]
6215 "ix86_match_ccmode (insn, CCZmode)
6216 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6217 {
6218 switch (get_attr_type (insn))
6219 {
6220 case TYPE_INCDEC:
6221 if (operands[2] == const1_rtx)
6222 return "inc{b}\t%0";
6223 else
6224 {
6225 gcc_assert (operands[2] == constm1_rtx
6226 || (GET_CODE (operands[2]) == CONST_INT
6227 && INTVAL (operands[2]) == 255));
6228 return "dec{b}\t%0";
6229 }
6230
6231 default:
6232 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6233 if (GET_CODE (operands[2]) == CONST_INT
6234 && INTVAL (operands[2]) < 0)
6235 {
6236 operands[2] = GEN_INT (-INTVAL (operands[2]));
6237 return "sub{b}\t{%2, %0|%0, %2}";
6238 }
6239 return "add{b}\t{%2, %0|%0, %2}";
6240 }
6241 }
6242 [(set (attr "type")
6243 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6244 (const_string "incdec")
6245 (const_string "alu")))
6246 (set_attr "mode" "QI")])
6247
6248 ; See comments above addsi_4 for details.
6249 (define_insn "*addqi_4"
6250 [(set (reg FLAGS_REG)
6251 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6252 (match_operand:QI 2 "const_int_operand" "n")))
6253 (clobber (match_scratch:QI 0 "=qm"))]
6254 "ix86_match_ccmode (insn, CCGCmode)
6255 && (INTVAL (operands[2]) & 0xff) != 0x80"
6256 {
6257 switch (get_attr_type (insn))
6258 {
6259 case TYPE_INCDEC:
6260 if (operands[2] == constm1_rtx
6261 || (GET_CODE (operands[2]) == CONST_INT
6262 && INTVAL (operands[2]) == 255))
6263 return "inc{b}\t%0";
6264 else
6265 {
6266 gcc_assert (operands[2] == const1_rtx);
6267 return "dec{b}\t%0";
6268 }
6269
6270 default:
6271 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6272 if (INTVAL (operands[2]) < 0)
6273 {
6274 operands[2] = GEN_INT (-INTVAL (operands[2]));
6275 return "add{b}\t{%2, %0|%0, %2}";
6276 }
6277 return "sub{b}\t{%2, %0|%0, %2}";
6278 }
6279 }
6280 [(set (attr "type")
6281 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6282 (const_string "incdec")
6283 (const_string "alu")))
6284 (set_attr "mode" "QI")])
6285
6286
6287 (define_insn "*addqi_5"
6288 [(set (reg FLAGS_REG)
6289 (compare
6290 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6291 (match_operand:QI 2 "general_operand" "qmni"))
6292 (const_int 0)))
6293 (clobber (match_scratch:QI 0 "=q"))]
6294 "ix86_match_ccmode (insn, CCGOCmode)
6295 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6296 {
6297 switch (get_attr_type (insn))
6298 {
6299 case TYPE_INCDEC:
6300 if (operands[2] == const1_rtx)
6301 return "inc{b}\t%0";
6302 else
6303 {
6304 gcc_assert (operands[2] == constm1_rtx
6305 || (GET_CODE (operands[2]) == CONST_INT
6306 && INTVAL (operands[2]) == 255));
6307 return "dec{b}\t%0";
6308 }
6309
6310 default:
6311 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6312 if (GET_CODE (operands[2]) == CONST_INT
6313 && INTVAL (operands[2]) < 0)
6314 {
6315 operands[2] = GEN_INT (-INTVAL (operands[2]));
6316 return "sub{b}\t{%2, %0|%0, %2}";
6317 }
6318 return "add{b}\t{%2, %0|%0, %2}";
6319 }
6320 }
6321 [(set (attr "type")
6322 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6323 (const_string "incdec")
6324 (const_string "alu")))
6325 (set_attr "mode" "QI")])
6326
6327
6328 (define_insn "addqi_ext_1"
6329 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6330 (const_int 8)
6331 (const_int 8))
6332 (plus:SI
6333 (zero_extract:SI
6334 (match_operand 1 "ext_register_operand" "0")
6335 (const_int 8)
6336 (const_int 8))
6337 (match_operand:QI 2 "general_operand" "Qmn")))
6338 (clobber (reg:CC FLAGS_REG))]
6339 "!TARGET_64BIT"
6340 {
6341 switch (get_attr_type (insn))
6342 {
6343 case TYPE_INCDEC:
6344 if (operands[2] == const1_rtx)
6345 return "inc{b}\t%h0";
6346 else
6347 {
6348 gcc_assert (operands[2] == constm1_rtx
6349 || (GET_CODE (operands[2]) == CONST_INT
6350 && INTVAL (operands[2]) == 255));
6351 return "dec{b}\t%h0";
6352 }
6353
6354 default:
6355 return "add{b}\t{%2, %h0|%h0, %2}";
6356 }
6357 }
6358 [(set (attr "type")
6359 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6360 (const_string "incdec")
6361 (const_string "alu")))
6362 (set_attr "mode" "QI")])
6363
6364 (define_insn "*addqi_ext_1_rex64"
6365 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6366 (const_int 8)
6367 (const_int 8))
6368 (plus:SI
6369 (zero_extract:SI
6370 (match_operand 1 "ext_register_operand" "0")
6371 (const_int 8)
6372 (const_int 8))
6373 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6374 (clobber (reg:CC FLAGS_REG))]
6375 "TARGET_64BIT"
6376 {
6377 switch (get_attr_type (insn))
6378 {
6379 case TYPE_INCDEC:
6380 if (operands[2] == const1_rtx)
6381 return "inc{b}\t%h0";
6382 else
6383 {
6384 gcc_assert (operands[2] == constm1_rtx
6385 || (GET_CODE (operands[2]) == CONST_INT
6386 && INTVAL (operands[2]) == 255));
6387 return "dec{b}\t%h0";
6388 }
6389
6390 default:
6391 return "add{b}\t{%2, %h0|%h0, %2}";
6392 }
6393 }
6394 [(set (attr "type")
6395 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6396 (const_string "incdec")
6397 (const_string "alu")))
6398 (set_attr "mode" "QI")])
6399
6400 (define_insn "*addqi_ext_2"
6401 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6402 (const_int 8)
6403 (const_int 8))
6404 (plus:SI
6405 (zero_extract:SI
6406 (match_operand 1 "ext_register_operand" "%0")
6407 (const_int 8)
6408 (const_int 8))
6409 (zero_extract:SI
6410 (match_operand 2 "ext_register_operand" "Q")
6411 (const_int 8)
6412 (const_int 8))))
6413 (clobber (reg:CC FLAGS_REG))]
6414 ""
6415 "add{b}\t{%h2, %h0|%h0, %h2}"
6416 [(set_attr "type" "alu")
6417 (set_attr "mode" "QI")])
6418
6419 ;; The patterns that match these are at the end of this file.
6420
6421 (define_expand "addxf3"
6422 [(set (match_operand:XF 0 "register_operand" "")
6423 (plus:XF (match_operand:XF 1 "register_operand" "")
6424 (match_operand:XF 2 "register_operand" "")))]
6425 "TARGET_80387"
6426 "")
6427
6428 (define_expand "adddf3"
6429 [(set (match_operand:DF 0 "register_operand" "")
6430 (plus:DF (match_operand:DF 1 "register_operand" "")
6431 (match_operand:DF 2 "nonimmediate_operand" "")))]
6432 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6433 "")
6434
6435 (define_expand "addsf3"
6436 [(set (match_operand:SF 0 "register_operand" "")
6437 (plus:SF (match_operand:SF 1 "register_operand" "")
6438 (match_operand:SF 2 "nonimmediate_operand" "")))]
6439 "TARGET_80387 || TARGET_SSE_MATH"
6440 "")
6441 \f
6442 ;; Subtract instructions
6443
6444 ;; %%% splits for subditi3
6445
6446 (define_expand "subti3"
6447 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6448 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6449 (match_operand:TI 2 "x86_64_general_operand" "")))
6450 (clobber (reg:CC FLAGS_REG))])]
6451 "TARGET_64BIT"
6452 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6453
6454 (define_insn "*subti3_1"
6455 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6456 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6457 (match_operand:TI 2 "general_operand" "roiF,riF")))
6458 (clobber (reg:CC FLAGS_REG))]
6459 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6460 "#")
6461
6462 (define_split
6463 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6464 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6465 (match_operand:TI 2 "general_operand" "")))
6466 (clobber (reg:CC FLAGS_REG))]
6467 "TARGET_64BIT && reload_completed"
6468 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6469 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6470 (parallel [(set (match_dup 3)
6471 (minus:DI (match_dup 4)
6472 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6473 (match_dup 5))))
6474 (clobber (reg:CC FLAGS_REG))])]
6475 "split_ti (operands+0, 1, operands+0, operands+3);
6476 split_ti (operands+1, 1, operands+1, operands+4);
6477 split_ti (operands+2, 1, operands+2, operands+5);")
6478
6479 ;; %%% splits for subsidi3
6480
6481 (define_expand "subdi3"
6482 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6483 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6484 (match_operand:DI 2 "x86_64_general_operand" "")))
6485 (clobber (reg:CC FLAGS_REG))])]
6486 ""
6487 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6488
6489 (define_insn "*subdi3_1"
6490 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6491 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6492 (match_operand:DI 2 "general_operand" "roiF,riF")))
6493 (clobber (reg:CC FLAGS_REG))]
6494 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6495 "#")
6496
6497 (define_split
6498 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6499 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6500 (match_operand:DI 2 "general_operand" "")))
6501 (clobber (reg:CC FLAGS_REG))]
6502 "!TARGET_64BIT && reload_completed"
6503 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6504 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6505 (parallel [(set (match_dup 3)
6506 (minus:SI (match_dup 4)
6507 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6508 (match_dup 5))))
6509 (clobber (reg:CC FLAGS_REG))])]
6510 "split_di (operands+0, 1, operands+0, operands+3);
6511 split_di (operands+1, 1, operands+1, operands+4);
6512 split_di (operands+2, 1, operands+2, operands+5);")
6513
6514 (define_insn "subdi3_carry_rex64"
6515 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6516 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6517 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6518 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6519 (clobber (reg:CC FLAGS_REG))]
6520 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6521 "sbb{q}\t{%2, %0|%0, %2}"
6522 [(set_attr "type" "alu")
6523 (set_attr "pent_pair" "pu")
6524 (set_attr "mode" "DI")])
6525
6526 (define_insn "*subdi_1_rex64"
6527 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6528 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6529 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6530 (clobber (reg:CC FLAGS_REG))]
6531 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6532 "sub{q}\t{%2, %0|%0, %2}"
6533 [(set_attr "type" "alu")
6534 (set_attr "mode" "DI")])
6535
6536 (define_insn "*subdi_2_rex64"
6537 [(set (reg FLAGS_REG)
6538 (compare
6539 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6540 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6541 (const_int 0)))
6542 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6543 (minus:DI (match_dup 1) (match_dup 2)))]
6544 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6545 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6546 "sub{q}\t{%2, %0|%0, %2}"
6547 [(set_attr "type" "alu")
6548 (set_attr "mode" "DI")])
6549
6550 (define_insn "*subdi_3_rex63"
6551 [(set (reg FLAGS_REG)
6552 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6553 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6554 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6555 (minus:DI (match_dup 1) (match_dup 2)))]
6556 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6557 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6558 "sub{q}\t{%2, %0|%0, %2}"
6559 [(set_attr "type" "alu")
6560 (set_attr "mode" "DI")])
6561
6562 (define_insn "subqi3_carry"
6563 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6564 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6565 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6566 (match_operand:QI 2 "general_operand" "qi,qm"))))
6567 (clobber (reg:CC FLAGS_REG))]
6568 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6569 "sbb{b}\t{%2, %0|%0, %2}"
6570 [(set_attr "type" "alu")
6571 (set_attr "pent_pair" "pu")
6572 (set_attr "mode" "QI")])
6573
6574 (define_insn "subhi3_carry"
6575 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6576 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6577 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6578 (match_operand:HI 2 "general_operand" "ri,rm"))))
6579 (clobber (reg:CC FLAGS_REG))]
6580 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6581 "sbb{w}\t{%2, %0|%0, %2}"
6582 [(set_attr "type" "alu")
6583 (set_attr "pent_pair" "pu")
6584 (set_attr "mode" "HI")])
6585
6586 (define_insn "subsi3_carry"
6587 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6588 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6589 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6590 (match_operand:SI 2 "general_operand" "ri,rm"))))
6591 (clobber (reg:CC FLAGS_REG))]
6592 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6593 "sbb{l}\t{%2, %0|%0, %2}"
6594 [(set_attr "type" "alu")
6595 (set_attr "pent_pair" "pu")
6596 (set_attr "mode" "SI")])
6597
6598 (define_insn "subsi3_carry_zext"
6599 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6600 (zero_extend:DI
6601 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6602 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6603 (match_operand:SI 2 "general_operand" "ri,rm")))))
6604 (clobber (reg:CC FLAGS_REG))]
6605 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6606 "sbb{l}\t{%2, %k0|%k0, %2}"
6607 [(set_attr "type" "alu")
6608 (set_attr "pent_pair" "pu")
6609 (set_attr "mode" "SI")])
6610
6611 (define_expand "subsi3"
6612 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6613 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6614 (match_operand:SI 2 "general_operand" "")))
6615 (clobber (reg:CC FLAGS_REG))])]
6616 ""
6617 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6618
6619 (define_insn "*subsi_1"
6620 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6621 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6622 (match_operand:SI 2 "general_operand" "ri,rm")))
6623 (clobber (reg:CC FLAGS_REG))]
6624 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6625 "sub{l}\t{%2, %0|%0, %2}"
6626 [(set_attr "type" "alu")
6627 (set_attr "mode" "SI")])
6628
6629 (define_insn "*subsi_1_zext"
6630 [(set (match_operand:DI 0 "register_operand" "=r")
6631 (zero_extend:DI
6632 (minus:SI (match_operand:SI 1 "register_operand" "0")
6633 (match_operand:SI 2 "general_operand" "rim"))))
6634 (clobber (reg:CC FLAGS_REG))]
6635 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6636 "sub{l}\t{%2, %k0|%k0, %2}"
6637 [(set_attr "type" "alu")
6638 (set_attr "mode" "SI")])
6639
6640 (define_insn "*subsi_2"
6641 [(set (reg FLAGS_REG)
6642 (compare
6643 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6644 (match_operand:SI 2 "general_operand" "ri,rm"))
6645 (const_int 0)))
6646 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6647 (minus:SI (match_dup 1) (match_dup 2)))]
6648 "ix86_match_ccmode (insn, CCGOCmode)
6649 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650 "sub{l}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "mode" "SI")])
6653
6654 (define_insn "*subsi_2_zext"
6655 [(set (reg FLAGS_REG)
6656 (compare
6657 (minus:SI (match_operand:SI 1 "register_operand" "0")
6658 (match_operand:SI 2 "general_operand" "rim"))
6659 (const_int 0)))
6660 (set (match_operand:DI 0 "register_operand" "=r")
6661 (zero_extend:DI
6662 (minus:SI (match_dup 1)
6663 (match_dup 2))))]
6664 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6666 "sub{l}\t{%2, %k0|%k0, %2}"
6667 [(set_attr "type" "alu")
6668 (set_attr "mode" "SI")])
6669
6670 (define_insn "*subsi_3"
6671 [(set (reg FLAGS_REG)
6672 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673 (match_operand:SI 2 "general_operand" "ri,rm")))
6674 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6675 (minus:SI (match_dup 1) (match_dup 2)))]
6676 "ix86_match_ccmode (insn, CCmode)
6677 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6678 "sub{l}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "mode" "SI")])
6681
6682 (define_insn "*subsi_3_zext"
6683 [(set (reg FLAGS_REG)
6684 (compare (match_operand:SI 1 "register_operand" "0")
6685 (match_operand:SI 2 "general_operand" "rim")))
6686 (set (match_operand:DI 0 "register_operand" "=r")
6687 (zero_extend:DI
6688 (minus:SI (match_dup 1)
6689 (match_dup 2))))]
6690 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6691 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6692 "sub{q}\t{%2, %0|%0, %2}"
6693 [(set_attr "type" "alu")
6694 (set_attr "mode" "DI")])
6695
6696 (define_expand "subhi3"
6697 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6698 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6699 (match_operand:HI 2 "general_operand" "")))
6700 (clobber (reg:CC FLAGS_REG))])]
6701 "TARGET_HIMODE_MATH"
6702 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6703
6704 (define_insn "*subhi_1"
6705 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6706 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6707 (match_operand:HI 2 "general_operand" "ri,rm")))
6708 (clobber (reg:CC FLAGS_REG))]
6709 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6710 "sub{w}\t{%2, %0|%0, %2}"
6711 [(set_attr "type" "alu")
6712 (set_attr "mode" "HI")])
6713
6714 (define_insn "*subhi_2"
6715 [(set (reg FLAGS_REG)
6716 (compare
6717 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6718 (match_operand:HI 2 "general_operand" "ri,rm"))
6719 (const_int 0)))
6720 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6721 (minus:HI (match_dup 1) (match_dup 2)))]
6722 "ix86_match_ccmode (insn, CCGOCmode)
6723 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6724 "sub{w}\t{%2, %0|%0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "mode" "HI")])
6727
6728 (define_insn "*subhi_3"
6729 [(set (reg FLAGS_REG)
6730 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6731 (match_operand:HI 2 "general_operand" "ri,rm")))
6732 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6733 (minus:HI (match_dup 1) (match_dup 2)))]
6734 "ix86_match_ccmode (insn, CCmode)
6735 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6736 "sub{w}\t{%2, %0|%0, %2}"
6737 [(set_attr "type" "alu")
6738 (set_attr "mode" "HI")])
6739
6740 (define_expand "subqi3"
6741 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6742 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6743 (match_operand:QI 2 "general_operand" "")))
6744 (clobber (reg:CC FLAGS_REG))])]
6745 "TARGET_QIMODE_MATH"
6746 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6747
6748 (define_insn "*subqi_1"
6749 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6750 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6751 (match_operand:QI 2 "general_operand" "qn,qmn")))
6752 (clobber (reg:CC FLAGS_REG))]
6753 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6754 "sub{b}\t{%2, %0|%0, %2}"
6755 [(set_attr "type" "alu")
6756 (set_attr "mode" "QI")])
6757
6758 (define_insn "*subqi_1_slp"
6759 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6760 (minus:QI (match_dup 0)
6761 (match_operand:QI 1 "general_operand" "qn,qmn")))
6762 (clobber (reg:CC FLAGS_REG))]
6763 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6764 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6765 "sub{b}\t{%1, %0|%0, %1}"
6766 [(set_attr "type" "alu1")
6767 (set_attr "mode" "QI")])
6768
6769 (define_insn "*subqi_2"
6770 [(set (reg FLAGS_REG)
6771 (compare
6772 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6773 (match_operand:QI 2 "general_operand" "qi,qm"))
6774 (const_int 0)))
6775 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6776 (minus:HI (match_dup 1) (match_dup 2)))]
6777 "ix86_match_ccmode (insn, CCGOCmode)
6778 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6779 "sub{b}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "QI")])
6782
6783 (define_insn "*subqi_3"
6784 [(set (reg FLAGS_REG)
6785 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6786 (match_operand:QI 2 "general_operand" "qi,qm")))
6787 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6788 (minus:HI (match_dup 1) (match_dup 2)))]
6789 "ix86_match_ccmode (insn, CCmode)
6790 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6791 "sub{b}\t{%2, %0|%0, %2}"
6792 [(set_attr "type" "alu")
6793 (set_attr "mode" "QI")])
6794
6795 ;; The patterns that match these are at the end of this file.
6796
6797 (define_expand "subxf3"
6798 [(set (match_operand:XF 0 "register_operand" "")
6799 (minus:XF (match_operand:XF 1 "register_operand" "")
6800 (match_operand:XF 2 "register_operand" "")))]
6801 "TARGET_80387"
6802 "")
6803
6804 (define_expand "subdf3"
6805 [(set (match_operand:DF 0 "register_operand" "")
6806 (minus:DF (match_operand:DF 1 "register_operand" "")
6807 (match_operand:DF 2 "nonimmediate_operand" "")))]
6808 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6809 "")
6810
6811 (define_expand "subsf3"
6812 [(set (match_operand:SF 0 "register_operand" "")
6813 (minus:SF (match_operand:SF 1 "register_operand" "")
6814 (match_operand:SF 2 "nonimmediate_operand" "")))]
6815 "TARGET_80387 || TARGET_SSE_MATH"
6816 "")
6817 \f
6818 ;; Multiply instructions
6819
6820 (define_expand "muldi3"
6821 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6822 (mult:DI (match_operand:DI 1 "register_operand" "")
6823 (match_operand:DI 2 "x86_64_general_operand" "")))
6824 (clobber (reg:CC FLAGS_REG))])]
6825 "TARGET_64BIT"
6826 "")
6827
6828 (define_insn "*muldi3_1_rex64"
6829 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6830 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6831 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6832 (clobber (reg:CC FLAGS_REG))]
6833 "TARGET_64BIT
6834 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6835 "@
6836 imul{q}\t{%2, %1, %0|%0, %1, %2}
6837 imul{q}\t{%2, %1, %0|%0, %1, %2}
6838 imul{q}\t{%2, %0|%0, %2}"
6839 [(set_attr "type" "imul")
6840 (set_attr "prefix_0f" "0,0,1")
6841 (set (attr "athlon_decode")
6842 (cond [(eq_attr "cpu" "athlon")
6843 (const_string "vector")
6844 (eq_attr "alternative" "1")
6845 (const_string "vector")
6846 (and (eq_attr "alternative" "2")
6847 (match_operand 1 "memory_operand" ""))
6848 (const_string "vector")]
6849 (const_string "direct")))
6850 (set_attr "mode" "DI")])
6851
6852 (define_expand "mulsi3"
6853 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6854 (mult:SI (match_operand:SI 1 "register_operand" "")
6855 (match_operand:SI 2 "general_operand" "")))
6856 (clobber (reg:CC FLAGS_REG))])]
6857 ""
6858 "")
6859
6860 (define_insn "*mulsi3_1"
6861 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6862 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6863 (match_operand:SI 2 "general_operand" "K,i,mr")))
6864 (clobber (reg:CC FLAGS_REG))]
6865 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6866 "@
6867 imul{l}\t{%2, %1, %0|%0, %1, %2}
6868 imul{l}\t{%2, %1, %0|%0, %1, %2}
6869 imul{l}\t{%2, %0|%0, %2}"
6870 [(set_attr "type" "imul")
6871 (set_attr "prefix_0f" "0,0,1")
6872 (set (attr "athlon_decode")
6873 (cond [(eq_attr "cpu" "athlon")
6874 (const_string "vector")
6875 (eq_attr "alternative" "1")
6876 (const_string "vector")
6877 (and (eq_attr "alternative" "2")
6878 (match_operand 1 "memory_operand" ""))
6879 (const_string "vector")]
6880 (const_string "direct")))
6881 (set_attr "mode" "SI")])
6882
6883 (define_insn "*mulsi3_1_zext"
6884 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6885 (zero_extend:DI
6886 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6887 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6888 (clobber (reg:CC FLAGS_REG))]
6889 "TARGET_64BIT
6890 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6891 "@
6892 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6893 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6894 imul{l}\t{%2, %k0|%k0, %2}"
6895 [(set_attr "type" "imul")
6896 (set_attr "prefix_0f" "0,0,1")
6897 (set (attr "athlon_decode")
6898 (cond [(eq_attr "cpu" "athlon")
6899 (const_string "vector")
6900 (eq_attr "alternative" "1")
6901 (const_string "vector")
6902 (and (eq_attr "alternative" "2")
6903 (match_operand 1 "memory_operand" ""))
6904 (const_string "vector")]
6905 (const_string "direct")))
6906 (set_attr "mode" "SI")])
6907
6908 (define_expand "mulhi3"
6909 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6910 (mult:HI (match_operand:HI 1 "register_operand" "")
6911 (match_operand:HI 2 "general_operand" "")))
6912 (clobber (reg:CC FLAGS_REG))])]
6913 "TARGET_HIMODE_MATH"
6914 "")
6915
6916 (define_insn "*mulhi3_1"
6917 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6918 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6919 (match_operand:HI 2 "general_operand" "K,i,mr")))
6920 (clobber (reg:CC FLAGS_REG))]
6921 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6922 "@
6923 imul{w}\t{%2, %1, %0|%0, %1, %2}
6924 imul{w}\t{%2, %1, %0|%0, %1, %2}
6925 imul{w}\t{%2, %0|%0, %2}"
6926 [(set_attr "type" "imul")
6927 (set_attr "prefix_0f" "0,0,1")
6928 (set (attr "athlon_decode")
6929 (cond [(eq_attr "cpu" "athlon")
6930 (const_string "vector")
6931 (eq_attr "alternative" "1,2")
6932 (const_string "vector")]
6933 (const_string "direct")))
6934 (set_attr "mode" "HI")])
6935
6936 (define_expand "mulqi3"
6937 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6938 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6939 (match_operand:QI 2 "register_operand" "")))
6940 (clobber (reg:CC FLAGS_REG))])]
6941 "TARGET_QIMODE_MATH"
6942 "")
6943
6944 (define_insn "*mulqi3_1"
6945 [(set (match_operand:QI 0 "register_operand" "=a")
6946 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6947 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6948 (clobber (reg:CC FLAGS_REG))]
6949 "TARGET_QIMODE_MATH
6950 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6951 "mul{b}\t%2"
6952 [(set_attr "type" "imul")
6953 (set_attr "length_immediate" "0")
6954 (set (attr "athlon_decode")
6955 (if_then_else (eq_attr "cpu" "athlon")
6956 (const_string "vector")
6957 (const_string "direct")))
6958 (set_attr "mode" "QI")])
6959
6960 (define_expand "umulqihi3"
6961 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6962 (mult:HI (zero_extend:HI
6963 (match_operand:QI 1 "nonimmediate_operand" ""))
6964 (zero_extend:HI
6965 (match_operand:QI 2 "register_operand" ""))))
6966 (clobber (reg:CC FLAGS_REG))])]
6967 "TARGET_QIMODE_MATH"
6968 "")
6969
6970 (define_insn "*umulqihi3_1"
6971 [(set (match_operand:HI 0 "register_operand" "=a")
6972 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6973 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6974 (clobber (reg:CC FLAGS_REG))]
6975 "TARGET_QIMODE_MATH
6976 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6977 "mul{b}\t%2"
6978 [(set_attr "type" "imul")
6979 (set_attr "length_immediate" "0")
6980 (set (attr "athlon_decode")
6981 (if_then_else (eq_attr "cpu" "athlon")
6982 (const_string "vector")
6983 (const_string "direct")))
6984 (set_attr "mode" "QI")])
6985
6986 (define_expand "mulqihi3"
6987 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6988 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6989 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6990 (clobber (reg:CC FLAGS_REG))])]
6991 "TARGET_QIMODE_MATH"
6992 "")
6993
6994 (define_insn "*mulqihi3_insn"
6995 [(set (match_operand:HI 0 "register_operand" "=a")
6996 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6997 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6998 (clobber (reg:CC FLAGS_REG))]
6999 "TARGET_QIMODE_MATH
7000 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7001 "imul{b}\t%2"
7002 [(set_attr "type" "imul")
7003 (set_attr "length_immediate" "0")
7004 (set (attr "athlon_decode")
7005 (if_then_else (eq_attr "cpu" "athlon")
7006 (const_string "vector")
7007 (const_string "direct")))
7008 (set_attr "mode" "QI")])
7009
7010 (define_expand "umulditi3"
7011 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7012 (mult:TI (zero_extend:TI
7013 (match_operand:DI 1 "nonimmediate_operand" ""))
7014 (zero_extend:TI
7015 (match_operand:DI 2 "register_operand" ""))))
7016 (clobber (reg:CC FLAGS_REG))])]
7017 "TARGET_64BIT"
7018 "")
7019
7020 (define_insn "*umulditi3_insn"
7021 [(set (match_operand:TI 0 "register_operand" "=A")
7022 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7023 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7024 (clobber (reg:CC FLAGS_REG))]
7025 "TARGET_64BIT
7026 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7027 "mul{q}\t%2"
7028 [(set_attr "type" "imul")
7029 (set_attr "length_immediate" "0")
7030 (set (attr "athlon_decode")
7031 (if_then_else (eq_attr "cpu" "athlon")
7032 (const_string "vector")
7033 (const_string "double")))
7034 (set_attr "mode" "DI")])
7035
7036 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7037 (define_expand "umulsidi3"
7038 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7039 (mult:DI (zero_extend:DI
7040 (match_operand:SI 1 "nonimmediate_operand" ""))
7041 (zero_extend:DI
7042 (match_operand:SI 2 "register_operand" ""))))
7043 (clobber (reg:CC FLAGS_REG))])]
7044 "!TARGET_64BIT"
7045 "")
7046
7047 (define_insn "*umulsidi3_insn"
7048 [(set (match_operand:DI 0 "register_operand" "=A")
7049 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7050 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7051 (clobber (reg:CC FLAGS_REG))]
7052 "!TARGET_64BIT
7053 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7054 "mul{l}\t%2"
7055 [(set_attr "type" "imul")
7056 (set_attr "length_immediate" "0")
7057 (set (attr "athlon_decode")
7058 (if_then_else (eq_attr "cpu" "athlon")
7059 (const_string "vector")
7060 (const_string "double")))
7061 (set_attr "mode" "SI")])
7062
7063 (define_expand "mulditi3"
7064 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7065 (mult:TI (sign_extend:TI
7066 (match_operand:DI 1 "nonimmediate_operand" ""))
7067 (sign_extend:TI
7068 (match_operand:DI 2 "register_operand" ""))))
7069 (clobber (reg:CC FLAGS_REG))])]
7070 "TARGET_64BIT"
7071 "")
7072
7073 (define_insn "*mulditi3_insn"
7074 [(set (match_operand:TI 0 "register_operand" "=A")
7075 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7076 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7077 (clobber (reg:CC FLAGS_REG))]
7078 "TARGET_64BIT
7079 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7080 "imul{q}\t%2"
7081 [(set_attr "type" "imul")
7082 (set_attr "length_immediate" "0")
7083 (set (attr "athlon_decode")
7084 (if_then_else (eq_attr "cpu" "athlon")
7085 (const_string "vector")
7086 (const_string "double")))
7087 (set_attr "mode" "DI")])
7088
7089 (define_expand "mulsidi3"
7090 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7091 (mult:DI (sign_extend:DI
7092 (match_operand:SI 1 "nonimmediate_operand" ""))
7093 (sign_extend:DI
7094 (match_operand:SI 2 "register_operand" ""))))
7095 (clobber (reg:CC FLAGS_REG))])]
7096 "!TARGET_64BIT"
7097 "")
7098
7099 (define_insn "*mulsidi3_insn"
7100 [(set (match_operand:DI 0 "register_operand" "=A")
7101 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7102 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7103 (clobber (reg:CC FLAGS_REG))]
7104 "!TARGET_64BIT
7105 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7106 "imul{l}\t%2"
7107 [(set_attr "type" "imul")
7108 (set_attr "length_immediate" "0")
7109 (set (attr "athlon_decode")
7110 (if_then_else (eq_attr "cpu" "athlon")
7111 (const_string "vector")
7112 (const_string "double")))
7113 (set_attr "mode" "SI")])
7114
7115 (define_expand "umuldi3_highpart"
7116 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7117 (truncate:DI
7118 (lshiftrt:TI
7119 (mult:TI (zero_extend:TI
7120 (match_operand:DI 1 "nonimmediate_operand" ""))
7121 (zero_extend:TI
7122 (match_operand:DI 2 "register_operand" "")))
7123 (const_int 64))))
7124 (clobber (match_scratch:DI 3 ""))
7125 (clobber (reg:CC FLAGS_REG))])]
7126 "TARGET_64BIT"
7127 "")
7128
7129 (define_insn "*umuldi3_highpart_rex64"
7130 [(set (match_operand:DI 0 "register_operand" "=d")
7131 (truncate:DI
7132 (lshiftrt:TI
7133 (mult:TI (zero_extend:TI
7134 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7135 (zero_extend:TI
7136 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7137 (const_int 64))))
7138 (clobber (match_scratch:DI 3 "=1"))
7139 (clobber (reg:CC FLAGS_REG))]
7140 "TARGET_64BIT
7141 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7142 "mul{q}\t%2"
7143 [(set_attr "type" "imul")
7144 (set_attr "length_immediate" "0")
7145 (set (attr "athlon_decode")
7146 (if_then_else (eq_attr "cpu" "athlon")
7147 (const_string "vector")
7148 (const_string "double")))
7149 (set_attr "mode" "DI")])
7150
7151 (define_expand "umulsi3_highpart"
7152 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7153 (truncate:SI
7154 (lshiftrt:DI
7155 (mult:DI (zero_extend:DI
7156 (match_operand:SI 1 "nonimmediate_operand" ""))
7157 (zero_extend:DI
7158 (match_operand:SI 2 "register_operand" "")))
7159 (const_int 32))))
7160 (clobber (match_scratch:SI 3 ""))
7161 (clobber (reg:CC FLAGS_REG))])]
7162 ""
7163 "")
7164
7165 (define_insn "*umulsi3_highpart_insn"
7166 [(set (match_operand:SI 0 "register_operand" "=d")
7167 (truncate:SI
7168 (lshiftrt:DI
7169 (mult:DI (zero_extend:DI
7170 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7171 (zero_extend:DI
7172 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7173 (const_int 32))))
7174 (clobber (match_scratch:SI 3 "=1"))
7175 (clobber (reg:CC FLAGS_REG))]
7176 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7177 "mul{l}\t%2"
7178 [(set_attr "type" "imul")
7179 (set_attr "length_immediate" "0")
7180 (set (attr "athlon_decode")
7181 (if_then_else (eq_attr "cpu" "athlon")
7182 (const_string "vector")
7183 (const_string "double")))
7184 (set_attr "mode" "SI")])
7185
7186 (define_insn "*umulsi3_highpart_zext"
7187 [(set (match_operand:DI 0 "register_operand" "=d")
7188 (zero_extend:DI (truncate:SI
7189 (lshiftrt:DI
7190 (mult:DI (zero_extend:DI
7191 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7192 (zero_extend:DI
7193 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7194 (const_int 32)))))
7195 (clobber (match_scratch:SI 3 "=1"))
7196 (clobber (reg:CC FLAGS_REG))]
7197 "TARGET_64BIT
7198 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7199 "mul{l}\t%2"
7200 [(set_attr "type" "imul")
7201 (set_attr "length_immediate" "0")
7202 (set (attr "athlon_decode")
7203 (if_then_else (eq_attr "cpu" "athlon")
7204 (const_string "vector")
7205 (const_string "double")))
7206 (set_attr "mode" "SI")])
7207
7208 (define_expand "smuldi3_highpart"
7209 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7210 (truncate:DI
7211 (lshiftrt:TI
7212 (mult:TI (sign_extend:TI
7213 (match_operand:DI 1 "nonimmediate_operand" ""))
7214 (sign_extend:TI
7215 (match_operand:DI 2 "register_operand" "")))
7216 (const_int 64))))
7217 (clobber (match_scratch:DI 3 ""))
7218 (clobber (reg:CC FLAGS_REG))])]
7219 "TARGET_64BIT"
7220 "")
7221
7222 (define_insn "*smuldi3_highpart_rex64"
7223 [(set (match_operand:DI 0 "register_operand" "=d")
7224 (truncate:DI
7225 (lshiftrt:TI
7226 (mult:TI (sign_extend:TI
7227 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7228 (sign_extend:TI
7229 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7230 (const_int 64))))
7231 (clobber (match_scratch:DI 3 "=1"))
7232 (clobber (reg:CC FLAGS_REG))]
7233 "TARGET_64BIT
7234 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235 "imul{q}\t%2"
7236 [(set_attr "type" "imul")
7237 (set (attr "athlon_decode")
7238 (if_then_else (eq_attr "cpu" "athlon")
7239 (const_string "vector")
7240 (const_string "double")))
7241 (set_attr "mode" "DI")])
7242
7243 (define_expand "smulsi3_highpart"
7244 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7245 (truncate:SI
7246 (lshiftrt:DI
7247 (mult:DI (sign_extend:DI
7248 (match_operand:SI 1 "nonimmediate_operand" ""))
7249 (sign_extend:DI
7250 (match_operand:SI 2 "register_operand" "")))
7251 (const_int 32))))
7252 (clobber (match_scratch:SI 3 ""))
7253 (clobber (reg:CC FLAGS_REG))])]
7254 ""
7255 "")
7256
7257 (define_insn "*smulsi3_highpart_insn"
7258 [(set (match_operand:SI 0 "register_operand" "=d")
7259 (truncate:SI
7260 (lshiftrt:DI
7261 (mult:DI (sign_extend:DI
7262 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7263 (sign_extend:DI
7264 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7265 (const_int 32))))
7266 (clobber (match_scratch:SI 3 "=1"))
7267 (clobber (reg:CC FLAGS_REG))]
7268 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7269 "imul{l}\t%2"
7270 [(set_attr "type" "imul")
7271 (set (attr "athlon_decode")
7272 (if_then_else (eq_attr "cpu" "athlon")
7273 (const_string "vector")
7274 (const_string "double")))
7275 (set_attr "mode" "SI")])
7276
7277 (define_insn "*smulsi3_highpart_zext"
7278 [(set (match_operand:DI 0 "register_operand" "=d")
7279 (zero_extend:DI (truncate:SI
7280 (lshiftrt:DI
7281 (mult:DI (sign_extend:DI
7282 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7283 (sign_extend:DI
7284 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7285 (const_int 32)))))
7286 (clobber (match_scratch:SI 3 "=1"))
7287 (clobber (reg:CC FLAGS_REG))]
7288 "TARGET_64BIT
7289 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7290 "imul{l}\t%2"
7291 [(set_attr "type" "imul")
7292 (set (attr "athlon_decode")
7293 (if_then_else (eq_attr "cpu" "athlon")
7294 (const_string "vector")
7295 (const_string "double")))
7296 (set_attr "mode" "SI")])
7297
7298 ;; The patterns that match these are at the end of this file.
7299
7300 (define_expand "mulxf3"
7301 [(set (match_operand:XF 0 "register_operand" "")
7302 (mult:XF (match_operand:XF 1 "register_operand" "")
7303 (match_operand:XF 2 "register_operand" "")))]
7304 "TARGET_80387"
7305 "")
7306
7307 (define_expand "muldf3"
7308 [(set (match_operand:DF 0 "register_operand" "")
7309 (mult:DF (match_operand:DF 1 "register_operand" "")
7310 (match_operand:DF 2 "nonimmediate_operand" "")))]
7311 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7312 "")
7313
7314 (define_expand "mulsf3"
7315 [(set (match_operand:SF 0 "register_operand" "")
7316 (mult:SF (match_operand:SF 1 "register_operand" "")
7317 (match_operand:SF 2 "nonimmediate_operand" "")))]
7318 "TARGET_80387 || TARGET_SSE_MATH"
7319 "")
7320 \f
7321 ;; Divide instructions
7322
7323 (define_insn "divqi3"
7324 [(set (match_operand:QI 0 "register_operand" "=a")
7325 (div:QI (match_operand:HI 1 "register_operand" "0")
7326 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7327 (clobber (reg:CC FLAGS_REG))]
7328 "TARGET_QIMODE_MATH"
7329 "idiv{b}\t%2"
7330 [(set_attr "type" "idiv")
7331 (set_attr "mode" "QI")])
7332
7333 (define_insn "udivqi3"
7334 [(set (match_operand:QI 0 "register_operand" "=a")
7335 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7336 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7337 (clobber (reg:CC FLAGS_REG))]
7338 "TARGET_QIMODE_MATH"
7339 "div{b}\t%2"
7340 [(set_attr "type" "idiv")
7341 (set_attr "mode" "QI")])
7342
7343 ;; The patterns that match these are at the end of this file.
7344
7345 (define_expand "divxf3"
7346 [(set (match_operand:XF 0 "register_operand" "")
7347 (div:XF (match_operand:XF 1 "register_operand" "")
7348 (match_operand:XF 2 "register_operand" "")))]
7349 "TARGET_80387"
7350 "")
7351
7352 (define_expand "divdf3"
7353 [(set (match_operand:DF 0 "register_operand" "")
7354 (div:DF (match_operand:DF 1 "register_operand" "")
7355 (match_operand:DF 2 "nonimmediate_operand" "")))]
7356 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7357 "")
7358
7359 (define_expand "divsf3"
7360 [(set (match_operand:SF 0 "register_operand" "")
7361 (div:SF (match_operand:SF 1 "register_operand" "")
7362 (match_operand:SF 2 "nonimmediate_operand" "")))]
7363 "TARGET_80387 || TARGET_SSE_MATH"
7364 "")
7365 \f
7366 ;; Remainder instructions.
7367
7368 (define_expand "divmoddi4"
7369 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7370 (div:DI (match_operand:DI 1 "register_operand" "")
7371 (match_operand:DI 2 "nonimmediate_operand" "")))
7372 (set (match_operand:DI 3 "register_operand" "")
7373 (mod:DI (match_dup 1) (match_dup 2)))
7374 (clobber (reg:CC FLAGS_REG))])]
7375 "TARGET_64BIT"
7376 "")
7377
7378 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7379 ;; Penalize eax case slightly because it results in worse scheduling
7380 ;; of code.
7381 (define_insn "*divmoddi4_nocltd_rex64"
7382 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7383 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7384 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7385 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7386 (mod:DI (match_dup 2) (match_dup 3)))
7387 (clobber (reg:CC FLAGS_REG))]
7388 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7389 "#"
7390 [(set_attr "type" "multi")])
7391
7392 (define_insn "*divmoddi4_cltd_rex64"
7393 [(set (match_operand:DI 0 "register_operand" "=a")
7394 (div:DI (match_operand:DI 2 "register_operand" "a")
7395 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7396 (set (match_operand:DI 1 "register_operand" "=&d")
7397 (mod:DI (match_dup 2) (match_dup 3)))
7398 (clobber (reg:CC FLAGS_REG))]
7399 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7400 "#"
7401 [(set_attr "type" "multi")])
7402
7403 (define_insn "*divmoddi_noext_rex64"
7404 [(set (match_operand:DI 0 "register_operand" "=a")
7405 (div:DI (match_operand:DI 1 "register_operand" "0")
7406 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7407 (set (match_operand:DI 3 "register_operand" "=d")
7408 (mod:DI (match_dup 1) (match_dup 2)))
7409 (use (match_operand:DI 4 "register_operand" "3"))
7410 (clobber (reg:CC FLAGS_REG))]
7411 "TARGET_64BIT"
7412 "idiv{q}\t%2"
7413 [(set_attr "type" "idiv")
7414 (set_attr "mode" "DI")])
7415
7416 (define_split
7417 [(set (match_operand:DI 0 "register_operand" "")
7418 (div:DI (match_operand:DI 1 "register_operand" "")
7419 (match_operand:DI 2 "nonimmediate_operand" "")))
7420 (set (match_operand:DI 3 "register_operand" "")
7421 (mod:DI (match_dup 1) (match_dup 2)))
7422 (clobber (reg:CC FLAGS_REG))]
7423 "TARGET_64BIT && reload_completed"
7424 [(parallel [(set (match_dup 3)
7425 (ashiftrt:DI (match_dup 4) (const_int 63)))
7426 (clobber (reg:CC FLAGS_REG))])
7427 (parallel [(set (match_dup 0)
7428 (div:DI (reg:DI 0) (match_dup 2)))
7429 (set (match_dup 3)
7430 (mod:DI (reg:DI 0) (match_dup 2)))
7431 (use (match_dup 3))
7432 (clobber (reg:CC FLAGS_REG))])]
7433 {
7434 /* Avoid use of cltd in favor of a mov+shift. */
7435 if (!TARGET_USE_CLTD && !optimize_size)
7436 {
7437 if (true_regnum (operands[1]))
7438 emit_move_insn (operands[0], operands[1]);
7439 else
7440 emit_move_insn (operands[3], operands[1]);
7441 operands[4] = operands[3];
7442 }
7443 else
7444 {
7445 gcc_assert (!true_regnum (operands[1]));
7446 operands[4] = operands[1];
7447 }
7448 })
7449
7450
7451 (define_expand "divmodsi4"
7452 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7453 (div:SI (match_operand:SI 1 "register_operand" "")
7454 (match_operand:SI 2 "nonimmediate_operand" "")))
7455 (set (match_operand:SI 3 "register_operand" "")
7456 (mod:SI (match_dup 1) (match_dup 2)))
7457 (clobber (reg:CC FLAGS_REG))])]
7458 ""
7459 "")
7460
7461 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7462 ;; Penalize eax case slightly because it results in worse scheduling
7463 ;; of code.
7464 (define_insn "*divmodsi4_nocltd"
7465 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7466 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7467 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7468 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7469 (mod:SI (match_dup 2) (match_dup 3)))
7470 (clobber (reg:CC FLAGS_REG))]
7471 "!optimize_size && !TARGET_USE_CLTD"
7472 "#"
7473 [(set_attr "type" "multi")])
7474
7475 (define_insn "*divmodsi4_cltd"
7476 [(set (match_operand:SI 0 "register_operand" "=a")
7477 (div:SI (match_operand:SI 2 "register_operand" "a")
7478 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7479 (set (match_operand:SI 1 "register_operand" "=&d")
7480 (mod:SI (match_dup 2) (match_dup 3)))
7481 (clobber (reg:CC FLAGS_REG))]
7482 "optimize_size || TARGET_USE_CLTD"
7483 "#"
7484 [(set_attr "type" "multi")])
7485
7486 (define_insn "*divmodsi_noext"
7487 [(set (match_operand:SI 0 "register_operand" "=a")
7488 (div:SI (match_operand:SI 1 "register_operand" "0")
7489 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7490 (set (match_operand:SI 3 "register_operand" "=d")
7491 (mod:SI (match_dup 1) (match_dup 2)))
7492 (use (match_operand:SI 4 "register_operand" "3"))
7493 (clobber (reg:CC FLAGS_REG))]
7494 ""
7495 "idiv{l}\t%2"
7496 [(set_attr "type" "idiv")
7497 (set_attr "mode" "SI")])
7498
7499 (define_split
7500 [(set (match_operand:SI 0 "register_operand" "")
7501 (div:SI (match_operand:SI 1 "register_operand" "")
7502 (match_operand:SI 2 "nonimmediate_operand" "")))
7503 (set (match_operand:SI 3 "register_operand" "")
7504 (mod:SI (match_dup 1) (match_dup 2)))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "reload_completed"
7507 [(parallel [(set (match_dup 3)
7508 (ashiftrt:SI (match_dup 4) (const_int 31)))
7509 (clobber (reg:CC FLAGS_REG))])
7510 (parallel [(set (match_dup 0)
7511 (div:SI (reg:SI 0) (match_dup 2)))
7512 (set (match_dup 3)
7513 (mod:SI (reg:SI 0) (match_dup 2)))
7514 (use (match_dup 3))
7515 (clobber (reg:CC FLAGS_REG))])]
7516 {
7517 /* Avoid use of cltd in favor of a mov+shift. */
7518 if (!TARGET_USE_CLTD && !optimize_size)
7519 {
7520 if (true_regnum (operands[1]))
7521 emit_move_insn (operands[0], operands[1]);
7522 else
7523 emit_move_insn (operands[3], operands[1]);
7524 operands[4] = operands[3];
7525 }
7526 else
7527 {
7528 gcc_assert (!true_regnum (operands[1]));
7529 operands[4] = operands[1];
7530 }
7531 })
7532 ;; %%% Split me.
7533 (define_insn "divmodhi4"
7534 [(set (match_operand:HI 0 "register_operand" "=a")
7535 (div:HI (match_operand:HI 1 "register_operand" "0")
7536 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7537 (set (match_operand:HI 3 "register_operand" "=&d")
7538 (mod:HI (match_dup 1) (match_dup 2)))
7539 (clobber (reg:CC FLAGS_REG))]
7540 "TARGET_HIMODE_MATH"
7541 "cwtd\;idiv{w}\t%2"
7542 [(set_attr "type" "multi")
7543 (set_attr "length_immediate" "0")
7544 (set_attr "mode" "SI")])
7545
7546 (define_insn "udivmoddi4"
7547 [(set (match_operand:DI 0 "register_operand" "=a")
7548 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7549 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7550 (set (match_operand:DI 3 "register_operand" "=&d")
7551 (umod:DI (match_dup 1) (match_dup 2)))
7552 (clobber (reg:CC FLAGS_REG))]
7553 "TARGET_64BIT"
7554 "xor{q}\t%3, %3\;div{q}\t%2"
7555 [(set_attr "type" "multi")
7556 (set_attr "length_immediate" "0")
7557 (set_attr "mode" "DI")])
7558
7559 (define_insn "*udivmoddi4_noext"
7560 [(set (match_operand:DI 0 "register_operand" "=a")
7561 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7562 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7563 (set (match_operand:DI 3 "register_operand" "=d")
7564 (umod:DI (match_dup 1) (match_dup 2)))
7565 (use (match_dup 3))
7566 (clobber (reg:CC FLAGS_REG))]
7567 "TARGET_64BIT"
7568 "div{q}\t%2"
7569 [(set_attr "type" "idiv")
7570 (set_attr "mode" "DI")])
7571
7572 (define_split
7573 [(set (match_operand:DI 0 "register_operand" "")
7574 (udiv:DI (match_operand:DI 1 "register_operand" "")
7575 (match_operand:DI 2 "nonimmediate_operand" "")))
7576 (set (match_operand:DI 3 "register_operand" "")
7577 (umod:DI (match_dup 1) (match_dup 2)))
7578 (clobber (reg:CC FLAGS_REG))]
7579 "TARGET_64BIT && reload_completed"
7580 [(set (match_dup 3) (const_int 0))
7581 (parallel [(set (match_dup 0)
7582 (udiv:DI (match_dup 1) (match_dup 2)))
7583 (set (match_dup 3)
7584 (umod:DI (match_dup 1) (match_dup 2)))
7585 (use (match_dup 3))
7586 (clobber (reg:CC FLAGS_REG))])]
7587 "")
7588
7589 (define_insn "udivmodsi4"
7590 [(set (match_operand:SI 0 "register_operand" "=a")
7591 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7592 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7593 (set (match_operand:SI 3 "register_operand" "=&d")
7594 (umod:SI (match_dup 1) (match_dup 2)))
7595 (clobber (reg:CC FLAGS_REG))]
7596 ""
7597 "xor{l}\t%3, %3\;div{l}\t%2"
7598 [(set_attr "type" "multi")
7599 (set_attr "length_immediate" "0")
7600 (set_attr "mode" "SI")])
7601
7602 (define_insn "*udivmodsi4_noext"
7603 [(set (match_operand:SI 0 "register_operand" "=a")
7604 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7605 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7606 (set (match_operand:SI 3 "register_operand" "=d")
7607 (umod:SI (match_dup 1) (match_dup 2)))
7608 (use (match_dup 3))
7609 (clobber (reg:CC FLAGS_REG))]
7610 ""
7611 "div{l}\t%2"
7612 [(set_attr "type" "idiv")
7613 (set_attr "mode" "SI")])
7614
7615 (define_split
7616 [(set (match_operand:SI 0 "register_operand" "")
7617 (udiv:SI (match_operand:SI 1 "register_operand" "")
7618 (match_operand:SI 2 "nonimmediate_operand" "")))
7619 (set (match_operand:SI 3 "register_operand" "")
7620 (umod:SI (match_dup 1) (match_dup 2)))
7621 (clobber (reg:CC FLAGS_REG))]
7622 "reload_completed"
7623 [(set (match_dup 3) (const_int 0))
7624 (parallel [(set (match_dup 0)
7625 (udiv:SI (match_dup 1) (match_dup 2)))
7626 (set (match_dup 3)
7627 (umod:SI (match_dup 1) (match_dup 2)))
7628 (use (match_dup 3))
7629 (clobber (reg:CC FLAGS_REG))])]
7630 "")
7631
7632 (define_expand "udivmodhi4"
7633 [(set (match_dup 4) (const_int 0))
7634 (parallel [(set (match_operand:HI 0 "register_operand" "")
7635 (udiv:HI (match_operand:HI 1 "register_operand" "")
7636 (match_operand:HI 2 "nonimmediate_operand" "")))
7637 (set (match_operand:HI 3 "register_operand" "")
7638 (umod:HI (match_dup 1) (match_dup 2)))
7639 (use (match_dup 4))
7640 (clobber (reg:CC FLAGS_REG))])]
7641 "TARGET_HIMODE_MATH"
7642 "operands[4] = gen_reg_rtx (HImode);")
7643
7644 (define_insn "*udivmodhi_noext"
7645 [(set (match_operand:HI 0 "register_operand" "=a")
7646 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7647 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7648 (set (match_operand:HI 3 "register_operand" "=d")
7649 (umod:HI (match_dup 1) (match_dup 2)))
7650 (use (match_operand:HI 4 "register_operand" "3"))
7651 (clobber (reg:CC FLAGS_REG))]
7652 ""
7653 "div{w}\t%2"
7654 [(set_attr "type" "idiv")
7655 (set_attr "mode" "HI")])
7656
7657 ;; We cannot use div/idiv for double division, because it causes
7658 ;; "division by zero" on the overflow and that's not what we expect
7659 ;; from truncate. Because true (non truncating) double division is
7660 ;; never generated, we can't create this insn anyway.
7661 ;
7662 ;(define_insn ""
7663 ; [(set (match_operand:SI 0 "register_operand" "=a")
7664 ; (truncate:SI
7665 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7666 ; (zero_extend:DI
7667 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7668 ; (set (match_operand:SI 3 "register_operand" "=d")
7669 ; (truncate:SI
7670 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7671 ; (clobber (reg:CC FLAGS_REG))]
7672 ; ""
7673 ; "div{l}\t{%2, %0|%0, %2}"
7674 ; [(set_attr "type" "idiv")])
7675 \f
7676 ;;- Logical AND instructions
7677
7678 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7679 ;; Note that this excludes ah.
7680
7681 (define_insn "*testdi_1_rex64"
7682 [(set (reg FLAGS_REG)
7683 (compare
7684 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7685 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7686 (const_int 0)))]
7687 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7688 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7689 "@
7690 test{l}\t{%k1, %k0|%k0, %k1}
7691 test{l}\t{%k1, %k0|%k0, %k1}
7692 test{q}\t{%1, %0|%0, %1}
7693 test{q}\t{%1, %0|%0, %1}
7694 test{q}\t{%1, %0|%0, %1}"
7695 [(set_attr "type" "test")
7696 (set_attr "modrm" "0,1,0,1,1")
7697 (set_attr "mode" "SI,SI,DI,DI,DI")
7698 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7699
7700 (define_insn "testsi_1"
7701 [(set (reg FLAGS_REG)
7702 (compare
7703 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7704 (match_operand:SI 1 "general_operand" "in,in,rin"))
7705 (const_int 0)))]
7706 "ix86_match_ccmode (insn, CCNOmode)
7707 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7708 "test{l}\t{%1, %0|%0, %1}"
7709 [(set_attr "type" "test")
7710 (set_attr "modrm" "0,1,1")
7711 (set_attr "mode" "SI")
7712 (set_attr "pent_pair" "uv,np,uv")])
7713
7714 (define_expand "testsi_ccno_1"
7715 [(set (reg:CCNO FLAGS_REG)
7716 (compare:CCNO
7717 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7718 (match_operand:SI 1 "nonmemory_operand" ""))
7719 (const_int 0)))]
7720 ""
7721 "")
7722
7723 (define_insn "*testhi_1"
7724 [(set (reg FLAGS_REG)
7725 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7726 (match_operand:HI 1 "general_operand" "n,n,rn"))
7727 (const_int 0)))]
7728 "ix86_match_ccmode (insn, CCNOmode)
7729 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7730 "test{w}\t{%1, %0|%0, %1}"
7731 [(set_attr "type" "test")
7732 (set_attr "modrm" "0,1,1")
7733 (set_attr "mode" "HI")
7734 (set_attr "pent_pair" "uv,np,uv")])
7735
7736 (define_expand "testqi_ccz_1"
7737 [(set (reg:CCZ FLAGS_REG)
7738 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7739 (match_operand:QI 1 "nonmemory_operand" ""))
7740 (const_int 0)))]
7741 ""
7742 "")
7743
7744 (define_insn "*testqi_1_maybe_si"
7745 [(set (reg FLAGS_REG)
7746 (compare
7747 (and:QI
7748 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7749 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7750 (const_int 0)))]
7751 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7752 && ix86_match_ccmode (insn,
7753 GET_CODE (operands[1]) == CONST_INT
7754 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7755 {
7756 if (which_alternative == 3)
7757 {
7758 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7759 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7760 return "test{l}\t{%1, %k0|%k0, %1}";
7761 }
7762 return "test{b}\t{%1, %0|%0, %1}";
7763 }
7764 [(set_attr "type" "test")
7765 (set_attr "modrm" "0,1,1,1")
7766 (set_attr "mode" "QI,QI,QI,SI")
7767 (set_attr "pent_pair" "uv,np,uv,np")])
7768
7769 (define_insn "*testqi_1"
7770 [(set (reg FLAGS_REG)
7771 (compare
7772 (and:QI
7773 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7774 (match_operand:QI 1 "general_operand" "n,n,qn"))
7775 (const_int 0)))]
7776 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7777 && ix86_match_ccmode (insn, CCNOmode)"
7778 "test{b}\t{%1, %0|%0, %1}"
7779 [(set_attr "type" "test")
7780 (set_attr "modrm" "0,1,1")
7781 (set_attr "mode" "QI")
7782 (set_attr "pent_pair" "uv,np,uv")])
7783
7784 (define_expand "testqi_ext_ccno_0"
7785 [(set (reg:CCNO FLAGS_REG)
7786 (compare:CCNO
7787 (and:SI
7788 (zero_extract:SI
7789 (match_operand 0 "ext_register_operand" "")
7790 (const_int 8)
7791 (const_int 8))
7792 (match_operand 1 "const_int_operand" ""))
7793 (const_int 0)))]
7794 ""
7795 "")
7796
7797 (define_insn "*testqi_ext_0"
7798 [(set (reg FLAGS_REG)
7799 (compare
7800 (and:SI
7801 (zero_extract:SI
7802 (match_operand 0 "ext_register_operand" "Q")
7803 (const_int 8)
7804 (const_int 8))
7805 (match_operand 1 "const_int_operand" "n"))
7806 (const_int 0)))]
7807 "ix86_match_ccmode (insn, CCNOmode)"
7808 "test{b}\t{%1, %h0|%h0, %1}"
7809 [(set_attr "type" "test")
7810 (set_attr "mode" "QI")
7811 (set_attr "length_immediate" "1")
7812 (set_attr "pent_pair" "np")])
7813
7814 (define_insn "*testqi_ext_1"
7815 [(set (reg FLAGS_REG)
7816 (compare
7817 (and:SI
7818 (zero_extract:SI
7819 (match_operand 0 "ext_register_operand" "Q")
7820 (const_int 8)
7821 (const_int 8))
7822 (zero_extend:SI
7823 (match_operand:QI 1 "general_operand" "Qm")))
7824 (const_int 0)))]
7825 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7826 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7827 "test{b}\t{%1, %h0|%h0, %1}"
7828 [(set_attr "type" "test")
7829 (set_attr "mode" "QI")])
7830
7831 (define_insn "*testqi_ext_1_rex64"
7832 [(set (reg FLAGS_REG)
7833 (compare
7834 (and:SI
7835 (zero_extract:SI
7836 (match_operand 0 "ext_register_operand" "Q")
7837 (const_int 8)
7838 (const_int 8))
7839 (zero_extend:SI
7840 (match_operand:QI 1 "register_operand" "Q")))
7841 (const_int 0)))]
7842 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7843 "test{b}\t{%1, %h0|%h0, %1}"
7844 [(set_attr "type" "test")
7845 (set_attr "mode" "QI")])
7846
7847 (define_insn "*testqi_ext_2"
7848 [(set (reg FLAGS_REG)
7849 (compare
7850 (and:SI
7851 (zero_extract:SI
7852 (match_operand 0 "ext_register_operand" "Q")
7853 (const_int 8)
7854 (const_int 8))
7855 (zero_extract:SI
7856 (match_operand 1 "ext_register_operand" "Q")
7857 (const_int 8)
7858 (const_int 8)))
7859 (const_int 0)))]
7860 "ix86_match_ccmode (insn, CCNOmode)"
7861 "test{b}\t{%h1, %h0|%h0, %h1}"
7862 [(set_attr "type" "test")
7863 (set_attr "mode" "QI")])
7864
7865 ;; Combine likes to form bit extractions for some tests. Humor it.
7866 (define_insn "*testqi_ext_3"
7867 [(set (reg FLAGS_REG)
7868 (compare (zero_extract:SI
7869 (match_operand 0 "nonimmediate_operand" "rm")
7870 (match_operand:SI 1 "const_int_operand" "")
7871 (match_operand:SI 2 "const_int_operand" ""))
7872 (const_int 0)))]
7873 "ix86_match_ccmode (insn, CCNOmode)
7874 && (GET_MODE (operands[0]) == SImode
7875 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7876 || GET_MODE (operands[0]) == HImode
7877 || GET_MODE (operands[0]) == QImode)"
7878 "#")
7879
7880 (define_insn "*testqi_ext_3_rex64"
7881 [(set (reg FLAGS_REG)
7882 (compare (zero_extract:DI
7883 (match_operand 0 "nonimmediate_operand" "rm")
7884 (match_operand:DI 1 "const_int_operand" "")
7885 (match_operand:DI 2 "const_int_operand" ""))
7886 (const_int 0)))]
7887 "TARGET_64BIT
7888 && ix86_match_ccmode (insn, CCNOmode)
7889 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7890 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7891 /* Ensure that resulting mask is zero or sign extended operand. */
7892 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7893 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7894 && INTVAL (operands[1]) > 32))
7895 && (GET_MODE (operands[0]) == SImode
7896 || GET_MODE (operands[0]) == DImode
7897 || GET_MODE (operands[0]) == HImode
7898 || GET_MODE (operands[0]) == QImode)"
7899 "#")
7900
7901 (define_split
7902 [(set (match_operand 0 "flags_reg_operand" "")
7903 (match_operator 1 "compare_operator"
7904 [(zero_extract
7905 (match_operand 2 "nonimmediate_operand" "")
7906 (match_operand 3 "const_int_operand" "")
7907 (match_operand 4 "const_int_operand" ""))
7908 (const_int 0)]))]
7909 "ix86_match_ccmode (insn, CCNOmode)"
7910 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7911 {
7912 rtx val = operands[2];
7913 HOST_WIDE_INT len = INTVAL (operands[3]);
7914 HOST_WIDE_INT pos = INTVAL (operands[4]);
7915 HOST_WIDE_INT mask;
7916 enum machine_mode mode, submode;
7917
7918 mode = GET_MODE (val);
7919 if (GET_CODE (val) == MEM)
7920 {
7921 /* ??? Combine likes to put non-volatile mem extractions in QImode
7922 no matter the size of the test. So find a mode that works. */
7923 if (! MEM_VOLATILE_P (val))
7924 {
7925 mode = smallest_mode_for_size (pos + len, MODE_INT);
7926 val = adjust_address (val, mode, 0);
7927 }
7928 }
7929 else if (GET_CODE (val) == SUBREG
7930 && (submode = GET_MODE (SUBREG_REG (val)),
7931 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7932 && pos + len <= GET_MODE_BITSIZE (submode))
7933 {
7934 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7935 mode = submode;
7936 val = SUBREG_REG (val);
7937 }
7938 else if (mode == HImode && pos + len <= 8)
7939 {
7940 /* Small HImode tests can be converted to QImode. */
7941 mode = QImode;
7942 val = gen_lowpart (QImode, val);
7943 }
7944
7945 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7946 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7947
7948 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7949 })
7950
7951 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7952 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7953 ;; this is relatively important trick.
7954 ;; Do the conversion only post-reload to avoid limiting of the register class
7955 ;; to QI regs.
7956 (define_split
7957 [(set (match_operand 0 "flags_reg_operand" "")
7958 (match_operator 1 "compare_operator"
7959 [(and (match_operand 2 "register_operand" "")
7960 (match_operand 3 "const_int_operand" ""))
7961 (const_int 0)]))]
7962 "reload_completed
7963 && QI_REG_P (operands[2])
7964 && GET_MODE (operands[2]) != QImode
7965 && ((ix86_match_ccmode (insn, CCZmode)
7966 && !(INTVAL (operands[3]) & ~(255 << 8)))
7967 || (ix86_match_ccmode (insn, CCNOmode)
7968 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7969 [(set (match_dup 0)
7970 (match_op_dup 1
7971 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7972 (match_dup 3))
7973 (const_int 0)]))]
7974 "operands[2] = gen_lowpart (SImode, operands[2]);
7975 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7976
7977 (define_split
7978 [(set (match_operand 0 "flags_reg_operand" "")
7979 (match_operator 1 "compare_operator"
7980 [(and (match_operand 2 "nonimmediate_operand" "")
7981 (match_operand 3 "const_int_operand" ""))
7982 (const_int 0)]))]
7983 "reload_completed
7984 && GET_MODE (operands[2]) != QImode
7985 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7986 && ((ix86_match_ccmode (insn, CCZmode)
7987 && !(INTVAL (operands[3]) & ~255))
7988 || (ix86_match_ccmode (insn, CCNOmode)
7989 && !(INTVAL (operands[3]) & ~127)))"
7990 [(set (match_dup 0)
7991 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7992 (const_int 0)]))]
7993 "operands[2] = gen_lowpart (QImode, operands[2]);
7994 operands[3] = gen_lowpart (QImode, operands[3]);")
7995
7996
7997 ;; %%% This used to optimize known byte-wide and operations to memory,
7998 ;; and sometimes to QImode registers. If this is considered useful,
7999 ;; it should be done with splitters.
8000
8001 (define_expand "anddi3"
8002 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8003 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8004 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8005 (clobber (reg:CC FLAGS_REG))]
8006 "TARGET_64BIT"
8007 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8008
8009 (define_insn "*anddi_1_rex64"
8010 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8011 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8012 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8013 (clobber (reg:CC FLAGS_REG))]
8014 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8015 {
8016 switch (get_attr_type (insn))
8017 {
8018 case TYPE_IMOVX:
8019 {
8020 enum machine_mode mode;
8021
8022 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8023 if (INTVAL (operands[2]) == 0xff)
8024 mode = QImode;
8025 else
8026 {
8027 gcc_assert (INTVAL (operands[2]) == 0xffff);
8028 mode = HImode;
8029 }
8030
8031 operands[1] = gen_lowpart (mode, operands[1]);
8032 if (mode == QImode)
8033 return "movz{bq|x}\t{%1,%0|%0, %1}";
8034 else
8035 return "movz{wq|x}\t{%1,%0|%0, %1}";
8036 }
8037
8038 default:
8039 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8040 if (get_attr_mode (insn) == MODE_SI)
8041 return "and{l}\t{%k2, %k0|%k0, %k2}";
8042 else
8043 return "and{q}\t{%2, %0|%0, %2}";
8044 }
8045 }
8046 [(set_attr "type" "alu,alu,alu,imovx")
8047 (set_attr "length_immediate" "*,*,*,0")
8048 (set_attr "mode" "SI,DI,DI,DI")])
8049
8050 (define_insn "*anddi_2"
8051 [(set (reg FLAGS_REG)
8052 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8053 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8054 (const_int 0)))
8055 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8056 (and:DI (match_dup 1) (match_dup 2)))]
8057 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8058 && ix86_binary_operator_ok (AND, DImode, operands)"
8059 "@
8060 and{l}\t{%k2, %k0|%k0, %k2}
8061 and{q}\t{%2, %0|%0, %2}
8062 and{q}\t{%2, %0|%0, %2}"
8063 [(set_attr "type" "alu")
8064 (set_attr "mode" "SI,DI,DI")])
8065
8066 (define_expand "andsi3"
8067 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8068 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8069 (match_operand:SI 2 "general_operand" "")))
8070 (clobber (reg:CC FLAGS_REG))]
8071 ""
8072 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8073
8074 (define_insn "*andsi_1"
8075 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8076 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8077 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8078 (clobber (reg:CC FLAGS_REG))]
8079 "ix86_binary_operator_ok (AND, SImode, operands)"
8080 {
8081 switch (get_attr_type (insn))
8082 {
8083 case TYPE_IMOVX:
8084 {
8085 enum machine_mode mode;
8086
8087 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8088 if (INTVAL (operands[2]) == 0xff)
8089 mode = QImode;
8090 else
8091 {
8092 gcc_assert (INTVAL (operands[2]) == 0xffff);
8093 mode = HImode;
8094 }
8095
8096 operands[1] = gen_lowpart (mode, operands[1]);
8097 if (mode == QImode)
8098 return "movz{bl|x}\t{%1,%0|%0, %1}";
8099 else
8100 return "movz{wl|x}\t{%1,%0|%0, %1}";
8101 }
8102
8103 default:
8104 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8105 return "and{l}\t{%2, %0|%0, %2}";
8106 }
8107 }
8108 [(set_attr "type" "alu,alu,imovx")
8109 (set_attr "length_immediate" "*,*,0")
8110 (set_attr "mode" "SI")])
8111
8112 (define_split
8113 [(set (match_operand 0 "register_operand" "")
8114 (and (match_dup 0)
8115 (const_int -65536)))
8116 (clobber (reg:CC FLAGS_REG))]
8117 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8118 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8119 "operands[1] = gen_lowpart (HImode, operands[0]);")
8120
8121 (define_split
8122 [(set (match_operand 0 "ext_register_operand" "")
8123 (and (match_dup 0)
8124 (const_int -256)))
8125 (clobber (reg:CC FLAGS_REG))]
8126 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8127 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8128 "operands[1] = gen_lowpart (QImode, operands[0]);")
8129
8130 (define_split
8131 [(set (match_operand 0 "ext_register_operand" "")
8132 (and (match_dup 0)
8133 (const_int -65281)))
8134 (clobber (reg:CC FLAGS_REG))]
8135 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8136 [(parallel [(set (zero_extract:SI (match_dup 0)
8137 (const_int 8)
8138 (const_int 8))
8139 (xor:SI
8140 (zero_extract:SI (match_dup 0)
8141 (const_int 8)
8142 (const_int 8))
8143 (zero_extract:SI (match_dup 0)
8144 (const_int 8)
8145 (const_int 8))))
8146 (clobber (reg:CC FLAGS_REG))])]
8147 "operands[0] = gen_lowpart (SImode, operands[0]);")
8148
8149 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8150 (define_insn "*andsi_1_zext"
8151 [(set (match_operand:DI 0 "register_operand" "=r")
8152 (zero_extend:DI
8153 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8154 (match_operand:SI 2 "general_operand" "rim"))))
8155 (clobber (reg:CC FLAGS_REG))]
8156 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8157 "and{l}\t{%2, %k0|%k0, %2}"
8158 [(set_attr "type" "alu")
8159 (set_attr "mode" "SI")])
8160
8161 (define_insn "*andsi_2"
8162 [(set (reg FLAGS_REG)
8163 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8164 (match_operand:SI 2 "general_operand" "rim,ri"))
8165 (const_int 0)))
8166 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8167 (and:SI (match_dup 1) (match_dup 2)))]
8168 "ix86_match_ccmode (insn, CCNOmode)
8169 && ix86_binary_operator_ok (AND, SImode, operands)"
8170 "and{l}\t{%2, %0|%0, %2}"
8171 [(set_attr "type" "alu")
8172 (set_attr "mode" "SI")])
8173
8174 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8175 (define_insn "*andsi_2_zext"
8176 [(set (reg FLAGS_REG)
8177 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8178 (match_operand:SI 2 "general_operand" "rim"))
8179 (const_int 0)))
8180 (set (match_operand:DI 0 "register_operand" "=r")
8181 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8182 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8183 && ix86_binary_operator_ok (AND, SImode, operands)"
8184 "and{l}\t{%2, %k0|%k0, %2}"
8185 [(set_attr "type" "alu")
8186 (set_attr "mode" "SI")])
8187
8188 (define_expand "andhi3"
8189 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8190 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8191 (match_operand:HI 2 "general_operand" "")))
8192 (clobber (reg:CC FLAGS_REG))]
8193 "TARGET_HIMODE_MATH"
8194 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8195
8196 (define_insn "*andhi_1"
8197 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8198 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8199 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8200 (clobber (reg:CC FLAGS_REG))]
8201 "ix86_binary_operator_ok (AND, HImode, operands)"
8202 {
8203 switch (get_attr_type (insn))
8204 {
8205 case TYPE_IMOVX:
8206 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8207 gcc_assert (INTVAL (operands[2]) == 0xff);
8208 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8209
8210 default:
8211 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8212
8213 return "and{w}\t{%2, %0|%0, %2}";
8214 }
8215 }
8216 [(set_attr "type" "alu,alu,imovx")
8217 (set_attr "length_immediate" "*,*,0")
8218 (set_attr "mode" "HI,HI,SI")])
8219
8220 (define_insn "*andhi_2"
8221 [(set (reg FLAGS_REG)
8222 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8223 (match_operand:HI 2 "general_operand" "rim,ri"))
8224 (const_int 0)))
8225 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8226 (and:HI (match_dup 1) (match_dup 2)))]
8227 "ix86_match_ccmode (insn, CCNOmode)
8228 && ix86_binary_operator_ok (AND, HImode, operands)"
8229 "and{w}\t{%2, %0|%0, %2}"
8230 [(set_attr "type" "alu")
8231 (set_attr "mode" "HI")])
8232
8233 (define_expand "andqi3"
8234 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8235 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8236 (match_operand:QI 2 "general_operand" "")))
8237 (clobber (reg:CC FLAGS_REG))]
8238 "TARGET_QIMODE_MATH"
8239 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8240
8241 ;; %%% Potential partial reg stall on alternative 2. What to do?
8242 (define_insn "*andqi_1"
8243 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8244 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8245 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8246 (clobber (reg:CC FLAGS_REG))]
8247 "ix86_binary_operator_ok (AND, QImode, operands)"
8248 "@
8249 and{b}\t{%2, %0|%0, %2}
8250 and{b}\t{%2, %0|%0, %2}
8251 and{l}\t{%k2, %k0|%k0, %k2}"
8252 [(set_attr "type" "alu")
8253 (set_attr "mode" "QI,QI,SI")])
8254
8255 (define_insn "*andqi_1_slp"
8256 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8257 (and:QI (match_dup 0)
8258 (match_operand:QI 1 "general_operand" "qi,qmi")))
8259 (clobber (reg:CC FLAGS_REG))]
8260 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8261 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8262 "and{b}\t{%1, %0|%0, %1}"
8263 [(set_attr "type" "alu1")
8264 (set_attr "mode" "QI")])
8265
8266 (define_insn "*andqi_2_maybe_si"
8267 [(set (reg FLAGS_REG)
8268 (compare (and:QI
8269 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8270 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8271 (const_int 0)))
8272 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8273 (and:QI (match_dup 1) (match_dup 2)))]
8274 "ix86_binary_operator_ok (AND, QImode, operands)
8275 && ix86_match_ccmode (insn,
8276 GET_CODE (operands[2]) == CONST_INT
8277 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8278 {
8279 if (which_alternative == 2)
8280 {
8281 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8282 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8283 return "and{l}\t{%2, %k0|%k0, %2}";
8284 }
8285 return "and{b}\t{%2, %0|%0, %2}";
8286 }
8287 [(set_attr "type" "alu")
8288 (set_attr "mode" "QI,QI,SI")])
8289
8290 (define_insn "*andqi_2"
8291 [(set (reg FLAGS_REG)
8292 (compare (and:QI
8293 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8294 (match_operand:QI 2 "general_operand" "qim,qi"))
8295 (const_int 0)))
8296 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8297 (and:QI (match_dup 1) (match_dup 2)))]
8298 "ix86_match_ccmode (insn, CCNOmode)
8299 && ix86_binary_operator_ok (AND, QImode, operands)"
8300 "and{b}\t{%2, %0|%0, %2}"
8301 [(set_attr "type" "alu")
8302 (set_attr "mode" "QI")])
8303
8304 (define_insn "*andqi_2_slp"
8305 [(set (reg FLAGS_REG)
8306 (compare (and:QI
8307 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8308 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8309 (const_int 0)))
8310 (set (strict_low_part (match_dup 0))
8311 (and:QI (match_dup 0) (match_dup 1)))]
8312 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8313 && ix86_match_ccmode (insn, CCNOmode)
8314 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8315 "and{b}\t{%1, %0|%0, %1}"
8316 [(set_attr "type" "alu1")
8317 (set_attr "mode" "QI")])
8318
8319 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8320 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8321 ;; for a QImode operand, which of course failed.
8322
8323 (define_insn "andqi_ext_0"
8324 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8325 (const_int 8)
8326 (const_int 8))
8327 (and:SI
8328 (zero_extract:SI
8329 (match_operand 1 "ext_register_operand" "0")
8330 (const_int 8)
8331 (const_int 8))
8332 (match_operand 2 "const_int_operand" "n")))
8333 (clobber (reg:CC FLAGS_REG))]
8334 ""
8335 "and{b}\t{%2, %h0|%h0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "length_immediate" "1")
8338 (set_attr "mode" "QI")])
8339
8340 ;; Generated by peephole translating test to and. This shows up
8341 ;; often in fp comparisons.
8342
8343 (define_insn "*andqi_ext_0_cc"
8344 [(set (reg FLAGS_REG)
8345 (compare
8346 (and:SI
8347 (zero_extract:SI
8348 (match_operand 1 "ext_register_operand" "0")
8349 (const_int 8)
8350 (const_int 8))
8351 (match_operand 2 "const_int_operand" "n"))
8352 (const_int 0)))
8353 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8354 (const_int 8)
8355 (const_int 8))
8356 (and:SI
8357 (zero_extract:SI
8358 (match_dup 1)
8359 (const_int 8)
8360 (const_int 8))
8361 (match_dup 2)))]
8362 "ix86_match_ccmode (insn, CCNOmode)"
8363 "and{b}\t{%2, %h0|%h0, %2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "length_immediate" "1")
8366 (set_attr "mode" "QI")])
8367
8368 (define_insn "*andqi_ext_1"
8369 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8370 (const_int 8)
8371 (const_int 8))
8372 (and:SI
8373 (zero_extract:SI
8374 (match_operand 1 "ext_register_operand" "0")
8375 (const_int 8)
8376 (const_int 8))
8377 (zero_extend:SI
8378 (match_operand:QI 2 "general_operand" "Qm"))))
8379 (clobber (reg:CC FLAGS_REG))]
8380 "!TARGET_64BIT"
8381 "and{b}\t{%2, %h0|%h0, %2}"
8382 [(set_attr "type" "alu")
8383 (set_attr "length_immediate" "0")
8384 (set_attr "mode" "QI")])
8385
8386 (define_insn "*andqi_ext_1_rex64"
8387 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8388 (const_int 8)
8389 (const_int 8))
8390 (and:SI
8391 (zero_extract:SI
8392 (match_operand 1 "ext_register_operand" "0")
8393 (const_int 8)
8394 (const_int 8))
8395 (zero_extend:SI
8396 (match_operand 2 "ext_register_operand" "Q"))))
8397 (clobber (reg:CC FLAGS_REG))]
8398 "TARGET_64BIT"
8399 "and{b}\t{%2, %h0|%h0, %2}"
8400 [(set_attr "type" "alu")
8401 (set_attr "length_immediate" "0")
8402 (set_attr "mode" "QI")])
8403
8404 (define_insn "*andqi_ext_2"
8405 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8406 (const_int 8)
8407 (const_int 8))
8408 (and:SI
8409 (zero_extract:SI
8410 (match_operand 1 "ext_register_operand" "%0")
8411 (const_int 8)
8412 (const_int 8))
8413 (zero_extract:SI
8414 (match_operand 2 "ext_register_operand" "Q")
8415 (const_int 8)
8416 (const_int 8))))
8417 (clobber (reg:CC FLAGS_REG))]
8418 ""
8419 "and{b}\t{%h2, %h0|%h0, %h2}"
8420 [(set_attr "type" "alu")
8421 (set_attr "length_immediate" "0")
8422 (set_attr "mode" "QI")])
8423
8424 ;; Convert wide AND instructions with immediate operand to shorter QImode
8425 ;; equivalents when possible.
8426 ;; Don't do the splitting with memory operands, since it introduces risk
8427 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8428 ;; for size, but that can (should?) be handled by generic code instead.
8429 (define_split
8430 [(set (match_operand 0 "register_operand" "")
8431 (and (match_operand 1 "register_operand" "")
8432 (match_operand 2 "const_int_operand" "")))
8433 (clobber (reg:CC FLAGS_REG))]
8434 "reload_completed
8435 && QI_REG_P (operands[0])
8436 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8437 && !(~INTVAL (operands[2]) & ~(255 << 8))
8438 && GET_MODE (operands[0]) != QImode"
8439 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8440 (and:SI (zero_extract:SI (match_dup 1)
8441 (const_int 8) (const_int 8))
8442 (match_dup 2)))
8443 (clobber (reg:CC FLAGS_REG))])]
8444 "operands[0] = gen_lowpart (SImode, operands[0]);
8445 operands[1] = gen_lowpart (SImode, operands[1]);
8446 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8447
8448 ;; Since AND can be encoded with sign extended immediate, this is only
8449 ;; profitable when 7th bit is not set.
8450 (define_split
8451 [(set (match_operand 0 "register_operand" "")
8452 (and (match_operand 1 "general_operand" "")
8453 (match_operand 2 "const_int_operand" "")))
8454 (clobber (reg:CC FLAGS_REG))]
8455 "reload_completed
8456 && ANY_QI_REG_P (operands[0])
8457 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8458 && !(~INTVAL (operands[2]) & ~255)
8459 && !(INTVAL (operands[2]) & 128)
8460 && GET_MODE (operands[0]) != QImode"
8461 [(parallel [(set (strict_low_part (match_dup 0))
8462 (and:QI (match_dup 1)
8463 (match_dup 2)))
8464 (clobber (reg:CC FLAGS_REG))])]
8465 "operands[0] = gen_lowpart (QImode, operands[0]);
8466 operands[1] = gen_lowpart (QImode, operands[1]);
8467 operands[2] = gen_lowpart (QImode, operands[2]);")
8468 \f
8469 ;; Logical inclusive OR instructions
8470
8471 ;; %%% This used to optimize known byte-wide and operations to memory.
8472 ;; If this is considered useful, it should be done with splitters.
8473
8474 (define_expand "iordi3"
8475 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8476 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8477 (match_operand:DI 2 "x86_64_general_operand" "")))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "TARGET_64BIT"
8480 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8481
8482 (define_insn "*iordi_1_rex64"
8483 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8484 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8485 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8486 (clobber (reg:CC FLAGS_REG))]
8487 "TARGET_64BIT
8488 && ix86_binary_operator_ok (IOR, DImode, operands)"
8489 "or{q}\t{%2, %0|%0, %2}"
8490 [(set_attr "type" "alu")
8491 (set_attr "mode" "DI")])
8492
8493 (define_insn "*iordi_2_rex64"
8494 [(set (reg FLAGS_REG)
8495 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8496 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8497 (const_int 0)))
8498 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8499 (ior:DI (match_dup 1) (match_dup 2)))]
8500 "TARGET_64BIT
8501 && ix86_match_ccmode (insn, CCNOmode)
8502 && ix86_binary_operator_ok (IOR, DImode, operands)"
8503 "or{q}\t{%2, %0|%0, %2}"
8504 [(set_attr "type" "alu")
8505 (set_attr "mode" "DI")])
8506
8507 (define_insn "*iordi_3_rex64"
8508 [(set (reg FLAGS_REG)
8509 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8510 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8511 (const_int 0)))
8512 (clobber (match_scratch:DI 0 "=r"))]
8513 "TARGET_64BIT
8514 && ix86_match_ccmode (insn, CCNOmode)
8515 && ix86_binary_operator_ok (IOR, DImode, operands)"
8516 "or{q}\t{%2, %0|%0, %2}"
8517 [(set_attr "type" "alu")
8518 (set_attr "mode" "DI")])
8519
8520
8521 (define_expand "iorsi3"
8522 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8523 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8524 (match_operand:SI 2 "general_operand" "")))
8525 (clobber (reg:CC FLAGS_REG))]
8526 ""
8527 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8528
8529 (define_insn "*iorsi_1"
8530 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8531 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8532 (match_operand:SI 2 "general_operand" "ri,rmi")))
8533 (clobber (reg:CC FLAGS_REG))]
8534 "ix86_binary_operator_ok (IOR, SImode, operands)"
8535 "or{l}\t{%2, %0|%0, %2}"
8536 [(set_attr "type" "alu")
8537 (set_attr "mode" "SI")])
8538
8539 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8540 (define_insn "*iorsi_1_zext"
8541 [(set (match_operand:DI 0 "register_operand" "=rm")
8542 (zero_extend:DI
8543 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8544 (match_operand:SI 2 "general_operand" "rim"))))
8545 (clobber (reg:CC FLAGS_REG))]
8546 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8547 "or{l}\t{%2, %k0|%k0, %2}"
8548 [(set_attr "type" "alu")
8549 (set_attr "mode" "SI")])
8550
8551 (define_insn "*iorsi_1_zext_imm"
8552 [(set (match_operand:DI 0 "register_operand" "=rm")
8553 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8554 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8555 (clobber (reg:CC FLAGS_REG))]
8556 "TARGET_64BIT"
8557 "or{l}\t{%2, %k0|%k0, %2}"
8558 [(set_attr "type" "alu")
8559 (set_attr "mode" "SI")])
8560
8561 (define_insn "*iorsi_2"
8562 [(set (reg FLAGS_REG)
8563 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8564 (match_operand:SI 2 "general_operand" "rim,ri"))
8565 (const_int 0)))
8566 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8567 (ior:SI (match_dup 1) (match_dup 2)))]
8568 "ix86_match_ccmode (insn, CCNOmode)
8569 && ix86_binary_operator_ok (IOR, SImode, operands)"
8570 "or{l}\t{%2, %0|%0, %2}"
8571 [(set_attr "type" "alu")
8572 (set_attr "mode" "SI")])
8573
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 ;; ??? Special case for immediate operand is missing - it is tricky.
8576 (define_insn "*iorsi_2_zext"
8577 [(set (reg FLAGS_REG)
8578 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8579 (match_operand:SI 2 "general_operand" "rim"))
8580 (const_int 0)))
8581 (set (match_operand:DI 0 "register_operand" "=r")
8582 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8583 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8584 && ix86_binary_operator_ok (IOR, SImode, operands)"
8585 "or{l}\t{%2, %k0|%k0, %2}"
8586 [(set_attr "type" "alu")
8587 (set_attr "mode" "SI")])
8588
8589 (define_insn "*iorsi_2_zext_imm"
8590 [(set (reg FLAGS_REG)
8591 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8592 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8593 (const_int 0)))
8594 (set (match_operand:DI 0 "register_operand" "=r")
8595 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8596 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8597 && ix86_binary_operator_ok (IOR, SImode, operands)"
8598 "or{l}\t{%2, %k0|%k0, %2}"
8599 [(set_attr "type" "alu")
8600 (set_attr "mode" "SI")])
8601
8602 (define_insn "*iorsi_3"
8603 [(set (reg FLAGS_REG)
8604 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8605 (match_operand:SI 2 "general_operand" "rim"))
8606 (const_int 0)))
8607 (clobber (match_scratch:SI 0 "=r"))]
8608 "ix86_match_ccmode (insn, CCNOmode)
8609 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8610 "or{l}\t{%2, %0|%0, %2}"
8611 [(set_attr "type" "alu")
8612 (set_attr "mode" "SI")])
8613
8614 (define_expand "iorhi3"
8615 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8616 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8617 (match_operand:HI 2 "general_operand" "")))
8618 (clobber (reg:CC FLAGS_REG))]
8619 "TARGET_HIMODE_MATH"
8620 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8621
8622 (define_insn "*iorhi_1"
8623 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8624 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8625 (match_operand:HI 2 "general_operand" "rmi,ri")))
8626 (clobber (reg:CC FLAGS_REG))]
8627 "ix86_binary_operator_ok (IOR, HImode, operands)"
8628 "or{w}\t{%2, %0|%0, %2}"
8629 [(set_attr "type" "alu")
8630 (set_attr "mode" "HI")])
8631
8632 (define_insn "*iorhi_2"
8633 [(set (reg FLAGS_REG)
8634 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8635 (match_operand:HI 2 "general_operand" "rim,ri"))
8636 (const_int 0)))
8637 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8638 (ior:HI (match_dup 1) (match_dup 2)))]
8639 "ix86_match_ccmode (insn, CCNOmode)
8640 && ix86_binary_operator_ok (IOR, HImode, operands)"
8641 "or{w}\t{%2, %0|%0, %2}"
8642 [(set_attr "type" "alu")
8643 (set_attr "mode" "HI")])
8644
8645 (define_insn "*iorhi_3"
8646 [(set (reg FLAGS_REG)
8647 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8648 (match_operand:HI 2 "general_operand" "rim"))
8649 (const_int 0)))
8650 (clobber (match_scratch:HI 0 "=r"))]
8651 "ix86_match_ccmode (insn, CCNOmode)
8652 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8653 "or{w}\t{%2, %0|%0, %2}"
8654 [(set_attr "type" "alu")
8655 (set_attr "mode" "HI")])
8656
8657 (define_expand "iorqi3"
8658 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8659 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8660 (match_operand:QI 2 "general_operand" "")))
8661 (clobber (reg:CC FLAGS_REG))]
8662 "TARGET_QIMODE_MATH"
8663 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8664
8665 ;; %%% Potential partial reg stall on alternative 2. What to do?
8666 (define_insn "*iorqi_1"
8667 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8668 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8669 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8670 (clobber (reg:CC FLAGS_REG))]
8671 "ix86_binary_operator_ok (IOR, QImode, operands)"
8672 "@
8673 or{b}\t{%2, %0|%0, %2}
8674 or{b}\t{%2, %0|%0, %2}
8675 or{l}\t{%k2, %k0|%k0, %k2}"
8676 [(set_attr "type" "alu")
8677 (set_attr "mode" "QI,QI,SI")])
8678
8679 (define_insn "*iorqi_1_slp"
8680 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8681 (ior:QI (match_dup 0)
8682 (match_operand:QI 1 "general_operand" "qmi,qi")))
8683 (clobber (reg:CC FLAGS_REG))]
8684 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8685 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8686 "or{b}\t{%1, %0|%0, %1}"
8687 [(set_attr "type" "alu1")
8688 (set_attr "mode" "QI")])
8689
8690 (define_insn "*iorqi_2"
8691 [(set (reg FLAGS_REG)
8692 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8693 (match_operand:QI 2 "general_operand" "qim,qi"))
8694 (const_int 0)))
8695 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8696 (ior:QI (match_dup 1) (match_dup 2)))]
8697 "ix86_match_ccmode (insn, CCNOmode)
8698 && ix86_binary_operator_ok (IOR, QImode, operands)"
8699 "or{b}\t{%2, %0|%0, %2}"
8700 [(set_attr "type" "alu")
8701 (set_attr "mode" "QI")])
8702
8703 (define_insn "*iorqi_2_slp"
8704 [(set (reg FLAGS_REG)
8705 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8706 (match_operand:QI 1 "general_operand" "qim,qi"))
8707 (const_int 0)))
8708 (set (strict_low_part (match_dup 0))
8709 (ior:QI (match_dup 0) (match_dup 1)))]
8710 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8711 && ix86_match_ccmode (insn, CCNOmode)
8712 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8713 "or{b}\t{%1, %0|%0, %1}"
8714 [(set_attr "type" "alu1")
8715 (set_attr "mode" "QI")])
8716
8717 (define_insn "*iorqi_3"
8718 [(set (reg FLAGS_REG)
8719 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8720 (match_operand:QI 2 "general_operand" "qim"))
8721 (const_int 0)))
8722 (clobber (match_scratch:QI 0 "=q"))]
8723 "ix86_match_ccmode (insn, CCNOmode)
8724 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8725 "or{b}\t{%2, %0|%0, %2}"
8726 [(set_attr "type" "alu")
8727 (set_attr "mode" "QI")])
8728
8729 (define_insn "iorqi_ext_0"
8730 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8731 (const_int 8)
8732 (const_int 8))
8733 (ior:SI
8734 (zero_extract:SI
8735 (match_operand 1 "ext_register_operand" "0")
8736 (const_int 8)
8737 (const_int 8))
8738 (match_operand 2 "const_int_operand" "n")))
8739 (clobber (reg:CC FLAGS_REG))]
8740 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8741 "or{b}\t{%2, %h0|%h0, %2}"
8742 [(set_attr "type" "alu")
8743 (set_attr "length_immediate" "1")
8744 (set_attr "mode" "QI")])
8745
8746 (define_insn "*iorqi_ext_1"
8747 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8748 (const_int 8)
8749 (const_int 8))
8750 (ior:SI
8751 (zero_extract:SI
8752 (match_operand 1 "ext_register_operand" "0")
8753 (const_int 8)
8754 (const_int 8))
8755 (zero_extend:SI
8756 (match_operand:QI 2 "general_operand" "Qm"))))
8757 (clobber (reg:CC FLAGS_REG))]
8758 "!TARGET_64BIT
8759 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8760 "or{b}\t{%2, %h0|%h0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "length_immediate" "0")
8763 (set_attr "mode" "QI")])
8764
8765 (define_insn "*iorqi_ext_1_rex64"
8766 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8767 (const_int 8)
8768 (const_int 8))
8769 (ior:SI
8770 (zero_extract:SI
8771 (match_operand 1 "ext_register_operand" "0")
8772 (const_int 8)
8773 (const_int 8))
8774 (zero_extend:SI
8775 (match_operand 2 "ext_register_operand" "Q"))))
8776 (clobber (reg:CC FLAGS_REG))]
8777 "TARGET_64BIT
8778 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8779 "or{b}\t{%2, %h0|%h0, %2}"
8780 [(set_attr "type" "alu")
8781 (set_attr "length_immediate" "0")
8782 (set_attr "mode" "QI")])
8783
8784 (define_insn "*iorqi_ext_2"
8785 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8786 (const_int 8)
8787 (const_int 8))
8788 (ior:SI
8789 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8790 (const_int 8)
8791 (const_int 8))
8792 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8793 (const_int 8)
8794 (const_int 8))))
8795 (clobber (reg:CC FLAGS_REG))]
8796 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8797 "ior{b}\t{%h2, %h0|%h0, %h2}"
8798 [(set_attr "type" "alu")
8799 (set_attr "length_immediate" "0")
8800 (set_attr "mode" "QI")])
8801
8802 (define_split
8803 [(set (match_operand 0 "register_operand" "")
8804 (ior (match_operand 1 "register_operand" "")
8805 (match_operand 2 "const_int_operand" "")))
8806 (clobber (reg:CC FLAGS_REG))]
8807 "reload_completed
8808 && QI_REG_P (operands[0])
8809 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8810 && !(INTVAL (operands[2]) & ~(255 << 8))
8811 && GET_MODE (operands[0]) != QImode"
8812 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8813 (ior:SI (zero_extract:SI (match_dup 1)
8814 (const_int 8) (const_int 8))
8815 (match_dup 2)))
8816 (clobber (reg:CC FLAGS_REG))])]
8817 "operands[0] = gen_lowpart (SImode, operands[0]);
8818 operands[1] = gen_lowpart (SImode, operands[1]);
8819 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8820
8821 ;; Since OR can be encoded with sign extended immediate, this is only
8822 ;; profitable when 7th bit is set.
8823 (define_split
8824 [(set (match_operand 0 "register_operand" "")
8825 (ior (match_operand 1 "general_operand" "")
8826 (match_operand 2 "const_int_operand" "")))
8827 (clobber (reg:CC FLAGS_REG))]
8828 "reload_completed
8829 && ANY_QI_REG_P (operands[0])
8830 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8831 && !(INTVAL (operands[2]) & ~255)
8832 && (INTVAL (operands[2]) & 128)
8833 && GET_MODE (operands[0]) != QImode"
8834 [(parallel [(set (strict_low_part (match_dup 0))
8835 (ior:QI (match_dup 1)
8836 (match_dup 2)))
8837 (clobber (reg:CC FLAGS_REG))])]
8838 "operands[0] = gen_lowpart (QImode, operands[0]);
8839 operands[1] = gen_lowpart (QImode, operands[1]);
8840 operands[2] = gen_lowpart (QImode, operands[2]);")
8841 \f
8842 ;; Logical XOR instructions
8843
8844 ;; %%% This used to optimize known byte-wide and operations to memory.
8845 ;; If this is considered useful, it should be done with splitters.
8846
8847 (define_expand "xordi3"
8848 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8849 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8850 (match_operand:DI 2 "x86_64_general_operand" "")))
8851 (clobber (reg:CC FLAGS_REG))]
8852 "TARGET_64BIT"
8853 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8854
8855 (define_insn "*xordi_1_rex64"
8856 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8857 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8858 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8859 (clobber (reg:CC FLAGS_REG))]
8860 "TARGET_64BIT
8861 && ix86_binary_operator_ok (XOR, DImode, operands)"
8862 "@
8863 xor{q}\t{%2, %0|%0, %2}
8864 xor{q}\t{%2, %0|%0, %2}"
8865 [(set_attr "type" "alu")
8866 (set_attr "mode" "DI,DI")])
8867
8868 (define_insn "*xordi_2_rex64"
8869 [(set (reg FLAGS_REG)
8870 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8871 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8872 (const_int 0)))
8873 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8874 (xor:DI (match_dup 1) (match_dup 2)))]
8875 "TARGET_64BIT
8876 && ix86_match_ccmode (insn, CCNOmode)
8877 && ix86_binary_operator_ok (XOR, DImode, operands)"
8878 "@
8879 xor{q}\t{%2, %0|%0, %2}
8880 xor{q}\t{%2, %0|%0, %2}"
8881 [(set_attr "type" "alu")
8882 (set_attr "mode" "DI,DI")])
8883
8884 (define_insn "*xordi_3_rex64"
8885 [(set (reg FLAGS_REG)
8886 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8887 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8888 (const_int 0)))
8889 (clobber (match_scratch:DI 0 "=r"))]
8890 "TARGET_64BIT
8891 && ix86_match_ccmode (insn, CCNOmode)
8892 && ix86_binary_operator_ok (XOR, DImode, operands)"
8893 "xor{q}\t{%2, %0|%0, %2}"
8894 [(set_attr "type" "alu")
8895 (set_attr "mode" "DI")])
8896
8897 (define_expand "xorsi3"
8898 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8899 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8900 (match_operand:SI 2 "general_operand" "")))
8901 (clobber (reg:CC FLAGS_REG))]
8902 ""
8903 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8904
8905 (define_insn "*xorsi_1"
8906 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8907 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8908 (match_operand:SI 2 "general_operand" "ri,rm")))
8909 (clobber (reg:CC FLAGS_REG))]
8910 "ix86_binary_operator_ok (XOR, SImode, operands)"
8911 "xor{l}\t{%2, %0|%0, %2}"
8912 [(set_attr "type" "alu")
8913 (set_attr "mode" "SI")])
8914
8915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8916 ;; Add speccase for immediates
8917 (define_insn "*xorsi_1_zext"
8918 [(set (match_operand:DI 0 "register_operand" "=r")
8919 (zero_extend:DI
8920 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8921 (match_operand:SI 2 "general_operand" "rim"))))
8922 (clobber (reg:CC FLAGS_REG))]
8923 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8924 "xor{l}\t{%2, %k0|%k0, %2}"
8925 [(set_attr "type" "alu")
8926 (set_attr "mode" "SI")])
8927
8928 (define_insn "*xorsi_1_zext_imm"
8929 [(set (match_operand:DI 0 "register_operand" "=r")
8930 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8931 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8932 (clobber (reg:CC FLAGS_REG))]
8933 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8934 "xor{l}\t{%2, %k0|%k0, %2}"
8935 [(set_attr "type" "alu")
8936 (set_attr "mode" "SI")])
8937
8938 (define_insn "*xorsi_2"
8939 [(set (reg FLAGS_REG)
8940 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8941 (match_operand:SI 2 "general_operand" "rim,ri"))
8942 (const_int 0)))
8943 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8944 (xor:SI (match_dup 1) (match_dup 2)))]
8945 "ix86_match_ccmode (insn, CCNOmode)
8946 && ix86_binary_operator_ok (XOR, SImode, operands)"
8947 "xor{l}\t{%2, %0|%0, %2}"
8948 [(set_attr "type" "alu")
8949 (set_attr "mode" "SI")])
8950
8951 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8952 ;; ??? Special case for immediate operand is missing - it is tricky.
8953 (define_insn "*xorsi_2_zext"
8954 [(set (reg FLAGS_REG)
8955 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956 (match_operand:SI 2 "general_operand" "rim"))
8957 (const_int 0)))
8958 (set (match_operand:DI 0 "register_operand" "=r")
8959 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8960 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8961 && ix86_binary_operator_ok (XOR, SImode, operands)"
8962 "xor{l}\t{%2, %k0|%k0, %2}"
8963 [(set_attr "type" "alu")
8964 (set_attr "mode" "SI")])
8965
8966 (define_insn "*xorsi_2_zext_imm"
8967 [(set (reg FLAGS_REG)
8968 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8969 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8970 (const_int 0)))
8971 (set (match_operand:DI 0 "register_operand" "=r")
8972 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8973 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8974 && ix86_binary_operator_ok (XOR, SImode, operands)"
8975 "xor{l}\t{%2, %k0|%k0, %2}"
8976 [(set_attr "type" "alu")
8977 (set_attr "mode" "SI")])
8978
8979 (define_insn "*xorsi_3"
8980 [(set (reg FLAGS_REG)
8981 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8982 (match_operand:SI 2 "general_operand" "rim"))
8983 (const_int 0)))
8984 (clobber (match_scratch:SI 0 "=r"))]
8985 "ix86_match_ccmode (insn, CCNOmode)
8986 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8987 "xor{l}\t{%2, %0|%0, %2}"
8988 [(set_attr "type" "alu")
8989 (set_attr "mode" "SI")])
8990
8991 (define_expand "xorhi3"
8992 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8993 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8994 (match_operand:HI 2 "general_operand" "")))
8995 (clobber (reg:CC FLAGS_REG))]
8996 "TARGET_HIMODE_MATH"
8997 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8998
8999 (define_insn "*xorhi_1"
9000 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9001 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9002 (match_operand:HI 2 "general_operand" "rmi,ri")))
9003 (clobber (reg:CC FLAGS_REG))]
9004 "ix86_binary_operator_ok (XOR, HImode, operands)"
9005 "xor{w}\t{%2, %0|%0, %2}"
9006 [(set_attr "type" "alu")
9007 (set_attr "mode" "HI")])
9008
9009 (define_insn "*xorhi_2"
9010 [(set (reg FLAGS_REG)
9011 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9012 (match_operand:HI 2 "general_operand" "rim,ri"))
9013 (const_int 0)))
9014 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9015 (xor:HI (match_dup 1) (match_dup 2)))]
9016 "ix86_match_ccmode (insn, CCNOmode)
9017 && ix86_binary_operator_ok (XOR, HImode, operands)"
9018 "xor{w}\t{%2, %0|%0, %2}"
9019 [(set_attr "type" "alu")
9020 (set_attr "mode" "HI")])
9021
9022 (define_insn "*xorhi_3"
9023 [(set (reg FLAGS_REG)
9024 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9025 (match_operand:HI 2 "general_operand" "rim"))
9026 (const_int 0)))
9027 (clobber (match_scratch:HI 0 "=r"))]
9028 "ix86_match_ccmode (insn, CCNOmode)
9029 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9030 "xor{w}\t{%2, %0|%0, %2}"
9031 [(set_attr "type" "alu")
9032 (set_attr "mode" "HI")])
9033
9034 (define_expand "xorqi3"
9035 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9036 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9037 (match_operand:QI 2 "general_operand" "")))
9038 (clobber (reg:CC FLAGS_REG))]
9039 "TARGET_QIMODE_MATH"
9040 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9041
9042 ;; %%% Potential partial reg stall on alternative 2. What to do?
9043 (define_insn "*xorqi_1"
9044 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9045 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9046 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9047 (clobber (reg:CC FLAGS_REG))]
9048 "ix86_binary_operator_ok (XOR, QImode, operands)"
9049 "@
9050 xor{b}\t{%2, %0|%0, %2}
9051 xor{b}\t{%2, %0|%0, %2}
9052 xor{l}\t{%k2, %k0|%k0, %k2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "mode" "QI,QI,SI")])
9055
9056 (define_insn "*xorqi_1_slp"
9057 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9058 (xor:QI (match_dup 0)
9059 (match_operand:QI 1 "general_operand" "qi,qmi")))
9060 (clobber (reg:CC FLAGS_REG))]
9061 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9062 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9063 "xor{b}\t{%1, %0|%0, %1}"
9064 [(set_attr "type" "alu1")
9065 (set_attr "mode" "QI")])
9066
9067 (define_insn "xorqi_ext_0"
9068 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9069 (const_int 8)
9070 (const_int 8))
9071 (xor:SI
9072 (zero_extract:SI
9073 (match_operand 1 "ext_register_operand" "0")
9074 (const_int 8)
9075 (const_int 8))
9076 (match_operand 2 "const_int_operand" "n")))
9077 (clobber (reg:CC FLAGS_REG))]
9078 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9079 "xor{b}\t{%2, %h0|%h0, %2}"
9080 [(set_attr "type" "alu")
9081 (set_attr "length_immediate" "1")
9082 (set_attr "mode" "QI")])
9083
9084 (define_insn "*xorqi_ext_1"
9085 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9086 (const_int 8)
9087 (const_int 8))
9088 (xor:SI
9089 (zero_extract:SI
9090 (match_operand 1 "ext_register_operand" "0")
9091 (const_int 8)
9092 (const_int 8))
9093 (zero_extend:SI
9094 (match_operand:QI 2 "general_operand" "Qm"))))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "!TARGET_64BIT
9097 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9098 "xor{b}\t{%2, %h0|%h0, %2}"
9099 [(set_attr "type" "alu")
9100 (set_attr "length_immediate" "0")
9101 (set_attr "mode" "QI")])
9102
9103 (define_insn "*xorqi_ext_1_rex64"
9104 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9105 (const_int 8)
9106 (const_int 8))
9107 (xor:SI
9108 (zero_extract:SI
9109 (match_operand 1 "ext_register_operand" "0")
9110 (const_int 8)
9111 (const_int 8))
9112 (zero_extend:SI
9113 (match_operand 2 "ext_register_operand" "Q"))))
9114 (clobber (reg:CC FLAGS_REG))]
9115 "TARGET_64BIT
9116 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9117 "xor{b}\t{%2, %h0|%h0, %2}"
9118 [(set_attr "type" "alu")
9119 (set_attr "length_immediate" "0")
9120 (set_attr "mode" "QI")])
9121
9122 (define_insn "*xorqi_ext_2"
9123 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9124 (const_int 8)
9125 (const_int 8))
9126 (xor:SI
9127 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9128 (const_int 8)
9129 (const_int 8))
9130 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9131 (const_int 8)
9132 (const_int 8))))
9133 (clobber (reg:CC FLAGS_REG))]
9134 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9135 "xor{b}\t{%h2, %h0|%h0, %h2}"
9136 [(set_attr "type" "alu")
9137 (set_attr "length_immediate" "0")
9138 (set_attr "mode" "QI")])
9139
9140 (define_insn "*xorqi_cc_1"
9141 [(set (reg FLAGS_REG)
9142 (compare
9143 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9144 (match_operand:QI 2 "general_operand" "qim,qi"))
9145 (const_int 0)))
9146 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9147 (xor:QI (match_dup 1) (match_dup 2)))]
9148 "ix86_match_ccmode (insn, CCNOmode)
9149 && ix86_binary_operator_ok (XOR, QImode, operands)"
9150 "xor{b}\t{%2, %0|%0, %2}"
9151 [(set_attr "type" "alu")
9152 (set_attr "mode" "QI")])
9153
9154 (define_insn "*xorqi_2_slp"
9155 [(set (reg FLAGS_REG)
9156 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9157 (match_operand:QI 1 "general_operand" "qim,qi"))
9158 (const_int 0)))
9159 (set (strict_low_part (match_dup 0))
9160 (xor:QI (match_dup 0) (match_dup 1)))]
9161 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9162 && ix86_match_ccmode (insn, CCNOmode)
9163 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9164 "xor{b}\t{%1, %0|%0, %1}"
9165 [(set_attr "type" "alu1")
9166 (set_attr "mode" "QI")])
9167
9168 (define_insn "*xorqi_cc_2"
9169 [(set (reg FLAGS_REG)
9170 (compare
9171 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9172 (match_operand:QI 2 "general_operand" "qim"))
9173 (const_int 0)))
9174 (clobber (match_scratch:QI 0 "=q"))]
9175 "ix86_match_ccmode (insn, CCNOmode)
9176 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9177 "xor{b}\t{%2, %0|%0, %2}"
9178 [(set_attr "type" "alu")
9179 (set_attr "mode" "QI")])
9180
9181 (define_insn "*xorqi_cc_ext_1"
9182 [(set (reg FLAGS_REG)
9183 (compare
9184 (xor:SI
9185 (zero_extract:SI
9186 (match_operand 1 "ext_register_operand" "0")
9187 (const_int 8)
9188 (const_int 8))
9189 (match_operand:QI 2 "general_operand" "qmn"))
9190 (const_int 0)))
9191 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9192 (const_int 8)
9193 (const_int 8))
9194 (xor:SI
9195 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9196 (match_dup 2)))]
9197 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9198 "xor{b}\t{%2, %h0|%h0, %2}"
9199 [(set_attr "type" "alu")
9200 (set_attr "mode" "QI")])
9201
9202 (define_insn "*xorqi_cc_ext_1_rex64"
9203 [(set (reg FLAGS_REG)
9204 (compare
9205 (xor:SI
9206 (zero_extract:SI
9207 (match_operand 1 "ext_register_operand" "0")
9208 (const_int 8)
9209 (const_int 8))
9210 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9211 (const_int 0)))
9212 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9213 (const_int 8)
9214 (const_int 8))
9215 (xor:SI
9216 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9217 (match_dup 2)))]
9218 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9219 "xor{b}\t{%2, %h0|%h0, %2}"
9220 [(set_attr "type" "alu")
9221 (set_attr "mode" "QI")])
9222
9223 (define_expand "xorqi_cc_ext_1"
9224 [(parallel [
9225 (set (reg:CCNO FLAGS_REG)
9226 (compare:CCNO
9227 (xor:SI
9228 (zero_extract:SI
9229 (match_operand 1 "ext_register_operand" "")
9230 (const_int 8)
9231 (const_int 8))
9232 (match_operand:QI 2 "general_operand" ""))
9233 (const_int 0)))
9234 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9235 (const_int 8)
9236 (const_int 8))
9237 (xor:SI
9238 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9239 (match_dup 2)))])]
9240 ""
9241 "")
9242
9243 (define_split
9244 [(set (match_operand 0 "register_operand" "")
9245 (xor (match_operand 1 "register_operand" "")
9246 (match_operand 2 "const_int_operand" "")))
9247 (clobber (reg:CC FLAGS_REG))]
9248 "reload_completed
9249 && QI_REG_P (operands[0])
9250 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9251 && !(INTVAL (operands[2]) & ~(255 << 8))
9252 && GET_MODE (operands[0]) != QImode"
9253 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9254 (xor:SI (zero_extract:SI (match_dup 1)
9255 (const_int 8) (const_int 8))
9256 (match_dup 2)))
9257 (clobber (reg:CC FLAGS_REG))])]
9258 "operands[0] = gen_lowpart (SImode, operands[0]);
9259 operands[1] = gen_lowpart (SImode, operands[1]);
9260 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9261
9262 ;; Since XOR can be encoded with sign extended immediate, this is only
9263 ;; profitable when 7th bit is set.
9264 (define_split
9265 [(set (match_operand 0 "register_operand" "")
9266 (xor (match_operand 1 "general_operand" "")
9267 (match_operand 2 "const_int_operand" "")))
9268 (clobber (reg:CC FLAGS_REG))]
9269 "reload_completed
9270 && ANY_QI_REG_P (operands[0])
9271 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9272 && !(INTVAL (operands[2]) & ~255)
9273 && (INTVAL (operands[2]) & 128)
9274 && GET_MODE (operands[0]) != QImode"
9275 [(parallel [(set (strict_low_part (match_dup 0))
9276 (xor:QI (match_dup 1)
9277 (match_dup 2)))
9278 (clobber (reg:CC FLAGS_REG))])]
9279 "operands[0] = gen_lowpart (QImode, operands[0]);
9280 operands[1] = gen_lowpart (QImode, operands[1]);
9281 operands[2] = gen_lowpart (QImode, operands[2]);")
9282 \f
9283 ;; Negation instructions
9284
9285 (define_expand "negti2"
9286 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9287 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9288 (clobber (reg:CC FLAGS_REG))])]
9289 "TARGET_64BIT"
9290 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9291
9292 (define_insn "*negti2_1"
9293 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9294 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9295 (clobber (reg:CC FLAGS_REG))]
9296 "TARGET_64BIT
9297 && ix86_unary_operator_ok (NEG, TImode, operands)"
9298 "#")
9299
9300 (define_split
9301 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9302 (neg:TI (match_operand:TI 1 "general_operand" "")))
9303 (clobber (reg:CC FLAGS_REG))]
9304 "TARGET_64BIT && reload_completed"
9305 [(parallel
9306 [(set (reg:CCZ FLAGS_REG)
9307 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9308 (set (match_dup 0) (neg:DI (match_dup 2)))])
9309 (parallel
9310 [(set (match_dup 1)
9311 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9312 (match_dup 3))
9313 (const_int 0)))
9314 (clobber (reg:CC FLAGS_REG))])
9315 (parallel
9316 [(set (match_dup 1)
9317 (neg:DI (match_dup 1)))
9318 (clobber (reg:CC FLAGS_REG))])]
9319 "split_ti (operands+1, 1, operands+2, operands+3);
9320 split_ti (operands+0, 1, operands+0, operands+1);")
9321
9322 (define_expand "negdi2"
9323 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9324 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9325 (clobber (reg:CC FLAGS_REG))])]
9326 ""
9327 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9328
9329 (define_insn "*negdi2_1"
9330 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9331 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9332 (clobber (reg:CC FLAGS_REG))]
9333 "!TARGET_64BIT
9334 && ix86_unary_operator_ok (NEG, DImode, operands)"
9335 "#")
9336
9337 (define_split
9338 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9339 (neg:DI (match_operand:DI 1 "general_operand" "")))
9340 (clobber (reg:CC FLAGS_REG))]
9341 "!TARGET_64BIT && reload_completed"
9342 [(parallel
9343 [(set (reg:CCZ FLAGS_REG)
9344 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9345 (set (match_dup 0) (neg:SI (match_dup 2)))])
9346 (parallel
9347 [(set (match_dup 1)
9348 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9349 (match_dup 3))
9350 (const_int 0)))
9351 (clobber (reg:CC FLAGS_REG))])
9352 (parallel
9353 [(set (match_dup 1)
9354 (neg:SI (match_dup 1)))
9355 (clobber (reg:CC FLAGS_REG))])]
9356 "split_di (operands+1, 1, operands+2, operands+3);
9357 split_di (operands+0, 1, operands+0, operands+1);")
9358
9359 (define_insn "*negdi2_1_rex64"
9360 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9361 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9362 (clobber (reg:CC FLAGS_REG))]
9363 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9364 "neg{q}\t%0"
9365 [(set_attr "type" "negnot")
9366 (set_attr "mode" "DI")])
9367
9368 ;; The problem with neg is that it does not perform (compare x 0),
9369 ;; it really performs (compare 0 x), which leaves us with the zero
9370 ;; flag being the only useful item.
9371
9372 (define_insn "*negdi2_cmpz_rex64"
9373 [(set (reg:CCZ FLAGS_REG)
9374 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9375 (const_int 0)))
9376 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9377 (neg:DI (match_dup 1)))]
9378 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9379 "neg{q}\t%0"
9380 [(set_attr "type" "negnot")
9381 (set_attr "mode" "DI")])
9382
9383
9384 (define_expand "negsi2"
9385 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9386 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9387 (clobber (reg:CC FLAGS_REG))])]
9388 ""
9389 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9390
9391 (define_insn "*negsi2_1"
9392 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9393 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9394 (clobber (reg:CC FLAGS_REG))]
9395 "ix86_unary_operator_ok (NEG, SImode, operands)"
9396 "neg{l}\t%0"
9397 [(set_attr "type" "negnot")
9398 (set_attr "mode" "SI")])
9399
9400 ;; Combine is quite creative about this pattern.
9401 (define_insn "*negsi2_1_zext"
9402 [(set (match_operand:DI 0 "register_operand" "=r")
9403 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9404 (const_int 32)))
9405 (const_int 32)))
9406 (clobber (reg:CC FLAGS_REG))]
9407 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9408 "neg{l}\t%k0"
9409 [(set_attr "type" "negnot")
9410 (set_attr "mode" "SI")])
9411
9412 ;; The problem with neg is that it does not perform (compare x 0),
9413 ;; it really performs (compare 0 x), which leaves us with the zero
9414 ;; flag being the only useful item.
9415
9416 (define_insn "*negsi2_cmpz"
9417 [(set (reg:CCZ FLAGS_REG)
9418 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9419 (const_int 0)))
9420 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9421 (neg:SI (match_dup 1)))]
9422 "ix86_unary_operator_ok (NEG, SImode, operands)"
9423 "neg{l}\t%0"
9424 [(set_attr "type" "negnot")
9425 (set_attr "mode" "SI")])
9426
9427 (define_insn "*negsi2_cmpz_zext"
9428 [(set (reg:CCZ FLAGS_REG)
9429 (compare:CCZ (lshiftrt:DI
9430 (neg:DI (ashift:DI
9431 (match_operand:DI 1 "register_operand" "0")
9432 (const_int 32)))
9433 (const_int 32))
9434 (const_int 0)))
9435 (set (match_operand:DI 0 "register_operand" "=r")
9436 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9437 (const_int 32)))
9438 (const_int 32)))]
9439 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9440 "neg{l}\t%k0"
9441 [(set_attr "type" "negnot")
9442 (set_attr "mode" "SI")])
9443
9444 (define_expand "neghi2"
9445 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9446 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9447 (clobber (reg:CC FLAGS_REG))])]
9448 "TARGET_HIMODE_MATH"
9449 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9450
9451 (define_insn "*neghi2_1"
9452 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9453 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9454 (clobber (reg:CC FLAGS_REG))]
9455 "ix86_unary_operator_ok (NEG, HImode, operands)"
9456 "neg{w}\t%0"
9457 [(set_attr "type" "negnot")
9458 (set_attr "mode" "HI")])
9459
9460 (define_insn "*neghi2_cmpz"
9461 [(set (reg:CCZ FLAGS_REG)
9462 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9463 (const_int 0)))
9464 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9465 (neg:HI (match_dup 1)))]
9466 "ix86_unary_operator_ok (NEG, HImode, operands)"
9467 "neg{w}\t%0"
9468 [(set_attr "type" "negnot")
9469 (set_attr "mode" "HI")])
9470
9471 (define_expand "negqi2"
9472 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9473 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9474 (clobber (reg:CC FLAGS_REG))])]
9475 "TARGET_QIMODE_MATH"
9476 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9477
9478 (define_insn "*negqi2_1"
9479 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9480 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9481 (clobber (reg:CC FLAGS_REG))]
9482 "ix86_unary_operator_ok (NEG, QImode, operands)"
9483 "neg{b}\t%0"
9484 [(set_attr "type" "negnot")
9485 (set_attr "mode" "QI")])
9486
9487 (define_insn "*negqi2_cmpz"
9488 [(set (reg:CCZ FLAGS_REG)
9489 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9490 (const_int 0)))
9491 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9492 (neg:QI (match_dup 1)))]
9493 "ix86_unary_operator_ok (NEG, QImode, operands)"
9494 "neg{b}\t%0"
9495 [(set_attr "type" "negnot")
9496 (set_attr "mode" "QI")])
9497
9498 ;; Changing of sign for FP values is doable using integer unit too.
9499
9500 (define_expand "negsf2"
9501 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9502 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9503 "TARGET_80387 || TARGET_SSE_MATH"
9504 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9505
9506 (define_expand "abssf2"
9507 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9508 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9509 "TARGET_80387 || TARGET_SSE_MATH"
9510 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9511
9512 (define_insn "*absnegsf2_mixed"
9513 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm")
9514 (match_operator:SF 3 "absneg_operator"
9515 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")]))
9516 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9517 (clobber (reg:CC FLAGS_REG))]
9518 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9519 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9520 "#")
9521
9522 (define_insn "*absnegsf2_sse"
9523 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9524 (match_operator:SF 3 "absneg_operator"
9525 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9526 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9527 (clobber (reg:CC FLAGS_REG))]
9528 "TARGET_SSE_MATH
9529 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9530 "#")
9531
9532 (define_insn "*absnegsf2_i387"
9533 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9534 (match_operator:SF 3 "absneg_operator"
9535 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9536 (use (match_operand 2 "" ""))
9537 (clobber (reg:CC FLAGS_REG))]
9538 "TARGET_80387 && !TARGET_SSE_MATH
9539 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9540 "#")
9541
9542 (define_expand "copysignsf3"
9543 [(match_operand:SF 0 "register_operand" "")
9544 (match_operand:SF 1 "nonmemory_operand" "")
9545 (match_operand:SF 2 "register_operand" "")]
9546 "TARGET_SSE_MATH"
9547 {
9548 ix86_expand_copysign (operands);
9549 DONE;
9550 })
9551
9552 (define_insn_and_split "copysignsf3_const"
9553 [(set (match_operand:SF 0 "register_operand" "=x")
9554 (unspec:SF
9555 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9556 (match_operand:SF 2 "register_operand" "0")
9557 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9558 UNSPEC_COPYSIGN))]
9559 "TARGET_SSE_MATH"
9560 "#"
9561 "&& reload_completed"
9562 [(const_int 0)]
9563 {
9564 ix86_split_copysign_const (operands);
9565 DONE;
9566 })
9567
9568 (define_insn "copysignsf3_var"
9569 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9570 (unspec:SF
9571 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9572 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9573 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9574 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9575 UNSPEC_COPYSIGN))
9576 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9577 "TARGET_SSE_MATH"
9578 "#")
9579
9580 (define_split
9581 [(set (match_operand:SF 0 "register_operand" "")
9582 (unspec:SF
9583 [(match_operand:SF 2 "register_operand" "")
9584 (match_operand:SF 3 "register_operand" "")
9585 (match_operand:V4SF 4 "" "")
9586 (match_operand:V4SF 5 "" "")]
9587 UNSPEC_COPYSIGN))
9588 (clobber (match_scratch:V4SF 1 ""))]
9589 "TARGET_SSE_MATH && reload_completed"
9590 [(const_int 0)]
9591 {
9592 ix86_split_copysign_var (operands);
9593 DONE;
9594 })
9595
9596 (define_expand "negdf2"
9597 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9598 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9599 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9600 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9601
9602 (define_expand "absdf2"
9603 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9604 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9605 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9606 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9607
9608 (define_insn "*absnegdf2_mixed"
9609 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm")
9610 (match_operator:DF 3 "absneg_operator"
9611 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")]))
9612 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9613 (clobber (reg:CC FLAGS_REG))]
9614 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9615 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9616 "#")
9617
9618 (define_insn "*absnegdf2_sse"
9619 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9620 (match_operator:DF 3 "absneg_operator"
9621 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9622 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X"))
9623 (clobber (reg:CC FLAGS_REG))]
9624 "TARGET_SSE2 && TARGET_SSE_MATH
9625 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9626 "#")
9627
9628 (define_insn "*absnegdf2_i387"
9629 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9630 (match_operator:DF 3 "absneg_operator"
9631 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9632 (use (match_operand 2 "" ""))
9633 (clobber (reg:CC FLAGS_REG))]
9634 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9635 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9636 "#")
9637
9638 (define_expand "copysigndf3"
9639 [(match_operand:DF 0 "register_operand" "")
9640 (match_operand:DF 1 "nonmemory_operand" "")
9641 (match_operand:DF 2 "register_operand" "")]
9642 "TARGET_SSE2 && TARGET_SSE_MATH"
9643 {
9644 ix86_expand_copysign (operands);
9645 DONE;
9646 })
9647
9648 (define_insn_and_split "copysigndf3_const"
9649 [(set (match_operand:DF 0 "register_operand" "=x")
9650 (unspec:DF
9651 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9652 (match_operand:DF 2 "register_operand" "0")
9653 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9654 UNSPEC_COPYSIGN))]
9655 "TARGET_SSE2 && TARGET_SSE_MATH"
9656 "#"
9657 "&& reload_completed"
9658 [(const_int 0)]
9659 {
9660 ix86_split_copysign_const (operands);
9661 DONE;
9662 })
9663
9664 (define_insn "copysigndf3_var"
9665 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9666 (unspec:DF
9667 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9668 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9669 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9670 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9671 UNSPEC_COPYSIGN))
9672 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9673 "TARGET_SSE2 && TARGET_SSE_MATH"
9674 "#")
9675
9676 (define_split
9677 [(set (match_operand:DF 0 "register_operand" "")
9678 (unspec:DF
9679 [(match_operand:DF 2 "register_operand" "")
9680 (match_operand:DF 3 "register_operand" "")
9681 (match_operand:V2DF 4 "" "")
9682 (match_operand:V2DF 5 "" "")]
9683 UNSPEC_COPYSIGN))
9684 (clobber (match_scratch:V2DF 1 ""))]
9685 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9686 [(const_int 0)]
9687 {
9688 ix86_split_copysign_var (operands);
9689 DONE;
9690 })
9691
9692 (define_expand "negxf2"
9693 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9694 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9695 "TARGET_80387"
9696 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9697
9698 (define_expand "absxf2"
9699 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9700 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9701 "TARGET_80387"
9702 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9703
9704 (define_insn "*absnegxf2_i387"
9705 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9706 (match_operator:XF 3 "absneg_operator"
9707 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9708 (use (match_operand 2 "" ""))
9709 (clobber (reg:CC FLAGS_REG))]
9710 "TARGET_80387
9711 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9712 "#")
9713
9714 ;; Splitters for fp abs and neg.
9715
9716 (define_split
9717 [(set (match_operand 0 "fp_register_operand" "")
9718 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9719 (use (match_operand 2 "" ""))
9720 (clobber (reg:CC FLAGS_REG))]
9721 "reload_completed"
9722 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9723
9724 (define_split
9725 [(set (match_operand 0 "register_operand" "")
9726 (match_operator 3 "absneg_operator"
9727 [(match_operand 1 "register_operand" "")]))
9728 (use (match_operand 2 "nonimmediate_operand" ""))
9729 (clobber (reg:CC FLAGS_REG))]
9730 "reload_completed && SSE_REG_P (operands[0])"
9731 [(set (match_dup 0) (match_dup 3))]
9732 {
9733 enum machine_mode mode = GET_MODE (operands[0]);
9734 enum machine_mode vmode = GET_MODE (operands[2]);
9735 rtx tmp;
9736
9737 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9738 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9739 if (operands_match_p (operands[0], operands[2]))
9740 {
9741 tmp = operands[1];
9742 operands[1] = operands[2];
9743 operands[2] = tmp;
9744 }
9745 if (GET_CODE (operands[3]) == ABS)
9746 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9747 else
9748 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9749 operands[3] = tmp;
9750 })
9751
9752 (define_split
9753 [(set (match_operand:SF 0 "register_operand" "")
9754 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9755 (use (match_operand:V4SF 2 "" ""))
9756 (clobber (reg:CC FLAGS_REG))]
9757 "reload_completed"
9758 [(parallel [(set (match_dup 0) (match_dup 1))
9759 (clobber (reg:CC FLAGS_REG))])]
9760 {
9761 rtx tmp;
9762 operands[0] = gen_lowpart (SImode, operands[0]);
9763 if (GET_CODE (operands[1]) == ABS)
9764 {
9765 tmp = gen_int_mode (0x7fffffff, SImode);
9766 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9767 }
9768 else
9769 {
9770 tmp = gen_int_mode (0x80000000, SImode);
9771 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9772 }
9773 operands[1] = tmp;
9774 })
9775
9776 (define_split
9777 [(set (match_operand:DF 0 "register_operand" "")
9778 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9779 (use (match_operand 2 "" ""))
9780 (clobber (reg:CC FLAGS_REG))]
9781 "reload_completed"
9782 [(parallel [(set (match_dup 0) (match_dup 1))
9783 (clobber (reg:CC FLAGS_REG))])]
9784 {
9785 rtx tmp;
9786 if (TARGET_64BIT)
9787 {
9788 tmp = gen_lowpart (DImode, operands[0]);
9789 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9790 operands[0] = tmp;
9791
9792 if (GET_CODE (operands[1]) == ABS)
9793 tmp = const0_rtx;
9794 else
9795 tmp = gen_rtx_NOT (DImode, tmp);
9796 }
9797 else
9798 {
9799 operands[0] = gen_highpart (SImode, operands[0]);
9800 if (GET_CODE (operands[1]) == ABS)
9801 {
9802 tmp = gen_int_mode (0x7fffffff, SImode);
9803 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9804 }
9805 else
9806 {
9807 tmp = gen_int_mode (0x80000000, SImode);
9808 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9809 }
9810 }
9811 operands[1] = tmp;
9812 })
9813
9814 (define_split
9815 [(set (match_operand:XF 0 "register_operand" "")
9816 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9817 (use (match_operand 2 "" ""))
9818 (clobber (reg:CC FLAGS_REG))]
9819 "reload_completed"
9820 [(parallel [(set (match_dup 0) (match_dup 1))
9821 (clobber (reg:CC FLAGS_REG))])]
9822 {
9823 rtx tmp;
9824 operands[0] = gen_rtx_REG (SImode,
9825 true_regnum (operands[0])
9826 + (TARGET_64BIT ? 1 : 2));
9827 if (GET_CODE (operands[1]) == ABS)
9828 {
9829 tmp = GEN_INT (0x7fff);
9830 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9831 }
9832 else
9833 {
9834 tmp = GEN_INT (0x8000);
9835 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9836 }
9837 operands[1] = tmp;
9838 })
9839
9840 (define_split
9841 [(set (match_operand 0 "memory_operand" "")
9842 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9843 (use (match_operand 2 "" ""))
9844 (clobber (reg:CC FLAGS_REG))]
9845 "reload_completed"
9846 [(parallel [(set (match_dup 0) (match_dup 1))
9847 (clobber (reg:CC FLAGS_REG))])]
9848 {
9849 enum machine_mode mode = GET_MODE (operands[0]);
9850 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9851 rtx tmp;
9852
9853 operands[0] = adjust_address (operands[0], QImode, size - 1);
9854 if (GET_CODE (operands[1]) == ABS)
9855 {
9856 tmp = gen_int_mode (0x7f, QImode);
9857 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9858 }
9859 else
9860 {
9861 tmp = gen_int_mode (0x80, QImode);
9862 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9863 }
9864 operands[1] = tmp;
9865 })
9866
9867 ;; Conditionalize these after reload. If they match before reload, we
9868 ;; lose the clobber and ability to use integer instructions.
9869
9870 (define_insn "*negsf2_1"
9871 [(set (match_operand:SF 0 "register_operand" "=f")
9872 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9873 "TARGET_80387 && reload_completed"
9874 "fchs"
9875 [(set_attr "type" "fsgn")
9876 (set_attr "mode" "SF")])
9877
9878 (define_insn "*negdf2_1"
9879 [(set (match_operand:DF 0 "register_operand" "=f")
9880 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9881 "TARGET_80387 && reload_completed"
9882 "fchs"
9883 [(set_attr "type" "fsgn")
9884 (set_attr "mode" "DF")])
9885
9886 (define_insn "*negxf2_1"
9887 [(set (match_operand:XF 0 "register_operand" "=f")
9888 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9889 "TARGET_80387 && reload_completed"
9890 "fchs"
9891 [(set_attr "type" "fsgn")
9892 (set_attr "mode" "XF")])
9893
9894 (define_insn "*abssf2_1"
9895 [(set (match_operand:SF 0 "register_operand" "=f")
9896 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9897 "TARGET_80387 && reload_completed"
9898 "fabs"
9899 [(set_attr "type" "fsgn")
9900 (set_attr "mode" "SF")])
9901
9902 (define_insn "*absdf2_1"
9903 [(set (match_operand:DF 0 "register_operand" "=f")
9904 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9905 "TARGET_80387 && reload_completed"
9906 "fabs"
9907 [(set_attr "type" "fsgn")
9908 (set_attr "mode" "DF")])
9909
9910 (define_insn "*absxf2_1"
9911 [(set (match_operand:XF 0 "register_operand" "=f")
9912 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9913 "TARGET_80387 && reload_completed"
9914 "fabs"
9915 [(set_attr "type" "fsgn")
9916 (set_attr "mode" "DF")])
9917
9918 (define_insn "*negextendsfdf2"
9919 [(set (match_operand:DF 0 "register_operand" "=f")
9920 (neg:DF (float_extend:DF
9921 (match_operand:SF 1 "register_operand" "0"))))]
9922 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9923 "fchs"
9924 [(set_attr "type" "fsgn")
9925 (set_attr "mode" "DF")])
9926
9927 (define_insn "*negextenddfxf2"
9928 [(set (match_operand:XF 0 "register_operand" "=f")
9929 (neg:XF (float_extend:XF
9930 (match_operand:DF 1 "register_operand" "0"))))]
9931 "TARGET_80387"
9932 "fchs"
9933 [(set_attr "type" "fsgn")
9934 (set_attr "mode" "XF")])
9935
9936 (define_insn "*negextendsfxf2"
9937 [(set (match_operand:XF 0 "register_operand" "=f")
9938 (neg:XF (float_extend:XF
9939 (match_operand:SF 1 "register_operand" "0"))))]
9940 "TARGET_80387"
9941 "fchs"
9942 [(set_attr "type" "fsgn")
9943 (set_attr "mode" "XF")])
9944
9945 (define_insn "*absextendsfdf2"
9946 [(set (match_operand:DF 0 "register_operand" "=f")
9947 (abs:DF (float_extend:DF
9948 (match_operand:SF 1 "register_operand" "0"))))]
9949 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9950 "fabs"
9951 [(set_attr "type" "fsgn")
9952 (set_attr "mode" "DF")])
9953
9954 (define_insn "*absextenddfxf2"
9955 [(set (match_operand:XF 0 "register_operand" "=f")
9956 (abs:XF (float_extend:XF
9957 (match_operand:DF 1 "register_operand" "0"))))]
9958 "TARGET_80387"
9959 "fabs"
9960 [(set_attr "type" "fsgn")
9961 (set_attr "mode" "XF")])
9962
9963 (define_insn "*absextendsfxf2"
9964 [(set (match_operand:XF 0 "register_operand" "=f")
9965 (abs:XF (float_extend:XF
9966 (match_operand:SF 1 "register_operand" "0"))))]
9967 "TARGET_80387"
9968 "fabs"
9969 [(set_attr "type" "fsgn")
9970 (set_attr "mode" "XF")])
9971 \f
9972 ;; One complement instructions
9973
9974 (define_expand "one_cmpldi2"
9975 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9976 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9977 "TARGET_64BIT"
9978 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9979
9980 (define_insn "*one_cmpldi2_1_rex64"
9981 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9982 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9983 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9984 "not{q}\t%0"
9985 [(set_attr "type" "negnot")
9986 (set_attr "mode" "DI")])
9987
9988 (define_insn "*one_cmpldi2_2_rex64"
9989 [(set (reg FLAGS_REG)
9990 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9991 (const_int 0)))
9992 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9993 (not:DI (match_dup 1)))]
9994 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9995 && ix86_unary_operator_ok (NOT, DImode, operands)"
9996 "#"
9997 [(set_attr "type" "alu1")
9998 (set_attr "mode" "DI")])
9999
10000 (define_split
10001 [(set (match_operand 0 "flags_reg_operand" "")
10002 (match_operator 2 "compare_operator"
10003 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10004 (const_int 0)]))
10005 (set (match_operand:DI 1 "nonimmediate_operand" "")
10006 (not:DI (match_dup 3)))]
10007 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10008 [(parallel [(set (match_dup 0)
10009 (match_op_dup 2
10010 [(xor:DI (match_dup 3) (const_int -1))
10011 (const_int 0)]))
10012 (set (match_dup 1)
10013 (xor:DI (match_dup 3) (const_int -1)))])]
10014 "")
10015
10016 (define_expand "one_cmplsi2"
10017 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10018 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10019 ""
10020 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10021
10022 (define_insn "*one_cmplsi2_1"
10023 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10024 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10025 "ix86_unary_operator_ok (NOT, SImode, operands)"
10026 "not{l}\t%0"
10027 [(set_attr "type" "negnot")
10028 (set_attr "mode" "SI")])
10029
10030 ;; ??? Currently never generated - xor is used instead.
10031 (define_insn "*one_cmplsi2_1_zext"
10032 [(set (match_operand:DI 0 "register_operand" "=r")
10033 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10034 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10035 "not{l}\t%k0"
10036 [(set_attr "type" "negnot")
10037 (set_attr "mode" "SI")])
10038
10039 (define_insn "*one_cmplsi2_2"
10040 [(set (reg FLAGS_REG)
10041 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10042 (const_int 0)))
10043 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10044 (not:SI (match_dup 1)))]
10045 "ix86_match_ccmode (insn, CCNOmode)
10046 && ix86_unary_operator_ok (NOT, SImode, operands)"
10047 "#"
10048 [(set_attr "type" "alu1")
10049 (set_attr "mode" "SI")])
10050
10051 (define_split
10052 [(set (match_operand 0 "flags_reg_operand" "")
10053 (match_operator 2 "compare_operator"
10054 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10055 (const_int 0)]))
10056 (set (match_operand:SI 1 "nonimmediate_operand" "")
10057 (not:SI (match_dup 3)))]
10058 "ix86_match_ccmode (insn, CCNOmode)"
10059 [(parallel [(set (match_dup 0)
10060 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10061 (const_int 0)]))
10062 (set (match_dup 1)
10063 (xor:SI (match_dup 3) (const_int -1)))])]
10064 "")
10065
10066 ;; ??? Currently never generated - xor is used instead.
10067 (define_insn "*one_cmplsi2_2_zext"
10068 [(set (reg FLAGS_REG)
10069 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10070 (const_int 0)))
10071 (set (match_operand:DI 0 "register_operand" "=r")
10072 (zero_extend:DI (not:SI (match_dup 1))))]
10073 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10074 && ix86_unary_operator_ok (NOT, SImode, operands)"
10075 "#"
10076 [(set_attr "type" "alu1")
10077 (set_attr "mode" "SI")])
10078
10079 (define_split
10080 [(set (match_operand 0 "flags_reg_operand" "")
10081 (match_operator 2 "compare_operator"
10082 [(not:SI (match_operand:SI 3 "register_operand" ""))
10083 (const_int 0)]))
10084 (set (match_operand:DI 1 "register_operand" "")
10085 (zero_extend:DI (not:SI (match_dup 3))))]
10086 "ix86_match_ccmode (insn, CCNOmode)"
10087 [(parallel [(set (match_dup 0)
10088 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10089 (const_int 0)]))
10090 (set (match_dup 1)
10091 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10092 "")
10093
10094 (define_expand "one_cmplhi2"
10095 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10096 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10097 "TARGET_HIMODE_MATH"
10098 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10099
10100 (define_insn "*one_cmplhi2_1"
10101 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10102 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10103 "ix86_unary_operator_ok (NOT, HImode, operands)"
10104 "not{w}\t%0"
10105 [(set_attr "type" "negnot")
10106 (set_attr "mode" "HI")])
10107
10108 (define_insn "*one_cmplhi2_2"
10109 [(set (reg FLAGS_REG)
10110 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10111 (const_int 0)))
10112 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10113 (not:HI (match_dup 1)))]
10114 "ix86_match_ccmode (insn, CCNOmode)
10115 && ix86_unary_operator_ok (NEG, HImode, operands)"
10116 "#"
10117 [(set_attr "type" "alu1")
10118 (set_attr "mode" "HI")])
10119
10120 (define_split
10121 [(set (match_operand 0 "flags_reg_operand" "")
10122 (match_operator 2 "compare_operator"
10123 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10124 (const_int 0)]))
10125 (set (match_operand:HI 1 "nonimmediate_operand" "")
10126 (not:HI (match_dup 3)))]
10127 "ix86_match_ccmode (insn, CCNOmode)"
10128 [(parallel [(set (match_dup 0)
10129 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10130 (const_int 0)]))
10131 (set (match_dup 1)
10132 (xor:HI (match_dup 3) (const_int -1)))])]
10133 "")
10134
10135 ;; %%% Potential partial reg stall on alternative 1. What to do?
10136 (define_expand "one_cmplqi2"
10137 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10138 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10139 "TARGET_QIMODE_MATH"
10140 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10141
10142 (define_insn "*one_cmplqi2_1"
10143 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10144 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10145 "ix86_unary_operator_ok (NOT, QImode, operands)"
10146 "@
10147 not{b}\t%0
10148 not{l}\t%k0"
10149 [(set_attr "type" "negnot")
10150 (set_attr "mode" "QI,SI")])
10151
10152 (define_insn "*one_cmplqi2_2"
10153 [(set (reg FLAGS_REG)
10154 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10155 (const_int 0)))
10156 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10157 (not:QI (match_dup 1)))]
10158 "ix86_match_ccmode (insn, CCNOmode)
10159 && ix86_unary_operator_ok (NOT, QImode, operands)"
10160 "#"
10161 [(set_attr "type" "alu1")
10162 (set_attr "mode" "QI")])
10163
10164 (define_split
10165 [(set (match_operand 0 "flags_reg_operand" "")
10166 (match_operator 2 "compare_operator"
10167 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10168 (const_int 0)]))
10169 (set (match_operand:QI 1 "nonimmediate_operand" "")
10170 (not:QI (match_dup 3)))]
10171 "ix86_match_ccmode (insn, CCNOmode)"
10172 [(parallel [(set (match_dup 0)
10173 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10174 (const_int 0)]))
10175 (set (match_dup 1)
10176 (xor:QI (match_dup 3) (const_int -1)))])]
10177 "")
10178 \f
10179 ;; Arithmetic shift instructions
10180
10181 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10182 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10183 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10184 ;; from the assembler input.
10185 ;;
10186 ;; This instruction shifts the target reg/mem as usual, but instead of
10187 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10188 ;; is a left shift double, bits are taken from the high order bits of
10189 ;; reg, else if the insn is a shift right double, bits are taken from the
10190 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10191 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10192 ;;
10193 ;; Since sh[lr]d does not change the `reg' operand, that is done
10194 ;; separately, making all shifts emit pairs of shift double and normal
10195 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10196 ;; support a 63 bit shift, each shift where the count is in a reg expands
10197 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10198 ;;
10199 ;; If the shift count is a constant, we need never emit more than one
10200 ;; shift pair, instead using moves and sign extension for counts greater
10201 ;; than 31.
10202
10203 (define_expand "ashlti3"
10204 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10205 (ashift:TI (match_operand:TI 1 "register_operand" "")
10206 (match_operand:QI 2 "nonmemory_operand" "")))
10207 (clobber (reg:CC FLAGS_REG))])]
10208 "TARGET_64BIT"
10209 {
10210 if (! immediate_operand (operands[2], QImode))
10211 {
10212 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10213 DONE;
10214 }
10215 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10216 DONE;
10217 })
10218
10219 (define_insn "ashlti3_1"
10220 [(set (match_operand:TI 0 "register_operand" "=r")
10221 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10222 (match_operand:QI 2 "register_operand" "c")))
10223 (clobber (match_scratch:DI 3 "=&r"))
10224 (clobber (reg:CC FLAGS_REG))]
10225 "TARGET_64BIT"
10226 "#"
10227 [(set_attr "type" "multi")])
10228
10229 (define_insn "*ashlti3_2"
10230 [(set (match_operand:TI 0 "register_operand" "=r")
10231 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10232 (match_operand:QI 2 "immediate_operand" "O")))
10233 (clobber (reg:CC FLAGS_REG))]
10234 "TARGET_64BIT"
10235 "#"
10236 [(set_attr "type" "multi")])
10237
10238 (define_split
10239 [(set (match_operand:TI 0 "register_operand" "")
10240 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10241 (match_operand:QI 2 "register_operand" "")))
10242 (clobber (match_scratch:DI 3 ""))
10243 (clobber (reg:CC FLAGS_REG))]
10244 "TARGET_64BIT && reload_completed"
10245 [(const_int 0)]
10246 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10247
10248 (define_split
10249 [(set (match_operand:TI 0 "register_operand" "")
10250 (ashift:TI (match_operand:TI 1 "register_operand" "")
10251 (match_operand:QI 2 "immediate_operand" "")))
10252 (clobber (reg:CC FLAGS_REG))]
10253 "TARGET_64BIT && reload_completed"
10254 [(const_int 0)]
10255 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10256
10257 (define_insn "x86_64_shld"
10258 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10259 (ior:DI (ashift:DI (match_dup 0)
10260 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10261 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10262 (minus:QI (const_int 64) (match_dup 2)))))
10263 (clobber (reg:CC FLAGS_REG))]
10264 "TARGET_64BIT"
10265 "@
10266 shld{q}\t{%2, %1, %0|%0, %1, %2}
10267 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10268 [(set_attr "type" "ishift")
10269 (set_attr "prefix_0f" "1")
10270 (set_attr "mode" "DI")
10271 (set_attr "athlon_decode" "vector")])
10272
10273 (define_expand "x86_64_shift_adj"
10274 [(set (reg:CCZ FLAGS_REG)
10275 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10276 (const_int 64))
10277 (const_int 0)))
10278 (set (match_operand:DI 0 "register_operand" "")
10279 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10280 (match_operand:DI 1 "register_operand" "")
10281 (match_dup 0)))
10282 (set (match_dup 1)
10283 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10284 (match_operand:DI 3 "register_operand" "r")
10285 (match_dup 1)))]
10286 "TARGET_64BIT"
10287 "")
10288
10289 (define_expand "ashldi3"
10290 [(set (match_operand:DI 0 "shiftdi_operand" "")
10291 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10292 (match_operand:QI 2 "nonmemory_operand" "")))]
10293 ""
10294 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10295
10296 (define_insn "*ashldi3_1_rex64"
10297 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10298 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10299 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10300 (clobber (reg:CC FLAGS_REG))]
10301 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10302 {
10303 switch (get_attr_type (insn))
10304 {
10305 case TYPE_ALU:
10306 gcc_assert (operands[2] == const1_rtx);
10307 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10308 return "add{q}\t{%0, %0|%0, %0}";
10309
10310 case TYPE_LEA:
10311 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10312 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10313 operands[1] = gen_rtx_MULT (DImode, operands[1],
10314 GEN_INT (1 << INTVAL (operands[2])));
10315 return "lea{q}\t{%a1, %0|%0, %a1}";
10316
10317 default:
10318 if (REG_P (operands[2]))
10319 return "sal{q}\t{%b2, %0|%0, %b2}";
10320 else if (operands[2] == const1_rtx
10321 && (TARGET_SHIFT1 || optimize_size))
10322 return "sal{q}\t%0";
10323 else
10324 return "sal{q}\t{%2, %0|%0, %2}";
10325 }
10326 }
10327 [(set (attr "type")
10328 (cond [(eq_attr "alternative" "1")
10329 (const_string "lea")
10330 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10331 (const_int 0))
10332 (match_operand 0 "register_operand" ""))
10333 (match_operand 2 "const1_operand" ""))
10334 (const_string "alu")
10335 ]
10336 (const_string "ishift")))
10337 (set_attr "mode" "DI")])
10338
10339 ;; Convert lea to the lea pattern to avoid flags dependency.
10340 (define_split
10341 [(set (match_operand:DI 0 "register_operand" "")
10342 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10343 (match_operand:QI 2 "immediate_operand" "")))
10344 (clobber (reg:CC FLAGS_REG))]
10345 "TARGET_64BIT && reload_completed
10346 && true_regnum (operands[0]) != true_regnum (operands[1])"
10347 [(set (match_dup 0)
10348 (mult:DI (match_dup 1)
10349 (match_dup 2)))]
10350 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10351
10352 ;; This pattern can't accept a variable shift count, since shifts by
10353 ;; zero don't affect the flags. We assume that shifts by constant
10354 ;; zero are optimized away.
10355 (define_insn "*ashldi3_cmp_rex64"
10356 [(set (reg FLAGS_REG)
10357 (compare
10358 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10359 (match_operand:QI 2 "immediate_operand" "e"))
10360 (const_int 0)))
10361 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10362 (ashift:DI (match_dup 1) (match_dup 2)))]
10363 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10364 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10365 {
10366 switch (get_attr_type (insn))
10367 {
10368 case TYPE_ALU:
10369 gcc_assert (operands[2] == const1_rtx);
10370 return "add{q}\t{%0, %0|%0, %0}";
10371
10372 default:
10373 if (REG_P (operands[2]))
10374 return "sal{q}\t{%b2, %0|%0, %b2}";
10375 else if (operands[2] == const1_rtx
10376 && (TARGET_SHIFT1 || optimize_size))
10377 return "sal{q}\t%0";
10378 else
10379 return "sal{q}\t{%2, %0|%0, %2}";
10380 }
10381 }
10382 [(set (attr "type")
10383 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10384 (const_int 0))
10385 (match_operand 0 "register_operand" ""))
10386 (match_operand 2 "const1_operand" ""))
10387 (const_string "alu")
10388 ]
10389 (const_string "ishift")))
10390 (set_attr "mode" "DI")])
10391
10392 (define_insn "*ashldi3_1"
10393 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10394 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10395 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10396 (clobber (reg:CC FLAGS_REG))]
10397 "!TARGET_64BIT"
10398 "#"
10399 [(set_attr "type" "multi")])
10400
10401 ;; By default we don't ask for a scratch register, because when DImode
10402 ;; values are manipulated, registers are already at a premium. But if
10403 ;; we have one handy, we won't turn it away.
10404 (define_peephole2
10405 [(match_scratch:SI 3 "r")
10406 (parallel [(set (match_operand:DI 0 "register_operand" "")
10407 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10408 (match_operand:QI 2 "nonmemory_operand" "")))
10409 (clobber (reg:CC FLAGS_REG))])
10410 (match_dup 3)]
10411 "!TARGET_64BIT && TARGET_CMOVE"
10412 [(const_int 0)]
10413 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10414
10415 (define_split
10416 [(set (match_operand:DI 0 "register_operand" "")
10417 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10418 (match_operand:QI 2 "nonmemory_operand" "")))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10421 [(const_int 0)]
10422 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10423
10424 (define_insn "x86_shld_1"
10425 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10426 (ior:SI (ashift:SI (match_dup 0)
10427 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10428 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10429 (minus:QI (const_int 32) (match_dup 2)))))
10430 (clobber (reg:CC FLAGS_REG))]
10431 ""
10432 "@
10433 shld{l}\t{%2, %1, %0|%0, %1, %2}
10434 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10435 [(set_attr "type" "ishift")
10436 (set_attr "prefix_0f" "1")
10437 (set_attr "mode" "SI")
10438 (set_attr "pent_pair" "np")
10439 (set_attr "athlon_decode" "vector")])
10440
10441 (define_expand "x86_shift_adj_1"
10442 [(set (reg:CCZ FLAGS_REG)
10443 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10444 (const_int 32))
10445 (const_int 0)))
10446 (set (match_operand:SI 0 "register_operand" "")
10447 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10448 (match_operand:SI 1 "register_operand" "")
10449 (match_dup 0)))
10450 (set (match_dup 1)
10451 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10452 (match_operand:SI 3 "register_operand" "r")
10453 (match_dup 1)))]
10454 "TARGET_CMOVE"
10455 "")
10456
10457 (define_expand "x86_shift_adj_2"
10458 [(use (match_operand:SI 0 "register_operand" ""))
10459 (use (match_operand:SI 1 "register_operand" ""))
10460 (use (match_operand:QI 2 "register_operand" ""))]
10461 ""
10462 {
10463 rtx label = gen_label_rtx ();
10464 rtx tmp;
10465
10466 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10467
10468 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10469 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10470 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10471 gen_rtx_LABEL_REF (VOIDmode, label),
10472 pc_rtx);
10473 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10474 JUMP_LABEL (tmp) = label;
10475
10476 emit_move_insn (operands[0], operands[1]);
10477 ix86_expand_clear (operands[1]);
10478
10479 emit_label (label);
10480 LABEL_NUSES (label) = 1;
10481
10482 DONE;
10483 })
10484
10485 (define_expand "ashlsi3"
10486 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10487 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10488 (match_operand:QI 2 "nonmemory_operand" "")))
10489 (clobber (reg:CC FLAGS_REG))]
10490 ""
10491 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10492
10493 (define_insn "*ashlsi3_1"
10494 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10495 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10496 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10497 (clobber (reg:CC FLAGS_REG))]
10498 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10499 {
10500 switch (get_attr_type (insn))
10501 {
10502 case TYPE_ALU:
10503 gcc_assert (operands[2] == const1_rtx);
10504 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10505 return "add{l}\t{%0, %0|%0, %0}";
10506
10507 case TYPE_LEA:
10508 return "#";
10509
10510 default:
10511 if (REG_P (operands[2]))
10512 return "sal{l}\t{%b2, %0|%0, %b2}";
10513 else if (operands[2] == const1_rtx
10514 && (TARGET_SHIFT1 || optimize_size))
10515 return "sal{l}\t%0";
10516 else
10517 return "sal{l}\t{%2, %0|%0, %2}";
10518 }
10519 }
10520 [(set (attr "type")
10521 (cond [(eq_attr "alternative" "1")
10522 (const_string "lea")
10523 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10524 (const_int 0))
10525 (match_operand 0 "register_operand" ""))
10526 (match_operand 2 "const1_operand" ""))
10527 (const_string "alu")
10528 ]
10529 (const_string "ishift")))
10530 (set_attr "mode" "SI")])
10531
10532 ;; Convert lea to the lea pattern to avoid flags dependency.
10533 (define_split
10534 [(set (match_operand 0 "register_operand" "")
10535 (ashift (match_operand 1 "index_register_operand" "")
10536 (match_operand:QI 2 "const_int_operand" "")))
10537 (clobber (reg:CC FLAGS_REG))]
10538 "reload_completed
10539 && true_regnum (operands[0]) != true_regnum (operands[1])
10540 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10541 [(const_int 0)]
10542 {
10543 rtx pat;
10544 enum machine_mode mode = GET_MODE (operands[0]);
10545
10546 if (GET_MODE_SIZE (mode) < 4)
10547 operands[0] = gen_lowpart (SImode, operands[0]);
10548 if (mode != Pmode)
10549 operands[1] = gen_lowpart (Pmode, operands[1]);
10550 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10551
10552 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10553 if (Pmode != SImode)
10554 pat = gen_rtx_SUBREG (SImode, pat, 0);
10555 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10556 DONE;
10557 })
10558
10559 ;; Rare case of shifting RSP is handled by generating move and shift
10560 (define_split
10561 [(set (match_operand 0 "register_operand" "")
10562 (ashift (match_operand 1 "register_operand" "")
10563 (match_operand:QI 2 "const_int_operand" "")))
10564 (clobber (reg:CC FLAGS_REG))]
10565 "reload_completed
10566 && true_regnum (operands[0]) != true_regnum (operands[1])"
10567 [(const_int 0)]
10568 {
10569 rtx pat, clob;
10570 emit_move_insn (operands[1], operands[0]);
10571 pat = gen_rtx_SET (VOIDmode, operands[0],
10572 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10573 operands[0], operands[2]));
10574 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10575 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10576 DONE;
10577 })
10578
10579 (define_insn "*ashlsi3_1_zext"
10580 [(set (match_operand:DI 0 "register_operand" "=r,r")
10581 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10582 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10583 (clobber (reg:CC FLAGS_REG))]
10584 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10585 {
10586 switch (get_attr_type (insn))
10587 {
10588 case TYPE_ALU:
10589 gcc_assert (operands[2] == const1_rtx);
10590 return "add{l}\t{%k0, %k0|%k0, %k0}";
10591
10592 case TYPE_LEA:
10593 return "#";
10594
10595 default:
10596 if (REG_P (operands[2]))
10597 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10598 else if (operands[2] == const1_rtx
10599 && (TARGET_SHIFT1 || optimize_size))
10600 return "sal{l}\t%k0";
10601 else
10602 return "sal{l}\t{%2, %k0|%k0, %2}";
10603 }
10604 }
10605 [(set (attr "type")
10606 (cond [(eq_attr "alternative" "1")
10607 (const_string "lea")
10608 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10609 (const_int 0))
10610 (match_operand 2 "const1_operand" ""))
10611 (const_string "alu")
10612 ]
10613 (const_string "ishift")))
10614 (set_attr "mode" "SI")])
10615
10616 ;; Convert lea to the lea pattern to avoid flags dependency.
10617 (define_split
10618 [(set (match_operand:DI 0 "register_operand" "")
10619 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10620 (match_operand:QI 2 "const_int_operand" ""))))
10621 (clobber (reg:CC FLAGS_REG))]
10622 "TARGET_64BIT && reload_completed
10623 && true_regnum (operands[0]) != true_regnum (operands[1])"
10624 [(set (match_dup 0) (zero_extend:DI
10625 (subreg:SI (mult:SI (match_dup 1)
10626 (match_dup 2)) 0)))]
10627 {
10628 operands[1] = gen_lowpart (Pmode, operands[1]);
10629 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10630 })
10631
10632 ;; This pattern can't accept a variable shift count, since shifts by
10633 ;; zero don't affect the flags. We assume that shifts by constant
10634 ;; zero are optimized away.
10635 (define_insn "*ashlsi3_cmp"
10636 [(set (reg FLAGS_REG)
10637 (compare
10638 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10639 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10640 (const_int 0)))
10641 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10642 (ashift:SI (match_dup 1) (match_dup 2)))]
10643 "ix86_match_ccmode (insn, CCGOCmode)
10644 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10645 {
10646 switch (get_attr_type (insn))
10647 {
10648 case TYPE_ALU:
10649 gcc_assert (operands[2] == const1_rtx);
10650 return "add{l}\t{%0, %0|%0, %0}";
10651
10652 default:
10653 if (REG_P (operands[2]))
10654 return "sal{l}\t{%b2, %0|%0, %b2}";
10655 else if (operands[2] == const1_rtx
10656 && (TARGET_SHIFT1 || optimize_size))
10657 return "sal{l}\t%0";
10658 else
10659 return "sal{l}\t{%2, %0|%0, %2}";
10660 }
10661 }
10662 [(set (attr "type")
10663 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10664 (const_int 0))
10665 (match_operand 0 "register_operand" ""))
10666 (match_operand 2 "const1_operand" ""))
10667 (const_string "alu")
10668 ]
10669 (const_string "ishift")))
10670 (set_attr "mode" "SI")])
10671
10672 (define_insn "*ashlsi3_cmp_zext"
10673 [(set (reg FLAGS_REG)
10674 (compare
10675 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10676 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10677 (const_int 0)))
10678 (set (match_operand:DI 0 "register_operand" "=r")
10679 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10680 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10681 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10682 {
10683 switch (get_attr_type (insn))
10684 {
10685 case TYPE_ALU:
10686 gcc_assert (operands[2] == const1_rtx);
10687 return "add{l}\t{%k0, %k0|%k0, %k0}";
10688
10689 default:
10690 if (REG_P (operands[2]))
10691 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10692 else if (operands[2] == const1_rtx
10693 && (TARGET_SHIFT1 || optimize_size))
10694 return "sal{l}\t%k0";
10695 else
10696 return "sal{l}\t{%2, %k0|%k0, %2}";
10697 }
10698 }
10699 [(set (attr "type")
10700 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10701 (const_int 0))
10702 (match_operand 2 "const1_operand" ""))
10703 (const_string "alu")
10704 ]
10705 (const_string "ishift")))
10706 (set_attr "mode" "SI")])
10707
10708 (define_expand "ashlhi3"
10709 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10710 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10711 (match_operand:QI 2 "nonmemory_operand" "")))
10712 (clobber (reg:CC FLAGS_REG))]
10713 "TARGET_HIMODE_MATH"
10714 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10715
10716 (define_insn "*ashlhi3_1_lea"
10717 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10718 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10719 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10720 (clobber (reg:CC FLAGS_REG))]
10721 "!TARGET_PARTIAL_REG_STALL
10722 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10723 {
10724 switch (get_attr_type (insn))
10725 {
10726 case TYPE_LEA:
10727 return "#";
10728 case TYPE_ALU:
10729 gcc_assert (operands[2] == const1_rtx);
10730 return "add{w}\t{%0, %0|%0, %0}";
10731
10732 default:
10733 if (REG_P (operands[2]))
10734 return "sal{w}\t{%b2, %0|%0, %b2}";
10735 else if (operands[2] == const1_rtx
10736 && (TARGET_SHIFT1 || optimize_size))
10737 return "sal{w}\t%0";
10738 else
10739 return "sal{w}\t{%2, %0|%0, %2}";
10740 }
10741 }
10742 [(set (attr "type")
10743 (cond [(eq_attr "alternative" "1")
10744 (const_string "lea")
10745 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10746 (const_int 0))
10747 (match_operand 0 "register_operand" ""))
10748 (match_operand 2 "const1_operand" ""))
10749 (const_string "alu")
10750 ]
10751 (const_string "ishift")))
10752 (set_attr "mode" "HI,SI")])
10753
10754 (define_insn "*ashlhi3_1"
10755 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10756 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10757 (match_operand:QI 2 "nonmemory_operand" "cI")))
10758 (clobber (reg:CC FLAGS_REG))]
10759 "TARGET_PARTIAL_REG_STALL
10760 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10761 {
10762 switch (get_attr_type (insn))
10763 {
10764 case TYPE_ALU:
10765 gcc_assert (operands[2] == const1_rtx);
10766 return "add{w}\t{%0, %0|%0, %0}";
10767
10768 default:
10769 if (REG_P (operands[2]))
10770 return "sal{w}\t{%b2, %0|%0, %b2}";
10771 else if (operands[2] == const1_rtx
10772 && (TARGET_SHIFT1 || optimize_size))
10773 return "sal{w}\t%0";
10774 else
10775 return "sal{w}\t{%2, %0|%0, %2}";
10776 }
10777 }
10778 [(set (attr "type")
10779 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10780 (const_int 0))
10781 (match_operand 0 "register_operand" ""))
10782 (match_operand 2 "const1_operand" ""))
10783 (const_string "alu")
10784 ]
10785 (const_string "ishift")))
10786 (set_attr "mode" "HI")])
10787
10788 ;; This pattern can't accept a variable shift count, since shifts by
10789 ;; zero don't affect the flags. We assume that shifts by constant
10790 ;; zero are optimized away.
10791 (define_insn "*ashlhi3_cmp"
10792 [(set (reg FLAGS_REG)
10793 (compare
10794 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10795 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10796 (const_int 0)))
10797 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10798 (ashift:HI (match_dup 1) (match_dup 2)))]
10799 "ix86_match_ccmode (insn, CCGOCmode)
10800 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10801 {
10802 switch (get_attr_type (insn))
10803 {
10804 case TYPE_ALU:
10805 gcc_assert (operands[2] == const1_rtx);
10806 return "add{w}\t{%0, %0|%0, %0}";
10807
10808 default:
10809 if (REG_P (operands[2]))
10810 return "sal{w}\t{%b2, %0|%0, %b2}";
10811 else if (operands[2] == const1_rtx
10812 && (TARGET_SHIFT1 || optimize_size))
10813 return "sal{w}\t%0";
10814 else
10815 return "sal{w}\t{%2, %0|%0, %2}";
10816 }
10817 }
10818 [(set (attr "type")
10819 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10820 (const_int 0))
10821 (match_operand 0 "register_operand" ""))
10822 (match_operand 2 "const1_operand" ""))
10823 (const_string "alu")
10824 ]
10825 (const_string "ishift")))
10826 (set_attr "mode" "HI")])
10827
10828 (define_expand "ashlqi3"
10829 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10830 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10831 (match_operand:QI 2 "nonmemory_operand" "")))
10832 (clobber (reg:CC FLAGS_REG))]
10833 "TARGET_QIMODE_MATH"
10834 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10835
10836 ;; %%% Potential partial reg stall on alternative 2. What to do?
10837
10838 (define_insn "*ashlqi3_1_lea"
10839 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10840 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10841 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10842 (clobber (reg:CC FLAGS_REG))]
10843 "!TARGET_PARTIAL_REG_STALL
10844 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10845 {
10846 switch (get_attr_type (insn))
10847 {
10848 case TYPE_LEA:
10849 return "#";
10850 case TYPE_ALU:
10851 gcc_assert (operands[2] == const1_rtx);
10852 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10853 return "add{l}\t{%k0, %k0|%k0, %k0}";
10854 else
10855 return "add{b}\t{%0, %0|%0, %0}";
10856
10857 default:
10858 if (REG_P (operands[2]))
10859 {
10860 if (get_attr_mode (insn) == MODE_SI)
10861 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10862 else
10863 return "sal{b}\t{%b2, %0|%0, %b2}";
10864 }
10865 else if (operands[2] == const1_rtx
10866 && (TARGET_SHIFT1 || optimize_size))
10867 {
10868 if (get_attr_mode (insn) == MODE_SI)
10869 return "sal{l}\t%0";
10870 else
10871 return "sal{b}\t%0";
10872 }
10873 else
10874 {
10875 if (get_attr_mode (insn) == MODE_SI)
10876 return "sal{l}\t{%2, %k0|%k0, %2}";
10877 else
10878 return "sal{b}\t{%2, %0|%0, %2}";
10879 }
10880 }
10881 }
10882 [(set (attr "type")
10883 (cond [(eq_attr "alternative" "2")
10884 (const_string "lea")
10885 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10886 (const_int 0))
10887 (match_operand 0 "register_operand" ""))
10888 (match_operand 2 "const1_operand" ""))
10889 (const_string "alu")
10890 ]
10891 (const_string "ishift")))
10892 (set_attr "mode" "QI,SI,SI")])
10893
10894 (define_insn "*ashlqi3_1"
10895 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10896 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10897 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10898 (clobber (reg:CC FLAGS_REG))]
10899 "TARGET_PARTIAL_REG_STALL
10900 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10901 {
10902 switch (get_attr_type (insn))
10903 {
10904 case TYPE_ALU:
10905 gcc_assert (operands[2] == const1_rtx);
10906 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10907 return "add{l}\t{%k0, %k0|%k0, %k0}";
10908 else
10909 return "add{b}\t{%0, %0|%0, %0}";
10910
10911 default:
10912 if (REG_P (operands[2]))
10913 {
10914 if (get_attr_mode (insn) == MODE_SI)
10915 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10916 else
10917 return "sal{b}\t{%b2, %0|%0, %b2}";
10918 }
10919 else if (operands[2] == const1_rtx
10920 && (TARGET_SHIFT1 || optimize_size))
10921 {
10922 if (get_attr_mode (insn) == MODE_SI)
10923 return "sal{l}\t%0";
10924 else
10925 return "sal{b}\t%0";
10926 }
10927 else
10928 {
10929 if (get_attr_mode (insn) == MODE_SI)
10930 return "sal{l}\t{%2, %k0|%k0, %2}";
10931 else
10932 return "sal{b}\t{%2, %0|%0, %2}";
10933 }
10934 }
10935 }
10936 [(set (attr "type")
10937 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10938 (const_int 0))
10939 (match_operand 0 "register_operand" ""))
10940 (match_operand 2 "const1_operand" ""))
10941 (const_string "alu")
10942 ]
10943 (const_string "ishift")))
10944 (set_attr "mode" "QI,SI")])
10945
10946 ;; This pattern can't accept a variable shift count, since shifts by
10947 ;; zero don't affect the flags. We assume that shifts by constant
10948 ;; zero are optimized away.
10949 (define_insn "*ashlqi3_cmp"
10950 [(set (reg FLAGS_REG)
10951 (compare
10952 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10953 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10954 (const_int 0)))
10955 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10956 (ashift:QI (match_dup 1) (match_dup 2)))]
10957 "ix86_match_ccmode (insn, CCGOCmode)
10958 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10959 {
10960 switch (get_attr_type (insn))
10961 {
10962 case TYPE_ALU:
10963 gcc_assert (operands[2] == const1_rtx);
10964 return "add{b}\t{%0, %0|%0, %0}";
10965
10966 default:
10967 if (REG_P (operands[2]))
10968 return "sal{b}\t{%b2, %0|%0, %b2}";
10969 else if (operands[2] == const1_rtx
10970 && (TARGET_SHIFT1 || optimize_size))
10971 return "sal{b}\t%0";
10972 else
10973 return "sal{b}\t{%2, %0|%0, %2}";
10974 }
10975 }
10976 [(set (attr "type")
10977 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10978 (const_int 0))
10979 (match_operand 0 "register_operand" ""))
10980 (match_operand 2 "const1_operand" ""))
10981 (const_string "alu")
10982 ]
10983 (const_string "ishift")))
10984 (set_attr "mode" "QI")])
10985
10986 ;; See comment above `ashldi3' about how this works.
10987
10988 (define_expand "ashrti3"
10989 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10990 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10991 (match_operand:QI 2 "nonmemory_operand" "")))
10992 (clobber (reg:CC FLAGS_REG))])]
10993 "TARGET_64BIT"
10994 {
10995 if (! immediate_operand (operands[2], QImode))
10996 {
10997 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
10998 DONE;
10999 }
11000 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11001 DONE;
11002 })
11003
11004 (define_insn "ashrti3_1"
11005 [(set (match_operand:TI 0 "register_operand" "=r")
11006 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11007 (match_operand:QI 2 "register_operand" "c")))
11008 (clobber (match_scratch:DI 3 "=&r"))
11009 (clobber (reg:CC FLAGS_REG))]
11010 "TARGET_64BIT"
11011 "#"
11012 [(set_attr "type" "multi")])
11013
11014 (define_insn "*ashrti3_2"
11015 [(set (match_operand:TI 0 "register_operand" "=r")
11016 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11017 (match_operand:QI 2 "immediate_operand" "O")))
11018 (clobber (reg:CC FLAGS_REG))]
11019 "TARGET_64BIT"
11020 "#"
11021 [(set_attr "type" "multi")])
11022
11023 (define_split
11024 [(set (match_operand:TI 0 "register_operand" "")
11025 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11026 (match_operand:QI 2 "register_operand" "")))
11027 (clobber (match_scratch:DI 3 ""))
11028 (clobber (reg:CC FLAGS_REG))]
11029 "TARGET_64BIT && reload_completed"
11030 [(const_int 0)]
11031 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11032
11033 (define_split
11034 [(set (match_operand:TI 0 "register_operand" "")
11035 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11036 (match_operand:QI 2 "immediate_operand" "")))
11037 (clobber (reg:CC FLAGS_REG))]
11038 "TARGET_64BIT && reload_completed"
11039 [(const_int 0)]
11040 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11041
11042 (define_insn "x86_64_shrd"
11043 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11044 (ior:DI (ashiftrt:DI (match_dup 0)
11045 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11046 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11047 (minus:QI (const_int 64) (match_dup 2)))))
11048 (clobber (reg:CC FLAGS_REG))]
11049 "TARGET_64BIT"
11050 "@
11051 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11052 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11053 [(set_attr "type" "ishift")
11054 (set_attr "prefix_0f" "1")
11055 (set_attr "mode" "DI")
11056 (set_attr "athlon_decode" "vector")])
11057
11058 (define_expand "ashrdi3"
11059 [(set (match_operand:DI 0 "shiftdi_operand" "")
11060 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11061 (match_operand:QI 2 "nonmemory_operand" "")))]
11062 ""
11063 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11064
11065 (define_insn "*ashrdi3_63_rex64"
11066 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11067 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11068 (match_operand:DI 2 "const_int_operand" "i,i")))
11069 (clobber (reg:CC FLAGS_REG))]
11070 "TARGET_64BIT && INTVAL (operands[2]) == 63
11071 && (TARGET_USE_CLTD || optimize_size)
11072 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11073 "@
11074 {cqto|cqo}
11075 sar{q}\t{%2, %0|%0, %2}"
11076 [(set_attr "type" "imovx,ishift")
11077 (set_attr "prefix_0f" "0,*")
11078 (set_attr "length_immediate" "0,*")
11079 (set_attr "modrm" "0,1")
11080 (set_attr "mode" "DI")])
11081
11082 (define_insn "*ashrdi3_1_one_bit_rex64"
11083 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11084 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11085 (match_operand:QI 2 "const1_operand" "")))
11086 (clobber (reg:CC FLAGS_REG))]
11087 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11088 && (TARGET_SHIFT1 || optimize_size)"
11089 "sar{q}\t%0"
11090 [(set_attr "type" "ishift")
11091 (set (attr "length")
11092 (if_then_else (match_operand:DI 0 "register_operand" "")
11093 (const_string "2")
11094 (const_string "*")))])
11095
11096 (define_insn "*ashrdi3_1_rex64"
11097 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11098 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11099 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11100 (clobber (reg:CC FLAGS_REG))]
11101 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11102 "@
11103 sar{q}\t{%2, %0|%0, %2}
11104 sar{q}\t{%b2, %0|%0, %b2}"
11105 [(set_attr "type" "ishift")
11106 (set_attr "mode" "DI")])
11107
11108 ;; This pattern can't accept a variable shift count, since shifts by
11109 ;; zero don't affect the flags. We assume that shifts by constant
11110 ;; zero are optimized away.
11111 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11112 [(set (reg FLAGS_REG)
11113 (compare
11114 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11115 (match_operand:QI 2 "const1_operand" ""))
11116 (const_int 0)))
11117 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11118 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11119 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11120 && (TARGET_SHIFT1 || optimize_size)
11121 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11122 "sar{q}\t%0"
11123 [(set_attr "type" "ishift")
11124 (set (attr "length")
11125 (if_then_else (match_operand:DI 0 "register_operand" "")
11126 (const_string "2")
11127 (const_string "*")))])
11128
11129 ;; This pattern can't accept a variable shift count, since shifts by
11130 ;; zero don't affect the flags. We assume that shifts by constant
11131 ;; zero are optimized away.
11132 (define_insn "*ashrdi3_cmp_rex64"
11133 [(set (reg FLAGS_REG)
11134 (compare
11135 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11136 (match_operand:QI 2 "const_int_operand" "n"))
11137 (const_int 0)))
11138 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11139 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11140 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11141 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11142 "sar{q}\t{%2, %0|%0, %2}"
11143 [(set_attr "type" "ishift")
11144 (set_attr "mode" "DI")])
11145
11146 (define_insn "*ashrdi3_1"
11147 [(set (match_operand:DI 0 "register_operand" "=r")
11148 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11149 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11150 (clobber (reg:CC FLAGS_REG))]
11151 "!TARGET_64BIT"
11152 "#"
11153 [(set_attr "type" "multi")])
11154
11155 ;; By default we don't ask for a scratch register, because when DImode
11156 ;; values are manipulated, registers are already at a premium. But if
11157 ;; we have one handy, we won't turn it away.
11158 (define_peephole2
11159 [(match_scratch:SI 3 "r")
11160 (parallel [(set (match_operand:DI 0 "register_operand" "")
11161 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11162 (match_operand:QI 2 "nonmemory_operand" "")))
11163 (clobber (reg:CC FLAGS_REG))])
11164 (match_dup 3)]
11165 "!TARGET_64BIT && TARGET_CMOVE"
11166 [(const_int 0)]
11167 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11168
11169 (define_split
11170 [(set (match_operand:DI 0 "register_operand" "")
11171 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11172 (match_operand:QI 2 "nonmemory_operand" "")))
11173 (clobber (reg:CC FLAGS_REG))]
11174 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11175 [(const_int 0)]
11176 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11177
11178 (define_insn "x86_shrd_1"
11179 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11180 (ior:SI (ashiftrt:SI (match_dup 0)
11181 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11182 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11183 (minus:QI (const_int 32) (match_dup 2)))))
11184 (clobber (reg:CC FLAGS_REG))]
11185 ""
11186 "@
11187 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11188 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11189 [(set_attr "type" "ishift")
11190 (set_attr "prefix_0f" "1")
11191 (set_attr "pent_pair" "np")
11192 (set_attr "mode" "SI")])
11193
11194 (define_expand "x86_shift_adj_3"
11195 [(use (match_operand:SI 0 "register_operand" ""))
11196 (use (match_operand:SI 1 "register_operand" ""))
11197 (use (match_operand:QI 2 "register_operand" ""))]
11198 ""
11199 {
11200 rtx label = gen_label_rtx ();
11201 rtx tmp;
11202
11203 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11204
11205 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11206 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11207 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11208 gen_rtx_LABEL_REF (VOIDmode, label),
11209 pc_rtx);
11210 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11211 JUMP_LABEL (tmp) = label;
11212
11213 emit_move_insn (operands[0], operands[1]);
11214 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11215
11216 emit_label (label);
11217 LABEL_NUSES (label) = 1;
11218
11219 DONE;
11220 })
11221
11222 (define_insn "ashrsi3_31"
11223 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11224 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11225 (match_operand:SI 2 "const_int_operand" "i,i")))
11226 (clobber (reg:CC FLAGS_REG))]
11227 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11228 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11229 "@
11230 {cltd|cdq}
11231 sar{l}\t{%2, %0|%0, %2}"
11232 [(set_attr "type" "imovx,ishift")
11233 (set_attr "prefix_0f" "0,*")
11234 (set_attr "length_immediate" "0,*")
11235 (set_attr "modrm" "0,1")
11236 (set_attr "mode" "SI")])
11237
11238 (define_insn "*ashrsi3_31_zext"
11239 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11240 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11241 (match_operand:SI 2 "const_int_operand" "i,i"))))
11242 (clobber (reg:CC FLAGS_REG))]
11243 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11244 && INTVAL (operands[2]) == 31
11245 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11246 "@
11247 {cltd|cdq}
11248 sar{l}\t{%2, %k0|%k0, %2}"
11249 [(set_attr "type" "imovx,ishift")
11250 (set_attr "prefix_0f" "0,*")
11251 (set_attr "length_immediate" "0,*")
11252 (set_attr "modrm" "0,1")
11253 (set_attr "mode" "SI")])
11254
11255 (define_expand "ashrsi3"
11256 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11257 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11258 (match_operand:QI 2 "nonmemory_operand" "")))
11259 (clobber (reg:CC FLAGS_REG))]
11260 ""
11261 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11262
11263 (define_insn "*ashrsi3_1_one_bit"
11264 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11265 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11266 (match_operand:QI 2 "const1_operand" "")))
11267 (clobber (reg:CC FLAGS_REG))]
11268 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11269 && (TARGET_SHIFT1 || optimize_size)"
11270 "sar{l}\t%0"
11271 [(set_attr "type" "ishift")
11272 (set (attr "length")
11273 (if_then_else (match_operand:SI 0 "register_operand" "")
11274 (const_string "2")
11275 (const_string "*")))])
11276
11277 (define_insn "*ashrsi3_1_one_bit_zext"
11278 [(set (match_operand:DI 0 "register_operand" "=r")
11279 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11280 (match_operand:QI 2 "const1_operand" ""))))
11281 (clobber (reg:CC FLAGS_REG))]
11282 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11283 && (TARGET_SHIFT1 || optimize_size)"
11284 "sar{l}\t%k0"
11285 [(set_attr "type" "ishift")
11286 (set_attr "length" "2")])
11287
11288 (define_insn "*ashrsi3_1"
11289 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11290 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11291 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11292 (clobber (reg:CC FLAGS_REG))]
11293 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11294 "@
11295 sar{l}\t{%2, %0|%0, %2}
11296 sar{l}\t{%b2, %0|%0, %b2}"
11297 [(set_attr "type" "ishift")
11298 (set_attr "mode" "SI")])
11299
11300 (define_insn "*ashrsi3_1_zext"
11301 [(set (match_operand:DI 0 "register_operand" "=r,r")
11302 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11303 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11304 (clobber (reg:CC FLAGS_REG))]
11305 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11306 "@
11307 sar{l}\t{%2, %k0|%k0, %2}
11308 sar{l}\t{%b2, %k0|%k0, %b2}"
11309 [(set_attr "type" "ishift")
11310 (set_attr "mode" "SI")])
11311
11312 ;; This pattern can't accept a variable shift count, since shifts by
11313 ;; zero don't affect the flags. We assume that shifts by constant
11314 ;; zero are optimized away.
11315 (define_insn "*ashrsi3_one_bit_cmp"
11316 [(set (reg FLAGS_REG)
11317 (compare
11318 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11319 (match_operand:QI 2 "const1_operand" ""))
11320 (const_int 0)))
11321 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11322 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11323 "ix86_match_ccmode (insn, CCGOCmode)
11324 && (TARGET_SHIFT1 || optimize_size)
11325 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11326 "sar{l}\t%0"
11327 [(set_attr "type" "ishift")
11328 (set (attr "length")
11329 (if_then_else (match_operand:SI 0 "register_operand" "")
11330 (const_string "2")
11331 (const_string "*")))])
11332
11333 (define_insn "*ashrsi3_one_bit_cmp_zext"
11334 [(set (reg FLAGS_REG)
11335 (compare
11336 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11337 (match_operand:QI 2 "const1_operand" ""))
11338 (const_int 0)))
11339 (set (match_operand:DI 0 "register_operand" "=r")
11340 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11341 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11342 && (TARGET_SHIFT1 || optimize_size)
11343 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11344 "sar{l}\t%k0"
11345 [(set_attr "type" "ishift")
11346 (set_attr "length" "2")])
11347
11348 ;; This pattern can't accept a variable shift count, since shifts by
11349 ;; zero don't affect the flags. We assume that shifts by constant
11350 ;; zero are optimized away.
11351 (define_insn "*ashrsi3_cmp"
11352 [(set (reg FLAGS_REG)
11353 (compare
11354 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11355 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11356 (const_int 0)))
11357 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11358 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11359 "ix86_match_ccmode (insn, CCGOCmode)
11360 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11361 "sar{l}\t{%2, %0|%0, %2}"
11362 [(set_attr "type" "ishift")
11363 (set_attr "mode" "SI")])
11364
11365 (define_insn "*ashrsi3_cmp_zext"
11366 [(set (reg FLAGS_REG)
11367 (compare
11368 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11369 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11370 (const_int 0)))
11371 (set (match_operand:DI 0 "register_operand" "=r")
11372 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11373 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11374 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11375 "sar{l}\t{%2, %k0|%k0, %2}"
11376 [(set_attr "type" "ishift")
11377 (set_attr "mode" "SI")])
11378
11379 (define_expand "ashrhi3"
11380 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11381 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11382 (match_operand:QI 2 "nonmemory_operand" "")))
11383 (clobber (reg:CC FLAGS_REG))]
11384 "TARGET_HIMODE_MATH"
11385 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11386
11387 (define_insn "*ashrhi3_1_one_bit"
11388 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11389 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11390 (match_operand:QI 2 "const1_operand" "")))
11391 (clobber (reg:CC FLAGS_REG))]
11392 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11393 && (TARGET_SHIFT1 || optimize_size)"
11394 "sar{w}\t%0"
11395 [(set_attr "type" "ishift")
11396 (set (attr "length")
11397 (if_then_else (match_operand 0 "register_operand" "")
11398 (const_string "2")
11399 (const_string "*")))])
11400
11401 (define_insn "*ashrhi3_1"
11402 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11403 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11404 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11405 (clobber (reg:CC FLAGS_REG))]
11406 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11407 "@
11408 sar{w}\t{%2, %0|%0, %2}
11409 sar{w}\t{%b2, %0|%0, %b2}"
11410 [(set_attr "type" "ishift")
11411 (set_attr "mode" "HI")])
11412
11413 ;; This pattern can't accept a variable shift count, since shifts by
11414 ;; zero don't affect the flags. We assume that shifts by constant
11415 ;; zero are optimized away.
11416 (define_insn "*ashrhi3_one_bit_cmp"
11417 [(set (reg FLAGS_REG)
11418 (compare
11419 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11420 (match_operand:QI 2 "const1_operand" ""))
11421 (const_int 0)))
11422 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11423 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11424 "ix86_match_ccmode (insn, CCGOCmode)
11425 && (TARGET_SHIFT1 || optimize_size)
11426 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11427 "sar{w}\t%0"
11428 [(set_attr "type" "ishift")
11429 (set (attr "length")
11430 (if_then_else (match_operand 0 "register_operand" "")
11431 (const_string "2")
11432 (const_string "*")))])
11433
11434 ;; This pattern can't accept a variable shift count, since shifts by
11435 ;; zero don't affect the flags. We assume that shifts by constant
11436 ;; zero are optimized away.
11437 (define_insn "*ashrhi3_cmp"
11438 [(set (reg FLAGS_REG)
11439 (compare
11440 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11441 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11442 (const_int 0)))
11443 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11444 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11445 "ix86_match_ccmode (insn, CCGOCmode)
11446 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11447 "sar{w}\t{%2, %0|%0, %2}"
11448 [(set_attr "type" "ishift")
11449 (set_attr "mode" "HI")])
11450
11451 (define_expand "ashrqi3"
11452 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11453 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11454 (match_operand:QI 2 "nonmemory_operand" "")))
11455 (clobber (reg:CC FLAGS_REG))]
11456 "TARGET_QIMODE_MATH"
11457 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11458
11459 (define_insn "*ashrqi3_1_one_bit"
11460 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11461 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11462 (match_operand:QI 2 "const1_operand" "")))
11463 (clobber (reg:CC FLAGS_REG))]
11464 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11465 && (TARGET_SHIFT1 || optimize_size)"
11466 "sar{b}\t%0"
11467 [(set_attr "type" "ishift")
11468 (set (attr "length")
11469 (if_then_else (match_operand 0 "register_operand" "")
11470 (const_string "2")
11471 (const_string "*")))])
11472
11473 (define_insn "*ashrqi3_1_one_bit_slp"
11474 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11475 (ashiftrt:QI (match_dup 0)
11476 (match_operand:QI 1 "const1_operand" "")))
11477 (clobber (reg:CC FLAGS_REG))]
11478 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11479 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11480 && (TARGET_SHIFT1 || optimize_size)"
11481 "sar{b}\t%0"
11482 [(set_attr "type" "ishift1")
11483 (set (attr "length")
11484 (if_then_else (match_operand 0 "register_operand" "")
11485 (const_string "2")
11486 (const_string "*")))])
11487
11488 (define_insn "*ashrqi3_1"
11489 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11490 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11491 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11492 (clobber (reg:CC FLAGS_REG))]
11493 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11494 "@
11495 sar{b}\t{%2, %0|%0, %2}
11496 sar{b}\t{%b2, %0|%0, %b2}"
11497 [(set_attr "type" "ishift")
11498 (set_attr "mode" "QI")])
11499
11500 (define_insn "*ashrqi3_1_slp"
11501 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11502 (ashiftrt:QI (match_dup 0)
11503 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11504 (clobber (reg:CC FLAGS_REG))]
11505 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11506 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11507 "@
11508 sar{b}\t{%1, %0|%0, %1}
11509 sar{b}\t{%b1, %0|%0, %b1}"
11510 [(set_attr "type" "ishift1")
11511 (set_attr "mode" "QI")])
11512
11513 ;; This pattern can't accept a variable shift count, since shifts by
11514 ;; zero don't affect the flags. We assume that shifts by constant
11515 ;; zero are optimized away.
11516 (define_insn "*ashrqi3_one_bit_cmp"
11517 [(set (reg FLAGS_REG)
11518 (compare
11519 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11520 (match_operand:QI 2 "const1_operand" "I"))
11521 (const_int 0)))
11522 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11523 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11524 "ix86_match_ccmode (insn, CCGOCmode)
11525 && (TARGET_SHIFT1 || optimize_size)
11526 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11527 "sar{b}\t%0"
11528 [(set_attr "type" "ishift")
11529 (set (attr "length")
11530 (if_then_else (match_operand 0 "register_operand" "")
11531 (const_string "2")
11532 (const_string "*")))])
11533
11534 ;; This pattern can't accept a variable shift count, since shifts by
11535 ;; zero don't affect the flags. We assume that shifts by constant
11536 ;; zero are optimized away.
11537 (define_insn "*ashrqi3_cmp"
11538 [(set (reg FLAGS_REG)
11539 (compare
11540 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11541 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11542 (const_int 0)))
11543 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11544 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11545 "ix86_match_ccmode (insn, CCGOCmode)
11546 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11547 "sar{b}\t{%2, %0|%0, %2}"
11548 [(set_attr "type" "ishift")
11549 (set_attr "mode" "QI")])
11550 \f
11551 ;; Logical shift instructions
11552
11553 ;; See comment above `ashldi3' about how this works.
11554
11555 (define_expand "lshrti3"
11556 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11557 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11558 (match_operand:QI 2 "nonmemory_operand" "")))
11559 (clobber (reg:CC FLAGS_REG))])]
11560 "TARGET_64BIT"
11561 {
11562 if (! immediate_operand (operands[2], QImode))
11563 {
11564 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11565 DONE;
11566 }
11567 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11568 DONE;
11569 })
11570
11571 (define_insn "lshrti3_1"
11572 [(set (match_operand:TI 0 "register_operand" "=r")
11573 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11574 (match_operand:QI 2 "register_operand" "c")))
11575 (clobber (match_scratch:DI 3 "=&r"))
11576 (clobber (reg:CC FLAGS_REG))]
11577 "TARGET_64BIT"
11578 "#"
11579 [(set_attr "type" "multi")])
11580
11581 (define_insn "*lshrti3_2"
11582 [(set (match_operand:TI 0 "register_operand" "=r")
11583 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11584 (match_operand:QI 2 "immediate_operand" "O")))
11585 (clobber (reg:CC FLAGS_REG))]
11586 "TARGET_64BIT"
11587 "#"
11588 [(set_attr "type" "multi")])
11589
11590 (define_split
11591 [(set (match_operand:TI 0 "register_operand" "")
11592 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11593 (match_operand:QI 2 "register_operand" "")))
11594 (clobber (match_scratch:DI 3 ""))
11595 (clobber (reg:CC FLAGS_REG))]
11596 "TARGET_64BIT && reload_completed"
11597 [(const_int 0)]
11598 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11599
11600 (define_split
11601 [(set (match_operand:TI 0 "register_operand" "")
11602 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11603 (match_operand:QI 2 "immediate_operand" "")))
11604 (clobber (reg:CC FLAGS_REG))]
11605 "TARGET_64BIT && reload_completed"
11606 [(const_int 0)]
11607 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11608
11609 (define_expand "lshrdi3"
11610 [(set (match_operand:DI 0 "shiftdi_operand" "")
11611 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11612 (match_operand:QI 2 "nonmemory_operand" "")))]
11613 ""
11614 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11615
11616 (define_insn "*lshrdi3_1_one_bit_rex64"
11617 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11618 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11619 (match_operand:QI 2 "const1_operand" "")))
11620 (clobber (reg:CC FLAGS_REG))]
11621 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11622 && (TARGET_SHIFT1 || optimize_size)"
11623 "shr{q}\t%0"
11624 [(set_attr "type" "ishift")
11625 (set (attr "length")
11626 (if_then_else (match_operand:DI 0 "register_operand" "")
11627 (const_string "2")
11628 (const_string "*")))])
11629
11630 (define_insn "*lshrdi3_1_rex64"
11631 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11632 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11633 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11634 (clobber (reg:CC FLAGS_REG))]
11635 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11636 "@
11637 shr{q}\t{%2, %0|%0, %2}
11638 shr{q}\t{%b2, %0|%0, %b2}"
11639 [(set_attr "type" "ishift")
11640 (set_attr "mode" "DI")])
11641
11642 ;; This pattern can't accept a variable shift count, since shifts by
11643 ;; zero don't affect the flags. We assume that shifts by constant
11644 ;; zero are optimized away.
11645 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11646 [(set (reg FLAGS_REG)
11647 (compare
11648 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11649 (match_operand:QI 2 "const1_operand" ""))
11650 (const_int 0)))
11651 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11652 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11653 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11654 && (TARGET_SHIFT1 || optimize_size)
11655 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11656 "shr{q}\t%0"
11657 [(set_attr "type" "ishift")
11658 (set (attr "length")
11659 (if_then_else (match_operand:DI 0 "register_operand" "")
11660 (const_string "2")
11661 (const_string "*")))])
11662
11663 ;; This pattern can't accept a variable shift count, since shifts by
11664 ;; zero don't affect the flags. We assume that shifts by constant
11665 ;; zero are optimized away.
11666 (define_insn "*lshrdi3_cmp_rex64"
11667 [(set (reg FLAGS_REG)
11668 (compare
11669 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11670 (match_operand:QI 2 "const_int_operand" "e"))
11671 (const_int 0)))
11672 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11673 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11674 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11675 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11676 "shr{q}\t{%2, %0|%0, %2}"
11677 [(set_attr "type" "ishift")
11678 (set_attr "mode" "DI")])
11679
11680 (define_insn "*lshrdi3_1"
11681 [(set (match_operand:DI 0 "register_operand" "=r")
11682 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11683 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11684 (clobber (reg:CC FLAGS_REG))]
11685 "!TARGET_64BIT"
11686 "#"
11687 [(set_attr "type" "multi")])
11688
11689 ;; By default we don't ask for a scratch register, because when DImode
11690 ;; values are manipulated, registers are already at a premium. But if
11691 ;; we have one handy, we won't turn it away.
11692 (define_peephole2
11693 [(match_scratch:SI 3 "r")
11694 (parallel [(set (match_operand:DI 0 "register_operand" "")
11695 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11696 (match_operand:QI 2 "nonmemory_operand" "")))
11697 (clobber (reg:CC FLAGS_REG))])
11698 (match_dup 3)]
11699 "!TARGET_64BIT && TARGET_CMOVE"
11700 [(const_int 0)]
11701 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11702
11703 (define_split
11704 [(set (match_operand:DI 0 "register_operand" "")
11705 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11706 (match_operand:QI 2 "nonmemory_operand" "")))
11707 (clobber (reg:CC FLAGS_REG))]
11708 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11709 [(const_int 0)]
11710 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11711
11712 (define_expand "lshrsi3"
11713 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11714 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11715 (match_operand:QI 2 "nonmemory_operand" "")))
11716 (clobber (reg:CC FLAGS_REG))]
11717 ""
11718 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11719
11720 (define_insn "*lshrsi3_1_one_bit"
11721 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11722 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11723 (match_operand:QI 2 "const1_operand" "")))
11724 (clobber (reg:CC FLAGS_REG))]
11725 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11726 && (TARGET_SHIFT1 || optimize_size)"
11727 "shr{l}\t%0"
11728 [(set_attr "type" "ishift")
11729 (set (attr "length")
11730 (if_then_else (match_operand:SI 0 "register_operand" "")
11731 (const_string "2")
11732 (const_string "*")))])
11733
11734 (define_insn "*lshrsi3_1_one_bit_zext"
11735 [(set (match_operand:DI 0 "register_operand" "=r")
11736 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11737 (match_operand:QI 2 "const1_operand" "")))
11738 (clobber (reg:CC FLAGS_REG))]
11739 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11740 && (TARGET_SHIFT1 || optimize_size)"
11741 "shr{l}\t%k0"
11742 [(set_attr "type" "ishift")
11743 (set_attr "length" "2")])
11744
11745 (define_insn "*lshrsi3_1"
11746 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11747 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11748 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11749 (clobber (reg:CC FLAGS_REG))]
11750 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11751 "@
11752 shr{l}\t{%2, %0|%0, %2}
11753 shr{l}\t{%b2, %0|%0, %b2}"
11754 [(set_attr "type" "ishift")
11755 (set_attr "mode" "SI")])
11756
11757 (define_insn "*lshrsi3_1_zext"
11758 [(set (match_operand:DI 0 "register_operand" "=r,r")
11759 (zero_extend:DI
11760 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11761 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11762 (clobber (reg:CC FLAGS_REG))]
11763 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11764 "@
11765 shr{l}\t{%2, %k0|%k0, %2}
11766 shr{l}\t{%b2, %k0|%k0, %b2}"
11767 [(set_attr "type" "ishift")
11768 (set_attr "mode" "SI")])
11769
11770 ;; This pattern can't accept a variable shift count, since shifts by
11771 ;; zero don't affect the flags. We assume that shifts by constant
11772 ;; zero are optimized away.
11773 (define_insn "*lshrsi3_one_bit_cmp"
11774 [(set (reg FLAGS_REG)
11775 (compare
11776 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11777 (match_operand:QI 2 "const1_operand" ""))
11778 (const_int 0)))
11779 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11780 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11781 "ix86_match_ccmode (insn, CCGOCmode)
11782 && (TARGET_SHIFT1 || optimize_size)
11783 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11784 "shr{l}\t%0"
11785 [(set_attr "type" "ishift")
11786 (set (attr "length")
11787 (if_then_else (match_operand:SI 0 "register_operand" "")
11788 (const_string "2")
11789 (const_string "*")))])
11790
11791 (define_insn "*lshrsi3_cmp_one_bit_zext"
11792 [(set (reg FLAGS_REG)
11793 (compare
11794 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11795 (match_operand:QI 2 "const1_operand" ""))
11796 (const_int 0)))
11797 (set (match_operand:DI 0 "register_operand" "=r")
11798 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11799 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11800 && (TARGET_SHIFT1 || optimize_size)
11801 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11802 "shr{l}\t%k0"
11803 [(set_attr "type" "ishift")
11804 (set_attr "length" "2")])
11805
11806 ;; This pattern can't accept a variable shift count, since shifts by
11807 ;; zero don't affect the flags. We assume that shifts by constant
11808 ;; zero are optimized away.
11809 (define_insn "*lshrsi3_cmp"
11810 [(set (reg FLAGS_REG)
11811 (compare
11812 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11813 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11814 (const_int 0)))
11815 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11816 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11817 "ix86_match_ccmode (insn, CCGOCmode)
11818 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11819 "shr{l}\t{%2, %0|%0, %2}"
11820 [(set_attr "type" "ishift")
11821 (set_attr "mode" "SI")])
11822
11823 (define_insn "*lshrsi3_cmp_zext"
11824 [(set (reg FLAGS_REG)
11825 (compare
11826 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11827 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11828 (const_int 0)))
11829 (set (match_operand:DI 0 "register_operand" "=r")
11830 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11831 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11832 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11833 "shr{l}\t{%2, %k0|%k0, %2}"
11834 [(set_attr "type" "ishift")
11835 (set_attr "mode" "SI")])
11836
11837 (define_expand "lshrhi3"
11838 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11839 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11840 (match_operand:QI 2 "nonmemory_operand" "")))
11841 (clobber (reg:CC FLAGS_REG))]
11842 "TARGET_HIMODE_MATH"
11843 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11844
11845 (define_insn "*lshrhi3_1_one_bit"
11846 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11847 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11848 (match_operand:QI 2 "const1_operand" "")))
11849 (clobber (reg:CC FLAGS_REG))]
11850 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11851 && (TARGET_SHIFT1 || optimize_size)"
11852 "shr{w}\t%0"
11853 [(set_attr "type" "ishift")
11854 (set (attr "length")
11855 (if_then_else (match_operand 0 "register_operand" "")
11856 (const_string "2")
11857 (const_string "*")))])
11858
11859 (define_insn "*lshrhi3_1"
11860 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11861 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11862 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11863 (clobber (reg:CC FLAGS_REG))]
11864 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11865 "@
11866 shr{w}\t{%2, %0|%0, %2}
11867 shr{w}\t{%b2, %0|%0, %b2}"
11868 [(set_attr "type" "ishift")
11869 (set_attr "mode" "HI")])
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 "*lshrhi3_one_bit_cmp"
11875 [(set (reg FLAGS_REG)
11876 (compare
11877 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11878 (match_operand:QI 2 "const1_operand" ""))
11879 (const_int 0)))
11880 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11881 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11882 "ix86_match_ccmode (insn, CCGOCmode)
11883 && (TARGET_SHIFT1 || optimize_size)
11884 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11885 "shr{w}\t%0"
11886 [(set_attr "type" "ishift")
11887 (set (attr "length")
11888 (if_then_else (match_operand:SI 0 "register_operand" "")
11889 (const_string "2")
11890 (const_string "*")))])
11891
11892 ;; This pattern can't accept a variable shift count, since shifts by
11893 ;; zero don't affect the flags. We assume that shifts by constant
11894 ;; zero are optimized away.
11895 (define_insn "*lshrhi3_cmp"
11896 [(set (reg FLAGS_REG)
11897 (compare
11898 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11899 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11900 (const_int 0)))
11901 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11902 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11903 "ix86_match_ccmode (insn, CCGOCmode)
11904 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11905 "shr{w}\t{%2, %0|%0, %2}"
11906 [(set_attr "type" "ishift")
11907 (set_attr "mode" "HI")])
11908
11909 (define_expand "lshrqi3"
11910 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11911 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11912 (match_operand:QI 2 "nonmemory_operand" "")))
11913 (clobber (reg:CC FLAGS_REG))]
11914 "TARGET_QIMODE_MATH"
11915 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11916
11917 (define_insn "*lshrqi3_1_one_bit"
11918 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11919 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11920 (match_operand:QI 2 "const1_operand" "")))
11921 (clobber (reg:CC FLAGS_REG))]
11922 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11923 && (TARGET_SHIFT1 || optimize_size)"
11924 "shr{b}\t%0"
11925 [(set_attr "type" "ishift")
11926 (set (attr "length")
11927 (if_then_else (match_operand 0 "register_operand" "")
11928 (const_string "2")
11929 (const_string "*")))])
11930
11931 (define_insn "*lshrqi3_1_one_bit_slp"
11932 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11933 (lshiftrt:QI (match_dup 0)
11934 (match_operand:QI 1 "const1_operand" "")))
11935 (clobber (reg:CC FLAGS_REG))]
11936 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11937 && (TARGET_SHIFT1 || optimize_size)"
11938 "shr{b}\t%0"
11939 [(set_attr "type" "ishift1")
11940 (set (attr "length")
11941 (if_then_else (match_operand 0 "register_operand" "")
11942 (const_string "2")
11943 (const_string "*")))])
11944
11945 (define_insn "*lshrqi3_1"
11946 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11947 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11948 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11949 (clobber (reg:CC FLAGS_REG))]
11950 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11951 "@
11952 shr{b}\t{%2, %0|%0, %2}
11953 shr{b}\t{%b2, %0|%0, %b2}"
11954 [(set_attr "type" "ishift")
11955 (set_attr "mode" "QI")])
11956
11957 (define_insn "*lshrqi3_1_slp"
11958 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11959 (lshiftrt:QI (match_dup 0)
11960 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11961 (clobber (reg:CC FLAGS_REG))]
11962 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11963 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11964 "@
11965 shr{b}\t{%1, %0|%0, %1}
11966 shr{b}\t{%b1, %0|%0, %b1}"
11967 [(set_attr "type" "ishift1")
11968 (set_attr "mode" "QI")])
11969
11970 ;; This pattern can't accept a variable shift count, since shifts by
11971 ;; zero don't affect the flags. We assume that shifts by constant
11972 ;; zero are optimized away.
11973 (define_insn "*lshrqi2_one_bit_cmp"
11974 [(set (reg FLAGS_REG)
11975 (compare
11976 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11977 (match_operand:QI 2 "const1_operand" ""))
11978 (const_int 0)))
11979 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11980 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11981 "ix86_match_ccmode (insn, CCGOCmode)
11982 && (TARGET_SHIFT1 || optimize_size)
11983 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11984 "shr{b}\t%0"
11985 [(set_attr "type" "ishift")
11986 (set (attr "length")
11987 (if_then_else (match_operand:SI 0 "register_operand" "")
11988 (const_string "2")
11989 (const_string "*")))])
11990
11991 ;; This pattern can't accept a variable shift count, since shifts by
11992 ;; zero don't affect the flags. We assume that shifts by constant
11993 ;; zero are optimized away.
11994 (define_insn "*lshrqi2_cmp"
11995 [(set (reg FLAGS_REG)
11996 (compare
11997 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11998 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11999 (const_int 0)))
12000 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12001 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12002 "ix86_match_ccmode (insn, CCGOCmode)
12003 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12004 "shr{b}\t{%2, %0|%0, %2}"
12005 [(set_attr "type" "ishift")
12006 (set_attr "mode" "QI")])
12007 \f
12008 ;; Rotate instructions
12009
12010 (define_expand "rotldi3"
12011 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12012 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12013 (match_operand:QI 2 "nonmemory_operand" "")))
12014 (clobber (reg:CC FLAGS_REG))]
12015 "TARGET_64BIT"
12016 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12017
12018 (define_insn "*rotlsi3_1_one_bit_rex64"
12019 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12020 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12021 (match_operand:QI 2 "const1_operand" "")))
12022 (clobber (reg:CC FLAGS_REG))]
12023 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12024 && (TARGET_SHIFT1 || optimize_size)"
12025 "rol{q}\t%0"
12026 [(set_attr "type" "rotate")
12027 (set (attr "length")
12028 (if_then_else (match_operand:DI 0 "register_operand" "")
12029 (const_string "2")
12030 (const_string "*")))])
12031
12032 (define_insn "*rotldi3_1_rex64"
12033 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12034 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12035 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12036 (clobber (reg:CC FLAGS_REG))]
12037 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12038 "@
12039 rol{q}\t{%2, %0|%0, %2}
12040 rol{q}\t{%b2, %0|%0, %b2}"
12041 [(set_attr "type" "rotate")
12042 (set_attr "mode" "DI")])
12043
12044 (define_expand "rotlsi3"
12045 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12046 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12047 (match_operand:QI 2 "nonmemory_operand" "")))
12048 (clobber (reg:CC FLAGS_REG))]
12049 ""
12050 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12051
12052 (define_insn "*rotlsi3_1_one_bit"
12053 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12054 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12055 (match_operand:QI 2 "const1_operand" "")))
12056 (clobber (reg:CC FLAGS_REG))]
12057 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12058 && (TARGET_SHIFT1 || optimize_size)"
12059 "rol{l}\t%0"
12060 [(set_attr "type" "rotate")
12061 (set (attr "length")
12062 (if_then_else (match_operand:SI 0 "register_operand" "")
12063 (const_string "2")
12064 (const_string "*")))])
12065
12066 (define_insn "*rotlsi3_1_one_bit_zext"
12067 [(set (match_operand:DI 0 "register_operand" "=r")
12068 (zero_extend:DI
12069 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12070 (match_operand:QI 2 "const1_operand" ""))))
12071 (clobber (reg:CC FLAGS_REG))]
12072 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12073 && (TARGET_SHIFT1 || optimize_size)"
12074 "rol{l}\t%k0"
12075 [(set_attr "type" "rotate")
12076 (set_attr "length" "2")])
12077
12078 (define_insn "*rotlsi3_1"
12079 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12080 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12081 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12082 (clobber (reg:CC FLAGS_REG))]
12083 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12084 "@
12085 rol{l}\t{%2, %0|%0, %2}
12086 rol{l}\t{%b2, %0|%0, %b2}"
12087 [(set_attr "type" "rotate")
12088 (set_attr "mode" "SI")])
12089
12090 (define_insn "*rotlsi3_1_zext"
12091 [(set (match_operand:DI 0 "register_operand" "=r,r")
12092 (zero_extend:DI
12093 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12094 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12095 (clobber (reg:CC FLAGS_REG))]
12096 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12097 "@
12098 rol{l}\t{%2, %k0|%k0, %2}
12099 rol{l}\t{%b2, %k0|%k0, %b2}"
12100 [(set_attr "type" "rotate")
12101 (set_attr "mode" "SI")])
12102
12103 (define_expand "rotlhi3"
12104 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12105 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12106 (match_operand:QI 2 "nonmemory_operand" "")))
12107 (clobber (reg:CC FLAGS_REG))]
12108 "TARGET_HIMODE_MATH"
12109 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12110
12111 (define_insn "*rotlhi3_1_one_bit"
12112 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12113 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12114 (match_operand:QI 2 "const1_operand" "")))
12115 (clobber (reg:CC FLAGS_REG))]
12116 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12117 && (TARGET_SHIFT1 || optimize_size)"
12118 "rol{w}\t%0"
12119 [(set_attr "type" "rotate")
12120 (set (attr "length")
12121 (if_then_else (match_operand 0 "register_operand" "")
12122 (const_string "2")
12123 (const_string "*")))])
12124
12125 (define_insn "*rotlhi3_1"
12126 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12127 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12128 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12129 (clobber (reg:CC FLAGS_REG))]
12130 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12131 "@
12132 rol{w}\t{%2, %0|%0, %2}
12133 rol{w}\t{%b2, %0|%0, %b2}"
12134 [(set_attr "type" "rotate")
12135 (set_attr "mode" "HI")])
12136
12137 (define_expand "rotlqi3"
12138 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12139 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12140 (match_operand:QI 2 "nonmemory_operand" "")))
12141 (clobber (reg:CC FLAGS_REG))]
12142 "TARGET_QIMODE_MATH"
12143 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12144
12145 (define_insn "*rotlqi3_1_one_bit_slp"
12146 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12147 (rotate:QI (match_dup 0)
12148 (match_operand:QI 1 "const1_operand" "")))
12149 (clobber (reg:CC FLAGS_REG))]
12150 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12151 && (TARGET_SHIFT1 || optimize_size)"
12152 "rol{b}\t%0"
12153 [(set_attr "type" "rotate1")
12154 (set (attr "length")
12155 (if_then_else (match_operand 0 "register_operand" "")
12156 (const_string "2")
12157 (const_string "*")))])
12158
12159 (define_insn "*rotlqi3_1_one_bit"
12160 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12161 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12162 (match_operand:QI 2 "const1_operand" "")))
12163 (clobber (reg:CC FLAGS_REG))]
12164 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12165 && (TARGET_SHIFT1 || optimize_size)"
12166 "rol{b}\t%0"
12167 [(set_attr "type" "rotate")
12168 (set (attr "length")
12169 (if_then_else (match_operand 0 "register_operand" "")
12170 (const_string "2")
12171 (const_string "*")))])
12172
12173 (define_insn "*rotlqi3_1_slp"
12174 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12175 (rotate:QI (match_dup 0)
12176 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12177 (clobber (reg:CC FLAGS_REG))]
12178 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12179 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12180 "@
12181 rol{b}\t{%1, %0|%0, %1}
12182 rol{b}\t{%b1, %0|%0, %b1}"
12183 [(set_attr "type" "rotate1")
12184 (set_attr "mode" "QI")])
12185
12186 (define_insn "*rotlqi3_1"
12187 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12188 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12189 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12190 (clobber (reg:CC FLAGS_REG))]
12191 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12192 "@
12193 rol{b}\t{%2, %0|%0, %2}
12194 rol{b}\t{%b2, %0|%0, %b2}"
12195 [(set_attr "type" "rotate")
12196 (set_attr "mode" "QI")])
12197
12198 (define_expand "rotrdi3"
12199 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12200 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12201 (match_operand:QI 2 "nonmemory_operand" "")))
12202 (clobber (reg:CC FLAGS_REG))]
12203 "TARGET_64BIT"
12204 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12205
12206 (define_insn "*rotrdi3_1_one_bit_rex64"
12207 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12208 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12209 (match_operand:QI 2 "const1_operand" "")))
12210 (clobber (reg:CC FLAGS_REG))]
12211 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12212 && (TARGET_SHIFT1 || optimize_size)"
12213 "ror{q}\t%0"
12214 [(set_attr "type" "rotate")
12215 (set (attr "length")
12216 (if_then_else (match_operand:DI 0 "register_operand" "")
12217 (const_string "2")
12218 (const_string "*")))])
12219
12220 (define_insn "*rotrdi3_1_rex64"
12221 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12222 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12223 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12224 (clobber (reg:CC FLAGS_REG))]
12225 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12226 "@
12227 ror{q}\t{%2, %0|%0, %2}
12228 ror{q}\t{%b2, %0|%0, %b2}"
12229 [(set_attr "type" "rotate")
12230 (set_attr "mode" "DI")])
12231
12232 (define_expand "rotrsi3"
12233 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12234 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12235 (match_operand:QI 2 "nonmemory_operand" "")))
12236 (clobber (reg:CC FLAGS_REG))]
12237 ""
12238 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12239
12240 (define_insn "*rotrsi3_1_one_bit"
12241 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12242 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12243 (match_operand:QI 2 "const1_operand" "")))
12244 (clobber (reg:CC FLAGS_REG))]
12245 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12246 && (TARGET_SHIFT1 || optimize_size)"
12247 "ror{l}\t%0"
12248 [(set_attr "type" "rotate")
12249 (set (attr "length")
12250 (if_then_else (match_operand:SI 0 "register_operand" "")
12251 (const_string "2")
12252 (const_string "*")))])
12253
12254 (define_insn "*rotrsi3_1_one_bit_zext"
12255 [(set (match_operand:DI 0 "register_operand" "=r")
12256 (zero_extend:DI
12257 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12258 (match_operand:QI 2 "const1_operand" ""))))
12259 (clobber (reg:CC FLAGS_REG))]
12260 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12261 && (TARGET_SHIFT1 || optimize_size)"
12262 "ror{l}\t%k0"
12263 [(set_attr "type" "rotate")
12264 (set (attr "length")
12265 (if_then_else (match_operand:SI 0 "register_operand" "")
12266 (const_string "2")
12267 (const_string "*")))])
12268
12269 (define_insn "*rotrsi3_1"
12270 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12271 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12272 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12273 (clobber (reg:CC FLAGS_REG))]
12274 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12275 "@
12276 ror{l}\t{%2, %0|%0, %2}
12277 ror{l}\t{%b2, %0|%0, %b2}"
12278 [(set_attr "type" "rotate")
12279 (set_attr "mode" "SI")])
12280
12281 (define_insn "*rotrsi3_1_zext"
12282 [(set (match_operand:DI 0 "register_operand" "=r,r")
12283 (zero_extend:DI
12284 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12285 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12286 (clobber (reg:CC FLAGS_REG))]
12287 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12288 "@
12289 ror{l}\t{%2, %k0|%k0, %2}
12290 ror{l}\t{%b2, %k0|%k0, %b2}"
12291 [(set_attr "type" "rotate")
12292 (set_attr "mode" "SI")])
12293
12294 (define_expand "rotrhi3"
12295 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12296 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12297 (match_operand:QI 2 "nonmemory_operand" "")))
12298 (clobber (reg:CC FLAGS_REG))]
12299 "TARGET_HIMODE_MATH"
12300 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12301
12302 (define_insn "*rotrhi3_one_bit"
12303 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12304 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12305 (match_operand:QI 2 "const1_operand" "")))
12306 (clobber (reg:CC FLAGS_REG))]
12307 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12308 && (TARGET_SHIFT1 || optimize_size)"
12309 "ror{w}\t%0"
12310 [(set_attr "type" "rotate")
12311 (set (attr "length")
12312 (if_then_else (match_operand 0 "register_operand" "")
12313 (const_string "2")
12314 (const_string "*")))])
12315
12316 (define_insn "*rotrhi3"
12317 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12318 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12319 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12320 (clobber (reg:CC FLAGS_REG))]
12321 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12322 "@
12323 ror{w}\t{%2, %0|%0, %2}
12324 ror{w}\t{%b2, %0|%0, %b2}"
12325 [(set_attr "type" "rotate")
12326 (set_attr "mode" "HI")])
12327
12328 (define_expand "rotrqi3"
12329 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12330 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12331 (match_operand:QI 2 "nonmemory_operand" "")))
12332 (clobber (reg:CC FLAGS_REG))]
12333 "TARGET_QIMODE_MATH"
12334 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12335
12336 (define_insn "*rotrqi3_1_one_bit"
12337 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12338 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12339 (match_operand:QI 2 "const1_operand" "")))
12340 (clobber (reg:CC FLAGS_REG))]
12341 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12342 && (TARGET_SHIFT1 || optimize_size)"
12343 "ror{b}\t%0"
12344 [(set_attr "type" "rotate")
12345 (set (attr "length")
12346 (if_then_else (match_operand 0 "register_operand" "")
12347 (const_string "2")
12348 (const_string "*")))])
12349
12350 (define_insn "*rotrqi3_1_one_bit_slp"
12351 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12352 (rotatert:QI (match_dup 0)
12353 (match_operand:QI 1 "const1_operand" "")))
12354 (clobber (reg:CC FLAGS_REG))]
12355 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12356 && (TARGET_SHIFT1 || optimize_size)"
12357 "ror{b}\t%0"
12358 [(set_attr "type" "rotate1")
12359 (set (attr "length")
12360 (if_then_else (match_operand 0 "register_operand" "")
12361 (const_string "2")
12362 (const_string "*")))])
12363
12364 (define_insn "*rotrqi3_1"
12365 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12366 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12367 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12368 (clobber (reg:CC FLAGS_REG))]
12369 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12370 "@
12371 ror{b}\t{%2, %0|%0, %2}
12372 ror{b}\t{%b2, %0|%0, %b2}"
12373 [(set_attr "type" "rotate")
12374 (set_attr "mode" "QI")])
12375
12376 (define_insn "*rotrqi3_1_slp"
12377 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12378 (rotatert:QI (match_dup 0)
12379 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12380 (clobber (reg:CC FLAGS_REG))]
12381 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12382 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12383 "@
12384 ror{b}\t{%1, %0|%0, %1}
12385 ror{b}\t{%b1, %0|%0, %b1}"
12386 [(set_attr "type" "rotate1")
12387 (set_attr "mode" "QI")])
12388 \f
12389 ;; Bit set / bit test instructions
12390
12391 (define_expand "extv"
12392 [(set (match_operand:SI 0 "register_operand" "")
12393 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12394 (match_operand:SI 2 "immediate_operand" "")
12395 (match_operand:SI 3 "immediate_operand" "")))]
12396 ""
12397 {
12398 /* Handle extractions from %ah et al. */
12399 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12400 FAIL;
12401
12402 /* From mips.md: extract_bit_field doesn't verify that our source
12403 matches the predicate, so check it again here. */
12404 if (! ext_register_operand (operands[1], VOIDmode))
12405 FAIL;
12406 })
12407
12408 (define_expand "extzv"
12409 [(set (match_operand:SI 0 "register_operand" "")
12410 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12411 (match_operand:SI 2 "immediate_operand" "")
12412 (match_operand:SI 3 "immediate_operand" "")))]
12413 ""
12414 {
12415 /* Handle extractions from %ah et al. */
12416 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12417 FAIL;
12418
12419 /* From mips.md: extract_bit_field doesn't verify that our source
12420 matches the predicate, so check it again here. */
12421 if (! ext_register_operand (operands[1], VOIDmode))
12422 FAIL;
12423 })
12424
12425 (define_expand "insv"
12426 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12427 (match_operand 1 "immediate_operand" "")
12428 (match_operand 2 "immediate_operand" ""))
12429 (match_operand 3 "register_operand" ""))]
12430 ""
12431 {
12432 /* Handle extractions from %ah et al. */
12433 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12434 FAIL;
12435
12436 /* From mips.md: insert_bit_field doesn't verify that our source
12437 matches the predicate, so check it again here. */
12438 if (! ext_register_operand (operands[0], VOIDmode))
12439 FAIL;
12440
12441 if (TARGET_64BIT)
12442 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12443 else
12444 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12445
12446 DONE;
12447 })
12448
12449 ;; %%% bts, btr, btc, bt.
12450 ;; In general these instructions are *slow* when applied to memory,
12451 ;; since they enforce atomic operation. When applied to registers,
12452 ;; it depends on the cpu implementation. They're never faster than
12453 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12454 ;; no point. But in 64-bit, we can't hold the relevant immediates
12455 ;; within the instruction itself, so operating on bits in the high
12456 ;; 32-bits of a register becomes easier.
12457 ;;
12458 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12459 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12460 ;; negdf respectively, so they can never be disabled entirely.
12461
12462 (define_insn "*btsq"
12463 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12464 (const_int 1)
12465 (match_operand:DI 1 "const_0_to_63_operand" ""))
12466 (const_int 1))
12467 (clobber (reg:CC FLAGS_REG))]
12468 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12469 "bts{q} %1,%0"
12470 [(set_attr "type" "alu1")])
12471
12472 (define_insn "*btrq"
12473 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12474 (const_int 1)
12475 (match_operand:DI 1 "const_0_to_63_operand" ""))
12476 (const_int 0))
12477 (clobber (reg:CC FLAGS_REG))]
12478 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12479 "btr{q} %1,%0"
12480 [(set_attr "type" "alu1")])
12481
12482 (define_insn "*btcq"
12483 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12484 (const_int 1)
12485 (match_operand:DI 1 "const_0_to_63_operand" ""))
12486 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12487 (clobber (reg:CC FLAGS_REG))]
12488 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12489 "btc{q} %1,%0"
12490 [(set_attr "type" "alu1")])
12491
12492 ;; Allow Nocona to avoid these instructions if a register is available.
12493
12494 (define_peephole2
12495 [(match_scratch:DI 2 "r")
12496 (parallel [(set (zero_extract:DI
12497 (match_operand:DI 0 "register_operand" "")
12498 (const_int 1)
12499 (match_operand:DI 1 "const_0_to_63_operand" ""))
12500 (const_int 1))
12501 (clobber (reg:CC FLAGS_REG))])]
12502 "TARGET_64BIT && !TARGET_USE_BT"
12503 [(const_int 0)]
12504 {
12505 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12506 rtx op1;
12507
12508 if (HOST_BITS_PER_WIDE_INT >= 64)
12509 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12510 else if (i < HOST_BITS_PER_WIDE_INT)
12511 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12512 else
12513 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12514
12515 op1 = immed_double_const (lo, hi, DImode);
12516 if (i >= 31)
12517 {
12518 emit_move_insn (operands[2], op1);
12519 op1 = operands[2];
12520 }
12521
12522 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12523 DONE;
12524 })
12525
12526 (define_peephole2
12527 [(match_scratch:DI 2 "r")
12528 (parallel [(set (zero_extract:DI
12529 (match_operand:DI 0 "register_operand" "")
12530 (const_int 1)
12531 (match_operand:DI 1 "const_0_to_63_operand" ""))
12532 (const_int 0))
12533 (clobber (reg:CC FLAGS_REG))])]
12534 "TARGET_64BIT && !TARGET_USE_BT"
12535 [(const_int 0)]
12536 {
12537 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12538 rtx op1;
12539
12540 if (HOST_BITS_PER_WIDE_INT >= 64)
12541 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12542 else if (i < HOST_BITS_PER_WIDE_INT)
12543 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12544 else
12545 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12546
12547 op1 = immed_double_const (~lo, ~hi, DImode);
12548 if (i >= 32)
12549 {
12550 emit_move_insn (operands[2], op1);
12551 op1 = operands[2];
12552 }
12553
12554 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12555 DONE;
12556 })
12557
12558 (define_peephole2
12559 [(match_scratch:DI 2 "r")
12560 (parallel [(set (zero_extract:DI
12561 (match_operand:DI 0 "register_operand" "")
12562 (const_int 1)
12563 (match_operand:DI 1 "const_0_to_63_operand" ""))
12564 (not:DI (zero_extract:DI
12565 (match_dup 0) (const_int 1) (match_dup 1))))
12566 (clobber (reg:CC FLAGS_REG))])]
12567 "TARGET_64BIT && !TARGET_USE_BT"
12568 [(const_int 0)]
12569 {
12570 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12571 rtx op1;
12572
12573 if (HOST_BITS_PER_WIDE_INT >= 64)
12574 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12575 else if (i < HOST_BITS_PER_WIDE_INT)
12576 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12577 else
12578 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12579
12580 op1 = immed_double_const (lo, hi, DImode);
12581 if (i >= 31)
12582 {
12583 emit_move_insn (operands[2], op1);
12584 op1 = operands[2];
12585 }
12586
12587 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12588 DONE;
12589 })
12590 \f
12591 ;; Store-flag instructions.
12592
12593 ;; For all sCOND expanders, also expand the compare or test insn that
12594 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12595
12596 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12597 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12598 ;; way, which can later delete the movzx if only QImode is needed.
12599
12600 (define_expand "seq"
12601 [(set (match_operand:QI 0 "register_operand" "")
12602 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12603 ""
12604 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12605
12606 (define_expand "sne"
12607 [(set (match_operand:QI 0 "register_operand" "")
12608 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12609 ""
12610 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12611
12612 (define_expand "sgt"
12613 [(set (match_operand:QI 0 "register_operand" "")
12614 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12615 ""
12616 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12617
12618 (define_expand "sgtu"
12619 [(set (match_operand:QI 0 "register_operand" "")
12620 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12621 ""
12622 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12623
12624 (define_expand "slt"
12625 [(set (match_operand:QI 0 "register_operand" "")
12626 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12627 ""
12628 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12629
12630 (define_expand "sltu"
12631 [(set (match_operand:QI 0 "register_operand" "")
12632 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12633 ""
12634 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12635
12636 (define_expand "sge"
12637 [(set (match_operand:QI 0 "register_operand" "")
12638 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12639 ""
12640 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12641
12642 (define_expand "sgeu"
12643 [(set (match_operand:QI 0 "register_operand" "")
12644 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12645 ""
12646 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12647
12648 (define_expand "sle"
12649 [(set (match_operand:QI 0 "register_operand" "")
12650 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12651 ""
12652 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12653
12654 (define_expand "sleu"
12655 [(set (match_operand:QI 0 "register_operand" "")
12656 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12657 ""
12658 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12659
12660 (define_expand "sunordered"
12661 [(set (match_operand:QI 0 "register_operand" "")
12662 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12663 "TARGET_80387 || TARGET_SSE"
12664 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12665
12666 (define_expand "sordered"
12667 [(set (match_operand:QI 0 "register_operand" "")
12668 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12669 "TARGET_80387"
12670 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12671
12672 (define_expand "suneq"
12673 [(set (match_operand:QI 0 "register_operand" "")
12674 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12675 "TARGET_80387 || TARGET_SSE"
12676 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12677
12678 (define_expand "sunge"
12679 [(set (match_operand:QI 0 "register_operand" "")
12680 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12681 "TARGET_80387 || TARGET_SSE"
12682 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12683
12684 (define_expand "sungt"
12685 [(set (match_operand:QI 0 "register_operand" "")
12686 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12687 "TARGET_80387 || TARGET_SSE"
12688 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12689
12690 (define_expand "sunle"
12691 [(set (match_operand:QI 0 "register_operand" "")
12692 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12693 "TARGET_80387 || TARGET_SSE"
12694 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12695
12696 (define_expand "sunlt"
12697 [(set (match_operand:QI 0 "register_operand" "")
12698 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12699 "TARGET_80387 || TARGET_SSE"
12700 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12701
12702 (define_expand "sltgt"
12703 [(set (match_operand:QI 0 "register_operand" "")
12704 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12705 "TARGET_80387 || TARGET_SSE"
12706 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12707
12708 (define_insn "*setcc_1"
12709 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12710 (match_operator:QI 1 "ix86_comparison_operator"
12711 [(reg FLAGS_REG) (const_int 0)]))]
12712 ""
12713 "set%C1\t%0"
12714 [(set_attr "type" "setcc")
12715 (set_attr "mode" "QI")])
12716
12717 (define_insn "*setcc_2"
12718 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12719 (match_operator:QI 1 "ix86_comparison_operator"
12720 [(reg FLAGS_REG) (const_int 0)]))]
12721 ""
12722 "set%C1\t%0"
12723 [(set_attr "type" "setcc")
12724 (set_attr "mode" "QI")])
12725
12726 ;; In general it is not safe to assume too much about CCmode registers,
12727 ;; so simplify-rtx stops when it sees a second one. Under certain
12728 ;; conditions this is safe on x86, so help combine not create
12729 ;;
12730 ;; seta %al
12731 ;; testb %al, %al
12732 ;; sete %al
12733
12734 (define_split
12735 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12736 (ne:QI (match_operator 1 "ix86_comparison_operator"
12737 [(reg FLAGS_REG) (const_int 0)])
12738 (const_int 0)))]
12739 ""
12740 [(set (match_dup 0) (match_dup 1))]
12741 {
12742 PUT_MODE (operands[1], QImode);
12743 })
12744
12745 (define_split
12746 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12747 (ne:QI (match_operator 1 "ix86_comparison_operator"
12748 [(reg FLAGS_REG) (const_int 0)])
12749 (const_int 0)))]
12750 ""
12751 [(set (match_dup 0) (match_dup 1))]
12752 {
12753 PUT_MODE (operands[1], QImode);
12754 })
12755
12756 (define_split
12757 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12758 (eq:QI (match_operator 1 "ix86_comparison_operator"
12759 [(reg FLAGS_REG) (const_int 0)])
12760 (const_int 0)))]
12761 ""
12762 [(set (match_dup 0) (match_dup 1))]
12763 {
12764 rtx new_op1 = copy_rtx (operands[1]);
12765 operands[1] = new_op1;
12766 PUT_MODE (new_op1, QImode);
12767 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12768 GET_MODE (XEXP (new_op1, 0))));
12769
12770 /* Make sure that (a) the CCmode we have for the flags is strong
12771 enough for the reversed compare or (b) we have a valid FP compare. */
12772 if (! ix86_comparison_operator (new_op1, VOIDmode))
12773 FAIL;
12774 })
12775
12776 (define_split
12777 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12778 (eq:QI (match_operator 1 "ix86_comparison_operator"
12779 [(reg FLAGS_REG) (const_int 0)])
12780 (const_int 0)))]
12781 ""
12782 [(set (match_dup 0) (match_dup 1))]
12783 {
12784 rtx new_op1 = copy_rtx (operands[1]);
12785 operands[1] = new_op1;
12786 PUT_MODE (new_op1, QImode);
12787 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12788 GET_MODE (XEXP (new_op1, 0))));
12789
12790 /* Make sure that (a) the CCmode we have for the flags is strong
12791 enough for the reversed compare or (b) we have a valid FP compare. */
12792 if (! ix86_comparison_operator (new_op1, VOIDmode))
12793 FAIL;
12794 })
12795
12796 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12797 ;; subsequent logical operations are used to imitate conditional moves.
12798 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12799 ;; it directly.
12800
12801 (define_insn "*sse_setccsf"
12802 [(set (match_operand:SF 0 "register_operand" "=x")
12803 (match_operator:SF 1 "sse_comparison_operator"
12804 [(match_operand:SF 2 "register_operand" "0")
12805 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12806 "TARGET_SSE"
12807 "cmp%D1ss\t{%3, %0|%0, %3}"
12808 [(set_attr "type" "ssecmp")
12809 (set_attr "mode" "SF")])
12810
12811 (define_insn "*sse_setccdf"
12812 [(set (match_operand:DF 0 "register_operand" "=Y")
12813 (match_operator:DF 1 "sse_comparison_operator"
12814 [(match_operand:DF 2 "register_operand" "0")
12815 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12816 "TARGET_SSE2"
12817 "cmp%D1sd\t{%3, %0|%0, %3}"
12818 [(set_attr "type" "ssecmp")
12819 (set_attr "mode" "DF")])
12820 \f
12821 ;; Basic conditional jump instructions.
12822 ;; We ignore the overflow flag for signed branch instructions.
12823
12824 ;; For all bCOND expanders, also expand the compare or test insn that
12825 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12826
12827 (define_expand "beq"
12828 [(set (pc)
12829 (if_then_else (match_dup 1)
12830 (label_ref (match_operand 0 "" ""))
12831 (pc)))]
12832 ""
12833 "ix86_expand_branch (EQ, operands[0]); DONE;")
12834
12835 (define_expand "bne"
12836 [(set (pc)
12837 (if_then_else (match_dup 1)
12838 (label_ref (match_operand 0 "" ""))
12839 (pc)))]
12840 ""
12841 "ix86_expand_branch (NE, operands[0]); DONE;")
12842
12843 (define_expand "bgt"
12844 [(set (pc)
12845 (if_then_else (match_dup 1)
12846 (label_ref (match_operand 0 "" ""))
12847 (pc)))]
12848 ""
12849 "ix86_expand_branch (GT, operands[0]); DONE;")
12850
12851 (define_expand "bgtu"
12852 [(set (pc)
12853 (if_then_else (match_dup 1)
12854 (label_ref (match_operand 0 "" ""))
12855 (pc)))]
12856 ""
12857 "ix86_expand_branch (GTU, operands[0]); DONE;")
12858
12859 (define_expand "blt"
12860 [(set (pc)
12861 (if_then_else (match_dup 1)
12862 (label_ref (match_operand 0 "" ""))
12863 (pc)))]
12864 ""
12865 "ix86_expand_branch (LT, operands[0]); DONE;")
12866
12867 (define_expand "bltu"
12868 [(set (pc)
12869 (if_then_else (match_dup 1)
12870 (label_ref (match_operand 0 "" ""))
12871 (pc)))]
12872 ""
12873 "ix86_expand_branch (LTU, operands[0]); DONE;")
12874
12875 (define_expand "bge"
12876 [(set (pc)
12877 (if_then_else (match_dup 1)
12878 (label_ref (match_operand 0 "" ""))
12879 (pc)))]
12880 ""
12881 "ix86_expand_branch (GE, operands[0]); DONE;")
12882
12883 (define_expand "bgeu"
12884 [(set (pc)
12885 (if_then_else (match_dup 1)
12886 (label_ref (match_operand 0 "" ""))
12887 (pc)))]
12888 ""
12889 "ix86_expand_branch (GEU, operands[0]); DONE;")
12890
12891 (define_expand "ble"
12892 [(set (pc)
12893 (if_then_else (match_dup 1)
12894 (label_ref (match_operand 0 "" ""))
12895 (pc)))]
12896 ""
12897 "ix86_expand_branch (LE, operands[0]); DONE;")
12898
12899 (define_expand "bleu"
12900 [(set (pc)
12901 (if_then_else (match_dup 1)
12902 (label_ref (match_operand 0 "" ""))
12903 (pc)))]
12904 ""
12905 "ix86_expand_branch (LEU, operands[0]); DONE;")
12906
12907 (define_expand "bunordered"
12908 [(set (pc)
12909 (if_then_else (match_dup 1)
12910 (label_ref (match_operand 0 "" ""))
12911 (pc)))]
12912 "TARGET_80387 || TARGET_SSE_MATH"
12913 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12914
12915 (define_expand "bordered"
12916 [(set (pc)
12917 (if_then_else (match_dup 1)
12918 (label_ref (match_operand 0 "" ""))
12919 (pc)))]
12920 "TARGET_80387 || TARGET_SSE_MATH"
12921 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12922
12923 (define_expand "buneq"
12924 [(set (pc)
12925 (if_then_else (match_dup 1)
12926 (label_ref (match_operand 0 "" ""))
12927 (pc)))]
12928 "TARGET_80387 || TARGET_SSE_MATH"
12929 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12930
12931 (define_expand "bunge"
12932 [(set (pc)
12933 (if_then_else (match_dup 1)
12934 (label_ref (match_operand 0 "" ""))
12935 (pc)))]
12936 "TARGET_80387 || TARGET_SSE_MATH"
12937 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12938
12939 (define_expand "bungt"
12940 [(set (pc)
12941 (if_then_else (match_dup 1)
12942 (label_ref (match_operand 0 "" ""))
12943 (pc)))]
12944 "TARGET_80387 || TARGET_SSE_MATH"
12945 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12946
12947 (define_expand "bunle"
12948 [(set (pc)
12949 (if_then_else (match_dup 1)
12950 (label_ref (match_operand 0 "" ""))
12951 (pc)))]
12952 "TARGET_80387 || TARGET_SSE_MATH"
12953 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12954
12955 (define_expand "bunlt"
12956 [(set (pc)
12957 (if_then_else (match_dup 1)
12958 (label_ref (match_operand 0 "" ""))
12959 (pc)))]
12960 "TARGET_80387 || TARGET_SSE_MATH"
12961 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12962
12963 (define_expand "bltgt"
12964 [(set (pc)
12965 (if_then_else (match_dup 1)
12966 (label_ref (match_operand 0 "" ""))
12967 (pc)))]
12968 "TARGET_80387 || TARGET_SSE_MATH"
12969 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12970
12971 (define_insn "*jcc_1"
12972 [(set (pc)
12973 (if_then_else (match_operator 1 "ix86_comparison_operator"
12974 [(reg FLAGS_REG) (const_int 0)])
12975 (label_ref (match_operand 0 "" ""))
12976 (pc)))]
12977 ""
12978 "%+j%C1\t%l0"
12979 [(set_attr "type" "ibr")
12980 (set_attr "modrm" "0")
12981 (set (attr "length")
12982 (if_then_else (and (ge (minus (match_dup 0) (pc))
12983 (const_int -126))
12984 (lt (minus (match_dup 0) (pc))
12985 (const_int 128)))
12986 (const_int 2)
12987 (const_int 6)))])
12988
12989 (define_insn "*jcc_2"
12990 [(set (pc)
12991 (if_then_else (match_operator 1 "ix86_comparison_operator"
12992 [(reg FLAGS_REG) (const_int 0)])
12993 (pc)
12994 (label_ref (match_operand 0 "" ""))))]
12995 ""
12996 "%+j%c1\t%l0"
12997 [(set_attr "type" "ibr")
12998 (set_attr "modrm" "0")
12999 (set (attr "length")
13000 (if_then_else (and (ge (minus (match_dup 0) (pc))
13001 (const_int -126))
13002 (lt (minus (match_dup 0) (pc))
13003 (const_int 128)))
13004 (const_int 2)
13005 (const_int 6)))])
13006
13007 ;; In general it is not safe to assume too much about CCmode registers,
13008 ;; so simplify-rtx stops when it sees a second one. Under certain
13009 ;; conditions this is safe on x86, so help combine not create
13010 ;;
13011 ;; seta %al
13012 ;; testb %al, %al
13013 ;; je Lfoo
13014
13015 (define_split
13016 [(set (pc)
13017 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13018 [(reg FLAGS_REG) (const_int 0)])
13019 (const_int 0))
13020 (label_ref (match_operand 1 "" ""))
13021 (pc)))]
13022 ""
13023 [(set (pc)
13024 (if_then_else (match_dup 0)
13025 (label_ref (match_dup 1))
13026 (pc)))]
13027 {
13028 PUT_MODE (operands[0], VOIDmode);
13029 })
13030
13031 (define_split
13032 [(set (pc)
13033 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13034 [(reg FLAGS_REG) (const_int 0)])
13035 (const_int 0))
13036 (label_ref (match_operand 1 "" ""))
13037 (pc)))]
13038 ""
13039 [(set (pc)
13040 (if_then_else (match_dup 0)
13041 (label_ref (match_dup 1))
13042 (pc)))]
13043 {
13044 rtx new_op0 = copy_rtx (operands[0]);
13045 operands[0] = new_op0;
13046 PUT_MODE (new_op0, VOIDmode);
13047 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13048 GET_MODE (XEXP (new_op0, 0))));
13049
13050 /* Make sure that (a) the CCmode we have for the flags is strong
13051 enough for the reversed compare or (b) we have a valid FP compare. */
13052 if (! ix86_comparison_operator (new_op0, VOIDmode))
13053 FAIL;
13054 })
13055
13056 ;; Define combination compare-and-branch fp compare instructions to use
13057 ;; during early optimization. Splitting the operation apart early makes
13058 ;; for bad code when we want to reverse the operation.
13059
13060 (define_insn "*fp_jcc_1_mixed"
13061 [(set (pc)
13062 (if_then_else (match_operator 0 "comparison_operator"
13063 [(match_operand 1 "register_operand" "f#x,x#f")
13064 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13065 (label_ref (match_operand 3 "" ""))
13066 (pc)))
13067 (clobber (reg:CCFP FPSR_REG))
13068 (clobber (reg:CCFP FLAGS_REG))]
13069 "TARGET_MIX_SSE_I387
13070 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13071 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13072 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13073 "#")
13074
13075 (define_insn "*fp_jcc_1_sse"
13076 [(set (pc)
13077 (if_then_else (match_operator 0 "comparison_operator"
13078 [(match_operand 1 "register_operand" "x")
13079 (match_operand 2 "nonimmediate_operand" "xm")])
13080 (label_ref (match_operand 3 "" ""))
13081 (pc)))
13082 (clobber (reg:CCFP FPSR_REG))
13083 (clobber (reg:CCFP FLAGS_REG))]
13084 "TARGET_SSE_MATH
13085 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13086 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13087 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13088 "#")
13089
13090 (define_insn "*fp_jcc_1_387"
13091 [(set (pc)
13092 (if_then_else (match_operator 0 "comparison_operator"
13093 [(match_operand 1 "register_operand" "f")
13094 (match_operand 2 "register_operand" "f")])
13095 (label_ref (match_operand 3 "" ""))
13096 (pc)))
13097 (clobber (reg:CCFP FPSR_REG))
13098 (clobber (reg:CCFP FLAGS_REG))]
13099 "TARGET_CMOVE && TARGET_80387
13100 && FLOAT_MODE_P (GET_MODE (operands[1]))
13101 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13102 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13103 "#")
13104
13105 (define_insn "*fp_jcc_2_mixed"
13106 [(set (pc)
13107 (if_then_else (match_operator 0 "comparison_operator"
13108 [(match_operand 1 "register_operand" "f#x,x#f")
13109 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13110 (pc)
13111 (label_ref (match_operand 3 "" ""))))
13112 (clobber (reg:CCFP FPSR_REG))
13113 (clobber (reg:CCFP FLAGS_REG))]
13114 "TARGET_MIX_SSE_I387
13115 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13116 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13117 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13118 "#")
13119
13120 (define_insn "*fp_jcc_2_sse"
13121 [(set (pc)
13122 (if_then_else (match_operator 0 "comparison_operator"
13123 [(match_operand 1 "register_operand" "x")
13124 (match_operand 2 "nonimmediate_operand" "xm")])
13125 (pc)
13126 (label_ref (match_operand 3 "" ""))))
13127 (clobber (reg:CCFP FPSR_REG))
13128 (clobber (reg:CCFP FLAGS_REG))]
13129 "TARGET_SSE_MATH
13130 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13131 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13132 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13133 "#")
13134
13135 (define_insn "*fp_jcc_2_387"
13136 [(set (pc)
13137 (if_then_else (match_operator 0 "comparison_operator"
13138 [(match_operand 1 "register_operand" "f")
13139 (match_operand 2 "register_operand" "f")])
13140 (pc)
13141 (label_ref (match_operand 3 "" ""))))
13142 (clobber (reg:CCFP FPSR_REG))
13143 (clobber (reg:CCFP FLAGS_REG))]
13144 "TARGET_CMOVE && TARGET_80387
13145 && FLOAT_MODE_P (GET_MODE (operands[1]))
13146 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13147 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13148 "#")
13149
13150 (define_insn "*fp_jcc_3_387"
13151 [(set (pc)
13152 (if_then_else (match_operator 0 "comparison_operator"
13153 [(match_operand 1 "register_operand" "f")
13154 (match_operand 2 "nonimmediate_operand" "fm")])
13155 (label_ref (match_operand 3 "" ""))
13156 (pc)))
13157 (clobber (reg:CCFP FPSR_REG))
13158 (clobber (reg:CCFP FLAGS_REG))
13159 (clobber (match_scratch:HI 4 "=a"))]
13160 "TARGET_80387
13161 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13162 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13163 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13164 && SELECT_CC_MODE (GET_CODE (operands[0]),
13165 operands[1], operands[2]) == CCFPmode
13166 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13167 "#")
13168
13169 (define_insn "*fp_jcc_4_387"
13170 [(set (pc)
13171 (if_then_else (match_operator 0 "comparison_operator"
13172 [(match_operand 1 "register_operand" "f")
13173 (match_operand 2 "nonimmediate_operand" "fm")])
13174 (pc)
13175 (label_ref (match_operand 3 "" ""))))
13176 (clobber (reg:CCFP FPSR_REG))
13177 (clobber (reg:CCFP FLAGS_REG))
13178 (clobber (match_scratch:HI 4 "=a"))]
13179 "TARGET_80387
13180 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13181 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13182 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13183 && SELECT_CC_MODE (GET_CODE (operands[0]),
13184 operands[1], operands[2]) == CCFPmode
13185 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13186 "#")
13187
13188 (define_insn "*fp_jcc_5_387"
13189 [(set (pc)
13190 (if_then_else (match_operator 0 "comparison_operator"
13191 [(match_operand 1 "register_operand" "f")
13192 (match_operand 2 "register_operand" "f")])
13193 (label_ref (match_operand 3 "" ""))
13194 (pc)))
13195 (clobber (reg:CCFP FPSR_REG))
13196 (clobber (reg:CCFP FLAGS_REG))
13197 (clobber (match_scratch:HI 4 "=a"))]
13198 "TARGET_80387
13199 && FLOAT_MODE_P (GET_MODE (operands[1]))
13200 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13201 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13202 "#")
13203
13204 (define_insn "*fp_jcc_6_387"
13205 [(set (pc)
13206 (if_then_else (match_operator 0 "comparison_operator"
13207 [(match_operand 1 "register_operand" "f")
13208 (match_operand 2 "register_operand" "f")])
13209 (pc)
13210 (label_ref (match_operand 3 "" ""))))
13211 (clobber (reg:CCFP FPSR_REG))
13212 (clobber (reg:CCFP FLAGS_REG))
13213 (clobber (match_scratch:HI 4 "=a"))]
13214 "TARGET_80387
13215 && FLOAT_MODE_P (GET_MODE (operands[1]))
13216 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13217 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13218 "#")
13219
13220 (define_insn "*fp_jcc_7_387"
13221 [(set (pc)
13222 (if_then_else (match_operator 0 "comparison_operator"
13223 [(match_operand 1 "register_operand" "f")
13224 (match_operand 2 "const0_operand" "X")])
13225 (label_ref (match_operand 3 "" ""))
13226 (pc)))
13227 (clobber (reg:CCFP FPSR_REG))
13228 (clobber (reg:CCFP FLAGS_REG))
13229 (clobber (match_scratch:HI 4 "=a"))]
13230 "TARGET_80387
13231 && FLOAT_MODE_P (GET_MODE (operands[1]))
13232 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13233 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13234 && SELECT_CC_MODE (GET_CODE (operands[0]),
13235 operands[1], operands[2]) == CCFPmode
13236 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13237 "#")
13238
13239 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13240 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13241 ;; with a precedence over other operators and is always put in the first
13242 ;; place. Swap condition and operands to match ficom instruction.
13243
13244 (define_insn "*fp_jcc_8<mode>_387"
13245 [(set (pc)
13246 (if_then_else (match_operator 0 "comparison_operator"
13247 [(match_operator 1 "float_operator"
13248 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13249 (match_operand 3 "register_operand" "f,f")])
13250 (label_ref (match_operand 4 "" ""))
13251 (pc)))
13252 (clobber (reg:CCFP FPSR_REG))
13253 (clobber (reg:CCFP FLAGS_REG))
13254 (clobber (match_scratch:HI 5 "=a,a"))]
13255 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13256 && FLOAT_MODE_P (GET_MODE (operands[3]))
13257 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13258 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13259 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13260 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13261 "#")
13262
13263 (define_split
13264 [(set (pc)
13265 (if_then_else (match_operator 0 "comparison_operator"
13266 [(match_operand 1 "register_operand" "")
13267 (match_operand 2 "nonimmediate_operand" "")])
13268 (match_operand 3 "" "")
13269 (match_operand 4 "" "")))
13270 (clobber (reg:CCFP FPSR_REG))
13271 (clobber (reg:CCFP FLAGS_REG))]
13272 "reload_completed"
13273 [(const_int 0)]
13274 {
13275 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13276 operands[3], operands[4], NULL_RTX, NULL_RTX);
13277 DONE;
13278 })
13279
13280 (define_split
13281 [(set (pc)
13282 (if_then_else (match_operator 0 "comparison_operator"
13283 [(match_operand 1 "register_operand" "")
13284 (match_operand 2 "general_operand" "")])
13285 (match_operand 3 "" "")
13286 (match_operand 4 "" "")))
13287 (clobber (reg:CCFP FPSR_REG))
13288 (clobber (reg:CCFP FLAGS_REG))
13289 (clobber (match_scratch:HI 5 "=a"))]
13290 "reload_completed"
13291 [(const_int 0)]
13292 {
13293 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13294 operands[3], operands[4], operands[5], NULL_RTX);
13295 DONE;
13296 })
13297
13298 (define_split
13299 [(set (pc)
13300 (if_then_else (match_operator 0 "comparison_operator"
13301 [(match_operator 1 "float_operator"
13302 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13303 (match_operand 3 "register_operand" "")])
13304 (match_operand 4 "" "")
13305 (match_operand 5 "" "")))
13306 (clobber (reg:CCFP FPSR_REG))
13307 (clobber (reg:CCFP FLAGS_REG))
13308 (clobber (match_scratch:HI 6 "=a"))]
13309 "reload_completed"
13310 [(const_int 0)]
13311 {
13312 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13313 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13314 operands[3], operands[7],
13315 operands[4], operands[5], operands[6], NULL_RTX);
13316 DONE;
13317 })
13318
13319 ;; %%% Kill this when reload knows how to do it.
13320 (define_split
13321 [(set (pc)
13322 (if_then_else (match_operator 0 "comparison_operator"
13323 [(match_operator 1 "float_operator"
13324 [(match_operand:X87MODEI12 2 "register_operand" "")])
13325 (match_operand 3 "register_operand" "")])
13326 (match_operand 4 "" "")
13327 (match_operand 5 "" "")))
13328 (clobber (reg:CCFP FPSR_REG))
13329 (clobber (reg:CCFP FLAGS_REG))
13330 (clobber (match_scratch:HI 6 "=a"))]
13331 "reload_completed"
13332 [(const_int 0)]
13333 {
13334 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13335 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13336 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13337 operands[3], operands[7],
13338 operands[4], operands[5], operands[6], operands[2]);
13339 DONE;
13340 })
13341 \f
13342 ;; Unconditional and other jump instructions
13343
13344 (define_insn "jump"
13345 [(set (pc)
13346 (label_ref (match_operand 0 "" "")))]
13347 ""
13348 "jmp\t%l0"
13349 [(set_attr "type" "ibr")
13350 (set (attr "length")
13351 (if_then_else (and (ge (minus (match_dup 0) (pc))
13352 (const_int -126))
13353 (lt (minus (match_dup 0) (pc))
13354 (const_int 128)))
13355 (const_int 2)
13356 (const_int 5)))
13357 (set_attr "modrm" "0")])
13358
13359 (define_expand "indirect_jump"
13360 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13361 ""
13362 "")
13363
13364 (define_insn "*indirect_jump"
13365 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13366 "!TARGET_64BIT"
13367 "jmp\t%A0"
13368 [(set_attr "type" "ibr")
13369 (set_attr "length_immediate" "0")])
13370
13371 (define_insn "*indirect_jump_rtx64"
13372 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13373 "TARGET_64BIT"
13374 "jmp\t%A0"
13375 [(set_attr "type" "ibr")
13376 (set_attr "length_immediate" "0")])
13377
13378 (define_expand "tablejump"
13379 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13380 (use (label_ref (match_operand 1 "" "")))])]
13381 ""
13382 {
13383 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13384 relative. Convert the relative address to an absolute address. */
13385 if (flag_pic)
13386 {
13387 rtx op0, op1;
13388 enum rtx_code code;
13389
13390 if (TARGET_64BIT)
13391 {
13392 code = PLUS;
13393 op0 = operands[0];
13394 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13395 }
13396 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13397 {
13398 code = PLUS;
13399 op0 = operands[0];
13400 op1 = pic_offset_table_rtx;
13401 }
13402 else
13403 {
13404 code = MINUS;
13405 op0 = pic_offset_table_rtx;
13406 op1 = operands[0];
13407 }
13408
13409 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13410 OPTAB_DIRECT);
13411 }
13412 })
13413
13414 (define_insn "*tablejump_1"
13415 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13416 (use (label_ref (match_operand 1 "" "")))]
13417 "!TARGET_64BIT"
13418 "jmp\t%A0"
13419 [(set_attr "type" "ibr")
13420 (set_attr "length_immediate" "0")])
13421
13422 (define_insn "*tablejump_1_rtx64"
13423 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13424 (use (label_ref (match_operand 1 "" "")))]
13425 "TARGET_64BIT"
13426 "jmp\t%A0"
13427 [(set_attr "type" "ibr")
13428 (set_attr "length_immediate" "0")])
13429 \f
13430 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13431
13432 (define_peephole2
13433 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13434 (set (match_operand:QI 1 "register_operand" "")
13435 (match_operator:QI 2 "ix86_comparison_operator"
13436 [(reg FLAGS_REG) (const_int 0)]))
13437 (set (match_operand 3 "q_regs_operand" "")
13438 (zero_extend (match_dup 1)))]
13439 "(peep2_reg_dead_p (3, operands[1])
13440 || operands_match_p (operands[1], operands[3]))
13441 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13442 [(set (match_dup 4) (match_dup 0))
13443 (set (strict_low_part (match_dup 5))
13444 (match_dup 2))]
13445 {
13446 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13447 operands[5] = gen_lowpart (QImode, operands[3]);
13448 ix86_expand_clear (operands[3]);
13449 })
13450
13451 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13452
13453 (define_peephole2
13454 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13455 (set (match_operand:QI 1 "register_operand" "")
13456 (match_operator:QI 2 "ix86_comparison_operator"
13457 [(reg FLAGS_REG) (const_int 0)]))
13458 (parallel [(set (match_operand 3 "q_regs_operand" "")
13459 (zero_extend (match_dup 1)))
13460 (clobber (reg:CC FLAGS_REG))])]
13461 "(peep2_reg_dead_p (3, operands[1])
13462 || operands_match_p (operands[1], operands[3]))
13463 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13464 [(set (match_dup 4) (match_dup 0))
13465 (set (strict_low_part (match_dup 5))
13466 (match_dup 2))]
13467 {
13468 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13469 operands[5] = gen_lowpart (QImode, operands[3]);
13470 ix86_expand_clear (operands[3]);
13471 })
13472 \f
13473 ;; Call instructions.
13474
13475 ;; The predicates normally associated with named expanders are not properly
13476 ;; checked for calls. This is a bug in the generic code, but it isn't that
13477 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13478
13479 ;; Call subroutine returning no value.
13480
13481 (define_expand "call_pop"
13482 [(parallel [(call (match_operand:QI 0 "" "")
13483 (match_operand:SI 1 "" ""))
13484 (set (reg:SI SP_REG)
13485 (plus:SI (reg:SI SP_REG)
13486 (match_operand:SI 3 "" "")))])]
13487 "!TARGET_64BIT"
13488 {
13489 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13490 DONE;
13491 })
13492
13493 (define_insn "*call_pop_0"
13494 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13495 (match_operand:SI 1 "" ""))
13496 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13497 (match_operand:SI 2 "immediate_operand" "")))]
13498 "!TARGET_64BIT"
13499 {
13500 if (SIBLING_CALL_P (insn))
13501 return "jmp\t%P0";
13502 else
13503 return "call\t%P0";
13504 }
13505 [(set_attr "type" "call")])
13506
13507 (define_insn "*call_pop_1"
13508 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13509 (match_operand:SI 1 "" ""))
13510 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13511 (match_operand:SI 2 "immediate_operand" "i")))]
13512 "!TARGET_64BIT"
13513 {
13514 if (constant_call_address_operand (operands[0], Pmode))
13515 {
13516 if (SIBLING_CALL_P (insn))
13517 return "jmp\t%P0";
13518 else
13519 return "call\t%P0";
13520 }
13521 if (SIBLING_CALL_P (insn))
13522 return "jmp\t%A0";
13523 else
13524 return "call\t%A0";
13525 }
13526 [(set_attr "type" "call")])
13527
13528 (define_expand "call"
13529 [(call (match_operand:QI 0 "" "")
13530 (match_operand 1 "" ""))
13531 (use (match_operand 2 "" ""))]
13532 ""
13533 {
13534 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13535 DONE;
13536 })
13537
13538 (define_expand "sibcall"
13539 [(call (match_operand:QI 0 "" "")
13540 (match_operand 1 "" ""))
13541 (use (match_operand 2 "" ""))]
13542 ""
13543 {
13544 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13545 DONE;
13546 })
13547
13548 (define_insn "*call_0"
13549 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13550 (match_operand 1 "" ""))]
13551 ""
13552 {
13553 if (SIBLING_CALL_P (insn))
13554 return "jmp\t%P0";
13555 else
13556 return "call\t%P0";
13557 }
13558 [(set_attr "type" "call")])
13559
13560 (define_insn "*call_1"
13561 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13562 (match_operand 1 "" ""))]
13563 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13564 {
13565 if (constant_call_address_operand (operands[0], Pmode))
13566 return "call\t%P0";
13567 return "call\t%A0";
13568 }
13569 [(set_attr "type" "call")])
13570
13571 (define_insn "*sibcall_1"
13572 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13573 (match_operand 1 "" ""))]
13574 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13575 {
13576 if (constant_call_address_operand (operands[0], Pmode))
13577 return "jmp\t%P0";
13578 return "jmp\t%A0";
13579 }
13580 [(set_attr "type" "call")])
13581
13582 (define_insn "*call_1_rex64"
13583 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13584 (match_operand 1 "" ""))]
13585 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13586 {
13587 if (constant_call_address_operand (operands[0], Pmode))
13588 return "call\t%P0";
13589 return "call\t%A0";
13590 }
13591 [(set_attr "type" "call")])
13592
13593 (define_insn "*sibcall_1_rex64"
13594 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13595 (match_operand 1 "" ""))]
13596 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13597 "jmp\t%P0"
13598 [(set_attr "type" "call")])
13599
13600 (define_insn "*sibcall_1_rex64_v"
13601 [(call (mem:QI (reg:DI 40))
13602 (match_operand 0 "" ""))]
13603 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13604 "jmp\t*%%r11"
13605 [(set_attr "type" "call")])
13606
13607
13608 ;; Call subroutine, returning value in operand 0
13609
13610 (define_expand "call_value_pop"
13611 [(parallel [(set (match_operand 0 "" "")
13612 (call (match_operand:QI 1 "" "")
13613 (match_operand:SI 2 "" "")))
13614 (set (reg:SI SP_REG)
13615 (plus:SI (reg:SI SP_REG)
13616 (match_operand:SI 4 "" "")))])]
13617 "!TARGET_64BIT"
13618 {
13619 ix86_expand_call (operands[0], operands[1], operands[2],
13620 operands[3], operands[4], 0);
13621 DONE;
13622 })
13623
13624 (define_expand "call_value"
13625 [(set (match_operand 0 "" "")
13626 (call (match_operand:QI 1 "" "")
13627 (match_operand:SI 2 "" "")))
13628 (use (match_operand:SI 3 "" ""))]
13629 ;; Operand 2 not used on the i386.
13630 ""
13631 {
13632 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13633 DONE;
13634 })
13635
13636 (define_expand "sibcall_value"
13637 [(set (match_operand 0 "" "")
13638 (call (match_operand:QI 1 "" "")
13639 (match_operand:SI 2 "" "")))
13640 (use (match_operand:SI 3 "" ""))]
13641 ;; Operand 2 not used on the i386.
13642 ""
13643 {
13644 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13645 DONE;
13646 })
13647
13648 ;; Call subroutine returning any type.
13649
13650 (define_expand "untyped_call"
13651 [(parallel [(call (match_operand 0 "" "")
13652 (const_int 0))
13653 (match_operand 1 "" "")
13654 (match_operand 2 "" "")])]
13655 ""
13656 {
13657 int i;
13658
13659 /* In order to give reg-stack an easier job in validating two
13660 coprocessor registers as containing a possible return value,
13661 simply pretend the untyped call returns a complex long double
13662 value. */
13663
13664 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13665 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13666 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13667 NULL, 0);
13668
13669 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13670 {
13671 rtx set = XVECEXP (operands[2], 0, i);
13672 emit_move_insn (SET_DEST (set), SET_SRC (set));
13673 }
13674
13675 /* The optimizer does not know that the call sets the function value
13676 registers we stored in the result block. We avoid problems by
13677 claiming that all hard registers are used and clobbered at this
13678 point. */
13679 emit_insn (gen_blockage (const0_rtx));
13680
13681 DONE;
13682 })
13683 \f
13684 ;; Prologue and epilogue instructions
13685
13686 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13687 ;; all of memory. This blocks insns from being moved across this point.
13688
13689 (define_insn "blockage"
13690 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13691 ""
13692 ""
13693 [(set_attr "length" "0")])
13694
13695 ;; Insn emitted into the body of a function to return from a function.
13696 ;; This is only done if the function's epilogue is known to be simple.
13697 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13698
13699 (define_expand "return"
13700 [(return)]
13701 "ix86_can_use_return_insn_p ()"
13702 {
13703 if (current_function_pops_args)
13704 {
13705 rtx popc = GEN_INT (current_function_pops_args);
13706 emit_jump_insn (gen_return_pop_internal (popc));
13707 DONE;
13708 }
13709 })
13710
13711 (define_insn "return_internal"
13712 [(return)]
13713 "reload_completed"
13714 "ret"
13715 [(set_attr "length" "1")
13716 (set_attr "length_immediate" "0")
13717 (set_attr "modrm" "0")])
13718
13719 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13720 ;; instruction Athlon and K8 have.
13721
13722 (define_insn "return_internal_long"
13723 [(return)
13724 (unspec [(const_int 0)] UNSPEC_REP)]
13725 "reload_completed"
13726 "rep {;} ret"
13727 [(set_attr "length" "1")
13728 (set_attr "length_immediate" "0")
13729 (set_attr "prefix_rep" "1")
13730 (set_attr "modrm" "0")])
13731
13732 (define_insn "return_pop_internal"
13733 [(return)
13734 (use (match_operand:SI 0 "const_int_operand" ""))]
13735 "reload_completed"
13736 "ret\t%0"
13737 [(set_attr "length" "3")
13738 (set_attr "length_immediate" "2")
13739 (set_attr "modrm" "0")])
13740
13741 (define_insn "return_indirect_internal"
13742 [(return)
13743 (use (match_operand:SI 0 "register_operand" "r"))]
13744 "reload_completed"
13745 "jmp\t%A0"
13746 [(set_attr "type" "ibr")
13747 (set_attr "length_immediate" "0")])
13748
13749 (define_insn "nop"
13750 [(const_int 0)]
13751 ""
13752 "nop"
13753 [(set_attr "length" "1")
13754 (set_attr "length_immediate" "0")
13755 (set_attr "modrm" "0")])
13756
13757 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13758 ;; branch prediction penalty for the third jump in a 16-byte
13759 ;; block on K8.
13760
13761 (define_insn "align"
13762 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13763 ""
13764 {
13765 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13766 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13767 #else
13768 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13769 The align insn is used to avoid 3 jump instructions in the row to improve
13770 branch prediction and the benefits hardly outweight the cost of extra 8
13771 nops on the average inserted by full alignment pseudo operation. */
13772 #endif
13773 return "";
13774 }
13775 [(set_attr "length" "16")])
13776
13777 (define_expand "prologue"
13778 [(const_int 1)]
13779 ""
13780 "ix86_expand_prologue (); DONE;")
13781
13782 (define_insn "set_got"
13783 [(set (match_operand:SI 0 "register_operand" "=r")
13784 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13785 (clobber (reg:CC FLAGS_REG))]
13786 "!TARGET_64BIT"
13787 { return output_set_got (operands[0]); }
13788 [(set_attr "type" "multi")
13789 (set_attr "length" "12")])
13790
13791 (define_expand "epilogue"
13792 [(const_int 1)]
13793 ""
13794 "ix86_expand_epilogue (1); DONE;")
13795
13796 (define_expand "sibcall_epilogue"
13797 [(const_int 1)]
13798 ""
13799 "ix86_expand_epilogue (0); DONE;")
13800
13801 (define_expand "eh_return"
13802 [(use (match_operand 0 "register_operand" ""))]
13803 ""
13804 {
13805 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13806
13807 /* Tricky bit: we write the address of the handler to which we will
13808 be returning into someone else's stack frame, one word below the
13809 stack address we wish to restore. */
13810 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13811 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13812 tmp = gen_rtx_MEM (Pmode, tmp);
13813 emit_move_insn (tmp, ra);
13814
13815 if (Pmode == SImode)
13816 emit_jump_insn (gen_eh_return_si (sa));
13817 else
13818 emit_jump_insn (gen_eh_return_di (sa));
13819 emit_barrier ();
13820 DONE;
13821 })
13822
13823 (define_insn_and_split "eh_return_si"
13824 [(set (pc)
13825 (unspec [(match_operand:SI 0 "register_operand" "c")]
13826 UNSPEC_EH_RETURN))]
13827 "!TARGET_64BIT"
13828 "#"
13829 "reload_completed"
13830 [(const_int 1)]
13831 "ix86_expand_epilogue (2); DONE;")
13832
13833 (define_insn_and_split "eh_return_di"
13834 [(set (pc)
13835 (unspec [(match_operand:DI 0 "register_operand" "c")]
13836 UNSPEC_EH_RETURN))]
13837 "TARGET_64BIT"
13838 "#"
13839 "reload_completed"
13840 [(const_int 1)]
13841 "ix86_expand_epilogue (2); DONE;")
13842
13843 (define_insn "leave"
13844 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13845 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13846 (clobber (mem:BLK (scratch)))]
13847 "!TARGET_64BIT"
13848 "leave"
13849 [(set_attr "type" "leave")])
13850
13851 (define_insn "leave_rex64"
13852 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13853 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13854 (clobber (mem:BLK (scratch)))]
13855 "TARGET_64BIT"
13856 "leave"
13857 [(set_attr "type" "leave")])
13858 \f
13859 (define_expand "ffssi2"
13860 [(parallel
13861 [(set (match_operand:SI 0 "register_operand" "")
13862 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13863 (clobber (match_scratch:SI 2 ""))
13864 (clobber (reg:CC FLAGS_REG))])]
13865 ""
13866 "")
13867
13868 (define_insn_and_split "*ffs_cmove"
13869 [(set (match_operand:SI 0 "register_operand" "=r")
13870 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13871 (clobber (match_scratch:SI 2 "=&r"))
13872 (clobber (reg:CC FLAGS_REG))]
13873 "TARGET_CMOVE"
13874 "#"
13875 "&& reload_completed"
13876 [(set (match_dup 2) (const_int -1))
13877 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13878 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13879 (set (match_dup 0) (if_then_else:SI
13880 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13881 (match_dup 2)
13882 (match_dup 0)))
13883 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13884 (clobber (reg:CC FLAGS_REG))])]
13885 "")
13886
13887 (define_insn_and_split "*ffs_no_cmove"
13888 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13889 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13890 (clobber (match_scratch:SI 2 "=&q"))
13891 (clobber (reg:CC FLAGS_REG))]
13892 ""
13893 "#"
13894 "reload_completed"
13895 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13896 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13897 (set (strict_low_part (match_dup 3))
13898 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13899 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13900 (clobber (reg:CC FLAGS_REG))])
13901 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13902 (clobber (reg:CC FLAGS_REG))])
13903 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13904 (clobber (reg:CC FLAGS_REG))])]
13905 {
13906 operands[3] = gen_lowpart (QImode, operands[2]);
13907 ix86_expand_clear (operands[2]);
13908 })
13909
13910 (define_insn "*ffssi_1"
13911 [(set (reg:CCZ FLAGS_REG)
13912 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13913 (const_int 0)))
13914 (set (match_operand:SI 0 "register_operand" "=r")
13915 (ctz:SI (match_dup 1)))]
13916 ""
13917 "bsf{l}\t{%1, %0|%0, %1}"
13918 [(set_attr "prefix_0f" "1")])
13919
13920 (define_expand "ffsdi2"
13921 [(parallel
13922 [(set (match_operand:DI 0 "register_operand" "")
13923 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13924 (clobber (match_scratch:DI 2 ""))
13925 (clobber (reg:CC FLAGS_REG))])]
13926 "TARGET_64BIT && TARGET_CMOVE"
13927 "")
13928
13929 (define_insn_and_split "*ffs_rex64"
13930 [(set (match_operand:DI 0 "register_operand" "=r")
13931 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13932 (clobber (match_scratch:DI 2 "=&r"))
13933 (clobber (reg:CC FLAGS_REG))]
13934 "TARGET_64BIT && TARGET_CMOVE"
13935 "#"
13936 "&& reload_completed"
13937 [(set (match_dup 2) (const_int -1))
13938 (parallel [(set (reg:CCZ FLAGS_REG)
13939 (compare:CCZ (match_dup 1) (const_int 0)))
13940 (set (match_dup 0) (ctz:DI (match_dup 1)))])
13941 (set (match_dup 0) (if_then_else:DI
13942 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13943 (match_dup 2)
13944 (match_dup 0)))
13945 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13946 (clobber (reg:CC FLAGS_REG))])]
13947 "")
13948
13949 (define_insn "*ffsdi_1"
13950 [(set (reg:CCZ FLAGS_REG)
13951 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13952 (const_int 0)))
13953 (set (match_operand:DI 0 "register_operand" "=r")
13954 (ctz:DI (match_dup 1)))]
13955 "TARGET_64BIT"
13956 "bsf{q}\t{%1, %0|%0, %1}"
13957 [(set_attr "prefix_0f" "1")])
13958
13959 (define_insn "ctzsi2"
13960 [(set (match_operand:SI 0 "register_operand" "=r")
13961 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13962 (clobber (reg:CC FLAGS_REG))]
13963 ""
13964 "bsf{l}\t{%1, %0|%0, %1}"
13965 [(set_attr "prefix_0f" "1")])
13966
13967 (define_insn "ctzdi2"
13968 [(set (match_operand:DI 0 "register_operand" "=r")
13969 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13970 (clobber (reg:CC FLAGS_REG))]
13971 "TARGET_64BIT"
13972 "bsf{q}\t{%1, %0|%0, %1}"
13973 [(set_attr "prefix_0f" "1")])
13974
13975 (define_expand "clzsi2"
13976 [(parallel
13977 [(set (match_operand:SI 0 "register_operand" "")
13978 (minus:SI (const_int 31)
13979 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13980 (clobber (reg:CC FLAGS_REG))])
13981 (parallel
13982 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13983 (clobber (reg:CC FLAGS_REG))])]
13984 ""
13985 "")
13986
13987 (define_insn "*bsr"
13988 [(set (match_operand:SI 0 "register_operand" "=r")
13989 (minus:SI (const_int 31)
13990 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13991 (clobber (reg:CC FLAGS_REG))]
13992 ""
13993 "bsr{l}\t{%1, %0|%0, %1}"
13994 [(set_attr "prefix_0f" "1")])
13995
13996 (define_expand "clzdi2"
13997 [(parallel
13998 [(set (match_operand:DI 0 "register_operand" "")
13999 (minus:DI (const_int 63)
14000 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14001 (clobber (reg:CC FLAGS_REG))])
14002 (parallel
14003 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14004 (clobber (reg:CC FLAGS_REG))])]
14005 "TARGET_64BIT"
14006 "")
14007
14008 (define_insn "*bsr_rex64"
14009 [(set (match_operand:DI 0 "register_operand" "=r")
14010 (minus:DI (const_int 63)
14011 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14012 (clobber (reg:CC FLAGS_REG))]
14013 "TARGET_64BIT"
14014 "bsr{q}\t{%1, %0|%0, %1}"
14015 [(set_attr "prefix_0f" "1")])
14016 \f
14017 ;; Thread-local storage patterns for ELF.
14018 ;;
14019 ;; Note that these code sequences must appear exactly as shown
14020 ;; in order to allow linker relaxation.
14021
14022 (define_insn "*tls_global_dynamic_32_gnu"
14023 [(set (match_operand:SI 0 "register_operand" "=a")
14024 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14025 (match_operand:SI 2 "tls_symbolic_operand" "")
14026 (match_operand:SI 3 "call_insn_operand" "")]
14027 UNSPEC_TLS_GD))
14028 (clobber (match_scratch:SI 4 "=d"))
14029 (clobber (match_scratch:SI 5 "=c"))
14030 (clobber (reg:CC FLAGS_REG))]
14031 "!TARGET_64BIT && TARGET_GNU_TLS"
14032 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14033 [(set_attr "type" "multi")
14034 (set_attr "length" "12")])
14035
14036 (define_insn "*tls_global_dynamic_32_sun"
14037 [(set (match_operand:SI 0 "register_operand" "=a")
14038 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14039 (match_operand:SI 2 "tls_symbolic_operand" "")
14040 (match_operand:SI 3 "call_insn_operand" "")]
14041 UNSPEC_TLS_GD))
14042 (clobber (match_scratch:SI 4 "=d"))
14043 (clobber (match_scratch:SI 5 "=c"))
14044 (clobber (reg:CC FLAGS_REG))]
14045 "!TARGET_64BIT && TARGET_SUN_TLS"
14046 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14047 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14048 [(set_attr "type" "multi")
14049 (set_attr "length" "14")])
14050
14051 (define_expand "tls_global_dynamic_32"
14052 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14053 (unspec:SI
14054 [(match_dup 2)
14055 (match_operand:SI 1 "tls_symbolic_operand" "")
14056 (match_dup 3)]
14057 UNSPEC_TLS_GD))
14058 (clobber (match_scratch:SI 4 ""))
14059 (clobber (match_scratch:SI 5 ""))
14060 (clobber (reg:CC FLAGS_REG))])]
14061 ""
14062 {
14063 if (flag_pic)
14064 operands[2] = pic_offset_table_rtx;
14065 else
14066 {
14067 operands[2] = gen_reg_rtx (Pmode);
14068 emit_insn (gen_set_got (operands[2]));
14069 }
14070 operands[3] = ix86_tls_get_addr ();
14071 })
14072
14073 (define_insn "*tls_global_dynamic_64"
14074 [(set (match_operand:DI 0 "register_operand" "=a")
14075 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14076 (match_operand:DI 3 "" "")))
14077 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14078 UNSPEC_TLS_GD)]
14079 "TARGET_64BIT"
14080 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14081 [(set_attr "type" "multi")
14082 (set_attr "length" "16")])
14083
14084 (define_expand "tls_global_dynamic_64"
14085 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14086 (call (mem:QI (match_dup 2)) (const_int 0)))
14087 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14088 UNSPEC_TLS_GD)])]
14089 ""
14090 {
14091 operands[2] = ix86_tls_get_addr ();
14092 })
14093
14094 (define_insn "*tls_local_dynamic_base_32_gnu"
14095 [(set (match_operand:SI 0 "register_operand" "=a")
14096 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14097 (match_operand:SI 2 "call_insn_operand" "")]
14098 UNSPEC_TLS_LD_BASE))
14099 (clobber (match_scratch:SI 3 "=d"))
14100 (clobber (match_scratch:SI 4 "=c"))
14101 (clobber (reg:CC FLAGS_REG))]
14102 "!TARGET_64BIT && TARGET_GNU_TLS"
14103 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14104 [(set_attr "type" "multi")
14105 (set_attr "length" "11")])
14106
14107 (define_insn "*tls_local_dynamic_base_32_sun"
14108 [(set (match_operand:SI 0 "register_operand" "=a")
14109 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14110 (match_operand:SI 2 "call_insn_operand" "")]
14111 UNSPEC_TLS_LD_BASE))
14112 (clobber (match_scratch:SI 3 "=d"))
14113 (clobber (match_scratch:SI 4 "=c"))
14114 (clobber (reg:CC FLAGS_REG))]
14115 "!TARGET_64BIT && TARGET_SUN_TLS"
14116 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14117 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14118 [(set_attr "type" "multi")
14119 (set_attr "length" "13")])
14120
14121 (define_expand "tls_local_dynamic_base_32"
14122 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14123 (unspec:SI [(match_dup 1) (match_dup 2)]
14124 UNSPEC_TLS_LD_BASE))
14125 (clobber (match_scratch:SI 3 ""))
14126 (clobber (match_scratch:SI 4 ""))
14127 (clobber (reg:CC FLAGS_REG))])]
14128 ""
14129 {
14130 if (flag_pic)
14131 operands[1] = pic_offset_table_rtx;
14132 else
14133 {
14134 operands[1] = gen_reg_rtx (Pmode);
14135 emit_insn (gen_set_got (operands[1]));
14136 }
14137 operands[2] = ix86_tls_get_addr ();
14138 })
14139
14140 (define_insn "*tls_local_dynamic_base_64"
14141 [(set (match_operand:DI 0 "register_operand" "=a")
14142 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14143 (match_operand:DI 2 "" "")))
14144 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14145 "TARGET_64BIT"
14146 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14147 [(set_attr "type" "multi")
14148 (set_attr "length" "12")])
14149
14150 (define_expand "tls_local_dynamic_base_64"
14151 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14152 (call (mem:QI (match_dup 1)) (const_int 0)))
14153 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14154 ""
14155 {
14156 operands[1] = ix86_tls_get_addr ();
14157 })
14158
14159 ;; Local dynamic of a single variable is a lose. Show combine how
14160 ;; to convert that back to global dynamic.
14161
14162 (define_insn_and_split "*tls_local_dynamic_32_once"
14163 [(set (match_operand:SI 0 "register_operand" "=a")
14164 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14165 (match_operand:SI 2 "call_insn_operand" "")]
14166 UNSPEC_TLS_LD_BASE)
14167 (const:SI (unspec:SI
14168 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14169 UNSPEC_DTPOFF))))
14170 (clobber (match_scratch:SI 4 "=d"))
14171 (clobber (match_scratch:SI 5 "=c"))
14172 (clobber (reg:CC FLAGS_REG))]
14173 ""
14174 "#"
14175 ""
14176 [(parallel [(set (match_dup 0)
14177 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14178 UNSPEC_TLS_GD))
14179 (clobber (match_dup 4))
14180 (clobber (match_dup 5))
14181 (clobber (reg:CC FLAGS_REG))])]
14182 "")
14183
14184 ;; Load and add the thread base pointer from %gs:0.
14185
14186 (define_insn "*load_tp_si"
14187 [(set (match_operand:SI 0 "register_operand" "=r")
14188 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14189 "!TARGET_64BIT"
14190 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14191 [(set_attr "type" "imov")
14192 (set_attr "modrm" "0")
14193 (set_attr "length" "7")
14194 (set_attr "memory" "load")
14195 (set_attr "imm_disp" "false")])
14196
14197 (define_insn "*add_tp_si"
14198 [(set (match_operand:SI 0 "register_operand" "=r")
14199 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14200 (match_operand:SI 1 "register_operand" "0")))
14201 (clobber (reg:CC FLAGS_REG))]
14202 "!TARGET_64BIT"
14203 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14204 [(set_attr "type" "alu")
14205 (set_attr "modrm" "0")
14206 (set_attr "length" "7")
14207 (set_attr "memory" "load")
14208 (set_attr "imm_disp" "false")])
14209
14210 (define_insn "*load_tp_di"
14211 [(set (match_operand:DI 0 "register_operand" "=r")
14212 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14213 "TARGET_64BIT"
14214 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14215 [(set_attr "type" "imov")
14216 (set_attr "modrm" "0")
14217 (set_attr "length" "7")
14218 (set_attr "memory" "load")
14219 (set_attr "imm_disp" "false")])
14220
14221 (define_insn "*add_tp_di"
14222 [(set (match_operand:DI 0 "register_operand" "=r")
14223 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14224 (match_operand:DI 1 "register_operand" "0")))
14225 (clobber (reg:CC FLAGS_REG))]
14226 "TARGET_64BIT"
14227 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14228 [(set_attr "type" "alu")
14229 (set_attr "modrm" "0")
14230 (set_attr "length" "7")
14231 (set_attr "memory" "load")
14232 (set_attr "imm_disp" "false")])
14233 \f
14234 ;; These patterns match the binary 387 instructions for addM3, subM3,
14235 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14236 ;; SFmode. The first is the normal insn, the second the same insn but
14237 ;; with one operand a conversion, and the third the same insn but with
14238 ;; the other operand a conversion. The conversion may be SFmode or
14239 ;; SImode if the target mode DFmode, but only SImode if the target mode
14240 ;; is SFmode.
14241
14242 ;; Gcc is slightly more smart about handling normal two address instructions
14243 ;; so use special patterns for add and mull.
14244
14245 (define_insn "*fop_sf_comm_mixed"
14246 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14247 (match_operator:SF 3 "binary_fp_operator"
14248 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14249 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14250 "TARGET_MIX_SSE_I387
14251 && COMMUTATIVE_ARITH_P (operands[3])
14252 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14253 "* return output_387_binary_op (insn, operands);"
14254 [(set (attr "type")
14255 (if_then_else (eq_attr "alternative" "1")
14256 (if_then_else (match_operand:SF 3 "mult_operator" "")
14257 (const_string "ssemul")
14258 (const_string "sseadd"))
14259 (if_then_else (match_operand:SF 3 "mult_operator" "")
14260 (const_string "fmul")
14261 (const_string "fop"))))
14262 (set_attr "mode" "SF")])
14263
14264 (define_insn "*fop_sf_comm_sse"
14265 [(set (match_operand:SF 0 "register_operand" "=x")
14266 (match_operator:SF 3 "binary_fp_operator"
14267 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14268 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14269 "TARGET_SSE_MATH
14270 && COMMUTATIVE_ARITH_P (operands[3])
14271 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14272 "* return output_387_binary_op (insn, operands);"
14273 [(set (attr "type")
14274 (if_then_else (match_operand:SF 3 "mult_operator" "")
14275 (const_string "ssemul")
14276 (const_string "sseadd")))
14277 (set_attr "mode" "SF")])
14278
14279 (define_insn "*fop_sf_comm_i387"
14280 [(set (match_operand:SF 0 "register_operand" "=f")
14281 (match_operator:SF 3 "binary_fp_operator"
14282 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14283 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14284 "TARGET_80387
14285 && COMMUTATIVE_ARITH_P (operands[3])
14286 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14287 "* return output_387_binary_op (insn, operands);"
14288 [(set (attr "type")
14289 (if_then_else (match_operand:SF 3 "mult_operator" "")
14290 (const_string "fmul")
14291 (const_string "fop")))
14292 (set_attr "mode" "SF")])
14293
14294 (define_insn "*fop_sf_1_mixed"
14295 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14296 (match_operator:SF 3 "binary_fp_operator"
14297 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14298 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14299 "TARGET_MIX_SSE_I387
14300 && !COMMUTATIVE_ARITH_P (operands[3])
14301 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14302 "* return output_387_binary_op (insn, operands);"
14303 [(set (attr "type")
14304 (cond [(and (eq_attr "alternative" "2")
14305 (match_operand:SF 3 "mult_operator" ""))
14306 (const_string "ssemul")
14307 (and (eq_attr "alternative" "2")
14308 (match_operand:SF 3 "div_operator" ""))
14309 (const_string "ssediv")
14310 (eq_attr "alternative" "2")
14311 (const_string "sseadd")
14312 (match_operand:SF 3 "mult_operator" "")
14313 (const_string "fmul")
14314 (match_operand:SF 3 "div_operator" "")
14315 (const_string "fdiv")
14316 ]
14317 (const_string "fop")))
14318 (set_attr "mode" "SF")])
14319
14320 (define_insn "*fop_sf_1_sse"
14321 [(set (match_operand:SF 0 "register_operand" "=x")
14322 (match_operator:SF 3 "binary_fp_operator"
14323 [(match_operand:SF 1 "register_operand" "0")
14324 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14325 "TARGET_SSE_MATH
14326 && !COMMUTATIVE_ARITH_P (operands[3])"
14327 "* return output_387_binary_op (insn, operands);"
14328 [(set (attr "type")
14329 (cond [(match_operand:SF 3 "mult_operator" "")
14330 (const_string "ssemul")
14331 (match_operand:SF 3 "div_operator" "")
14332 (const_string "ssediv")
14333 ]
14334 (const_string "sseadd")))
14335 (set_attr "mode" "SF")])
14336
14337 ;; This pattern is not fully shadowed by the pattern above.
14338 (define_insn "*fop_sf_1_i387"
14339 [(set (match_operand:SF 0 "register_operand" "=f,f")
14340 (match_operator:SF 3 "binary_fp_operator"
14341 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14342 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14343 "TARGET_80387 && !TARGET_SSE_MATH
14344 && !COMMUTATIVE_ARITH_P (operands[3])
14345 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14346 "* return output_387_binary_op (insn, operands);"
14347 [(set (attr "type")
14348 (cond [(match_operand:SF 3 "mult_operator" "")
14349 (const_string "fmul")
14350 (match_operand:SF 3 "div_operator" "")
14351 (const_string "fdiv")
14352 ]
14353 (const_string "fop")))
14354 (set_attr "mode" "SF")])
14355
14356 ;; ??? Add SSE splitters for these!
14357 (define_insn "*fop_sf_2<mode>_i387"
14358 [(set (match_operand:SF 0 "register_operand" "=f,f")
14359 (match_operator:SF 3 "binary_fp_operator"
14360 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14361 (match_operand:SF 2 "register_operand" "0,0")]))]
14362 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14363 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14364 [(set (attr "type")
14365 (cond [(match_operand:SF 3 "mult_operator" "")
14366 (const_string "fmul")
14367 (match_operand:SF 3 "div_operator" "")
14368 (const_string "fdiv")
14369 ]
14370 (const_string "fop")))
14371 (set_attr "fp_int_src" "true")
14372 (set_attr "mode" "<MODE>")])
14373
14374 (define_insn "*fop_sf_3<mode>_i387"
14375 [(set (match_operand:SF 0 "register_operand" "=f,f")
14376 (match_operator:SF 3 "binary_fp_operator"
14377 [(match_operand:SF 1 "register_operand" "0,0")
14378 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14379 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14380 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14381 [(set (attr "type")
14382 (cond [(match_operand:SF 3 "mult_operator" "")
14383 (const_string "fmul")
14384 (match_operand:SF 3 "div_operator" "")
14385 (const_string "fdiv")
14386 ]
14387 (const_string "fop")))
14388 (set_attr "fp_int_src" "true")
14389 (set_attr "mode" "<MODE>")])
14390
14391 (define_insn "*fop_df_comm_mixed"
14392 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14393 (match_operator:DF 3 "binary_fp_operator"
14394 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14395 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14396 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14397 && COMMUTATIVE_ARITH_P (operands[3])
14398 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14399 "* return output_387_binary_op (insn, operands);"
14400 [(set (attr "type")
14401 (if_then_else (eq_attr "alternative" "1")
14402 (if_then_else (match_operand:SF 3 "mult_operator" "")
14403 (const_string "ssemul")
14404 (const_string "sseadd"))
14405 (if_then_else (match_operand:SF 3 "mult_operator" "")
14406 (const_string "fmul")
14407 (const_string "fop"))))
14408 (set_attr "mode" "DF")])
14409
14410 (define_insn "*fop_df_comm_sse"
14411 [(set (match_operand:DF 0 "register_operand" "=Y")
14412 (match_operator:DF 3 "binary_fp_operator"
14413 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14414 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14415 "TARGET_SSE2 && TARGET_SSE_MATH
14416 && COMMUTATIVE_ARITH_P (operands[3])
14417 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14418 "* return output_387_binary_op (insn, operands);"
14419 [(set (attr "type")
14420 (if_then_else (match_operand:SF 3 "mult_operator" "")
14421 (const_string "ssemul")
14422 (const_string "sseadd")))
14423 (set_attr "mode" "DF")])
14424
14425 (define_insn "*fop_df_comm_i387"
14426 [(set (match_operand:DF 0 "register_operand" "=f")
14427 (match_operator:DF 3 "binary_fp_operator"
14428 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14429 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14430 "TARGET_80387
14431 && COMMUTATIVE_ARITH_P (operands[3])
14432 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14433 "* return output_387_binary_op (insn, operands);"
14434 [(set (attr "type")
14435 (if_then_else (match_operand:SF 3 "mult_operator" "")
14436 (const_string "fmul")
14437 (const_string "fop")))
14438 (set_attr "mode" "DF")])
14439
14440 (define_insn "*fop_df_1_mixed"
14441 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14442 (match_operator:DF 3 "binary_fp_operator"
14443 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14444 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14445 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14446 && !COMMUTATIVE_ARITH_P (operands[3])
14447 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14448 "* return output_387_binary_op (insn, operands);"
14449 [(set (attr "type")
14450 (cond [(and (eq_attr "alternative" "2")
14451 (match_operand:SF 3 "mult_operator" ""))
14452 (const_string "ssemul")
14453 (and (eq_attr "alternative" "2")
14454 (match_operand:SF 3 "div_operator" ""))
14455 (const_string "ssediv")
14456 (eq_attr "alternative" "2")
14457 (const_string "sseadd")
14458 (match_operand:DF 3 "mult_operator" "")
14459 (const_string "fmul")
14460 (match_operand:DF 3 "div_operator" "")
14461 (const_string "fdiv")
14462 ]
14463 (const_string "fop")))
14464 (set_attr "mode" "DF")])
14465
14466 (define_insn "*fop_df_1_sse"
14467 [(set (match_operand:DF 0 "register_operand" "=Y")
14468 (match_operator:DF 3 "binary_fp_operator"
14469 [(match_operand:DF 1 "register_operand" "0")
14470 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14471 "TARGET_SSE2 && TARGET_SSE_MATH
14472 && !COMMUTATIVE_ARITH_P (operands[3])"
14473 "* return output_387_binary_op (insn, operands);"
14474 [(set_attr "mode" "DF")
14475 (set (attr "type")
14476 (cond [(match_operand:SF 3 "mult_operator" "")
14477 (const_string "ssemul")
14478 (match_operand:SF 3 "div_operator" "")
14479 (const_string "ssediv")
14480 ]
14481 (const_string "sseadd")))])
14482
14483 ;; This pattern is not fully shadowed by the pattern above.
14484 (define_insn "*fop_df_1_i387"
14485 [(set (match_operand:DF 0 "register_operand" "=f,f")
14486 (match_operator:DF 3 "binary_fp_operator"
14487 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14488 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14489 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14490 && !COMMUTATIVE_ARITH_P (operands[3])
14491 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14492 "* return output_387_binary_op (insn, operands);"
14493 [(set (attr "type")
14494 (cond [(match_operand:DF 3 "mult_operator" "")
14495 (const_string "fmul")
14496 (match_operand:DF 3 "div_operator" "")
14497 (const_string "fdiv")
14498 ]
14499 (const_string "fop")))
14500 (set_attr "mode" "DF")])
14501
14502 ;; ??? Add SSE splitters for these!
14503 (define_insn "*fop_df_2<mode>_i387"
14504 [(set (match_operand:DF 0 "register_operand" "=f,f")
14505 (match_operator:DF 3 "binary_fp_operator"
14506 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14507 (match_operand:DF 2 "register_operand" "0,0")]))]
14508 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14509 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14510 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14511 [(set (attr "type")
14512 (cond [(match_operand:DF 3 "mult_operator" "")
14513 (const_string "fmul")
14514 (match_operand:DF 3 "div_operator" "")
14515 (const_string "fdiv")
14516 ]
14517 (const_string "fop")))
14518 (set_attr "fp_int_src" "true")
14519 (set_attr "mode" "<MODE>")])
14520
14521 (define_insn "*fop_df_3<mode>_i387"
14522 [(set (match_operand:DF 0 "register_operand" "=f,f")
14523 (match_operator:DF 3 "binary_fp_operator"
14524 [(match_operand:DF 1 "register_operand" "0,0")
14525 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14526 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14527 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14528 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14529 [(set (attr "type")
14530 (cond [(match_operand:DF 3 "mult_operator" "")
14531 (const_string "fmul")
14532 (match_operand:DF 3 "div_operator" "")
14533 (const_string "fdiv")
14534 ]
14535 (const_string "fop")))
14536 (set_attr "fp_int_src" "true")
14537 (set_attr "mode" "<MODE>")])
14538
14539 (define_insn "*fop_df_4_i387"
14540 [(set (match_operand:DF 0 "register_operand" "=f,f")
14541 (match_operator:DF 3 "binary_fp_operator"
14542 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14543 (match_operand:DF 2 "register_operand" "0,f")]))]
14544 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14545 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14546 "* return output_387_binary_op (insn, operands);"
14547 [(set (attr "type")
14548 (cond [(match_operand:DF 3 "mult_operator" "")
14549 (const_string "fmul")
14550 (match_operand:DF 3 "div_operator" "")
14551 (const_string "fdiv")
14552 ]
14553 (const_string "fop")))
14554 (set_attr "mode" "SF")])
14555
14556 (define_insn "*fop_df_5_i387"
14557 [(set (match_operand:DF 0 "register_operand" "=f,f")
14558 (match_operator:DF 3 "binary_fp_operator"
14559 [(match_operand:DF 1 "register_operand" "0,f")
14560 (float_extend:DF
14561 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14562 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14563 "* return output_387_binary_op (insn, operands);"
14564 [(set (attr "type")
14565 (cond [(match_operand:DF 3 "mult_operator" "")
14566 (const_string "fmul")
14567 (match_operand:DF 3 "div_operator" "")
14568 (const_string "fdiv")
14569 ]
14570 (const_string "fop")))
14571 (set_attr "mode" "SF")])
14572
14573 (define_insn "*fop_df_6_i387"
14574 [(set (match_operand:DF 0 "register_operand" "=f,f")
14575 (match_operator:DF 3 "binary_fp_operator"
14576 [(float_extend:DF
14577 (match_operand:SF 1 "register_operand" "0,f"))
14578 (float_extend:DF
14579 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14580 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14581 "* return output_387_binary_op (insn, operands);"
14582 [(set (attr "type")
14583 (cond [(match_operand:DF 3 "mult_operator" "")
14584 (const_string "fmul")
14585 (match_operand:DF 3 "div_operator" "")
14586 (const_string "fdiv")
14587 ]
14588 (const_string "fop")))
14589 (set_attr "mode" "SF")])
14590
14591 (define_insn "*fop_xf_comm_i387"
14592 [(set (match_operand:XF 0 "register_operand" "=f")
14593 (match_operator:XF 3 "binary_fp_operator"
14594 [(match_operand:XF 1 "register_operand" "%0")
14595 (match_operand:XF 2 "register_operand" "f")]))]
14596 "TARGET_80387
14597 && COMMUTATIVE_ARITH_P (operands[3])"
14598 "* return output_387_binary_op (insn, operands);"
14599 [(set (attr "type")
14600 (if_then_else (match_operand:XF 3 "mult_operator" "")
14601 (const_string "fmul")
14602 (const_string "fop")))
14603 (set_attr "mode" "XF")])
14604
14605 (define_insn "*fop_xf_1_i387"
14606 [(set (match_operand:XF 0 "register_operand" "=f,f")
14607 (match_operator:XF 3 "binary_fp_operator"
14608 [(match_operand:XF 1 "register_operand" "0,f")
14609 (match_operand:XF 2 "register_operand" "f,0")]))]
14610 "TARGET_80387
14611 && !COMMUTATIVE_ARITH_P (operands[3])"
14612 "* return output_387_binary_op (insn, operands);"
14613 [(set (attr "type")
14614 (cond [(match_operand:XF 3 "mult_operator" "")
14615 (const_string "fmul")
14616 (match_operand:XF 3 "div_operator" "")
14617 (const_string "fdiv")
14618 ]
14619 (const_string "fop")))
14620 (set_attr "mode" "XF")])
14621
14622 (define_insn "*fop_xf_2<mode>_i387"
14623 [(set (match_operand:XF 0 "register_operand" "=f,f")
14624 (match_operator:XF 3 "binary_fp_operator"
14625 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14626 (match_operand:XF 2 "register_operand" "0,0")]))]
14627 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14628 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14629 [(set (attr "type")
14630 (cond [(match_operand:XF 3 "mult_operator" "")
14631 (const_string "fmul")
14632 (match_operand:XF 3 "div_operator" "")
14633 (const_string "fdiv")
14634 ]
14635 (const_string "fop")))
14636 (set_attr "fp_int_src" "true")
14637 (set_attr "mode" "<MODE>")])
14638
14639 (define_insn "*fop_xf_3<mode>_i387"
14640 [(set (match_operand:XF 0 "register_operand" "=f,f")
14641 (match_operator:XF 3 "binary_fp_operator"
14642 [(match_operand:XF 1 "register_operand" "0,0")
14643 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14644 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14645 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14646 [(set (attr "type")
14647 (cond [(match_operand:XF 3 "mult_operator" "")
14648 (const_string "fmul")
14649 (match_operand:XF 3 "div_operator" "")
14650 (const_string "fdiv")
14651 ]
14652 (const_string "fop")))
14653 (set_attr "fp_int_src" "true")
14654 (set_attr "mode" "<MODE>")])
14655
14656 (define_insn "*fop_xf_4_i387"
14657 [(set (match_operand:XF 0 "register_operand" "=f,f")
14658 (match_operator:XF 3 "binary_fp_operator"
14659 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14660 (match_operand:XF 2 "register_operand" "0,f")]))]
14661 "TARGET_80387"
14662 "* return output_387_binary_op (insn, operands);"
14663 [(set (attr "type")
14664 (cond [(match_operand:XF 3 "mult_operator" "")
14665 (const_string "fmul")
14666 (match_operand:XF 3 "div_operator" "")
14667 (const_string "fdiv")
14668 ]
14669 (const_string "fop")))
14670 (set_attr "mode" "SF")])
14671
14672 (define_insn "*fop_xf_5_i387"
14673 [(set (match_operand:XF 0 "register_operand" "=f,f")
14674 (match_operator:XF 3 "binary_fp_operator"
14675 [(match_operand:XF 1 "register_operand" "0,f")
14676 (float_extend:XF
14677 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14678 "TARGET_80387"
14679 "* return output_387_binary_op (insn, operands);"
14680 [(set (attr "type")
14681 (cond [(match_operand:XF 3 "mult_operator" "")
14682 (const_string "fmul")
14683 (match_operand:XF 3 "div_operator" "")
14684 (const_string "fdiv")
14685 ]
14686 (const_string "fop")))
14687 (set_attr "mode" "SF")])
14688
14689 (define_insn "*fop_xf_6_i387"
14690 [(set (match_operand:XF 0 "register_operand" "=f,f")
14691 (match_operator:XF 3 "binary_fp_operator"
14692 [(float_extend:XF
14693 (match_operand 1 "register_operand" "0,f"))
14694 (float_extend:XF
14695 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14696 "TARGET_80387"
14697 "* return output_387_binary_op (insn, operands);"
14698 [(set (attr "type")
14699 (cond [(match_operand:XF 3 "mult_operator" "")
14700 (const_string "fmul")
14701 (match_operand:XF 3 "div_operator" "")
14702 (const_string "fdiv")
14703 ]
14704 (const_string "fop")))
14705 (set_attr "mode" "SF")])
14706
14707 (define_split
14708 [(set (match_operand 0 "register_operand" "")
14709 (match_operator 3 "binary_fp_operator"
14710 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14711 (match_operand 2 "register_operand" "")]))]
14712 "TARGET_80387 && reload_completed
14713 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14714 [(const_int 0)]
14715 {
14716 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14717 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14718 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14719 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14720 GET_MODE (operands[3]),
14721 operands[4],
14722 operands[2])));
14723 ix86_free_from_memory (GET_MODE (operands[1]));
14724 DONE;
14725 })
14726
14727 (define_split
14728 [(set (match_operand 0 "register_operand" "")
14729 (match_operator 3 "binary_fp_operator"
14730 [(match_operand 1 "register_operand" "")
14731 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14732 "TARGET_80387 && reload_completed
14733 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14734 [(const_int 0)]
14735 {
14736 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14737 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14738 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14739 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14740 GET_MODE (operands[3]),
14741 operands[1],
14742 operands[4])));
14743 ix86_free_from_memory (GET_MODE (operands[2]));
14744 DONE;
14745 })
14746 \f
14747 ;; FPU special functions.
14748
14749 (define_expand "sqrtsf2"
14750 [(set (match_operand:SF 0 "register_operand" "")
14751 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14752 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14753 {
14754 if (!TARGET_SSE_MATH)
14755 operands[1] = force_reg (SFmode, operands[1]);
14756 })
14757
14758 (define_insn "*sqrtsf2_mixed"
14759 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14760 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14761 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14762 "@
14763 fsqrt
14764 sqrtss\t{%1, %0|%0, %1}"
14765 [(set_attr "type" "fpspc,sse")
14766 (set_attr "mode" "SF,SF")
14767 (set_attr "athlon_decode" "direct,*")])
14768
14769 (define_insn "*sqrtsf2_sse"
14770 [(set (match_operand:SF 0 "register_operand" "=x")
14771 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14772 "TARGET_SSE_MATH"
14773 "sqrtss\t{%1, %0|%0, %1}"
14774 [(set_attr "type" "sse")
14775 (set_attr "mode" "SF")
14776 (set_attr "athlon_decode" "*")])
14777
14778 (define_insn "*sqrtsf2_i387"
14779 [(set (match_operand:SF 0 "register_operand" "=f")
14780 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14781 "TARGET_USE_FANCY_MATH_387"
14782 "fsqrt"
14783 [(set_attr "type" "fpspc")
14784 (set_attr "mode" "SF")
14785 (set_attr "athlon_decode" "direct")])
14786
14787 (define_expand "sqrtdf2"
14788 [(set (match_operand:DF 0 "register_operand" "")
14789 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14790 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14791 {
14792 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14793 operands[1] = force_reg (DFmode, operands[1]);
14794 })
14795
14796 (define_insn "*sqrtdf2_mixed"
14797 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14798 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14799 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14800 "@
14801 fsqrt
14802 sqrtsd\t{%1, %0|%0, %1}"
14803 [(set_attr "type" "fpspc,sse")
14804 (set_attr "mode" "DF,DF")
14805 (set_attr "athlon_decode" "direct,*")])
14806
14807 (define_insn "*sqrtdf2_sse"
14808 [(set (match_operand:DF 0 "register_operand" "=Y")
14809 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14810 "TARGET_SSE2 && TARGET_SSE_MATH"
14811 "sqrtsd\t{%1, %0|%0, %1}"
14812 [(set_attr "type" "sse")
14813 (set_attr "mode" "DF")
14814 (set_attr "athlon_decode" "*")])
14815
14816 (define_insn "*sqrtdf2_i387"
14817 [(set (match_operand:DF 0 "register_operand" "=f")
14818 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14819 "TARGET_USE_FANCY_MATH_387"
14820 "fsqrt"
14821 [(set_attr "type" "fpspc")
14822 (set_attr "mode" "DF")
14823 (set_attr "athlon_decode" "direct")])
14824
14825 (define_insn "*sqrtextendsfdf2_i387"
14826 [(set (match_operand:DF 0 "register_operand" "=f")
14827 (sqrt:DF (float_extend:DF
14828 (match_operand:SF 1 "register_operand" "0"))))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14831 "fsqrt"
14832 [(set_attr "type" "fpspc")
14833 (set_attr "mode" "DF")
14834 (set_attr "athlon_decode" "direct")])
14835
14836 (define_insn "sqrtxf2"
14837 [(set (match_operand:XF 0 "register_operand" "=f")
14838 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14839 "TARGET_USE_FANCY_MATH_387
14840 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14841 "fsqrt"
14842 [(set_attr "type" "fpspc")
14843 (set_attr "mode" "XF")
14844 (set_attr "athlon_decode" "direct")])
14845
14846 (define_insn "*sqrtextendsfxf2_i387"
14847 [(set (match_operand:XF 0 "register_operand" "=f")
14848 (sqrt:XF (float_extend:XF
14849 (match_operand:SF 1 "register_operand" "0"))))]
14850 "TARGET_USE_FANCY_MATH_387"
14851 "fsqrt"
14852 [(set_attr "type" "fpspc")
14853 (set_attr "mode" "XF")
14854 (set_attr "athlon_decode" "direct")])
14855
14856 (define_insn "*sqrtextenddfxf2_i387"
14857 [(set (match_operand:XF 0 "register_operand" "=f")
14858 (sqrt:XF (float_extend:XF
14859 (match_operand:DF 1 "register_operand" "0"))))]
14860 "TARGET_USE_FANCY_MATH_387"
14861 "fsqrt"
14862 [(set_attr "type" "fpspc")
14863 (set_attr "mode" "XF")
14864 (set_attr "athlon_decode" "direct")])
14865
14866 (define_insn "fpremxf4"
14867 [(set (match_operand:XF 0 "register_operand" "=f")
14868 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14869 (match_operand:XF 3 "register_operand" "1")]
14870 UNSPEC_FPREM_F))
14871 (set (match_operand:XF 1 "register_operand" "=u")
14872 (unspec:XF [(match_dup 2) (match_dup 3)]
14873 UNSPEC_FPREM_U))
14874 (set (reg:CCFP FPSR_REG)
14875 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14876 "TARGET_USE_FANCY_MATH_387
14877 && flag_unsafe_math_optimizations"
14878 "fprem"
14879 [(set_attr "type" "fpspc")
14880 (set_attr "mode" "XF")])
14881
14882 (define_expand "fmodsf3"
14883 [(use (match_operand:SF 0 "register_operand" ""))
14884 (use (match_operand:SF 1 "register_operand" ""))
14885 (use (match_operand:SF 2 "register_operand" ""))]
14886 "TARGET_USE_FANCY_MATH_387
14887 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14888 && flag_unsafe_math_optimizations"
14889 {
14890 rtx label = gen_label_rtx ();
14891
14892 rtx op1 = gen_reg_rtx (XFmode);
14893 rtx op2 = gen_reg_rtx (XFmode);
14894
14895 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14896 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14897
14898 emit_label (label);
14899
14900 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14901 ix86_emit_fp_unordered_jump (label);
14902
14903 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14904 DONE;
14905 })
14906
14907 (define_expand "fmoddf3"
14908 [(use (match_operand:DF 0 "register_operand" ""))
14909 (use (match_operand:DF 1 "register_operand" ""))
14910 (use (match_operand:DF 2 "register_operand" ""))]
14911 "TARGET_USE_FANCY_MATH_387
14912 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14913 && flag_unsafe_math_optimizations"
14914 {
14915 rtx label = gen_label_rtx ();
14916
14917 rtx op1 = gen_reg_rtx (XFmode);
14918 rtx op2 = gen_reg_rtx (XFmode);
14919
14920 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14921 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14922
14923 emit_label (label);
14924
14925 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14926 ix86_emit_fp_unordered_jump (label);
14927
14928 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14929 DONE;
14930 })
14931
14932 (define_expand "fmodxf3"
14933 [(use (match_operand:XF 0 "register_operand" ""))
14934 (use (match_operand:XF 1 "register_operand" ""))
14935 (use (match_operand:XF 2 "register_operand" ""))]
14936 "TARGET_USE_FANCY_MATH_387
14937 && flag_unsafe_math_optimizations"
14938 {
14939 rtx label = gen_label_rtx ();
14940
14941 emit_label (label);
14942
14943 emit_insn (gen_fpremxf4 (operands[1], operands[2],
14944 operands[1], operands[2]));
14945 ix86_emit_fp_unordered_jump (label);
14946
14947 emit_move_insn (operands[0], operands[1]);
14948 DONE;
14949 })
14950
14951 (define_insn "fprem1xf4"
14952 [(set (match_operand:XF 0 "register_operand" "=f")
14953 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14954 (match_operand:XF 3 "register_operand" "1")]
14955 UNSPEC_FPREM1_F))
14956 (set (match_operand:XF 1 "register_operand" "=u")
14957 (unspec:XF [(match_dup 2) (match_dup 3)]
14958 UNSPEC_FPREM1_U))
14959 (set (reg:CCFP FPSR_REG)
14960 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14961 "TARGET_USE_FANCY_MATH_387
14962 && flag_unsafe_math_optimizations"
14963 "fprem1"
14964 [(set_attr "type" "fpspc")
14965 (set_attr "mode" "XF")])
14966
14967 (define_expand "dremsf3"
14968 [(use (match_operand:SF 0 "register_operand" ""))
14969 (use (match_operand:SF 1 "register_operand" ""))
14970 (use (match_operand:SF 2 "register_operand" ""))]
14971 "TARGET_USE_FANCY_MATH_387
14972 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14973 && flag_unsafe_math_optimizations"
14974 {
14975 rtx label = gen_label_rtx ();
14976
14977 rtx op1 = gen_reg_rtx (XFmode);
14978 rtx op2 = gen_reg_rtx (XFmode);
14979
14980 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14981 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14982
14983 emit_label (label);
14984
14985 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14986 ix86_emit_fp_unordered_jump (label);
14987
14988 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14989 DONE;
14990 })
14991
14992 (define_expand "dremdf3"
14993 [(use (match_operand:DF 0 "register_operand" ""))
14994 (use (match_operand:DF 1 "register_operand" ""))
14995 (use (match_operand:DF 2 "register_operand" ""))]
14996 "TARGET_USE_FANCY_MATH_387
14997 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14998 && flag_unsafe_math_optimizations"
14999 {
15000 rtx label = gen_label_rtx ();
15001
15002 rtx op1 = gen_reg_rtx (XFmode);
15003 rtx op2 = gen_reg_rtx (XFmode);
15004
15005 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15006 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15007
15008 emit_label (label);
15009
15010 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15011 ix86_emit_fp_unordered_jump (label);
15012
15013 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15014 DONE;
15015 })
15016
15017 (define_expand "dremxf3"
15018 [(use (match_operand:XF 0 "register_operand" ""))
15019 (use (match_operand:XF 1 "register_operand" ""))
15020 (use (match_operand:XF 2 "register_operand" ""))]
15021 "TARGET_USE_FANCY_MATH_387
15022 && flag_unsafe_math_optimizations"
15023 {
15024 rtx label = gen_label_rtx ();
15025
15026 emit_label (label);
15027
15028 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15029 operands[1], operands[2]));
15030 ix86_emit_fp_unordered_jump (label);
15031
15032 emit_move_insn (operands[0], operands[1]);
15033 DONE;
15034 })
15035
15036 (define_insn "*sindf2"
15037 [(set (match_operand:DF 0 "register_operand" "=f")
15038 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15039 "TARGET_USE_FANCY_MATH_387
15040 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15041 && flag_unsafe_math_optimizations"
15042 "fsin"
15043 [(set_attr "type" "fpspc")
15044 (set_attr "mode" "DF")])
15045
15046 (define_insn "*sinsf2"
15047 [(set (match_operand:SF 0 "register_operand" "=f")
15048 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15049 "TARGET_USE_FANCY_MATH_387
15050 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15051 && flag_unsafe_math_optimizations"
15052 "fsin"
15053 [(set_attr "type" "fpspc")
15054 (set_attr "mode" "SF")])
15055
15056 (define_insn "*sinextendsfdf2"
15057 [(set (match_operand:DF 0 "register_operand" "=f")
15058 (unspec:DF [(float_extend:DF
15059 (match_operand:SF 1 "register_operand" "0"))]
15060 UNSPEC_SIN))]
15061 "TARGET_USE_FANCY_MATH_387
15062 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15063 && flag_unsafe_math_optimizations"
15064 "fsin"
15065 [(set_attr "type" "fpspc")
15066 (set_attr "mode" "DF")])
15067
15068 (define_insn "*sinxf2"
15069 [(set (match_operand:XF 0 "register_operand" "=f")
15070 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15071 "TARGET_USE_FANCY_MATH_387
15072 && flag_unsafe_math_optimizations"
15073 "fsin"
15074 [(set_attr "type" "fpspc")
15075 (set_attr "mode" "XF")])
15076
15077 (define_insn "*cosdf2"
15078 [(set (match_operand:DF 0 "register_operand" "=f")
15079 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15080 "TARGET_USE_FANCY_MATH_387
15081 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15082 && flag_unsafe_math_optimizations"
15083 "fcos"
15084 [(set_attr "type" "fpspc")
15085 (set_attr "mode" "DF")])
15086
15087 (define_insn "*cossf2"
15088 [(set (match_operand:SF 0 "register_operand" "=f")
15089 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15090 "TARGET_USE_FANCY_MATH_387
15091 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15092 && flag_unsafe_math_optimizations"
15093 "fcos"
15094 [(set_attr "type" "fpspc")
15095 (set_attr "mode" "SF")])
15096
15097 (define_insn "*cosextendsfdf2"
15098 [(set (match_operand:DF 0 "register_operand" "=f")
15099 (unspec:DF [(float_extend:DF
15100 (match_operand:SF 1 "register_operand" "0"))]
15101 UNSPEC_COS))]
15102 "TARGET_USE_FANCY_MATH_387
15103 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15104 && flag_unsafe_math_optimizations"
15105 "fcos"
15106 [(set_attr "type" "fpspc")
15107 (set_attr "mode" "DF")])
15108
15109 (define_insn "*cosxf2"
15110 [(set (match_operand:XF 0 "register_operand" "=f")
15111 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15112 "TARGET_USE_FANCY_MATH_387
15113 && flag_unsafe_math_optimizations"
15114 "fcos"
15115 [(set_attr "type" "fpspc")
15116 (set_attr "mode" "XF")])
15117
15118 ;; With sincos pattern defined, sin and cos builtin function will be
15119 ;; expanded to sincos pattern with one of its outputs left unused.
15120 ;; Cse pass will detected, if two sincos patterns can be combined,
15121 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15122 ;; depending on the unused output.
15123
15124 (define_insn "sincosdf3"
15125 [(set (match_operand:DF 0 "register_operand" "=f")
15126 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15127 UNSPEC_SINCOS_COS))
15128 (set (match_operand:DF 1 "register_operand" "=u")
15129 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15130 "TARGET_USE_FANCY_MATH_387
15131 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15132 && flag_unsafe_math_optimizations"
15133 "fsincos"
15134 [(set_attr "type" "fpspc")
15135 (set_attr "mode" "DF")])
15136
15137 (define_split
15138 [(set (match_operand:DF 0 "register_operand" "")
15139 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15140 UNSPEC_SINCOS_COS))
15141 (set (match_operand:DF 1 "register_operand" "")
15142 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15143 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15144 && !reload_completed && !reload_in_progress"
15145 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15146 "")
15147
15148 (define_split
15149 [(set (match_operand:DF 0 "register_operand" "")
15150 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15151 UNSPEC_SINCOS_COS))
15152 (set (match_operand:DF 1 "register_operand" "")
15153 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15154 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15155 && !reload_completed && !reload_in_progress"
15156 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15157 "")
15158
15159 (define_insn "sincossf3"
15160 [(set (match_operand:SF 0 "register_operand" "=f")
15161 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15162 UNSPEC_SINCOS_COS))
15163 (set (match_operand:SF 1 "register_operand" "=u")
15164 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15165 "TARGET_USE_FANCY_MATH_387
15166 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15167 && flag_unsafe_math_optimizations"
15168 "fsincos"
15169 [(set_attr "type" "fpspc")
15170 (set_attr "mode" "SF")])
15171
15172 (define_split
15173 [(set (match_operand:SF 0 "register_operand" "")
15174 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15175 UNSPEC_SINCOS_COS))
15176 (set (match_operand:SF 1 "register_operand" "")
15177 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15178 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15179 && !reload_completed && !reload_in_progress"
15180 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15181 "")
15182
15183 (define_split
15184 [(set (match_operand:SF 0 "register_operand" "")
15185 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15186 UNSPEC_SINCOS_COS))
15187 (set (match_operand:SF 1 "register_operand" "")
15188 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15189 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15190 && !reload_completed && !reload_in_progress"
15191 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15192 "")
15193
15194 (define_insn "*sincosextendsfdf3"
15195 [(set (match_operand:DF 0 "register_operand" "=f")
15196 (unspec:DF [(float_extend:DF
15197 (match_operand:SF 2 "register_operand" "0"))]
15198 UNSPEC_SINCOS_COS))
15199 (set (match_operand:DF 1 "register_operand" "=u")
15200 (unspec:DF [(float_extend:DF
15201 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15202 "TARGET_USE_FANCY_MATH_387
15203 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15204 && flag_unsafe_math_optimizations"
15205 "fsincos"
15206 [(set_attr "type" "fpspc")
15207 (set_attr "mode" "DF")])
15208
15209 (define_split
15210 [(set (match_operand:DF 0 "register_operand" "")
15211 (unspec:DF [(float_extend:DF
15212 (match_operand:SF 2 "register_operand" ""))]
15213 UNSPEC_SINCOS_COS))
15214 (set (match_operand:DF 1 "register_operand" "")
15215 (unspec:DF [(float_extend:DF
15216 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15217 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15218 && !reload_completed && !reload_in_progress"
15219 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15220 (match_dup 2))] UNSPEC_SIN))]
15221 "")
15222
15223 (define_split
15224 [(set (match_operand:DF 0 "register_operand" "")
15225 (unspec:DF [(float_extend:DF
15226 (match_operand:SF 2 "register_operand" ""))]
15227 UNSPEC_SINCOS_COS))
15228 (set (match_operand:DF 1 "register_operand" "")
15229 (unspec:DF [(float_extend:DF
15230 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15231 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15232 && !reload_completed && !reload_in_progress"
15233 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15234 (match_dup 2))] UNSPEC_COS))]
15235 "")
15236
15237 (define_insn "sincosxf3"
15238 [(set (match_operand:XF 0 "register_operand" "=f")
15239 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15240 UNSPEC_SINCOS_COS))
15241 (set (match_operand:XF 1 "register_operand" "=u")
15242 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15243 "TARGET_USE_FANCY_MATH_387
15244 && flag_unsafe_math_optimizations"
15245 "fsincos"
15246 [(set_attr "type" "fpspc")
15247 (set_attr "mode" "XF")])
15248
15249 (define_split
15250 [(set (match_operand:XF 0 "register_operand" "")
15251 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15252 UNSPEC_SINCOS_COS))
15253 (set (match_operand:XF 1 "register_operand" "")
15254 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15255 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15256 && !reload_completed && !reload_in_progress"
15257 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15258 "")
15259
15260 (define_split
15261 [(set (match_operand:XF 0 "register_operand" "")
15262 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15263 UNSPEC_SINCOS_COS))
15264 (set (match_operand:XF 1 "register_operand" "")
15265 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15266 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15267 && !reload_completed && !reload_in_progress"
15268 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15269 "")
15270
15271 (define_insn "*tandf3_1"
15272 [(set (match_operand:DF 0 "register_operand" "=f")
15273 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15274 UNSPEC_TAN_ONE))
15275 (set (match_operand:DF 1 "register_operand" "=u")
15276 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15277 "TARGET_USE_FANCY_MATH_387
15278 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15279 && flag_unsafe_math_optimizations"
15280 "fptan"
15281 [(set_attr "type" "fpspc")
15282 (set_attr "mode" "DF")])
15283
15284 ;; optimize sequence: fptan
15285 ;; fstp %st(0)
15286 ;; fld1
15287 ;; into fptan insn.
15288
15289 (define_peephole2
15290 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15291 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15292 UNSPEC_TAN_ONE))
15293 (set (match_operand:DF 1 "register_operand" "")
15294 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15295 (set (match_dup 0)
15296 (match_operand:DF 3 "immediate_operand" ""))]
15297 "standard_80387_constant_p (operands[3]) == 2"
15298 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15299 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15300 "")
15301
15302 (define_expand "tandf2"
15303 [(parallel [(set (match_dup 2)
15304 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15305 UNSPEC_TAN_ONE))
15306 (set (match_operand:DF 0 "register_operand" "")
15307 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15308 "TARGET_USE_FANCY_MATH_387
15309 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15310 && flag_unsafe_math_optimizations"
15311 {
15312 operands[2] = gen_reg_rtx (DFmode);
15313 })
15314
15315 (define_insn "*tansf3_1"
15316 [(set (match_operand:SF 0 "register_operand" "=f")
15317 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15318 UNSPEC_TAN_ONE))
15319 (set (match_operand:SF 1 "register_operand" "=u")
15320 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15321 "TARGET_USE_FANCY_MATH_387
15322 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15323 && flag_unsafe_math_optimizations"
15324 "fptan"
15325 [(set_attr "type" "fpspc")
15326 (set_attr "mode" "SF")])
15327
15328 ;; optimize sequence: fptan
15329 ;; fstp %st(0)
15330 ;; fld1
15331 ;; into fptan insn.
15332
15333 (define_peephole2
15334 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15335 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15336 UNSPEC_TAN_ONE))
15337 (set (match_operand:SF 1 "register_operand" "")
15338 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15339 (set (match_dup 0)
15340 (match_operand:SF 3 "immediate_operand" ""))]
15341 "standard_80387_constant_p (operands[3]) == 2"
15342 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15343 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15344 "")
15345
15346 (define_expand "tansf2"
15347 [(parallel [(set (match_dup 2)
15348 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15349 UNSPEC_TAN_ONE))
15350 (set (match_operand:SF 0 "register_operand" "")
15351 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15352 "TARGET_USE_FANCY_MATH_387
15353 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15354 && flag_unsafe_math_optimizations"
15355 {
15356 operands[2] = gen_reg_rtx (SFmode);
15357 })
15358
15359 (define_insn "*tanxf3_1"
15360 [(set (match_operand:XF 0 "register_operand" "=f")
15361 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15362 UNSPEC_TAN_ONE))
15363 (set (match_operand:XF 1 "register_operand" "=u")
15364 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15365 "TARGET_USE_FANCY_MATH_387
15366 && flag_unsafe_math_optimizations"
15367 "fptan"
15368 [(set_attr "type" "fpspc")
15369 (set_attr "mode" "XF")])
15370
15371 ;; optimize sequence: fptan
15372 ;; fstp %st(0)
15373 ;; fld1
15374 ;; into fptan insn.
15375
15376 (define_peephole2
15377 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15378 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15379 UNSPEC_TAN_ONE))
15380 (set (match_operand:XF 1 "register_operand" "")
15381 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15382 (set (match_dup 0)
15383 (match_operand:XF 3 "immediate_operand" ""))]
15384 "standard_80387_constant_p (operands[3]) == 2"
15385 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15386 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15387 "")
15388
15389 (define_expand "tanxf2"
15390 [(parallel [(set (match_dup 2)
15391 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15392 UNSPEC_TAN_ONE))
15393 (set (match_operand:XF 0 "register_operand" "")
15394 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15395 "TARGET_USE_FANCY_MATH_387
15396 && flag_unsafe_math_optimizations"
15397 {
15398 operands[2] = gen_reg_rtx (XFmode);
15399 })
15400
15401 (define_insn "atan2df3_1"
15402 [(set (match_operand:DF 0 "register_operand" "=f")
15403 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15404 (match_operand:DF 1 "register_operand" "u")]
15405 UNSPEC_FPATAN))
15406 (clobber (match_scratch:DF 3 "=1"))]
15407 "TARGET_USE_FANCY_MATH_387
15408 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15409 && flag_unsafe_math_optimizations"
15410 "fpatan"
15411 [(set_attr "type" "fpspc")
15412 (set_attr "mode" "DF")])
15413
15414 (define_expand "atan2df3"
15415 [(use (match_operand:DF 0 "register_operand" ""))
15416 (use (match_operand:DF 2 "register_operand" ""))
15417 (use (match_operand:DF 1 "register_operand" ""))]
15418 "TARGET_USE_FANCY_MATH_387
15419 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15420 && flag_unsafe_math_optimizations"
15421 {
15422 rtx copy = gen_reg_rtx (DFmode);
15423 emit_move_insn (copy, operands[1]);
15424 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15425 DONE;
15426 })
15427
15428 (define_expand "atandf2"
15429 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15430 (unspec:DF [(match_dup 2)
15431 (match_operand:DF 1 "register_operand" "")]
15432 UNSPEC_FPATAN))
15433 (clobber (match_scratch:DF 3 ""))])]
15434 "TARGET_USE_FANCY_MATH_387
15435 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15436 && flag_unsafe_math_optimizations"
15437 {
15438 operands[2] = gen_reg_rtx (DFmode);
15439 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15440 })
15441
15442 (define_insn "atan2sf3_1"
15443 [(set (match_operand:SF 0 "register_operand" "=f")
15444 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15445 (match_operand:SF 1 "register_operand" "u")]
15446 UNSPEC_FPATAN))
15447 (clobber (match_scratch:SF 3 "=1"))]
15448 "TARGET_USE_FANCY_MATH_387
15449 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15450 && flag_unsafe_math_optimizations"
15451 "fpatan"
15452 [(set_attr "type" "fpspc")
15453 (set_attr "mode" "SF")])
15454
15455 (define_expand "atan2sf3"
15456 [(use (match_operand:SF 0 "register_operand" ""))
15457 (use (match_operand:SF 2 "register_operand" ""))
15458 (use (match_operand:SF 1 "register_operand" ""))]
15459 "TARGET_USE_FANCY_MATH_387
15460 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15461 && flag_unsafe_math_optimizations"
15462 {
15463 rtx copy = gen_reg_rtx (SFmode);
15464 emit_move_insn (copy, operands[1]);
15465 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15466 DONE;
15467 })
15468
15469 (define_expand "atansf2"
15470 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15471 (unspec:SF [(match_dup 2)
15472 (match_operand:SF 1 "register_operand" "")]
15473 UNSPEC_FPATAN))
15474 (clobber (match_scratch:SF 3 ""))])]
15475 "TARGET_USE_FANCY_MATH_387
15476 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15477 && flag_unsafe_math_optimizations"
15478 {
15479 operands[2] = gen_reg_rtx (SFmode);
15480 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15481 })
15482
15483 (define_insn "atan2xf3_1"
15484 [(set (match_operand:XF 0 "register_operand" "=f")
15485 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15486 (match_operand:XF 1 "register_operand" "u")]
15487 UNSPEC_FPATAN))
15488 (clobber (match_scratch:XF 3 "=1"))]
15489 "TARGET_USE_FANCY_MATH_387
15490 && flag_unsafe_math_optimizations"
15491 "fpatan"
15492 [(set_attr "type" "fpspc")
15493 (set_attr "mode" "XF")])
15494
15495 (define_expand "atan2xf3"
15496 [(use (match_operand:XF 0 "register_operand" ""))
15497 (use (match_operand:XF 2 "register_operand" ""))
15498 (use (match_operand:XF 1 "register_operand" ""))]
15499 "TARGET_USE_FANCY_MATH_387
15500 && flag_unsafe_math_optimizations"
15501 {
15502 rtx copy = gen_reg_rtx (XFmode);
15503 emit_move_insn (copy, operands[1]);
15504 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15505 DONE;
15506 })
15507
15508 (define_expand "atanxf2"
15509 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15510 (unspec:XF [(match_dup 2)
15511 (match_operand:XF 1 "register_operand" "")]
15512 UNSPEC_FPATAN))
15513 (clobber (match_scratch:XF 3 ""))])]
15514 "TARGET_USE_FANCY_MATH_387
15515 && flag_unsafe_math_optimizations"
15516 {
15517 operands[2] = gen_reg_rtx (XFmode);
15518 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15519 })
15520
15521 (define_expand "asindf2"
15522 [(set (match_dup 2)
15523 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15524 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15525 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15526 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15527 (parallel [(set (match_dup 7)
15528 (unspec:XF [(match_dup 6) (match_dup 2)]
15529 UNSPEC_FPATAN))
15530 (clobber (match_scratch:XF 8 ""))])
15531 (set (match_operand:DF 0 "register_operand" "")
15532 (float_truncate:DF (match_dup 7)))]
15533 "TARGET_USE_FANCY_MATH_387
15534 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15535 && flag_unsafe_math_optimizations"
15536 {
15537 int i;
15538
15539 for (i=2; i<8; i++)
15540 operands[i] = gen_reg_rtx (XFmode);
15541
15542 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15543 })
15544
15545 (define_expand "asinsf2"
15546 [(set (match_dup 2)
15547 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15548 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15549 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15550 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15551 (parallel [(set (match_dup 7)
15552 (unspec:XF [(match_dup 6) (match_dup 2)]
15553 UNSPEC_FPATAN))
15554 (clobber (match_scratch:XF 8 ""))])
15555 (set (match_operand:SF 0 "register_operand" "")
15556 (float_truncate:SF (match_dup 7)))]
15557 "TARGET_USE_FANCY_MATH_387
15558 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15559 && flag_unsafe_math_optimizations"
15560 {
15561 int i;
15562
15563 for (i=2; i<8; i++)
15564 operands[i] = gen_reg_rtx (XFmode);
15565
15566 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15567 })
15568
15569 (define_expand "asinxf2"
15570 [(set (match_dup 2)
15571 (mult:XF (match_operand:XF 1 "register_operand" "")
15572 (match_dup 1)))
15573 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15574 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15575 (parallel [(set (match_operand:XF 0 "register_operand" "")
15576 (unspec:XF [(match_dup 5) (match_dup 1)]
15577 UNSPEC_FPATAN))
15578 (clobber (match_scratch:XF 6 ""))])]
15579 "TARGET_USE_FANCY_MATH_387
15580 && flag_unsafe_math_optimizations"
15581 {
15582 int i;
15583
15584 for (i=2; i<6; i++)
15585 operands[i] = gen_reg_rtx (XFmode);
15586
15587 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15588 })
15589
15590 (define_expand "acosdf2"
15591 [(set (match_dup 2)
15592 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15593 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15594 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15595 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15596 (parallel [(set (match_dup 7)
15597 (unspec:XF [(match_dup 2) (match_dup 6)]
15598 UNSPEC_FPATAN))
15599 (clobber (match_scratch:XF 8 ""))])
15600 (set (match_operand:DF 0 "register_operand" "")
15601 (float_truncate:DF (match_dup 7)))]
15602 "TARGET_USE_FANCY_MATH_387
15603 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15604 && flag_unsafe_math_optimizations"
15605 {
15606 int i;
15607
15608 for (i=2; i<8; i++)
15609 operands[i] = gen_reg_rtx (XFmode);
15610
15611 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15612 })
15613
15614 (define_expand "acossf2"
15615 [(set (match_dup 2)
15616 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15617 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15618 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15619 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15620 (parallel [(set (match_dup 7)
15621 (unspec:XF [(match_dup 2) (match_dup 6)]
15622 UNSPEC_FPATAN))
15623 (clobber (match_scratch:XF 8 ""))])
15624 (set (match_operand:SF 0 "register_operand" "")
15625 (float_truncate:SF (match_dup 7)))]
15626 "TARGET_USE_FANCY_MATH_387
15627 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15628 && flag_unsafe_math_optimizations"
15629 {
15630 int i;
15631
15632 for (i=2; i<8; i++)
15633 operands[i] = gen_reg_rtx (XFmode);
15634
15635 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15636 })
15637
15638 (define_expand "acosxf2"
15639 [(set (match_dup 2)
15640 (mult:XF (match_operand:XF 1 "register_operand" "")
15641 (match_dup 1)))
15642 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15643 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15644 (parallel [(set (match_operand:XF 0 "register_operand" "")
15645 (unspec:XF [(match_dup 1) (match_dup 5)]
15646 UNSPEC_FPATAN))
15647 (clobber (match_scratch:XF 6 ""))])]
15648 "TARGET_USE_FANCY_MATH_387
15649 && flag_unsafe_math_optimizations"
15650 {
15651 int i;
15652
15653 for (i=2; i<6; i++)
15654 operands[i] = gen_reg_rtx (XFmode);
15655
15656 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15657 })
15658
15659 (define_insn "fyl2x_xf3"
15660 [(set (match_operand:XF 0 "register_operand" "=f")
15661 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15662 (match_operand:XF 1 "register_operand" "u")]
15663 UNSPEC_FYL2X))
15664 (clobber (match_scratch:XF 3 "=1"))]
15665 "TARGET_USE_FANCY_MATH_387
15666 && flag_unsafe_math_optimizations"
15667 "fyl2x"
15668 [(set_attr "type" "fpspc")
15669 (set_attr "mode" "XF")])
15670
15671 (define_expand "logsf2"
15672 [(set (match_dup 2)
15673 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15674 (parallel [(set (match_dup 4)
15675 (unspec:XF [(match_dup 2)
15676 (match_dup 3)] UNSPEC_FYL2X))
15677 (clobber (match_scratch:XF 5 ""))])
15678 (set (match_operand:SF 0 "register_operand" "")
15679 (float_truncate:SF (match_dup 4)))]
15680 "TARGET_USE_FANCY_MATH_387
15681 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15682 && flag_unsafe_math_optimizations"
15683 {
15684 rtx temp;
15685
15686 operands[2] = gen_reg_rtx (XFmode);
15687 operands[3] = gen_reg_rtx (XFmode);
15688 operands[4] = gen_reg_rtx (XFmode);
15689
15690 temp = standard_80387_constant_rtx (4); /* fldln2 */
15691 emit_move_insn (operands[3], temp);
15692 })
15693
15694 (define_expand "logdf2"
15695 [(set (match_dup 2)
15696 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15697 (parallel [(set (match_dup 4)
15698 (unspec:XF [(match_dup 2)
15699 (match_dup 3)] UNSPEC_FYL2X))
15700 (clobber (match_scratch:XF 5 ""))])
15701 (set (match_operand:DF 0 "register_operand" "")
15702 (float_truncate:DF (match_dup 4)))]
15703 "TARGET_USE_FANCY_MATH_387
15704 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15705 && flag_unsafe_math_optimizations"
15706 {
15707 rtx temp;
15708
15709 operands[2] = gen_reg_rtx (XFmode);
15710 operands[3] = gen_reg_rtx (XFmode);
15711 operands[4] = gen_reg_rtx (XFmode);
15712
15713 temp = standard_80387_constant_rtx (4); /* fldln2 */
15714 emit_move_insn (operands[3], temp);
15715 })
15716
15717 (define_expand "logxf2"
15718 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15719 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15720 (match_dup 2)] UNSPEC_FYL2X))
15721 (clobber (match_scratch:XF 3 ""))])]
15722 "TARGET_USE_FANCY_MATH_387
15723 && flag_unsafe_math_optimizations"
15724 {
15725 rtx temp;
15726
15727 operands[2] = gen_reg_rtx (XFmode);
15728 temp = standard_80387_constant_rtx (4); /* fldln2 */
15729 emit_move_insn (operands[2], temp);
15730 })
15731
15732 (define_expand "log10sf2"
15733 [(set (match_dup 2)
15734 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15735 (parallel [(set (match_dup 4)
15736 (unspec:XF [(match_dup 2)
15737 (match_dup 3)] UNSPEC_FYL2X))
15738 (clobber (match_scratch:XF 5 ""))])
15739 (set (match_operand:SF 0 "register_operand" "")
15740 (float_truncate:SF (match_dup 4)))]
15741 "TARGET_USE_FANCY_MATH_387
15742 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15743 && flag_unsafe_math_optimizations"
15744 {
15745 rtx temp;
15746
15747 operands[2] = gen_reg_rtx (XFmode);
15748 operands[3] = gen_reg_rtx (XFmode);
15749 operands[4] = gen_reg_rtx (XFmode);
15750
15751 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15752 emit_move_insn (operands[3], temp);
15753 })
15754
15755 (define_expand "log10df2"
15756 [(set (match_dup 2)
15757 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15758 (parallel [(set (match_dup 4)
15759 (unspec:XF [(match_dup 2)
15760 (match_dup 3)] UNSPEC_FYL2X))
15761 (clobber (match_scratch:XF 5 ""))])
15762 (set (match_operand:DF 0 "register_operand" "")
15763 (float_truncate:DF (match_dup 4)))]
15764 "TARGET_USE_FANCY_MATH_387
15765 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15766 && flag_unsafe_math_optimizations"
15767 {
15768 rtx temp;
15769
15770 operands[2] = gen_reg_rtx (XFmode);
15771 operands[3] = gen_reg_rtx (XFmode);
15772 operands[4] = gen_reg_rtx (XFmode);
15773
15774 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15775 emit_move_insn (operands[3], temp);
15776 })
15777
15778 (define_expand "log10xf2"
15779 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15780 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15781 (match_dup 2)] UNSPEC_FYL2X))
15782 (clobber (match_scratch:XF 3 ""))])]
15783 "TARGET_USE_FANCY_MATH_387
15784 && flag_unsafe_math_optimizations"
15785 {
15786 rtx temp;
15787
15788 operands[2] = gen_reg_rtx (XFmode);
15789 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15790 emit_move_insn (operands[2], temp);
15791 })
15792
15793 (define_expand "log2sf2"
15794 [(set (match_dup 2)
15795 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15796 (parallel [(set (match_dup 4)
15797 (unspec:XF [(match_dup 2)
15798 (match_dup 3)] UNSPEC_FYL2X))
15799 (clobber (match_scratch:XF 5 ""))])
15800 (set (match_operand:SF 0 "register_operand" "")
15801 (float_truncate:SF (match_dup 4)))]
15802 "TARGET_USE_FANCY_MATH_387
15803 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15804 && flag_unsafe_math_optimizations"
15805 {
15806 operands[2] = gen_reg_rtx (XFmode);
15807 operands[3] = gen_reg_rtx (XFmode);
15808 operands[4] = gen_reg_rtx (XFmode);
15809
15810 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15811 })
15812
15813 (define_expand "log2df2"
15814 [(set (match_dup 2)
15815 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15816 (parallel [(set (match_dup 4)
15817 (unspec:XF [(match_dup 2)
15818 (match_dup 3)] UNSPEC_FYL2X))
15819 (clobber (match_scratch:XF 5 ""))])
15820 (set (match_operand:DF 0 "register_operand" "")
15821 (float_truncate:DF (match_dup 4)))]
15822 "TARGET_USE_FANCY_MATH_387
15823 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15824 && flag_unsafe_math_optimizations"
15825 {
15826 operands[2] = gen_reg_rtx (XFmode);
15827 operands[3] = gen_reg_rtx (XFmode);
15828 operands[4] = gen_reg_rtx (XFmode);
15829
15830 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15831 })
15832
15833 (define_expand "log2xf2"
15834 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15835 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15836 (match_dup 2)] UNSPEC_FYL2X))
15837 (clobber (match_scratch:XF 3 ""))])]
15838 "TARGET_USE_FANCY_MATH_387
15839 && flag_unsafe_math_optimizations"
15840 {
15841 operands[2] = gen_reg_rtx (XFmode);
15842 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15843 })
15844
15845 (define_insn "fyl2xp1_xf3"
15846 [(set (match_operand:XF 0 "register_operand" "=f")
15847 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15848 (match_operand:XF 1 "register_operand" "u")]
15849 UNSPEC_FYL2XP1))
15850 (clobber (match_scratch:XF 3 "=1"))]
15851 "TARGET_USE_FANCY_MATH_387
15852 && flag_unsafe_math_optimizations"
15853 "fyl2xp1"
15854 [(set_attr "type" "fpspc")
15855 (set_attr "mode" "XF")])
15856
15857 (define_expand "log1psf2"
15858 [(use (match_operand:SF 0 "register_operand" ""))
15859 (use (match_operand:SF 1 "register_operand" ""))]
15860 "TARGET_USE_FANCY_MATH_387
15861 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15862 && flag_unsafe_math_optimizations"
15863 {
15864 rtx op0 = gen_reg_rtx (XFmode);
15865 rtx op1 = gen_reg_rtx (XFmode);
15866
15867 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15868 ix86_emit_i387_log1p (op0, op1);
15869 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15870 DONE;
15871 })
15872
15873 (define_expand "log1pdf2"
15874 [(use (match_operand:DF 0 "register_operand" ""))
15875 (use (match_operand:DF 1 "register_operand" ""))]
15876 "TARGET_USE_FANCY_MATH_387
15877 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15878 && flag_unsafe_math_optimizations"
15879 {
15880 rtx op0 = gen_reg_rtx (XFmode);
15881 rtx op1 = gen_reg_rtx (XFmode);
15882
15883 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15884 ix86_emit_i387_log1p (op0, op1);
15885 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15886 DONE;
15887 })
15888
15889 (define_expand "log1pxf2"
15890 [(use (match_operand:XF 0 "register_operand" ""))
15891 (use (match_operand:XF 1 "register_operand" ""))]
15892 "TARGET_USE_FANCY_MATH_387
15893 && flag_unsafe_math_optimizations"
15894 {
15895 ix86_emit_i387_log1p (operands[0], operands[1]);
15896 DONE;
15897 })
15898
15899 (define_insn "*fxtractxf3"
15900 [(set (match_operand:XF 0 "register_operand" "=f")
15901 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15902 UNSPEC_XTRACT_FRACT))
15903 (set (match_operand:XF 1 "register_operand" "=u")
15904 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15905 "TARGET_USE_FANCY_MATH_387
15906 && flag_unsafe_math_optimizations"
15907 "fxtract"
15908 [(set_attr "type" "fpspc")
15909 (set_attr "mode" "XF")])
15910
15911 (define_expand "logbsf2"
15912 [(set (match_dup 2)
15913 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15914 (parallel [(set (match_dup 3)
15915 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15916 (set (match_dup 4)
15917 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15918 (set (match_operand:SF 0 "register_operand" "")
15919 (float_truncate:SF (match_dup 4)))]
15920 "TARGET_USE_FANCY_MATH_387
15921 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15922 && flag_unsafe_math_optimizations"
15923 {
15924 operands[2] = gen_reg_rtx (XFmode);
15925 operands[3] = gen_reg_rtx (XFmode);
15926 operands[4] = gen_reg_rtx (XFmode);
15927 })
15928
15929 (define_expand "logbdf2"
15930 [(set (match_dup 2)
15931 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15932 (parallel [(set (match_dup 3)
15933 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15934 (set (match_dup 4)
15935 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15936 (set (match_operand:DF 0 "register_operand" "")
15937 (float_truncate:DF (match_dup 4)))]
15938 "TARGET_USE_FANCY_MATH_387
15939 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15940 && flag_unsafe_math_optimizations"
15941 {
15942 operands[2] = gen_reg_rtx (XFmode);
15943 operands[3] = gen_reg_rtx (XFmode);
15944 operands[4] = gen_reg_rtx (XFmode);
15945 })
15946
15947 (define_expand "logbxf2"
15948 [(parallel [(set (match_dup 2)
15949 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15950 UNSPEC_XTRACT_FRACT))
15951 (set (match_operand:XF 0 "register_operand" "")
15952 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15953 "TARGET_USE_FANCY_MATH_387
15954 && flag_unsafe_math_optimizations"
15955 {
15956 operands[2] = gen_reg_rtx (XFmode);
15957 })
15958
15959 (define_expand "ilogbsi2"
15960 [(parallel [(set (match_dup 2)
15961 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15962 UNSPEC_XTRACT_FRACT))
15963 (set (match_operand:XF 3 "register_operand" "")
15964 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15965 (parallel [(set (match_operand:SI 0 "register_operand" "")
15966 (fix:SI (match_dup 3)))
15967 (clobber (reg:CC FLAGS_REG))])]
15968 "TARGET_USE_FANCY_MATH_387
15969 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15970 && flag_unsafe_math_optimizations"
15971 {
15972 operands[2] = gen_reg_rtx (XFmode);
15973 operands[3] = gen_reg_rtx (XFmode);
15974 })
15975
15976 (define_insn "*f2xm1xf2"
15977 [(set (match_operand:XF 0 "register_operand" "=f")
15978 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15979 UNSPEC_F2XM1))]
15980 "TARGET_USE_FANCY_MATH_387
15981 && flag_unsafe_math_optimizations"
15982 "f2xm1"
15983 [(set_attr "type" "fpspc")
15984 (set_attr "mode" "XF")])
15985
15986 (define_insn "*fscalexf4"
15987 [(set (match_operand:XF 0 "register_operand" "=f")
15988 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15989 (match_operand:XF 3 "register_operand" "1")]
15990 UNSPEC_FSCALE_FRACT))
15991 (set (match_operand:XF 1 "register_operand" "=u")
15992 (unspec:XF [(match_dup 2) (match_dup 3)]
15993 UNSPEC_FSCALE_EXP))]
15994 "TARGET_USE_FANCY_MATH_387
15995 && flag_unsafe_math_optimizations"
15996 "fscale"
15997 [(set_attr "type" "fpspc")
15998 (set_attr "mode" "XF")])
15999
16000 (define_expand "expsf2"
16001 [(set (match_dup 2)
16002 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16003 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16004 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16005 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16006 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16007 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16008 (parallel [(set (match_dup 10)
16009 (unspec:XF [(match_dup 9) (match_dup 5)]
16010 UNSPEC_FSCALE_FRACT))
16011 (set (match_dup 11)
16012 (unspec:XF [(match_dup 9) (match_dup 5)]
16013 UNSPEC_FSCALE_EXP))])
16014 (set (match_operand:SF 0 "register_operand" "")
16015 (float_truncate:SF (match_dup 10)))]
16016 "TARGET_USE_FANCY_MATH_387
16017 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16018 && flag_unsafe_math_optimizations"
16019 {
16020 rtx temp;
16021 int i;
16022
16023 for (i=2; i<12; i++)
16024 operands[i] = gen_reg_rtx (XFmode);
16025 temp = standard_80387_constant_rtx (5); /* fldl2e */
16026 emit_move_insn (operands[3], temp);
16027 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16028 })
16029
16030 (define_expand "expdf2"
16031 [(set (match_dup 2)
16032 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16033 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16034 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16035 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16036 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16037 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16038 (parallel [(set (match_dup 10)
16039 (unspec:XF [(match_dup 9) (match_dup 5)]
16040 UNSPEC_FSCALE_FRACT))
16041 (set (match_dup 11)
16042 (unspec:XF [(match_dup 9) (match_dup 5)]
16043 UNSPEC_FSCALE_EXP))])
16044 (set (match_operand:DF 0 "register_operand" "")
16045 (float_truncate:DF (match_dup 10)))]
16046 "TARGET_USE_FANCY_MATH_387
16047 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16048 && flag_unsafe_math_optimizations"
16049 {
16050 rtx temp;
16051 int i;
16052
16053 for (i=2; i<12; i++)
16054 operands[i] = gen_reg_rtx (XFmode);
16055 temp = standard_80387_constant_rtx (5); /* fldl2e */
16056 emit_move_insn (operands[3], temp);
16057 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16058 })
16059
16060 (define_expand "expxf2"
16061 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16062 (match_dup 2)))
16063 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16064 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16065 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16066 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16067 (parallel [(set (match_operand:XF 0 "register_operand" "")
16068 (unspec:XF [(match_dup 8) (match_dup 4)]
16069 UNSPEC_FSCALE_FRACT))
16070 (set (match_dup 9)
16071 (unspec:XF [(match_dup 8) (match_dup 4)]
16072 UNSPEC_FSCALE_EXP))])]
16073 "TARGET_USE_FANCY_MATH_387
16074 && flag_unsafe_math_optimizations"
16075 {
16076 rtx temp;
16077 int i;
16078
16079 for (i=2; i<10; i++)
16080 operands[i] = gen_reg_rtx (XFmode);
16081 temp = standard_80387_constant_rtx (5); /* fldl2e */
16082 emit_move_insn (operands[2], temp);
16083 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16084 })
16085
16086 (define_expand "exp10sf2"
16087 [(set (match_dup 2)
16088 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16089 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16090 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16091 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16092 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16093 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16094 (parallel [(set (match_dup 10)
16095 (unspec:XF [(match_dup 9) (match_dup 5)]
16096 UNSPEC_FSCALE_FRACT))
16097 (set (match_dup 11)
16098 (unspec:XF [(match_dup 9) (match_dup 5)]
16099 UNSPEC_FSCALE_EXP))])
16100 (set (match_operand:SF 0 "register_operand" "")
16101 (float_truncate:SF (match_dup 10)))]
16102 "TARGET_USE_FANCY_MATH_387
16103 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16104 && flag_unsafe_math_optimizations"
16105 {
16106 rtx temp;
16107 int i;
16108
16109 for (i=2; i<12; i++)
16110 operands[i] = gen_reg_rtx (XFmode);
16111 temp = standard_80387_constant_rtx (6); /* fldl2t */
16112 emit_move_insn (operands[3], temp);
16113 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16114 })
16115
16116 (define_expand "exp10df2"
16117 [(set (match_dup 2)
16118 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16119 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16120 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16121 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16122 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16123 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16124 (parallel [(set (match_dup 10)
16125 (unspec:XF [(match_dup 9) (match_dup 5)]
16126 UNSPEC_FSCALE_FRACT))
16127 (set (match_dup 11)
16128 (unspec:XF [(match_dup 9) (match_dup 5)]
16129 UNSPEC_FSCALE_EXP))])
16130 (set (match_operand:DF 0 "register_operand" "")
16131 (float_truncate:DF (match_dup 10)))]
16132 "TARGET_USE_FANCY_MATH_387
16133 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16134 && flag_unsafe_math_optimizations"
16135 {
16136 rtx temp;
16137 int i;
16138
16139 for (i=2; i<12; i++)
16140 operands[i] = gen_reg_rtx (XFmode);
16141 temp = standard_80387_constant_rtx (6); /* fldl2t */
16142 emit_move_insn (operands[3], temp);
16143 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16144 })
16145
16146 (define_expand "exp10xf2"
16147 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16148 (match_dup 2)))
16149 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16150 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16151 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16152 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16153 (parallel [(set (match_operand:XF 0 "register_operand" "")
16154 (unspec:XF [(match_dup 8) (match_dup 4)]
16155 UNSPEC_FSCALE_FRACT))
16156 (set (match_dup 9)
16157 (unspec:XF [(match_dup 8) (match_dup 4)]
16158 UNSPEC_FSCALE_EXP))])]
16159 "TARGET_USE_FANCY_MATH_387
16160 && flag_unsafe_math_optimizations"
16161 {
16162 rtx temp;
16163 int i;
16164
16165 for (i=2; i<10; i++)
16166 operands[i] = gen_reg_rtx (XFmode);
16167 temp = standard_80387_constant_rtx (6); /* fldl2t */
16168 emit_move_insn (operands[2], temp);
16169 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16170 })
16171
16172 (define_expand "exp2sf2"
16173 [(set (match_dup 2)
16174 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16175 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16176 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16177 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16178 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16179 (parallel [(set (match_dup 8)
16180 (unspec:XF [(match_dup 7) (match_dup 3)]
16181 UNSPEC_FSCALE_FRACT))
16182 (set (match_dup 9)
16183 (unspec:XF [(match_dup 7) (match_dup 3)]
16184 UNSPEC_FSCALE_EXP))])
16185 (set (match_operand:SF 0 "register_operand" "")
16186 (float_truncate:SF (match_dup 8)))]
16187 "TARGET_USE_FANCY_MATH_387
16188 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16189 && flag_unsafe_math_optimizations"
16190 {
16191 int i;
16192
16193 for (i=2; i<10; i++)
16194 operands[i] = gen_reg_rtx (XFmode);
16195 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16196 })
16197
16198 (define_expand "exp2df2"
16199 [(set (match_dup 2)
16200 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16201 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16202 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16203 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16204 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16205 (parallel [(set (match_dup 8)
16206 (unspec:XF [(match_dup 7) (match_dup 3)]
16207 UNSPEC_FSCALE_FRACT))
16208 (set (match_dup 9)
16209 (unspec:XF [(match_dup 7) (match_dup 3)]
16210 UNSPEC_FSCALE_EXP))])
16211 (set (match_operand:DF 0 "register_operand" "")
16212 (float_truncate:DF (match_dup 8)))]
16213 "TARGET_USE_FANCY_MATH_387
16214 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16215 && flag_unsafe_math_optimizations"
16216 {
16217 int i;
16218
16219 for (i=2; i<10; i++)
16220 operands[i] = gen_reg_rtx (XFmode);
16221 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16222 })
16223
16224 (define_expand "exp2xf2"
16225 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16226 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16227 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16228 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16229 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16230 (parallel [(set (match_operand:XF 0 "register_operand" "")
16231 (unspec:XF [(match_dup 7) (match_dup 3)]
16232 UNSPEC_FSCALE_FRACT))
16233 (set (match_dup 8)
16234 (unspec:XF [(match_dup 7) (match_dup 3)]
16235 UNSPEC_FSCALE_EXP))])]
16236 "TARGET_USE_FANCY_MATH_387
16237 && flag_unsafe_math_optimizations"
16238 {
16239 int i;
16240
16241 for (i=2; i<9; i++)
16242 operands[i] = gen_reg_rtx (XFmode);
16243 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16244 })
16245
16246 (define_expand "expm1df2"
16247 [(set (match_dup 2)
16248 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16249 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16250 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16251 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16252 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16253 (parallel [(set (match_dup 8)
16254 (unspec:XF [(match_dup 7) (match_dup 5)]
16255 UNSPEC_FSCALE_FRACT))
16256 (set (match_dup 9)
16257 (unspec:XF [(match_dup 7) (match_dup 5)]
16258 UNSPEC_FSCALE_EXP))])
16259 (parallel [(set (match_dup 11)
16260 (unspec:XF [(match_dup 10) (match_dup 9)]
16261 UNSPEC_FSCALE_FRACT))
16262 (set (match_dup 12)
16263 (unspec:XF [(match_dup 10) (match_dup 9)]
16264 UNSPEC_FSCALE_EXP))])
16265 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16266 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16267 (set (match_operand:DF 0 "register_operand" "")
16268 (float_truncate:DF (match_dup 14)))]
16269 "TARGET_USE_FANCY_MATH_387
16270 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16271 && flag_unsafe_math_optimizations"
16272 {
16273 rtx temp;
16274 int i;
16275
16276 for (i=2; i<15; i++)
16277 operands[i] = gen_reg_rtx (XFmode);
16278 temp = standard_80387_constant_rtx (5); /* fldl2e */
16279 emit_move_insn (operands[3], temp);
16280 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16281 })
16282
16283 (define_expand "expm1sf2"
16284 [(set (match_dup 2)
16285 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16286 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16287 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16288 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16289 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16290 (parallel [(set (match_dup 8)
16291 (unspec:XF [(match_dup 7) (match_dup 5)]
16292 UNSPEC_FSCALE_FRACT))
16293 (set (match_dup 9)
16294 (unspec:XF [(match_dup 7) (match_dup 5)]
16295 UNSPEC_FSCALE_EXP))])
16296 (parallel [(set (match_dup 11)
16297 (unspec:XF [(match_dup 10) (match_dup 9)]
16298 UNSPEC_FSCALE_FRACT))
16299 (set (match_dup 12)
16300 (unspec:XF [(match_dup 10) (match_dup 9)]
16301 UNSPEC_FSCALE_EXP))])
16302 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16303 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16304 (set (match_operand:SF 0 "register_operand" "")
16305 (float_truncate:SF (match_dup 14)))]
16306 "TARGET_USE_FANCY_MATH_387
16307 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16308 && flag_unsafe_math_optimizations"
16309 {
16310 rtx temp;
16311 int i;
16312
16313 for (i=2; i<15; i++)
16314 operands[i] = gen_reg_rtx (XFmode);
16315 temp = standard_80387_constant_rtx (5); /* fldl2e */
16316 emit_move_insn (operands[3], temp);
16317 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16318 })
16319
16320 (define_expand "expm1xf2"
16321 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16322 (match_dup 2)))
16323 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16324 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16325 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16326 (parallel [(set (match_dup 7)
16327 (unspec:XF [(match_dup 6) (match_dup 4)]
16328 UNSPEC_FSCALE_FRACT))
16329 (set (match_dup 8)
16330 (unspec:XF [(match_dup 6) (match_dup 4)]
16331 UNSPEC_FSCALE_EXP))])
16332 (parallel [(set (match_dup 10)
16333 (unspec:XF [(match_dup 9) (match_dup 8)]
16334 UNSPEC_FSCALE_FRACT))
16335 (set (match_dup 11)
16336 (unspec:XF [(match_dup 9) (match_dup 8)]
16337 UNSPEC_FSCALE_EXP))])
16338 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16339 (set (match_operand:XF 0 "register_operand" "")
16340 (plus:XF (match_dup 12) (match_dup 7)))]
16341 "TARGET_USE_FANCY_MATH_387
16342 && flag_unsafe_math_optimizations"
16343 {
16344 rtx temp;
16345 int i;
16346
16347 for (i=2; i<13; i++)
16348 operands[i] = gen_reg_rtx (XFmode);
16349 temp = standard_80387_constant_rtx (5); /* fldl2e */
16350 emit_move_insn (operands[2], temp);
16351 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16352 })
16353
16354 (define_expand "ldexpdf3"
16355 [(set (match_dup 3)
16356 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16357 (set (match_dup 4)
16358 (float:XF (match_operand:SI 2 "register_operand" "")))
16359 (parallel [(set (match_dup 5)
16360 (unspec:XF [(match_dup 3) (match_dup 4)]
16361 UNSPEC_FSCALE_FRACT))
16362 (set (match_dup 6)
16363 (unspec:XF [(match_dup 3) (match_dup 4)]
16364 UNSPEC_FSCALE_EXP))])
16365 (set (match_operand:DF 0 "register_operand" "")
16366 (float_truncate:DF (match_dup 5)))]
16367 "TARGET_USE_FANCY_MATH_387
16368 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16369 && flag_unsafe_math_optimizations"
16370 {
16371 int i;
16372
16373 for (i=3; i<7; i++)
16374 operands[i] = gen_reg_rtx (XFmode);
16375 })
16376
16377 (define_expand "ldexpsf3"
16378 [(set (match_dup 3)
16379 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16380 (set (match_dup 4)
16381 (float:XF (match_operand:SI 2 "register_operand" "")))
16382 (parallel [(set (match_dup 5)
16383 (unspec:XF [(match_dup 3) (match_dup 4)]
16384 UNSPEC_FSCALE_FRACT))
16385 (set (match_dup 6)
16386 (unspec:XF [(match_dup 3) (match_dup 4)]
16387 UNSPEC_FSCALE_EXP))])
16388 (set (match_operand:SF 0 "register_operand" "")
16389 (float_truncate:SF (match_dup 5)))]
16390 "TARGET_USE_FANCY_MATH_387
16391 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16392 && flag_unsafe_math_optimizations"
16393 {
16394 int i;
16395
16396 for (i=3; i<7; i++)
16397 operands[i] = gen_reg_rtx (XFmode);
16398 })
16399
16400 (define_expand "ldexpxf3"
16401 [(set (match_dup 3)
16402 (float:XF (match_operand:SI 2 "register_operand" "")))
16403 (parallel [(set (match_operand:XF 0 " register_operand" "")
16404 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16405 (match_dup 3)]
16406 UNSPEC_FSCALE_FRACT))
16407 (set (match_dup 4)
16408 (unspec:XF [(match_dup 1) (match_dup 3)]
16409 UNSPEC_FSCALE_EXP))])]
16410 "TARGET_USE_FANCY_MATH_387
16411 && flag_unsafe_math_optimizations"
16412 {
16413 int i;
16414
16415 for (i=3; i<5; i++)
16416 operands[i] = gen_reg_rtx (XFmode);
16417 })
16418 \f
16419
16420 (define_insn "frndintxf2"
16421 [(set (match_operand:XF 0 "register_operand" "=f")
16422 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16423 UNSPEC_FRNDINT))]
16424 "TARGET_USE_FANCY_MATH_387
16425 && flag_unsafe_math_optimizations"
16426 "frndint"
16427 [(set_attr "type" "fpspc")
16428 (set_attr "mode" "XF")])
16429
16430 (define_expand "rintdf2"
16431 [(use (match_operand:DF 0 "register_operand" ""))
16432 (use (match_operand:DF 1 "register_operand" ""))]
16433 "TARGET_USE_FANCY_MATH_387
16434 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16435 && flag_unsafe_math_optimizations"
16436 {
16437 rtx op0 = gen_reg_rtx (XFmode);
16438 rtx op1 = gen_reg_rtx (XFmode);
16439
16440 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16441 emit_insn (gen_frndintxf2 (op0, op1));
16442
16443 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16444 DONE;
16445 })
16446
16447 (define_expand "rintsf2"
16448 [(use (match_operand:SF 0 "register_operand" ""))
16449 (use (match_operand:SF 1 "register_operand" ""))]
16450 "TARGET_USE_FANCY_MATH_387
16451 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16452 && flag_unsafe_math_optimizations"
16453 {
16454 rtx op0 = gen_reg_rtx (XFmode);
16455 rtx op1 = gen_reg_rtx (XFmode);
16456
16457 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16458 emit_insn (gen_frndintxf2 (op0, op1));
16459
16460 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16461 DONE;
16462 })
16463
16464 (define_expand "rintxf2"
16465 [(use (match_operand:XF 0 "register_operand" ""))
16466 (use (match_operand:XF 1 "register_operand" ""))]
16467 "TARGET_USE_FANCY_MATH_387
16468 && flag_unsafe_math_optimizations"
16469 {
16470 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16471 DONE;
16472 })
16473
16474 (define_insn "fistdi2"
16475 [(set (match_operand:DI 0 "memory_operand" "=m")
16476 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16477 UNSPEC_FIST))
16478 (clobber (match_scratch:XF 2 "=&1f"))]
16479 "TARGET_USE_FANCY_MATH_387
16480 && flag_unsafe_math_optimizations"
16481 "* return output_fix_trunc (insn, operands, 0);"
16482 [(set_attr "type" "fpspc")
16483 (set_attr "mode" "DI")])
16484
16485 (define_insn "fistdi2_with_temp"
16486 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16487 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16488 UNSPEC_FIST))
16489 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16490 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16491 "TARGET_USE_FANCY_MATH_387
16492 && flag_unsafe_math_optimizations"
16493 "#"
16494 [(set_attr "type" "fpspc")
16495 (set_attr "mode" "DI")])
16496
16497 (define_split
16498 [(set (match_operand:DI 0 "register_operand" "")
16499 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16500 UNSPEC_FIST))
16501 (clobber (match_operand:DI 2 "memory_operand" ""))
16502 (clobber (match_scratch 3 ""))]
16503 "reload_completed"
16504 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16505 (clobber (match_dup 3))])
16506 (set (match_dup 0) (match_dup 2))]
16507 "")
16508
16509 (define_split
16510 [(set (match_operand:DI 0 "memory_operand" "")
16511 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16512 UNSPEC_FIST))
16513 (clobber (match_operand:DI 2 "memory_operand" ""))
16514 (clobber (match_scratch 3 ""))]
16515 "reload_completed"
16516 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16517 (clobber (match_dup 3))])]
16518 "")
16519
16520 (define_insn "fist<mode>2"
16521 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16522 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16523 UNSPEC_FIST))]
16524 "TARGET_USE_FANCY_MATH_387
16525 && flag_unsafe_math_optimizations"
16526 "* return output_fix_trunc (insn, operands, 0);"
16527 [(set_attr "type" "fpspc")
16528 (set_attr "mode" "<MODE>")])
16529
16530 (define_insn "fist<mode>2_with_temp"
16531 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16532 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16533 UNSPEC_FIST))
16534 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16535 "TARGET_USE_FANCY_MATH_387
16536 && flag_unsafe_math_optimizations"
16537 "#"
16538 [(set_attr "type" "fpspc")
16539 (set_attr "mode" "<MODE>")])
16540
16541 (define_split
16542 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16543 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16544 UNSPEC_FIST))
16545 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16546 "reload_completed"
16547 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16548 UNSPEC_FIST))
16549 (set (match_dup 0) (match_dup 2))]
16550 "")
16551
16552 (define_split
16553 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16554 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16555 UNSPEC_FIST))
16556 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16557 "reload_completed"
16558 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16559 UNSPEC_FIST))]
16560 "")
16561
16562 (define_expand "lrint<mode>2"
16563 [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16564 (use (match_operand:XF 1 "register_operand" ""))]
16565 "TARGET_USE_FANCY_MATH_387
16566 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16567 && flag_unsafe_math_optimizations"
16568 {
16569 if (memory_operand (operands[0], VOIDmode))
16570 emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16571 else
16572 {
16573 rtx op = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16574 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16575 op));
16576 }
16577 DONE;
16578 })
16579
16580 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16581 (define_insn_and_split "frndintxf2_floor"
16582 [(set (match_operand:XF 0 "register_operand" "=f")
16583 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16584 UNSPEC_FRNDINT_FLOOR))
16585 (clobber (reg:CC FLAGS_REG))]
16586 "TARGET_USE_FANCY_MATH_387
16587 && flag_unsafe_math_optimizations
16588 && !(reload_completed || reload_in_progress)"
16589 "#"
16590 "&& 1"
16591 [(const_int 0)]
16592 {
16593 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16594
16595 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16596 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16597
16598 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16599 operands[2], operands[3]));
16600 DONE;
16601 }
16602 [(set_attr "type" "frndint")
16603 (set_attr "i387_cw" "floor")
16604 (set_attr "mode" "XF")])
16605
16606 (define_insn "frndintxf2_floor_i387"
16607 [(set (match_operand:XF 0 "register_operand" "=f")
16608 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16609 UNSPEC_FRNDINT_FLOOR))
16610 (use (match_operand:HI 2 "memory_operand" "m"))
16611 (use (match_operand:HI 3 "memory_operand" "m"))]
16612 "TARGET_USE_FANCY_MATH_387
16613 && flag_unsafe_math_optimizations"
16614 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16615 [(set_attr "type" "frndint")
16616 (set_attr "i387_cw" "floor")
16617 (set_attr "mode" "XF")])
16618
16619 (define_expand "floorxf2"
16620 [(use (match_operand:XF 0 "register_operand" ""))
16621 (use (match_operand:XF 1 "register_operand" ""))]
16622 "TARGET_USE_FANCY_MATH_387
16623 && flag_unsafe_math_optimizations"
16624 {
16625 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16626 DONE;
16627 })
16628
16629 (define_expand "floordf2"
16630 [(use (match_operand:DF 0 "register_operand" ""))
16631 (use (match_operand:DF 1 "register_operand" ""))]
16632 "TARGET_USE_FANCY_MATH_387
16633 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16634 && flag_unsafe_math_optimizations"
16635 {
16636 rtx op0 = gen_reg_rtx (XFmode);
16637 rtx op1 = gen_reg_rtx (XFmode);
16638
16639 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16640 emit_insn (gen_frndintxf2_floor (op0, op1));
16641
16642 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16643 DONE;
16644 })
16645
16646 (define_expand "floorsf2"
16647 [(use (match_operand:SF 0 "register_operand" ""))
16648 (use (match_operand:SF 1 "register_operand" ""))]
16649 "TARGET_USE_FANCY_MATH_387
16650 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16651 && flag_unsafe_math_optimizations"
16652 {
16653 rtx op0 = gen_reg_rtx (XFmode);
16654 rtx op1 = gen_reg_rtx (XFmode);
16655
16656 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16657 emit_insn (gen_frndintxf2_floor (op0, op1));
16658
16659 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16660 DONE;
16661 })
16662
16663 (define_insn_and_split "*fist<mode>2_floor_1"
16664 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16665 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16666 UNSPEC_FIST_FLOOR))
16667 (clobber (reg:CC FLAGS_REG))]
16668 "TARGET_USE_FANCY_MATH_387
16669 && flag_unsafe_math_optimizations
16670 && !(reload_completed || reload_in_progress)"
16671 "#"
16672 "&& 1"
16673 [(const_int 0)]
16674 {
16675 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16676
16677 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16678 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16679 if (memory_operand (operands[0], VOIDmode))
16680 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16681 operands[2], operands[3]));
16682 else
16683 {
16684 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16685 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16686 operands[2], operands[3],
16687 operands[4]));
16688 }
16689 DONE;
16690 }
16691 [(set_attr "type" "fistp")
16692 (set_attr "i387_cw" "floor")
16693 (set_attr "mode" "<MODE>")])
16694
16695 (define_insn "fistdi2_floor"
16696 [(set (match_operand:DI 0 "memory_operand" "=m")
16697 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16698 UNSPEC_FIST_FLOOR))
16699 (use (match_operand:HI 2 "memory_operand" "m"))
16700 (use (match_operand:HI 3 "memory_operand" "m"))
16701 (clobber (match_scratch:XF 4 "=&1f"))]
16702 "TARGET_USE_FANCY_MATH_387
16703 && flag_unsafe_math_optimizations"
16704 "* return output_fix_trunc (insn, operands, 0);"
16705 [(set_attr "type" "fistp")
16706 (set_attr "i387_cw" "floor")
16707 (set_attr "mode" "DI")])
16708
16709 (define_insn "fistdi2_floor_with_temp"
16710 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16711 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16712 UNSPEC_FIST_FLOOR))
16713 (use (match_operand:HI 2 "memory_operand" "m,m"))
16714 (use (match_operand:HI 3 "memory_operand" "m,m"))
16715 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16716 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16717 "TARGET_USE_FANCY_MATH_387
16718 && flag_unsafe_math_optimizations"
16719 "#"
16720 [(set_attr "type" "fistp")
16721 (set_attr "i387_cw" "floor")
16722 (set_attr "mode" "DI")])
16723
16724 (define_split
16725 [(set (match_operand:DI 0 "register_operand" "")
16726 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16727 UNSPEC_FIST_FLOOR))
16728 (use (match_operand:HI 2 "memory_operand" ""))
16729 (use (match_operand:HI 3 "memory_operand" ""))
16730 (clobber (match_operand:DI 4 "memory_operand" ""))
16731 (clobber (match_scratch 5 ""))]
16732 "reload_completed"
16733 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16734 (use (match_dup 2))
16735 (use (match_dup 3))
16736 (clobber (match_dup 5))])
16737 (set (match_dup 0) (match_dup 4))]
16738 "")
16739
16740 (define_split
16741 [(set (match_operand:DI 0 "memory_operand" "")
16742 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16743 UNSPEC_FIST_FLOOR))
16744 (use (match_operand:HI 2 "memory_operand" ""))
16745 (use (match_operand:HI 3 "memory_operand" ""))
16746 (clobber (match_operand:DI 4 "memory_operand" ""))
16747 (clobber (match_scratch 5 ""))]
16748 "reload_completed"
16749 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16750 (use (match_dup 2))
16751 (use (match_dup 3))
16752 (clobber (match_dup 5))])]
16753 "")
16754
16755 (define_insn "fist<mode>2_floor"
16756 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16757 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16758 UNSPEC_FIST_FLOOR))
16759 (use (match_operand:HI 2 "memory_operand" "m"))
16760 (use (match_operand:HI 3 "memory_operand" "m"))]
16761 "TARGET_USE_FANCY_MATH_387
16762 && flag_unsafe_math_optimizations"
16763 "* return output_fix_trunc (insn, operands, 0);"
16764 [(set_attr "type" "fistp")
16765 (set_attr "i387_cw" "floor")
16766 (set_attr "mode" "<MODE>")])
16767
16768 (define_insn "fist<mode>2_floor_with_temp"
16769 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16770 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16771 UNSPEC_FIST_FLOOR))
16772 (use (match_operand:HI 2 "memory_operand" "m,m"))
16773 (use (match_operand:HI 3 "memory_operand" "m,m"))
16774 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16775 "TARGET_USE_FANCY_MATH_387
16776 && flag_unsafe_math_optimizations"
16777 "#"
16778 [(set_attr "type" "fistp")
16779 (set_attr "i387_cw" "floor")
16780 (set_attr "mode" "<MODE>")])
16781
16782 (define_split
16783 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16784 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16785 UNSPEC_FIST_FLOOR))
16786 (use (match_operand:HI 2 "memory_operand" ""))
16787 (use (match_operand:HI 3 "memory_operand" ""))
16788 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16789 "reload_completed"
16790 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16791 UNSPEC_FIST_FLOOR))
16792 (use (match_dup 2))
16793 (use (match_dup 3))])
16794 (set (match_dup 0) (match_dup 4))]
16795 "")
16796
16797 (define_split
16798 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16799 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16800 UNSPEC_FIST_FLOOR))
16801 (use (match_operand:HI 2 "memory_operand" ""))
16802 (use (match_operand:HI 3 "memory_operand" ""))
16803 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16804 "reload_completed"
16805 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16806 UNSPEC_FIST_FLOOR))
16807 (use (match_dup 2))
16808 (use (match_dup 3))])]
16809 "")
16810
16811 (define_expand "lfloor<mode>2"
16812 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16813 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16814 UNSPEC_FIST_FLOOR))
16815 (clobber (reg:CC FLAGS_REG))])]
16816 "TARGET_USE_FANCY_MATH_387
16817 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16818 && flag_unsafe_math_optimizations"
16819 "")
16820
16821 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16822 (define_insn_and_split "frndintxf2_ceil"
16823 [(set (match_operand:XF 0 "register_operand" "=f")
16824 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16825 UNSPEC_FRNDINT_CEIL))
16826 (clobber (reg:CC FLAGS_REG))]
16827 "TARGET_USE_FANCY_MATH_387
16828 && flag_unsafe_math_optimizations
16829 && !(reload_completed || reload_in_progress)"
16830 "#"
16831 "&& 1"
16832 [(const_int 0)]
16833 {
16834 ix86_optimize_mode_switching[I387_CEIL] = 1;
16835
16836 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16837 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16838
16839 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16840 operands[2], operands[3]));
16841 DONE;
16842 }
16843 [(set_attr "type" "frndint")
16844 (set_attr "i387_cw" "ceil")
16845 (set_attr "mode" "XF")])
16846
16847 (define_insn "frndintxf2_ceil_i387"
16848 [(set (match_operand:XF 0 "register_operand" "=f")
16849 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16850 UNSPEC_FRNDINT_CEIL))
16851 (use (match_operand:HI 2 "memory_operand" "m"))
16852 (use (match_operand:HI 3 "memory_operand" "m"))]
16853 "TARGET_USE_FANCY_MATH_387
16854 && flag_unsafe_math_optimizations"
16855 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16856 [(set_attr "type" "frndint")
16857 (set_attr "i387_cw" "ceil")
16858 (set_attr "mode" "XF")])
16859
16860 (define_expand "ceilxf2"
16861 [(use (match_operand:XF 0 "register_operand" ""))
16862 (use (match_operand:XF 1 "register_operand" ""))]
16863 "TARGET_USE_FANCY_MATH_387
16864 && flag_unsafe_math_optimizations"
16865 {
16866 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16867 DONE;
16868 })
16869
16870 (define_expand "ceildf2"
16871 [(use (match_operand:DF 0 "register_operand" ""))
16872 (use (match_operand:DF 1 "register_operand" ""))]
16873 "TARGET_USE_FANCY_MATH_387
16874 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16875 && flag_unsafe_math_optimizations"
16876 {
16877 rtx op0 = gen_reg_rtx (XFmode);
16878 rtx op1 = gen_reg_rtx (XFmode);
16879
16880 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16881 emit_insn (gen_frndintxf2_ceil (op0, op1));
16882
16883 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16884 DONE;
16885 })
16886
16887 (define_expand "ceilsf2"
16888 [(use (match_operand:SF 0 "register_operand" ""))
16889 (use (match_operand:SF 1 "register_operand" ""))]
16890 "TARGET_USE_FANCY_MATH_387
16891 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16892 && flag_unsafe_math_optimizations"
16893 {
16894 rtx op0 = gen_reg_rtx (XFmode);
16895 rtx op1 = gen_reg_rtx (XFmode);
16896
16897 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16898 emit_insn (gen_frndintxf2_ceil (op0, op1));
16899
16900 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16901 DONE;
16902 })
16903
16904 (define_insn_and_split "*fist<mode>2_ceil_1"
16905 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16906 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16907 UNSPEC_FIST_CEIL))
16908 (clobber (reg:CC FLAGS_REG))]
16909 "TARGET_USE_FANCY_MATH_387
16910 && flag_unsafe_math_optimizations
16911 && !(reload_completed || reload_in_progress)"
16912 "#"
16913 "&& 1"
16914 [(const_int 0)]
16915 {
16916 ix86_optimize_mode_switching[I387_CEIL] = 1;
16917
16918 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16919 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16920 if (memory_operand (operands[0], VOIDmode))
16921 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16922 operands[2], operands[3]));
16923 else
16924 {
16925 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16926 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16927 operands[2], operands[3],
16928 operands[4]));
16929 }
16930 DONE;
16931 }
16932 [(set_attr "type" "fistp")
16933 (set_attr "i387_cw" "ceil")
16934 (set_attr "mode" "<MODE>")])
16935
16936 (define_insn "fistdi2_ceil"
16937 [(set (match_operand:DI 0 "memory_operand" "=m")
16938 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16939 UNSPEC_FIST_CEIL))
16940 (use (match_operand:HI 2 "memory_operand" "m"))
16941 (use (match_operand:HI 3 "memory_operand" "m"))
16942 (clobber (match_scratch:XF 4 "=&1f"))]
16943 "TARGET_USE_FANCY_MATH_387
16944 && flag_unsafe_math_optimizations"
16945 "* return output_fix_trunc (insn, operands, 0);"
16946 [(set_attr "type" "fistp")
16947 (set_attr "i387_cw" "ceil")
16948 (set_attr "mode" "DI")])
16949
16950 (define_insn "fistdi2_ceil_with_temp"
16951 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16952 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16953 UNSPEC_FIST_CEIL))
16954 (use (match_operand:HI 2 "memory_operand" "m,m"))
16955 (use (match_operand:HI 3 "memory_operand" "m,m"))
16956 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16957 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16958 "TARGET_USE_FANCY_MATH_387
16959 && flag_unsafe_math_optimizations"
16960 "#"
16961 [(set_attr "type" "fistp")
16962 (set_attr "i387_cw" "ceil")
16963 (set_attr "mode" "DI")])
16964
16965 (define_split
16966 [(set (match_operand:DI 0 "register_operand" "")
16967 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16968 UNSPEC_FIST_CEIL))
16969 (use (match_operand:HI 2 "memory_operand" ""))
16970 (use (match_operand:HI 3 "memory_operand" ""))
16971 (clobber (match_operand:DI 4 "memory_operand" ""))
16972 (clobber (match_scratch 5 ""))]
16973 "reload_completed"
16974 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16975 (use (match_dup 2))
16976 (use (match_dup 3))
16977 (clobber (match_dup 5))])
16978 (set (match_dup 0) (match_dup 4))]
16979 "")
16980
16981 (define_split
16982 [(set (match_operand:DI 0 "memory_operand" "")
16983 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16984 UNSPEC_FIST_CEIL))
16985 (use (match_operand:HI 2 "memory_operand" ""))
16986 (use (match_operand:HI 3 "memory_operand" ""))
16987 (clobber (match_operand:DI 4 "memory_operand" ""))
16988 (clobber (match_scratch 5 ""))]
16989 "reload_completed"
16990 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16991 (use (match_dup 2))
16992 (use (match_dup 3))
16993 (clobber (match_dup 5))])]
16994 "")
16995
16996 (define_insn "fist<mode>2_ceil"
16997 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16998 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16999 UNSPEC_FIST_CEIL))
17000 (use (match_operand:HI 2 "memory_operand" "m"))
17001 (use (match_operand:HI 3 "memory_operand" "m"))]
17002 "TARGET_USE_FANCY_MATH_387
17003 && flag_unsafe_math_optimizations"
17004 "* return output_fix_trunc (insn, operands, 0);"
17005 [(set_attr "type" "fistp")
17006 (set_attr "i387_cw" "ceil")
17007 (set_attr "mode" "<MODE>")])
17008
17009 (define_insn "fist<mode>2_ceil_with_temp"
17010 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17011 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17012 UNSPEC_FIST_CEIL))
17013 (use (match_operand:HI 2 "memory_operand" "m,m"))
17014 (use (match_operand:HI 3 "memory_operand" "m,m"))
17015 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17016 "TARGET_USE_FANCY_MATH_387
17017 && flag_unsafe_math_optimizations"
17018 "#"
17019 [(set_attr "type" "fistp")
17020 (set_attr "i387_cw" "ceil")
17021 (set_attr "mode" "<MODE>")])
17022
17023 (define_split
17024 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17025 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17026 UNSPEC_FIST_CEIL))
17027 (use (match_operand:HI 2 "memory_operand" ""))
17028 (use (match_operand:HI 3 "memory_operand" ""))
17029 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17030 "reload_completed"
17031 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17032 UNSPEC_FIST_CEIL))
17033 (use (match_dup 2))
17034 (use (match_dup 3))])
17035 (set (match_dup 0) (match_dup 4))]
17036 "")
17037
17038 (define_split
17039 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17040 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17041 UNSPEC_FIST_CEIL))
17042 (use (match_operand:HI 2 "memory_operand" ""))
17043 (use (match_operand:HI 3 "memory_operand" ""))
17044 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17045 "reload_completed"
17046 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17047 UNSPEC_FIST_CEIL))
17048 (use (match_dup 2))
17049 (use (match_dup 3))])]
17050 "")
17051
17052 (define_expand "lceil<mode>2"
17053 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17054 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17055 UNSPEC_FIST_CEIL))
17056 (clobber (reg:CC FLAGS_REG))])]
17057 "TARGET_USE_FANCY_MATH_387
17058 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17059 && flag_unsafe_math_optimizations"
17060 "")
17061
17062 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17063 (define_insn_and_split "frndintxf2_trunc"
17064 [(set (match_operand:XF 0 "register_operand" "=f")
17065 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17066 UNSPEC_FRNDINT_TRUNC))
17067 (clobber (reg:CC FLAGS_REG))]
17068 "TARGET_USE_FANCY_MATH_387
17069 && flag_unsafe_math_optimizations
17070 && !(reload_completed || reload_in_progress)"
17071 "#"
17072 "&& 1"
17073 [(const_int 0)]
17074 {
17075 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17076
17077 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17078 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17079
17080 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17081 operands[2], operands[3]));
17082 DONE;
17083 }
17084 [(set_attr "type" "frndint")
17085 (set_attr "i387_cw" "trunc")
17086 (set_attr "mode" "XF")])
17087
17088 (define_insn "frndintxf2_trunc_i387"
17089 [(set (match_operand:XF 0 "register_operand" "=f")
17090 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17091 UNSPEC_FRNDINT_TRUNC))
17092 (use (match_operand:HI 2 "memory_operand" "m"))
17093 (use (match_operand:HI 3 "memory_operand" "m"))]
17094 "TARGET_USE_FANCY_MATH_387
17095 && flag_unsafe_math_optimizations"
17096 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17097 [(set_attr "type" "frndint")
17098 (set_attr "i387_cw" "trunc")
17099 (set_attr "mode" "XF")])
17100
17101 (define_expand "btruncxf2"
17102 [(use (match_operand:XF 0 "register_operand" ""))
17103 (use (match_operand:XF 1 "register_operand" ""))]
17104 "TARGET_USE_FANCY_MATH_387
17105 && flag_unsafe_math_optimizations"
17106 {
17107 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17108 DONE;
17109 })
17110
17111 (define_expand "btruncdf2"
17112 [(use (match_operand:DF 0 "register_operand" ""))
17113 (use (match_operand:DF 1 "register_operand" ""))]
17114 "TARGET_USE_FANCY_MATH_387
17115 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17116 && flag_unsafe_math_optimizations"
17117 {
17118 rtx op0 = gen_reg_rtx (XFmode);
17119 rtx op1 = gen_reg_rtx (XFmode);
17120
17121 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17122 emit_insn (gen_frndintxf2_trunc (op0, op1));
17123
17124 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17125 DONE;
17126 })
17127
17128 (define_expand "btruncsf2"
17129 [(use (match_operand:SF 0 "register_operand" ""))
17130 (use (match_operand:SF 1 "register_operand" ""))]
17131 "TARGET_USE_FANCY_MATH_387
17132 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17133 && flag_unsafe_math_optimizations"
17134 {
17135 rtx op0 = gen_reg_rtx (XFmode);
17136 rtx op1 = gen_reg_rtx (XFmode);
17137
17138 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17139 emit_insn (gen_frndintxf2_trunc (op0, op1));
17140
17141 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17142 DONE;
17143 })
17144
17145 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17146 (define_insn_and_split "frndintxf2_mask_pm"
17147 [(set (match_operand:XF 0 "register_operand" "=f")
17148 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17149 UNSPEC_FRNDINT_MASK_PM))
17150 (clobber (reg:CC FLAGS_REG))]
17151 "TARGET_USE_FANCY_MATH_387
17152 && flag_unsafe_math_optimizations
17153 && !(reload_completed || reload_in_progress)"
17154 "#"
17155 "&& 1"
17156 [(const_int 0)]
17157 {
17158 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17159
17160 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17161 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17162
17163 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17164 operands[2], operands[3]));
17165 DONE;
17166 }
17167 [(set_attr "type" "frndint")
17168 (set_attr "i387_cw" "mask_pm")
17169 (set_attr "mode" "XF")])
17170
17171 (define_insn "frndintxf2_mask_pm_i387"
17172 [(set (match_operand:XF 0 "register_operand" "=f")
17173 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17174 UNSPEC_FRNDINT_MASK_PM))
17175 (use (match_operand:HI 2 "memory_operand" "m"))
17176 (use (match_operand:HI 3 "memory_operand" "m"))]
17177 "TARGET_USE_FANCY_MATH_387
17178 && flag_unsafe_math_optimizations"
17179 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17180 [(set_attr "type" "frndint")
17181 (set_attr "i387_cw" "mask_pm")
17182 (set_attr "mode" "XF")])
17183
17184 (define_expand "nearbyintxf2"
17185 [(use (match_operand:XF 0 "register_operand" ""))
17186 (use (match_operand:XF 1 "register_operand" ""))]
17187 "TARGET_USE_FANCY_MATH_387
17188 && flag_unsafe_math_optimizations"
17189 {
17190 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17191
17192 DONE;
17193 })
17194
17195 (define_expand "nearbyintdf2"
17196 [(use (match_operand:DF 0 "register_operand" ""))
17197 (use (match_operand:DF 1 "register_operand" ""))]
17198 "TARGET_USE_FANCY_MATH_387
17199 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17200 && flag_unsafe_math_optimizations"
17201 {
17202 rtx op0 = gen_reg_rtx (XFmode);
17203 rtx op1 = gen_reg_rtx (XFmode);
17204
17205 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17206 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17207
17208 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17209 DONE;
17210 })
17211
17212 (define_expand "nearbyintsf2"
17213 [(use (match_operand:SF 0 "register_operand" ""))
17214 (use (match_operand:SF 1 "register_operand" ""))]
17215 "TARGET_USE_FANCY_MATH_387
17216 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17217 && flag_unsafe_math_optimizations"
17218 {
17219 rtx op0 = gen_reg_rtx (XFmode);
17220 rtx op1 = gen_reg_rtx (XFmode);
17221
17222 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17223 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17224
17225 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17226 DONE;
17227 })
17228
17229 \f
17230 ;; Block operation instructions
17231
17232 (define_insn "cld"
17233 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17234 ""
17235 "cld"
17236 [(set_attr "type" "cld")])
17237
17238 (define_expand "movmemsi"
17239 [(use (match_operand:BLK 0 "memory_operand" ""))
17240 (use (match_operand:BLK 1 "memory_operand" ""))
17241 (use (match_operand:SI 2 "nonmemory_operand" ""))
17242 (use (match_operand:SI 3 "const_int_operand" ""))]
17243 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17244 {
17245 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17246 DONE;
17247 else
17248 FAIL;
17249 })
17250
17251 (define_expand "movmemdi"
17252 [(use (match_operand:BLK 0 "memory_operand" ""))
17253 (use (match_operand:BLK 1 "memory_operand" ""))
17254 (use (match_operand:DI 2 "nonmemory_operand" ""))
17255 (use (match_operand:DI 3 "const_int_operand" ""))]
17256 "TARGET_64BIT"
17257 {
17258 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17259 DONE;
17260 else
17261 FAIL;
17262 })
17263
17264 ;; Most CPUs don't like single string operations
17265 ;; Handle this case here to simplify previous expander.
17266
17267 (define_expand "strmov"
17268 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17269 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17270 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17271 (clobber (reg:CC FLAGS_REG))])
17272 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17273 (clobber (reg:CC FLAGS_REG))])]
17274 ""
17275 {
17276 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17277
17278 /* If .md ever supports :P for Pmode, these can be directly
17279 in the pattern above. */
17280 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17281 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17282
17283 if (TARGET_SINGLE_STRINGOP || optimize_size)
17284 {
17285 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17286 operands[2], operands[3],
17287 operands[5], operands[6]));
17288 DONE;
17289 }
17290
17291 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17292 })
17293
17294 (define_expand "strmov_singleop"
17295 [(parallel [(set (match_operand 1 "memory_operand" "")
17296 (match_operand 3 "memory_operand" ""))
17297 (set (match_operand 0 "register_operand" "")
17298 (match_operand 4 "" ""))
17299 (set (match_operand 2 "register_operand" "")
17300 (match_operand 5 "" ""))
17301 (use (reg:SI DIRFLAG_REG))])]
17302 "TARGET_SINGLE_STRINGOP || optimize_size"
17303 "")
17304
17305 (define_insn "*strmovdi_rex_1"
17306 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17307 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17308 (set (match_operand:DI 0 "register_operand" "=D")
17309 (plus:DI (match_dup 2)
17310 (const_int 8)))
17311 (set (match_operand:DI 1 "register_operand" "=S")
17312 (plus:DI (match_dup 3)
17313 (const_int 8)))
17314 (use (reg:SI DIRFLAG_REG))]
17315 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17316 "movsq"
17317 [(set_attr "type" "str")
17318 (set_attr "mode" "DI")
17319 (set_attr "memory" "both")])
17320
17321 (define_insn "*strmovsi_1"
17322 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17323 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17324 (set (match_operand:SI 0 "register_operand" "=D")
17325 (plus:SI (match_dup 2)
17326 (const_int 4)))
17327 (set (match_operand:SI 1 "register_operand" "=S")
17328 (plus:SI (match_dup 3)
17329 (const_int 4)))
17330 (use (reg:SI DIRFLAG_REG))]
17331 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17332 "{movsl|movsd}"
17333 [(set_attr "type" "str")
17334 (set_attr "mode" "SI")
17335 (set_attr "memory" "both")])
17336
17337 (define_insn "*strmovsi_rex_1"
17338 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17339 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17340 (set (match_operand:DI 0 "register_operand" "=D")
17341 (plus:DI (match_dup 2)
17342 (const_int 4)))
17343 (set (match_operand:DI 1 "register_operand" "=S")
17344 (plus:DI (match_dup 3)
17345 (const_int 4)))
17346 (use (reg:SI DIRFLAG_REG))]
17347 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17348 "{movsl|movsd}"
17349 [(set_attr "type" "str")
17350 (set_attr "mode" "SI")
17351 (set_attr "memory" "both")])
17352
17353 (define_insn "*strmovhi_1"
17354 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17355 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17356 (set (match_operand:SI 0 "register_operand" "=D")
17357 (plus:SI (match_dup 2)
17358 (const_int 2)))
17359 (set (match_operand:SI 1 "register_operand" "=S")
17360 (plus:SI (match_dup 3)
17361 (const_int 2)))
17362 (use (reg:SI DIRFLAG_REG))]
17363 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17364 "movsw"
17365 [(set_attr "type" "str")
17366 (set_attr "memory" "both")
17367 (set_attr "mode" "HI")])
17368
17369 (define_insn "*strmovhi_rex_1"
17370 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17371 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17372 (set (match_operand:DI 0 "register_operand" "=D")
17373 (plus:DI (match_dup 2)
17374 (const_int 2)))
17375 (set (match_operand:DI 1 "register_operand" "=S")
17376 (plus:DI (match_dup 3)
17377 (const_int 2)))
17378 (use (reg:SI DIRFLAG_REG))]
17379 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17380 "movsw"
17381 [(set_attr "type" "str")
17382 (set_attr "memory" "both")
17383 (set_attr "mode" "HI")])
17384
17385 (define_insn "*strmovqi_1"
17386 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17387 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17388 (set (match_operand:SI 0 "register_operand" "=D")
17389 (plus:SI (match_dup 2)
17390 (const_int 1)))
17391 (set (match_operand:SI 1 "register_operand" "=S")
17392 (plus:SI (match_dup 3)
17393 (const_int 1)))
17394 (use (reg:SI DIRFLAG_REG))]
17395 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17396 "movsb"
17397 [(set_attr "type" "str")
17398 (set_attr "memory" "both")
17399 (set_attr "mode" "QI")])
17400
17401 (define_insn "*strmovqi_rex_1"
17402 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17403 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17404 (set (match_operand:DI 0 "register_operand" "=D")
17405 (plus:DI (match_dup 2)
17406 (const_int 1)))
17407 (set (match_operand:DI 1 "register_operand" "=S")
17408 (plus:DI (match_dup 3)
17409 (const_int 1)))
17410 (use (reg:SI DIRFLAG_REG))]
17411 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17412 "movsb"
17413 [(set_attr "type" "str")
17414 (set_attr "memory" "both")
17415 (set_attr "mode" "QI")])
17416
17417 (define_expand "rep_mov"
17418 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17419 (set (match_operand 0 "register_operand" "")
17420 (match_operand 5 "" ""))
17421 (set (match_operand 2 "register_operand" "")
17422 (match_operand 6 "" ""))
17423 (set (match_operand 1 "memory_operand" "")
17424 (match_operand 3 "memory_operand" ""))
17425 (use (match_dup 4))
17426 (use (reg:SI DIRFLAG_REG))])]
17427 ""
17428 "")
17429
17430 (define_insn "*rep_movdi_rex64"
17431 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17432 (set (match_operand:DI 0 "register_operand" "=D")
17433 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17434 (const_int 3))
17435 (match_operand:DI 3 "register_operand" "0")))
17436 (set (match_operand:DI 1 "register_operand" "=S")
17437 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17438 (match_operand:DI 4 "register_operand" "1")))
17439 (set (mem:BLK (match_dup 3))
17440 (mem:BLK (match_dup 4)))
17441 (use (match_dup 5))
17442 (use (reg:SI DIRFLAG_REG))]
17443 "TARGET_64BIT"
17444 "{rep\;movsq|rep movsq}"
17445 [(set_attr "type" "str")
17446 (set_attr "prefix_rep" "1")
17447 (set_attr "memory" "both")
17448 (set_attr "mode" "DI")])
17449
17450 (define_insn "*rep_movsi"
17451 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17452 (set (match_operand:SI 0 "register_operand" "=D")
17453 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17454 (const_int 2))
17455 (match_operand:SI 3 "register_operand" "0")))
17456 (set (match_operand:SI 1 "register_operand" "=S")
17457 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17458 (match_operand:SI 4 "register_operand" "1")))
17459 (set (mem:BLK (match_dup 3))
17460 (mem:BLK (match_dup 4)))
17461 (use (match_dup 5))
17462 (use (reg:SI DIRFLAG_REG))]
17463 "!TARGET_64BIT"
17464 "{rep\;movsl|rep movsd}"
17465 [(set_attr "type" "str")
17466 (set_attr "prefix_rep" "1")
17467 (set_attr "memory" "both")
17468 (set_attr "mode" "SI")])
17469
17470 (define_insn "*rep_movsi_rex64"
17471 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17472 (set (match_operand:DI 0 "register_operand" "=D")
17473 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17474 (const_int 2))
17475 (match_operand:DI 3 "register_operand" "0")))
17476 (set (match_operand:DI 1 "register_operand" "=S")
17477 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17478 (match_operand:DI 4 "register_operand" "1")))
17479 (set (mem:BLK (match_dup 3))
17480 (mem:BLK (match_dup 4)))
17481 (use (match_dup 5))
17482 (use (reg:SI DIRFLAG_REG))]
17483 "TARGET_64BIT"
17484 "{rep\;movsl|rep movsd}"
17485 [(set_attr "type" "str")
17486 (set_attr "prefix_rep" "1")
17487 (set_attr "memory" "both")
17488 (set_attr "mode" "SI")])
17489
17490 (define_insn "*rep_movqi"
17491 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17492 (set (match_operand:SI 0 "register_operand" "=D")
17493 (plus:SI (match_operand:SI 3 "register_operand" "0")
17494 (match_operand:SI 5 "register_operand" "2")))
17495 (set (match_operand:SI 1 "register_operand" "=S")
17496 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17497 (set (mem:BLK (match_dup 3))
17498 (mem:BLK (match_dup 4)))
17499 (use (match_dup 5))
17500 (use (reg:SI DIRFLAG_REG))]
17501 "!TARGET_64BIT"
17502 "{rep\;movsb|rep movsb}"
17503 [(set_attr "type" "str")
17504 (set_attr "prefix_rep" "1")
17505 (set_attr "memory" "both")
17506 (set_attr "mode" "SI")])
17507
17508 (define_insn "*rep_movqi_rex64"
17509 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17510 (set (match_operand:DI 0 "register_operand" "=D")
17511 (plus:DI (match_operand:DI 3 "register_operand" "0")
17512 (match_operand:DI 5 "register_operand" "2")))
17513 (set (match_operand:DI 1 "register_operand" "=S")
17514 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17515 (set (mem:BLK (match_dup 3))
17516 (mem:BLK (match_dup 4)))
17517 (use (match_dup 5))
17518 (use (reg:SI DIRFLAG_REG))]
17519 "TARGET_64BIT"
17520 "{rep\;movsb|rep movsb}"
17521 [(set_attr "type" "str")
17522 (set_attr "prefix_rep" "1")
17523 (set_attr "memory" "both")
17524 (set_attr "mode" "SI")])
17525
17526 (define_expand "setmemsi"
17527 [(use (match_operand:BLK 0 "memory_operand" ""))
17528 (use (match_operand:SI 1 "nonmemory_operand" ""))
17529 (use (match_operand 2 "const_int_operand" ""))
17530 (use (match_operand 3 "const_int_operand" ""))]
17531 ""
17532 {
17533 /* If value to set is not zero, use the library routine. */
17534 if (operands[2] != const0_rtx)
17535 FAIL;
17536
17537 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17538 DONE;
17539 else
17540 FAIL;
17541 })
17542
17543 (define_expand "setmemdi"
17544 [(use (match_operand:BLK 0 "memory_operand" ""))
17545 (use (match_operand:DI 1 "nonmemory_operand" ""))
17546 (use (match_operand 2 "const_int_operand" ""))
17547 (use (match_operand 3 "const_int_operand" ""))]
17548 "TARGET_64BIT"
17549 {
17550 /* If value to set is not zero, use the library routine. */
17551 if (operands[2] != const0_rtx)
17552 FAIL;
17553
17554 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17555 DONE;
17556 else
17557 FAIL;
17558 })
17559
17560 ;; Most CPUs don't like single string operations
17561 ;; Handle this case here to simplify previous expander.
17562
17563 (define_expand "strset"
17564 [(set (match_operand 1 "memory_operand" "")
17565 (match_operand 2 "register_operand" ""))
17566 (parallel [(set (match_operand 0 "register_operand" "")
17567 (match_dup 3))
17568 (clobber (reg:CC FLAGS_REG))])]
17569 ""
17570 {
17571 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17572 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17573
17574 /* If .md ever supports :P for Pmode, this can be directly
17575 in the pattern above. */
17576 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17577 GEN_INT (GET_MODE_SIZE (GET_MODE
17578 (operands[2]))));
17579 if (TARGET_SINGLE_STRINGOP || optimize_size)
17580 {
17581 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17582 operands[3]));
17583 DONE;
17584 }
17585 })
17586
17587 (define_expand "strset_singleop"
17588 [(parallel [(set (match_operand 1 "memory_operand" "")
17589 (match_operand 2 "register_operand" ""))
17590 (set (match_operand 0 "register_operand" "")
17591 (match_operand 3 "" ""))
17592 (use (reg:SI DIRFLAG_REG))])]
17593 "TARGET_SINGLE_STRINGOP || optimize_size"
17594 "")
17595
17596 (define_insn "*strsetdi_rex_1"
17597 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17598 (match_operand:DI 2 "register_operand" "a"))
17599 (set (match_operand:DI 0 "register_operand" "=D")
17600 (plus:DI (match_dup 1)
17601 (const_int 8)))
17602 (use (reg:SI DIRFLAG_REG))]
17603 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17604 "stosq"
17605 [(set_attr "type" "str")
17606 (set_attr "memory" "store")
17607 (set_attr "mode" "DI")])
17608
17609 (define_insn "*strsetsi_1"
17610 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17611 (match_operand:SI 2 "register_operand" "a"))
17612 (set (match_operand:SI 0 "register_operand" "=D")
17613 (plus:SI (match_dup 1)
17614 (const_int 4)))
17615 (use (reg:SI DIRFLAG_REG))]
17616 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17617 "{stosl|stosd}"
17618 [(set_attr "type" "str")
17619 (set_attr "memory" "store")
17620 (set_attr "mode" "SI")])
17621
17622 (define_insn "*strsetsi_rex_1"
17623 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17624 (match_operand:SI 2 "register_operand" "a"))
17625 (set (match_operand:DI 0 "register_operand" "=D")
17626 (plus:DI (match_dup 1)
17627 (const_int 4)))
17628 (use (reg:SI DIRFLAG_REG))]
17629 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17630 "{stosl|stosd}"
17631 [(set_attr "type" "str")
17632 (set_attr "memory" "store")
17633 (set_attr "mode" "SI")])
17634
17635 (define_insn "*strsethi_1"
17636 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17637 (match_operand:HI 2 "register_operand" "a"))
17638 (set (match_operand:SI 0 "register_operand" "=D")
17639 (plus:SI (match_dup 1)
17640 (const_int 2)))
17641 (use (reg:SI DIRFLAG_REG))]
17642 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17643 "stosw"
17644 [(set_attr "type" "str")
17645 (set_attr "memory" "store")
17646 (set_attr "mode" "HI")])
17647
17648 (define_insn "*strsethi_rex_1"
17649 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17650 (match_operand:HI 2 "register_operand" "a"))
17651 (set (match_operand:DI 0 "register_operand" "=D")
17652 (plus:DI (match_dup 1)
17653 (const_int 2)))
17654 (use (reg:SI DIRFLAG_REG))]
17655 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17656 "stosw"
17657 [(set_attr "type" "str")
17658 (set_attr "memory" "store")
17659 (set_attr "mode" "HI")])
17660
17661 (define_insn "*strsetqi_1"
17662 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17663 (match_operand:QI 2 "register_operand" "a"))
17664 (set (match_operand:SI 0 "register_operand" "=D")
17665 (plus:SI (match_dup 1)
17666 (const_int 1)))
17667 (use (reg:SI DIRFLAG_REG))]
17668 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17669 "stosb"
17670 [(set_attr "type" "str")
17671 (set_attr "memory" "store")
17672 (set_attr "mode" "QI")])
17673
17674 (define_insn "*strsetqi_rex_1"
17675 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17676 (match_operand:QI 2 "register_operand" "a"))
17677 (set (match_operand:DI 0 "register_operand" "=D")
17678 (plus:DI (match_dup 1)
17679 (const_int 1)))
17680 (use (reg:SI DIRFLAG_REG))]
17681 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17682 "stosb"
17683 [(set_attr "type" "str")
17684 (set_attr "memory" "store")
17685 (set_attr "mode" "QI")])
17686
17687 (define_expand "rep_stos"
17688 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17689 (set (match_operand 0 "register_operand" "")
17690 (match_operand 4 "" ""))
17691 (set (match_operand 2 "memory_operand" "") (const_int 0))
17692 (use (match_operand 3 "register_operand" ""))
17693 (use (match_dup 1))
17694 (use (reg:SI DIRFLAG_REG))])]
17695 ""
17696 "")
17697
17698 (define_insn "*rep_stosdi_rex64"
17699 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17700 (set (match_operand:DI 0 "register_operand" "=D")
17701 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17702 (const_int 3))
17703 (match_operand:DI 3 "register_operand" "0")))
17704 (set (mem:BLK (match_dup 3))
17705 (const_int 0))
17706 (use (match_operand:DI 2 "register_operand" "a"))
17707 (use (match_dup 4))
17708 (use (reg:SI DIRFLAG_REG))]
17709 "TARGET_64BIT"
17710 "{rep\;stosq|rep stosq}"
17711 [(set_attr "type" "str")
17712 (set_attr "prefix_rep" "1")
17713 (set_attr "memory" "store")
17714 (set_attr "mode" "DI")])
17715
17716 (define_insn "*rep_stossi"
17717 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17718 (set (match_operand:SI 0 "register_operand" "=D")
17719 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17720 (const_int 2))
17721 (match_operand:SI 3 "register_operand" "0")))
17722 (set (mem:BLK (match_dup 3))
17723 (const_int 0))
17724 (use (match_operand:SI 2 "register_operand" "a"))
17725 (use (match_dup 4))
17726 (use (reg:SI DIRFLAG_REG))]
17727 "!TARGET_64BIT"
17728 "{rep\;stosl|rep stosd}"
17729 [(set_attr "type" "str")
17730 (set_attr "prefix_rep" "1")
17731 (set_attr "memory" "store")
17732 (set_attr "mode" "SI")])
17733
17734 (define_insn "*rep_stossi_rex64"
17735 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17736 (set (match_operand:DI 0 "register_operand" "=D")
17737 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17738 (const_int 2))
17739 (match_operand:DI 3 "register_operand" "0")))
17740 (set (mem:BLK (match_dup 3))
17741 (const_int 0))
17742 (use (match_operand:SI 2 "register_operand" "a"))
17743 (use (match_dup 4))
17744 (use (reg:SI DIRFLAG_REG))]
17745 "TARGET_64BIT"
17746 "{rep\;stosl|rep stosd}"
17747 [(set_attr "type" "str")
17748 (set_attr "prefix_rep" "1")
17749 (set_attr "memory" "store")
17750 (set_attr "mode" "SI")])
17751
17752 (define_insn "*rep_stosqi"
17753 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17754 (set (match_operand:SI 0 "register_operand" "=D")
17755 (plus:SI (match_operand:SI 3 "register_operand" "0")
17756 (match_operand:SI 4 "register_operand" "1")))
17757 (set (mem:BLK (match_dup 3))
17758 (const_int 0))
17759 (use (match_operand:QI 2 "register_operand" "a"))
17760 (use (match_dup 4))
17761 (use (reg:SI DIRFLAG_REG))]
17762 "!TARGET_64BIT"
17763 "{rep\;stosb|rep stosb}"
17764 [(set_attr "type" "str")
17765 (set_attr "prefix_rep" "1")
17766 (set_attr "memory" "store")
17767 (set_attr "mode" "QI")])
17768
17769 (define_insn "*rep_stosqi_rex64"
17770 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17771 (set (match_operand:DI 0 "register_operand" "=D")
17772 (plus:DI (match_operand:DI 3 "register_operand" "0")
17773 (match_operand:DI 4 "register_operand" "1")))
17774 (set (mem:BLK (match_dup 3))
17775 (const_int 0))
17776 (use (match_operand:QI 2 "register_operand" "a"))
17777 (use (match_dup 4))
17778 (use (reg:SI DIRFLAG_REG))]
17779 "TARGET_64BIT"
17780 "{rep\;stosb|rep stosb}"
17781 [(set_attr "type" "str")
17782 (set_attr "prefix_rep" "1")
17783 (set_attr "memory" "store")
17784 (set_attr "mode" "QI")])
17785
17786 (define_expand "cmpstrnsi"
17787 [(set (match_operand:SI 0 "register_operand" "")
17788 (compare:SI (match_operand:BLK 1 "general_operand" "")
17789 (match_operand:BLK 2 "general_operand" "")))
17790 (use (match_operand 3 "general_operand" ""))
17791 (use (match_operand 4 "immediate_operand" ""))]
17792 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17793 {
17794 rtx addr1, addr2, out, outlow, count, countreg, align;
17795
17796 /* Can't use this if the user has appropriated esi or edi. */
17797 if (global_regs[4] || global_regs[5])
17798 FAIL;
17799
17800 out = operands[0];
17801 if (GET_CODE (out) != REG)
17802 out = gen_reg_rtx (SImode);
17803
17804 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17805 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17806 if (addr1 != XEXP (operands[1], 0))
17807 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17808 if (addr2 != XEXP (operands[2], 0))
17809 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17810
17811 count = operands[3];
17812 countreg = ix86_zero_extend_to_Pmode (count);
17813
17814 /* %%% Iff we are testing strict equality, we can use known alignment
17815 to good advantage. This may be possible with combine, particularly
17816 once cc0 is dead. */
17817 align = operands[4];
17818
17819 emit_insn (gen_cld ());
17820 if (GET_CODE (count) == CONST_INT)
17821 {
17822 if (INTVAL (count) == 0)
17823 {
17824 emit_move_insn (operands[0], const0_rtx);
17825 DONE;
17826 }
17827 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17828 operands[1], operands[2]));
17829 }
17830 else
17831 {
17832 if (TARGET_64BIT)
17833 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17834 else
17835 emit_insn (gen_cmpsi_1 (countreg, countreg));
17836 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17837 operands[1], operands[2]));
17838 }
17839
17840 outlow = gen_lowpart (QImode, out);
17841 emit_insn (gen_cmpintqi (outlow));
17842 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17843
17844 if (operands[0] != out)
17845 emit_move_insn (operands[0], out);
17846
17847 DONE;
17848 })
17849
17850 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17851
17852 (define_expand "cmpintqi"
17853 [(set (match_dup 1)
17854 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17855 (set (match_dup 2)
17856 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17857 (parallel [(set (match_operand:QI 0 "register_operand" "")
17858 (minus:QI (match_dup 1)
17859 (match_dup 2)))
17860 (clobber (reg:CC FLAGS_REG))])]
17861 ""
17862 "operands[1] = gen_reg_rtx (QImode);
17863 operands[2] = gen_reg_rtx (QImode);")
17864
17865 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17866 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17867
17868 (define_expand "cmpstrnqi_nz_1"
17869 [(parallel [(set (reg:CC FLAGS_REG)
17870 (compare:CC (match_operand 4 "memory_operand" "")
17871 (match_operand 5 "memory_operand" "")))
17872 (use (match_operand 2 "register_operand" ""))
17873 (use (match_operand:SI 3 "immediate_operand" ""))
17874 (use (reg:SI DIRFLAG_REG))
17875 (clobber (match_operand 0 "register_operand" ""))
17876 (clobber (match_operand 1 "register_operand" ""))
17877 (clobber (match_dup 2))])]
17878 ""
17879 "")
17880
17881 (define_insn "*cmpstrnqi_nz_1"
17882 [(set (reg:CC FLAGS_REG)
17883 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17884 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17885 (use (match_operand:SI 6 "register_operand" "2"))
17886 (use (match_operand:SI 3 "immediate_operand" "i"))
17887 (use (reg:SI DIRFLAG_REG))
17888 (clobber (match_operand:SI 0 "register_operand" "=S"))
17889 (clobber (match_operand:SI 1 "register_operand" "=D"))
17890 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17891 "!TARGET_64BIT"
17892 "repz{\;| }cmpsb"
17893 [(set_attr "type" "str")
17894 (set_attr "mode" "QI")
17895 (set_attr "prefix_rep" "1")])
17896
17897 (define_insn "*cmpstrnqi_nz_rex_1"
17898 [(set (reg:CC FLAGS_REG)
17899 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17900 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17901 (use (match_operand:DI 6 "register_operand" "2"))
17902 (use (match_operand:SI 3 "immediate_operand" "i"))
17903 (use (reg:SI DIRFLAG_REG))
17904 (clobber (match_operand:DI 0 "register_operand" "=S"))
17905 (clobber (match_operand:DI 1 "register_operand" "=D"))
17906 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17907 "TARGET_64BIT"
17908 "repz{\;| }cmpsb"
17909 [(set_attr "type" "str")
17910 (set_attr "mode" "QI")
17911 (set_attr "prefix_rep" "1")])
17912
17913 ;; The same, but the count is not known to not be zero.
17914
17915 (define_expand "cmpstrnqi_1"
17916 [(parallel [(set (reg:CC FLAGS_REG)
17917 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17918 (const_int 0))
17919 (compare:CC (match_operand 4 "memory_operand" "")
17920 (match_operand 5 "memory_operand" ""))
17921 (const_int 0)))
17922 (use (match_operand:SI 3 "immediate_operand" ""))
17923 (use (reg:CC FLAGS_REG))
17924 (use (reg:SI DIRFLAG_REG))
17925 (clobber (match_operand 0 "register_operand" ""))
17926 (clobber (match_operand 1 "register_operand" ""))
17927 (clobber (match_dup 2))])]
17928 ""
17929 "")
17930
17931 (define_insn "*cmpstrnqi_1"
17932 [(set (reg:CC FLAGS_REG)
17933 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17934 (const_int 0))
17935 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17936 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17937 (const_int 0)))
17938 (use (match_operand:SI 3 "immediate_operand" "i"))
17939 (use (reg:CC FLAGS_REG))
17940 (use (reg:SI DIRFLAG_REG))
17941 (clobber (match_operand:SI 0 "register_operand" "=S"))
17942 (clobber (match_operand:SI 1 "register_operand" "=D"))
17943 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17944 "!TARGET_64BIT"
17945 "repz{\;| }cmpsb"
17946 [(set_attr "type" "str")
17947 (set_attr "mode" "QI")
17948 (set_attr "prefix_rep" "1")])
17949
17950 (define_insn "*cmpstrnqi_rex_1"
17951 [(set (reg:CC FLAGS_REG)
17952 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17953 (const_int 0))
17954 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17955 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17956 (const_int 0)))
17957 (use (match_operand:SI 3 "immediate_operand" "i"))
17958 (use (reg:CC FLAGS_REG))
17959 (use (reg:SI DIRFLAG_REG))
17960 (clobber (match_operand:DI 0 "register_operand" "=S"))
17961 (clobber (match_operand:DI 1 "register_operand" "=D"))
17962 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17963 "TARGET_64BIT"
17964 "repz{\;| }cmpsb"
17965 [(set_attr "type" "str")
17966 (set_attr "mode" "QI")
17967 (set_attr "prefix_rep" "1")])
17968
17969 (define_expand "strlensi"
17970 [(set (match_operand:SI 0 "register_operand" "")
17971 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17972 (match_operand:QI 2 "immediate_operand" "")
17973 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17974 ""
17975 {
17976 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17977 DONE;
17978 else
17979 FAIL;
17980 })
17981
17982 (define_expand "strlendi"
17983 [(set (match_operand:DI 0 "register_operand" "")
17984 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17985 (match_operand:QI 2 "immediate_operand" "")
17986 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17987 ""
17988 {
17989 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17990 DONE;
17991 else
17992 FAIL;
17993 })
17994
17995 (define_expand "strlenqi_1"
17996 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17997 (use (reg:SI DIRFLAG_REG))
17998 (clobber (match_operand 1 "register_operand" ""))
17999 (clobber (reg:CC FLAGS_REG))])]
18000 ""
18001 "")
18002
18003 (define_insn "*strlenqi_1"
18004 [(set (match_operand:SI 0 "register_operand" "=&c")
18005 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18006 (match_operand:QI 2 "register_operand" "a")
18007 (match_operand:SI 3 "immediate_operand" "i")
18008 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18009 (use (reg:SI DIRFLAG_REG))
18010 (clobber (match_operand:SI 1 "register_operand" "=D"))
18011 (clobber (reg:CC FLAGS_REG))]
18012 "!TARGET_64BIT"
18013 "repnz{\;| }scasb"
18014 [(set_attr "type" "str")
18015 (set_attr "mode" "QI")
18016 (set_attr "prefix_rep" "1")])
18017
18018 (define_insn "*strlenqi_rex_1"
18019 [(set (match_operand:DI 0 "register_operand" "=&c")
18020 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18021 (match_operand:QI 2 "register_operand" "a")
18022 (match_operand:DI 3 "immediate_operand" "i")
18023 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18024 (use (reg:SI DIRFLAG_REG))
18025 (clobber (match_operand:DI 1 "register_operand" "=D"))
18026 (clobber (reg:CC FLAGS_REG))]
18027 "TARGET_64BIT"
18028 "repnz{\;| }scasb"
18029 [(set_attr "type" "str")
18030 (set_attr "mode" "QI")
18031 (set_attr "prefix_rep" "1")])
18032
18033 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18034 ;; handled in combine, but it is not currently up to the task.
18035 ;; When used for their truth value, the cmpstrn* expanders generate
18036 ;; code like this:
18037 ;;
18038 ;; repz cmpsb
18039 ;; seta %al
18040 ;; setb %dl
18041 ;; cmpb %al, %dl
18042 ;; jcc label
18043 ;;
18044 ;; The intermediate three instructions are unnecessary.
18045
18046 ;; This one handles cmpstrn*_nz_1...
18047 (define_peephole2
18048 [(parallel[
18049 (set (reg:CC FLAGS_REG)
18050 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18051 (mem:BLK (match_operand 5 "register_operand" ""))))
18052 (use (match_operand 6 "register_operand" ""))
18053 (use (match_operand:SI 3 "immediate_operand" ""))
18054 (use (reg:SI DIRFLAG_REG))
18055 (clobber (match_operand 0 "register_operand" ""))
18056 (clobber (match_operand 1 "register_operand" ""))
18057 (clobber (match_operand 2 "register_operand" ""))])
18058 (set (match_operand:QI 7 "register_operand" "")
18059 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18060 (set (match_operand:QI 8 "register_operand" "")
18061 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18062 (set (reg FLAGS_REG)
18063 (compare (match_dup 7) (match_dup 8)))
18064 ]
18065 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18066 [(parallel[
18067 (set (reg:CC FLAGS_REG)
18068 (compare:CC (mem:BLK (match_dup 4))
18069 (mem:BLK (match_dup 5))))
18070 (use (match_dup 6))
18071 (use (match_dup 3))
18072 (use (reg:SI DIRFLAG_REG))
18073 (clobber (match_dup 0))
18074 (clobber (match_dup 1))
18075 (clobber (match_dup 2))])]
18076 "")
18077
18078 ;; ...and this one handles cmpstrn*_1.
18079 (define_peephole2
18080 [(parallel[
18081 (set (reg:CC FLAGS_REG)
18082 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18083 (const_int 0))
18084 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18085 (mem:BLK (match_operand 5 "register_operand" "")))
18086 (const_int 0)))
18087 (use (match_operand:SI 3 "immediate_operand" ""))
18088 (use (reg:CC FLAGS_REG))
18089 (use (reg:SI DIRFLAG_REG))
18090 (clobber (match_operand 0 "register_operand" ""))
18091 (clobber (match_operand 1 "register_operand" ""))
18092 (clobber (match_operand 2 "register_operand" ""))])
18093 (set (match_operand:QI 7 "register_operand" "")
18094 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18095 (set (match_operand:QI 8 "register_operand" "")
18096 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18097 (set (reg FLAGS_REG)
18098 (compare (match_dup 7) (match_dup 8)))
18099 ]
18100 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18101 [(parallel[
18102 (set (reg:CC FLAGS_REG)
18103 (if_then_else:CC (ne (match_dup 6)
18104 (const_int 0))
18105 (compare:CC (mem:BLK (match_dup 4))
18106 (mem:BLK (match_dup 5)))
18107 (const_int 0)))
18108 (use (match_dup 3))
18109 (use (reg:CC FLAGS_REG))
18110 (use (reg:SI DIRFLAG_REG))
18111 (clobber (match_dup 0))
18112 (clobber (match_dup 1))
18113 (clobber (match_dup 2))])]
18114 "")
18115
18116
18117 \f
18118 ;; Conditional move instructions.
18119
18120 (define_expand "movdicc"
18121 [(set (match_operand:DI 0 "register_operand" "")
18122 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18123 (match_operand:DI 2 "general_operand" "")
18124 (match_operand:DI 3 "general_operand" "")))]
18125 "TARGET_64BIT"
18126 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18127
18128 (define_insn "x86_movdicc_0_m1_rex64"
18129 [(set (match_operand:DI 0 "register_operand" "=r")
18130 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18131 (const_int -1)
18132 (const_int 0)))
18133 (clobber (reg:CC FLAGS_REG))]
18134 "TARGET_64BIT"
18135 "sbb{q}\t%0, %0"
18136 ; Since we don't have the proper number of operands for an alu insn,
18137 ; fill in all the blanks.
18138 [(set_attr "type" "alu")
18139 (set_attr "pent_pair" "pu")
18140 (set_attr "memory" "none")
18141 (set_attr "imm_disp" "false")
18142 (set_attr "mode" "DI")
18143 (set_attr "length_immediate" "0")])
18144
18145 (define_insn "*movdicc_c_rex64"
18146 [(set (match_operand:DI 0 "register_operand" "=r,r")
18147 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18148 [(reg FLAGS_REG) (const_int 0)])
18149 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18150 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18151 "TARGET_64BIT && TARGET_CMOVE
18152 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18153 "@
18154 cmov%O2%C1\t{%2, %0|%0, %2}
18155 cmov%O2%c1\t{%3, %0|%0, %3}"
18156 [(set_attr "type" "icmov")
18157 (set_attr "mode" "DI")])
18158
18159 (define_expand "movsicc"
18160 [(set (match_operand:SI 0 "register_operand" "")
18161 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18162 (match_operand:SI 2 "general_operand" "")
18163 (match_operand:SI 3 "general_operand" "")))]
18164 ""
18165 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18166
18167 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18168 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18169 ;; So just document what we're doing explicitly.
18170
18171 (define_insn "x86_movsicc_0_m1"
18172 [(set (match_operand:SI 0 "register_operand" "=r")
18173 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18174 (const_int -1)
18175 (const_int 0)))
18176 (clobber (reg:CC FLAGS_REG))]
18177 ""
18178 "sbb{l}\t%0, %0"
18179 ; Since we don't have the proper number of operands for an alu insn,
18180 ; fill in all the blanks.
18181 [(set_attr "type" "alu")
18182 (set_attr "pent_pair" "pu")
18183 (set_attr "memory" "none")
18184 (set_attr "imm_disp" "false")
18185 (set_attr "mode" "SI")
18186 (set_attr "length_immediate" "0")])
18187
18188 (define_insn "*movsicc_noc"
18189 [(set (match_operand:SI 0 "register_operand" "=r,r")
18190 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18191 [(reg FLAGS_REG) (const_int 0)])
18192 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18193 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18194 "TARGET_CMOVE
18195 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18196 "@
18197 cmov%O2%C1\t{%2, %0|%0, %2}
18198 cmov%O2%c1\t{%3, %0|%0, %3}"
18199 [(set_attr "type" "icmov")
18200 (set_attr "mode" "SI")])
18201
18202 (define_expand "movhicc"
18203 [(set (match_operand:HI 0 "register_operand" "")
18204 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18205 (match_operand:HI 2 "general_operand" "")
18206 (match_operand:HI 3 "general_operand" "")))]
18207 "TARGET_HIMODE_MATH"
18208 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18209
18210 (define_insn "*movhicc_noc"
18211 [(set (match_operand:HI 0 "register_operand" "=r,r")
18212 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18213 [(reg FLAGS_REG) (const_int 0)])
18214 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18215 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18216 "TARGET_CMOVE
18217 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18218 "@
18219 cmov%O2%C1\t{%2, %0|%0, %2}
18220 cmov%O2%c1\t{%3, %0|%0, %3}"
18221 [(set_attr "type" "icmov")
18222 (set_attr "mode" "HI")])
18223
18224 (define_expand "movqicc"
18225 [(set (match_operand:QI 0 "register_operand" "")
18226 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18227 (match_operand:QI 2 "general_operand" "")
18228 (match_operand:QI 3 "general_operand" "")))]
18229 "TARGET_QIMODE_MATH"
18230 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18231
18232 (define_insn_and_split "*movqicc_noc"
18233 [(set (match_operand:QI 0 "register_operand" "=r,r")
18234 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18235 [(match_operand 4 "flags_reg_operand" "")
18236 (const_int 0)])
18237 (match_operand:QI 2 "register_operand" "r,0")
18238 (match_operand:QI 3 "register_operand" "0,r")))]
18239 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18240 "#"
18241 "&& reload_completed"
18242 [(set (match_dup 0)
18243 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18244 (match_dup 2)
18245 (match_dup 3)))]
18246 "operands[0] = gen_lowpart (SImode, operands[0]);
18247 operands[2] = gen_lowpart (SImode, operands[2]);
18248 operands[3] = gen_lowpart (SImode, operands[3]);"
18249 [(set_attr "type" "icmov")
18250 (set_attr "mode" "SI")])
18251
18252 (define_expand "movsfcc"
18253 [(set (match_operand:SF 0 "register_operand" "")
18254 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18255 (match_operand:SF 2 "register_operand" "")
18256 (match_operand:SF 3 "register_operand" "")))]
18257 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18258 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18259
18260 (define_insn "*movsfcc_1_387"
18261 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18262 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18263 [(reg FLAGS_REG) (const_int 0)])
18264 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18265 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18266 "TARGET_80387 && TARGET_CMOVE
18267 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18268 "@
18269 fcmov%F1\t{%2, %0|%0, %2}
18270 fcmov%f1\t{%3, %0|%0, %3}
18271 cmov%O2%C1\t{%2, %0|%0, %2}
18272 cmov%O2%c1\t{%3, %0|%0, %3}"
18273 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18274 (set_attr "mode" "SF,SF,SI,SI")])
18275
18276 (define_expand "movdfcc"
18277 [(set (match_operand:DF 0 "register_operand" "")
18278 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18279 (match_operand:DF 2 "register_operand" "")
18280 (match_operand:DF 3 "register_operand" "")))]
18281 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18282 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18283
18284 (define_insn "*movdfcc_1"
18285 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18286 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18287 [(reg FLAGS_REG) (const_int 0)])
18288 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18289 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18290 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18291 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18292 "@
18293 fcmov%F1\t{%2, %0|%0, %2}
18294 fcmov%f1\t{%3, %0|%0, %3}
18295 #
18296 #"
18297 [(set_attr "type" "fcmov,fcmov,multi,multi")
18298 (set_attr "mode" "DF")])
18299
18300 (define_insn "*movdfcc_1_rex64"
18301 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18302 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18303 [(reg FLAGS_REG) (const_int 0)])
18304 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18305 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18306 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18307 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18308 "@
18309 fcmov%F1\t{%2, %0|%0, %2}
18310 fcmov%f1\t{%3, %0|%0, %3}
18311 cmov%O2%C1\t{%2, %0|%0, %2}
18312 cmov%O2%c1\t{%3, %0|%0, %3}"
18313 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18314 (set_attr "mode" "DF")])
18315
18316 (define_split
18317 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18318 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18319 [(match_operand 4 "flags_reg_operand" "")
18320 (const_int 0)])
18321 (match_operand:DF 2 "nonimmediate_operand" "")
18322 (match_operand:DF 3 "nonimmediate_operand" "")))]
18323 "!TARGET_64BIT && reload_completed"
18324 [(set (match_dup 2)
18325 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18326 (match_dup 5)
18327 (match_dup 7)))
18328 (set (match_dup 3)
18329 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18330 (match_dup 6)
18331 (match_dup 8)))]
18332 "split_di (operands+2, 1, operands+5, operands+6);
18333 split_di (operands+3, 1, operands+7, operands+8);
18334 split_di (operands, 1, operands+2, operands+3);")
18335
18336 (define_expand "movxfcc"
18337 [(set (match_operand:XF 0 "register_operand" "")
18338 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18339 (match_operand:XF 2 "register_operand" "")
18340 (match_operand:XF 3 "register_operand" "")))]
18341 "TARGET_80387 && TARGET_CMOVE"
18342 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18343
18344 (define_insn "*movxfcc_1"
18345 [(set (match_operand:XF 0 "register_operand" "=f,f")
18346 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18347 [(reg FLAGS_REG) (const_int 0)])
18348 (match_operand:XF 2 "register_operand" "f,0")
18349 (match_operand:XF 3 "register_operand" "0,f")))]
18350 "TARGET_80387 && TARGET_CMOVE"
18351 "@
18352 fcmov%F1\t{%2, %0|%0, %2}
18353 fcmov%f1\t{%3, %0|%0, %3}"
18354 [(set_attr "type" "fcmov")
18355 (set_attr "mode" "XF")])
18356
18357 ;; These versions of the min/max patterns are intentionally ignorant of
18358 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18359 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18360 ;; are undefined in this condition, we're certain this is correct.
18361
18362 (define_insn "sminsf3"
18363 [(set (match_operand:SF 0 "register_operand" "=x")
18364 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18365 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18366 "TARGET_SSE_MATH"
18367 "minss\t{%2, %0|%0, %2}"
18368 [(set_attr "type" "sseadd")
18369 (set_attr "mode" "SF")])
18370
18371 (define_insn "smaxsf3"
18372 [(set (match_operand:SF 0 "register_operand" "=x")
18373 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18374 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18375 "TARGET_SSE_MATH"
18376 "maxss\t{%2, %0|%0, %2}"
18377 [(set_attr "type" "sseadd")
18378 (set_attr "mode" "SF")])
18379
18380 (define_insn "smindf3"
18381 [(set (match_operand:DF 0 "register_operand" "=x")
18382 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18383 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18384 "TARGET_SSE2 && TARGET_SSE_MATH"
18385 "minsd\t{%2, %0|%0, %2}"
18386 [(set_attr "type" "sseadd")
18387 (set_attr "mode" "DF")])
18388
18389 (define_insn "smaxdf3"
18390 [(set (match_operand:DF 0 "register_operand" "=x")
18391 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18392 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18393 "TARGET_SSE2 && TARGET_SSE_MATH"
18394 "maxsd\t{%2, %0|%0, %2}"
18395 [(set_attr "type" "sseadd")
18396 (set_attr "mode" "DF")])
18397
18398 ;; These versions of the min/max patterns implement exactly the operations
18399 ;; min = (op1 < op2 ? op1 : op2)
18400 ;; max = (!(op1 < op2) ? op1 : op2)
18401 ;; Their operands are not commutative, and thus they may be used in the
18402 ;; presence of -0.0 and NaN.
18403
18404 (define_insn "*ieee_sminsf3"
18405 [(set (match_operand:SF 0 "register_operand" "=x")
18406 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18407 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18408 UNSPEC_IEEE_MIN))]
18409 "TARGET_SSE_MATH"
18410 "minss\t{%2, %0|%0, %2}"
18411 [(set_attr "type" "sseadd")
18412 (set_attr "mode" "SF")])
18413
18414 (define_insn "*ieee_smaxsf3"
18415 [(set (match_operand:SF 0 "register_operand" "=x")
18416 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18417 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18418 UNSPEC_IEEE_MAX))]
18419 "TARGET_SSE_MATH"
18420 "maxss\t{%2, %0|%0, %2}"
18421 [(set_attr "type" "sseadd")
18422 (set_attr "mode" "SF")])
18423
18424 (define_insn "*ieee_smindf3"
18425 [(set (match_operand:DF 0 "register_operand" "=x")
18426 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18427 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18428 UNSPEC_IEEE_MIN))]
18429 "TARGET_SSE2 && TARGET_SSE_MATH"
18430 "minsd\t{%2, %0|%0, %2}"
18431 [(set_attr "type" "sseadd")
18432 (set_attr "mode" "DF")])
18433
18434 (define_insn "*ieee_smaxdf3"
18435 [(set (match_operand:DF 0 "register_operand" "=x")
18436 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18437 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18438 UNSPEC_IEEE_MAX))]
18439 "TARGET_SSE2 && TARGET_SSE_MATH"
18440 "maxsd\t{%2, %0|%0, %2}"
18441 [(set_attr "type" "sseadd")
18442 (set_attr "mode" "DF")])
18443
18444 ;; Conditional addition patterns
18445 (define_expand "addqicc"
18446 [(match_operand:QI 0 "register_operand" "")
18447 (match_operand 1 "comparison_operator" "")
18448 (match_operand:QI 2 "register_operand" "")
18449 (match_operand:QI 3 "const_int_operand" "")]
18450 ""
18451 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18452
18453 (define_expand "addhicc"
18454 [(match_operand:HI 0 "register_operand" "")
18455 (match_operand 1 "comparison_operator" "")
18456 (match_operand:HI 2 "register_operand" "")
18457 (match_operand:HI 3 "const_int_operand" "")]
18458 ""
18459 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18460
18461 (define_expand "addsicc"
18462 [(match_operand:SI 0 "register_operand" "")
18463 (match_operand 1 "comparison_operator" "")
18464 (match_operand:SI 2 "register_operand" "")
18465 (match_operand:SI 3 "const_int_operand" "")]
18466 ""
18467 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18468
18469 (define_expand "adddicc"
18470 [(match_operand:DI 0 "register_operand" "")
18471 (match_operand 1 "comparison_operator" "")
18472 (match_operand:DI 2 "register_operand" "")
18473 (match_operand:DI 3 "const_int_operand" "")]
18474 "TARGET_64BIT"
18475 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18476
18477 \f
18478 ;; Misc patterns (?)
18479
18480 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18481 ;; Otherwise there will be nothing to keep
18482 ;;
18483 ;; [(set (reg ebp) (reg esp))]
18484 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18485 ;; (clobber (eflags)]
18486 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18487 ;;
18488 ;; in proper program order.
18489 (define_insn "pro_epilogue_adjust_stack_1"
18490 [(set (match_operand:SI 0 "register_operand" "=r,r")
18491 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18492 (match_operand:SI 2 "immediate_operand" "i,i")))
18493 (clobber (reg:CC FLAGS_REG))
18494 (clobber (mem:BLK (scratch)))]
18495 "!TARGET_64BIT"
18496 {
18497 switch (get_attr_type (insn))
18498 {
18499 case TYPE_IMOV:
18500 return "mov{l}\t{%1, %0|%0, %1}";
18501
18502 case TYPE_ALU:
18503 if (GET_CODE (operands[2]) == CONST_INT
18504 && (INTVAL (operands[2]) == 128
18505 || (INTVAL (operands[2]) < 0
18506 && INTVAL (operands[2]) != -128)))
18507 {
18508 operands[2] = GEN_INT (-INTVAL (operands[2]));
18509 return "sub{l}\t{%2, %0|%0, %2}";
18510 }
18511 return "add{l}\t{%2, %0|%0, %2}";
18512
18513 case TYPE_LEA:
18514 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18515 return "lea{l}\t{%a2, %0|%0, %a2}";
18516
18517 default:
18518 gcc_unreachable ();
18519 }
18520 }
18521 [(set (attr "type")
18522 (cond [(eq_attr "alternative" "0")
18523 (const_string "alu")
18524 (match_operand:SI 2 "const0_operand" "")
18525 (const_string "imov")
18526 ]
18527 (const_string "lea")))
18528 (set_attr "mode" "SI")])
18529
18530 (define_insn "pro_epilogue_adjust_stack_rex64"
18531 [(set (match_operand:DI 0 "register_operand" "=r,r")
18532 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18533 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18534 (clobber (reg:CC FLAGS_REG))
18535 (clobber (mem:BLK (scratch)))]
18536 "TARGET_64BIT"
18537 {
18538 switch (get_attr_type (insn))
18539 {
18540 case TYPE_IMOV:
18541 return "mov{q}\t{%1, %0|%0, %1}";
18542
18543 case TYPE_ALU:
18544 if (GET_CODE (operands[2]) == CONST_INT
18545 /* Avoid overflows. */
18546 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18547 && (INTVAL (operands[2]) == 128
18548 || (INTVAL (operands[2]) < 0
18549 && INTVAL (operands[2]) != -128)))
18550 {
18551 operands[2] = GEN_INT (-INTVAL (operands[2]));
18552 return "sub{q}\t{%2, %0|%0, %2}";
18553 }
18554 return "add{q}\t{%2, %0|%0, %2}";
18555
18556 case TYPE_LEA:
18557 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18558 return "lea{q}\t{%a2, %0|%0, %a2}";
18559
18560 default:
18561 gcc_unreachable ();
18562 }
18563 }
18564 [(set (attr "type")
18565 (cond [(eq_attr "alternative" "0")
18566 (const_string "alu")
18567 (match_operand:DI 2 "const0_operand" "")
18568 (const_string "imov")
18569 ]
18570 (const_string "lea")))
18571 (set_attr "mode" "DI")])
18572
18573 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18574 [(set (match_operand:DI 0 "register_operand" "=r,r")
18575 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18576 (match_operand:DI 3 "immediate_operand" "i,i")))
18577 (use (match_operand:DI 2 "register_operand" "r,r"))
18578 (clobber (reg:CC FLAGS_REG))
18579 (clobber (mem:BLK (scratch)))]
18580 "TARGET_64BIT"
18581 {
18582 switch (get_attr_type (insn))
18583 {
18584 case TYPE_ALU:
18585 return "add{q}\t{%2, %0|%0, %2}";
18586
18587 case TYPE_LEA:
18588 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18589 return "lea{q}\t{%a2, %0|%0, %a2}";
18590
18591 default:
18592 gcc_unreachable ();
18593 }
18594 }
18595 [(set_attr "type" "alu,lea")
18596 (set_attr "mode" "DI")])
18597
18598 (define_expand "allocate_stack_worker"
18599 [(match_operand:SI 0 "register_operand" "")]
18600 "TARGET_STACK_PROBE"
18601 {
18602 if (reload_completed)
18603 {
18604 if (TARGET_64BIT)
18605 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18606 else
18607 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18608 }
18609 else
18610 {
18611 if (TARGET_64BIT)
18612 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18613 else
18614 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18615 }
18616 DONE;
18617 })
18618
18619 (define_insn "allocate_stack_worker_1"
18620 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18621 UNSPECV_STACK_PROBE)
18622 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18623 (clobber (match_scratch:SI 1 "=0"))
18624 (clobber (reg:CC FLAGS_REG))]
18625 "!TARGET_64BIT && TARGET_STACK_PROBE"
18626 "call\t__alloca"
18627 [(set_attr "type" "multi")
18628 (set_attr "length" "5")])
18629
18630 (define_expand "allocate_stack_worker_postreload"
18631 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18632 UNSPECV_STACK_PROBE)
18633 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18634 (clobber (match_dup 0))
18635 (clobber (reg:CC FLAGS_REG))])]
18636 ""
18637 "")
18638
18639 (define_insn "allocate_stack_worker_rex64"
18640 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18641 UNSPECV_STACK_PROBE)
18642 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18643 (clobber (match_scratch:DI 1 "=0"))
18644 (clobber (reg:CC FLAGS_REG))]
18645 "TARGET_64BIT && TARGET_STACK_PROBE"
18646 "call\t__alloca"
18647 [(set_attr "type" "multi")
18648 (set_attr "length" "5")])
18649
18650 (define_expand "allocate_stack_worker_rex64_postreload"
18651 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18652 UNSPECV_STACK_PROBE)
18653 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18654 (clobber (match_dup 0))
18655 (clobber (reg:CC FLAGS_REG))])]
18656 ""
18657 "")
18658
18659 (define_expand "allocate_stack"
18660 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18661 (minus:SI (reg:SI SP_REG)
18662 (match_operand:SI 1 "general_operand" "")))
18663 (clobber (reg:CC FLAGS_REG))])
18664 (parallel [(set (reg:SI SP_REG)
18665 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18666 (clobber (reg:CC FLAGS_REG))])]
18667 "TARGET_STACK_PROBE"
18668 {
18669 #ifdef CHECK_STACK_LIMIT
18670 if (GET_CODE (operands[1]) == CONST_INT
18671 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18672 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18673 operands[1]));
18674 else
18675 #endif
18676 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18677 operands[1])));
18678
18679 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18680 DONE;
18681 })
18682
18683 (define_expand "builtin_setjmp_receiver"
18684 [(label_ref (match_operand 0 "" ""))]
18685 "!TARGET_64BIT && flag_pic"
18686 {
18687 emit_insn (gen_set_got (pic_offset_table_rtx));
18688 DONE;
18689 })
18690 \f
18691 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18692
18693 (define_split
18694 [(set (match_operand 0 "register_operand" "")
18695 (match_operator 3 "promotable_binary_operator"
18696 [(match_operand 1 "register_operand" "")
18697 (match_operand 2 "aligned_operand" "")]))
18698 (clobber (reg:CC FLAGS_REG))]
18699 "! TARGET_PARTIAL_REG_STALL && reload_completed
18700 && ((GET_MODE (operands[0]) == HImode
18701 && ((!optimize_size && !TARGET_FAST_PREFIX)
18702 || GET_CODE (operands[2]) != CONST_INT
18703 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18704 || (GET_MODE (operands[0]) == QImode
18705 && (TARGET_PROMOTE_QImode || optimize_size)))"
18706 [(parallel [(set (match_dup 0)
18707 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18708 (clobber (reg:CC FLAGS_REG))])]
18709 "operands[0] = gen_lowpart (SImode, operands[0]);
18710 operands[1] = gen_lowpart (SImode, operands[1]);
18711 if (GET_CODE (operands[3]) != ASHIFT)
18712 operands[2] = gen_lowpart (SImode, operands[2]);
18713 PUT_MODE (operands[3], SImode);")
18714
18715 ; Promote the QImode tests, as i386 has encoding of the AND
18716 ; instruction with 32-bit sign-extended immediate and thus the
18717 ; instruction size is unchanged, except in the %eax case for
18718 ; which it is increased by one byte, hence the ! optimize_size.
18719 (define_split
18720 [(set (match_operand 0 "flags_reg_operand" "")
18721 (match_operator 2 "compare_operator"
18722 [(and (match_operand 3 "aligned_operand" "")
18723 (match_operand 4 "const_int_operand" ""))
18724 (const_int 0)]))
18725 (set (match_operand 1 "register_operand" "")
18726 (and (match_dup 3) (match_dup 4)))]
18727 "! TARGET_PARTIAL_REG_STALL && reload_completed
18728 /* Ensure that the operand will remain sign-extended immediate. */
18729 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18730 && ! optimize_size
18731 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18732 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18733 [(parallel [(set (match_dup 0)
18734 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18735 (const_int 0)]))
18736 (set (match_dup 1)
18737 (and:SI (match_dup 3) (match_dup 4)))])]
18738 {
18739 operands[4]
18740 = gen_int_mode (INTVAL (operands[4])
18741 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18742 operands[1] = gen_lowpart (SImode, operands[1]);
18743 operands[3] = gen_lowpart (SImode, operands[3]);
18744 })
18745
18746 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18747 ; the TEST instruction with 32-bit sign-extended immediate and thus
18748 ; the instruction size would at least double, which is not what we
18749 ; want even with ! optimize_size.
18750 (define_split
18751 [(set (match_operand 0 "flags_reg_operand" "")
18752 (match_operator 1 "compare_operator"
18753 [(and (match_operand:HI 2 "aligned_operand" "")
18754 (match_operand:HI 3 "const_int_operand" ""))
18755 (const_int 0)]))]
18756 "! TARGET_PARTIAL_REG_STALL && reload_completed
18757 /* Ensure that the operand will remain sign-extended immediate. */
18758 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18759 && ! TARGET_FAST_PREFIX
18760 && ! optimize_size"
18761 [(set (match_dup 0)
18762 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18763 (const_int 0)]))]
18764 {
18765 operands[3]
18766 = gen_int_mode (INTVAL (operands[3])
18767 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18768 operands[2] = gen_lowpart (SImode, operands[2]);
18769 })
18770
18771 (define_split
18772 [(set (match_operand 0 "register_operand" "")
18773 (neg (match_operand 1 "register_operand" "")))
18774 (clobber (reg:CC FLAGS_REG))]
18775 "! TARGET_PARTIAL_REG_STALL && reload_completed
18776 && (GET_MODE (operands[0]) == HImode
18777 || (GET_MODE (operands[0]) == QImode
18778 && (TARGET_PROMOTE_QImode || optimize_size)))"
18779 [(parallel [(set (match_dup 0)
18780 (neg:SI (match_dup 1)))
18781 (clobber (reg:CC FLAGS_REG))])]
18782 "operands[0] = gen_lowpart (SImode, operands[0]);
18783 operands[1] = gen_lowpart (SImode, operands[1]);")
18784
18785 (define_split
18786 [(set (match_operand 0 "register_operand" "")
18787 (not (match_operand 1 "register_operand" "")))]
18788 "! TARGET_PARTIAL_REG_STALL && reload_completed
18789 && (GET_MODE (operands[0]) == HImode
18790 || (GET_MODE (operands[0]) == QImode
18791 && (TARGET_PROMOTE_QImode || optimize_size)))"
18792 [(set (match_dup 0)
18793 (not:SI (match_dup 1)))]
18794 "operands[0] = gen_lowpart (SImode, operands[0]);
18795 operands[1] = gen_lowpart (SImode, operands[1]);")
18796
18797 (define_split
18798 [(set (match_operand 0 "register_operand" "")
18799 (if_then_else (match_operator 1 "comparison_operator"
18800 [(reg FLAGS_REG) (const_int 0)])
18801 (match_operand 2 "register_operand" "")
18802 (match_operand 3 "register_operand" "")))]
18803 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18804 && (GET_MODE (operands[0]) == HImode
18805 || (GET_MODE (operands[0]) == QImode
18806 && (TARGET_PROMOTE_QImode || optimize_size)))"
18807 [(set (match_dup 0)
18808 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18809 "operands[0] = gen_lowpart (SImode, operands[0]);
18810 operands[2] = gen_lowpart (SImode, operands[2]);
18811 operands[3] = gen_lowpart (SImode, operands[3]);")
18812
18813 \f
18814 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18815 ;; transform a complex memory operation into two memory to register operations.
18816
18817 ;; Don't push memory operands
18818 (define_peephole2
18819 [(set (match_operand:SI 0 "push_operand" "")
18820 (match_operand:SI 1 "memory_operand" ""))
18821 (match_scratch:SI 2 "r")]
18822 "! optimize_size && ! TARGET_PUSH_MEMORY"
18823 [(set (match_dup 2) (match_dup 1))
18824 (set (match_dup 0) (match_dup 2))]
18825 "")
18826
18827 (define_peephole2
18828 [(set (match_operand:DI 0 "push_operand" "")
18829 (match_operand:DI 1 "memory_operand" ""))
18830 (match_scratch:DI 2 "r")]
18831 "! optimize_size && ! TARGET_PUSH_MEMORY"
18832 [(set (match_dup 2) (match_dup 1))
18833 (set (match_dup 0) (match_dup 2))]
18834 "")
18835
18836 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18837 ;; SImode pushes.
18838 (define_peephole2
18839 [(set (match_operand:SF 0 "push_operand" "")
18840 (match_operand:SF 1 "memory_operand" ""))
18841 (match_scratch:SF 2 "r")]
18842 "! optimize_size && ! TARGET_PUSH_MEMORY"
18843 [(set (match_dup 2) (match_dup 1))
18844 (set (match_dup 0) (match_dup 2))]
18845 "")
18846
18847 (define_peephole2
18848 [(set (match_operand:HI 0 "push_operand" "")
18849 (match_operand:HI 1 "memory_operand" ""))
18850 (match_scratch:HI 2 "r")]
18851 "! optimize_size && ! TARGET_PUSH_MEMORY"
18852 [(set (match_dup 2) (match_dup 1))
18853 (set (match_dup 0) (match_dup 2))]
18854 "")
18855
18856 (define_peephole2
18857 [(set (match_operand:QI 0 "push_operand" "")
18858 (match_operand:QI 1 "memory_operand" ""))
18859 (match_scratch:QI 2 "q")]
18860 "! optimize_size && ! TARGET_PUSH_MEMORY"
18861 [(set (match_dup 2) (match_dup 1))
18862 (set (match_dup 0) (match_dup 2))]
18863 "")
18864
18865 ;; Don't move an immediate directly to memory when the instruction
18866 ;; gets too big.
18867 (define_peephole2
18868 [(match_scratch:SI 1 "r")
18869 (set (match_operand:SI 0 "memory_operand" "")
18870 (const_int 0))]
18871 "! optimize_size
18872 && ! TARGET_USE_MOV0
18873 && TARGET_SPLIT_LONG_MOVES
18874 && get_attr_length (insn) >= ix86_cost->large_insn
18875 && peep2_regno_dead_p (0, FLAGS_REG)"
18876 [(parallel [(set (match_dup 1) (const_int 0))
18877 (clobber (reg:CC FLAGS_REG))])
18878 (set (match_dup 0) (match_dup 1))]
18879 "")
18880
18881 (define_peephole2
18882 [(match_scratch:HI 1 "r")
18883 (set (match_operand:HI 0 "memory_operand" "")
18884 (const_int 0))]
18885 "! optimize_size
18886 && ! TARGET_USE_MOV0
18887 && TARGET_SPLIT_LONG_MOVES
18888 && get_attr_length (insn) >= ix86_cost->large_insn
18889 && peep2_regno_dead_p (0, FLAGS_REG)"
18890 [(parallel [(set (match_dup 2) (const_int 0))
18891 (clobber (reg:CC FLAGS_REG))])
18892 (set (match_dup 0) (match_dup 1))]
18893 "operands[2] = gen_lowpart (SImode, operands[1]);")
18894
18895 (define_peephole2
18896 [(match_scratch:QI 1 "q")
18897 (set (match_operand:QI 0 "memory_operand" "")
18898 (const_int 0))]
18899 "! optimize_size
18900 && ! TARGET_USE_MOV0
18901 && TARGET_SPLIT_LONG_MOVES
18902 && get_attr_length (insn) >= ix86_cost->large_insn
18903 && peep2_regno_dead_p (0, FLAGS_REG)"
18904 [(parallel [(set (match_dup 2) (const_int 0))
18905 (clobber (reg:CC FLAGS_REG))])
18906 (set (match_dup 0) (match_dup 1))]
18907 "operands[2] = gen_lowpart (SImode, operands[1]);")
18908
18909 (define_peephole2
18910 [(match_scratch:SI 2 "r")
18911 (set (match_operand:SI 0 "memory_operand" "")
18912 (match_operand:SI 1 "immediate_operand" ""))]
18913 "! optimize_size
18914 && get_attr_length (insn) >= ix86_cost->large_insn
18915 && TARGET_SPLIT_LONG_MOVES"
18916 [(set (match_dup 2) (match_dup 1))
18917 (set (match_dup 0) (match_dup 2))]
18918 "")
18919
18920 (define_peephole2
18921 [(match_scratch:HI 2 "r")
18922 (set (match_operand:HI 0 "memory_operand" "")
18923 (match_operand:HI 1 "immediate_operand" ""))]
18924 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18925 && TARGET_SPLIT_LONG_MOVES"
18926 [(set (match_dup 2) (match_dup 1))
18927 (set (match_dup 0) (match_dup 2))]
18928 "")
18929
18930 (define_peephole2
18931 [(match_scratch:QI 2 "q")
18932 (set (match_operand:QI 0 "memory_operand" "")
18933 (match_operand:QI 1 "immediate_operand" ""))]
18934 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18935 && TARGET_SPLIT_LONG_MOVES"
18936 [(set (match_dup 2) (match_dup 1))
18937 (set (match_dup 0) (match_dup 2))]
18938 "")
18939
18940 ;; Don't compare memory with zero, load and use a test instead.
18941 (define_peephole2
18942 [(set (match_operand 0 "flags_reg_operand" "")
18943 (match_operator 1 "compare_operator"
18944 [(match_operand:SI 2 "memory_operand" "")
18945 (const_int 0)]))
18946 (match_scratch:SI 3 "r")]
18947 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18948 [(set (match_dup 3) (match_dup 2))
18949 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18950 "")
18951
18952 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18953 ;; Don't split NOTs with a displacement operand, because resulting XOR
18954 ;; will not be pairable anyway.
18955 ;;
18956 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18957 ;; represented using a modRM byte. The XOR replacement is long decoded,
18958 ;; so this split helps here as well.
18959 ;;
18960 ;; Note: Can't do this as a regular split because we can't get proper
18961 ;; lifetime information then.
18962
18963 (define_peephole2
18964 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18965 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18966 "!optimize_size
18967 && peep2_regno_dead_p (0, FLAGS_REG)
18968 && ((TARGET_PENTIUM
18969 && (GET_CODE (operands[0]) != MEM
18970 || !memory_displacement_operand (operands[0], SImode)))
18971 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18972 [(parallel [(set (match_dup 0)
18973 (xor:SI (match_dup 1) (const_int -1)))
18974 (clobber (reg:CC FLAGS_REG))])]
18975 "")
18976
18977 (define_peephole2
18978 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18979 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18980 "!optimize_size
18981 && peep2_regno_dead_p (0, FLAGS_REG)
18982 && ((TARGET_PENTIUM
18983 && (GET_CODE (operands[0]) != MEM
18984 || !memory_displacement_operand (operands[0], HImode)))
18985 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18986 [(parallel [(set (match_dup 0)
18987 (xor:HI (match_dup 1) (const_int -1)))
18988 (clobber (reg:CC FLAGS_REG))])]
18989 "")
18990
18991 (define_peephole2
18992 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18993 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18994 "!optimize_size
18995 && peep2_regno_dead_p (0, FLAGS_REG)
18996 && ((TARGET_PENTIUM
18997 && (GET_CODE (operands[0]) != MEM
18998 || !memory_displacement_operand (operands[0], QImode)))
18999 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19000 [(parallel [(set (match_dup 0)
19001 (xor:QI (match_dup 1) (const_int -1)))
19002 (clobber (reg:CC FLAGS_REG))])]
19003 "")
19004
19005 ;; Non pairable "test imm, reg" instructions can be translated to
19006 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19007 ;; byte opcode instead of two, have a short form for byte operands),
19008 ;; so do it for other CPUs as well. Given that the value was dead,
19009 ;; this should not create any new dependencies. Pass on the sub-word
19010 ;; versions if we're concerned about partial register stalls.
19011
19012 (define_peephole2
19013 [(set (match_operand 0 "flags_reg_operand" "")
19014 (match_operator 1 "compare_operator"
19015 [(and:SI (match_operand:SI 2 "register_operand" "")
19016 (match_operand:SI 3 "immediate_operand" ""))
19017 (const_int 0)]))]
19018 "ix86_match_ccmode (insn, CCNOmode)
19019 && (true_regnum (operands[2]) != 0
19020 || (GET_CODE (operands[3]) == CONST_INT
19021 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19022 && peep2_reg_dead_p (1, operands[2])"
19023 [(parallel
19024 [(set (match_dup 0)
19025 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19026 (const_int 0)]))
19027 (set (match_dup 2)
19028 (and:SI (match_dup 2) (match_dup 3)))])]
19029 "")
19030
19031 ;; We don't need to handle HImode case, because it will be promoted to SImode
19032 ;; on ! TARGET_PARTIAL_REG_STALL
19033
19034 (define_peephole2
19035 [(set (match_operand 0 "flags_reg_operand" "")
19036 (match_operator 1 "compare_operator"
19037 [(and:QI (match_operand:QI 2 "register_operand" "")
19038 (match_operand:QI 3 "immediate_operand" ""))
19039 (const_int 0)]))]
19040 "! TARGET_PARTIAL_REG_STALL
19041 && ix86_match_ccmode (insn, CCNOmode)
19042 && true_regnum (operands[2]) != 0
19043 && peep2_reg_dead_p (1, operands[2])"
19044 [(parallel
19045 [(set (match_dup 0)
19046 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19047 (const_int 0)]))
19048 (set (match_dup 2)
19049 (and:QI (match_dup 2) (match_dup 3)))])]
19050 "")
19051
19052 (define_peephole2
19053 [(set (match_operand 0 "flags_reg_operand" "")
19054 (match_operator 1 "compare_operator"
19055 [(and:SI
19056 (zero_extract:SI
19057 (match_operand 2 "ext_register_operand" "")
19058 (const_int 8)
19059 (const_int 8))
19060 (match_operand 3 "const_int_operand" ""))
19061 (const_int 0)]))]
19062 "! TARGET_PARTIAL_REG_STALL
19063 && ix86_match_ccmode (insn, CCNOmode)
19064 && true_regnum (operands[2]) != 0
19065 && peep2_reg_dead_p (1, operands[2])"
19066 [(parallel [(set (match_dup 0)
19067 (match_op_dup 1
19068 [(and:SI
19069 (zero_extract:SI
19070 (match_dup 2)
19071 (const_int 8)
19072 (const_int 8))
19073 (match_dup 3))
19074 (const_int 0)]))
19075 (set (zero_extract:SI (match_dup 2)
19076 (const_int 8)
19077 (const_int 8))
19078 (and:SI
19079 (zero_extract:SI
19080 (match_dup 2)
19081 (const_int 8)
19082 (const_int 8))
19083 (match_dup 3)))])]
19084 "")
19085
19086 ;; Don't do logical operations with memory inputs.
19087 (define_peephole2
19088 [(match_scratch:SI 2 "r")
19089 (parallel [(set (match_operand:SI 0 "register_operand" "")
19090 (match_operator:SI 3 "arith_or_logical_operator"
19091 [(match_dup 0)
19092 (match_operand:SI 1 "memory_operand" "")]))
19093 (clobber (reg:CC FLAGS_REG))])]
19094 "! optimize_size && ! TARGET_READ_MODIFY"
19095 [(set (match_dup 2) (match_dup 1))
19096 (parallel [(set (match_dup 0)
19097 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19098 (clobber (reg:CC FLAGS_REG))])]
19099 "")
19100
19101 (define_peephole2
19102 [(match_scratch:SI 2 "r")
19103 (parallel [(set (match_operand:SI 0 "register_operand" "")
19104 (match_operator:SI 3 "arith_or_logical_operator"
19105 [(match_operand:SI 1 "memory_operand" "")
19106 (match_dup 0)]))
19107 (clobber (reg:CC FLAGS_REG))])]
19108 "! optimize_size && ! TARGET_READ_MODIFY"
19109 [(set (match_dup 2) (match_dup 1))
19110 (parallel [(set (match_dup 0)
19111 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19112 (clobber (reg:CC FLAGS_REG))])]
19113 "")
19114
19115 ; Don't do logical operations with memory outputs
19116 ;
19117 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19118 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19119 ; the same decoder scheduling characteristics as the original.
19120
19121 (define_peephole2
19122 [(match_scratch:SI 2 "r")
19123 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19124 (match_operator:SI 3 "arith_or_logical_operator"
19125 [(match_dup 0)
19126 (match_operand:SI 1 "nonmemory_operand" "")]))
19127 (clobber (reg:CC FLAGS_REG))])]
19128 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19129 [(set (match_dup 2) (match_dup 0))
19130 (parallel [(set (match_dup 2)
19131 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19132 (clobber (reg:CC FLAGS_REG))])
19133 (set (match_dup 0) (match_dup 2))]
19134 "")
19135
19136 (define_peephole2
19137 [(match_scratch:SI 2 "r")
19138 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19139 (match_operator:SI 3 "arith_or_logical_operator"
19140 [(match_operand:SI 1 "nonmemory_operand" "")
19141 (match_dup 0)]))
19142 (clobber (reg:CC FLAGS_REG))])]
19143 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19144 [(set (match_dup 2) (match_dup 0))
19145 (parallel [(set (match_dup 2)
19146 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19147 (clobber (reg:CC FLAGS_REG))])
19148 (set (match_dup 0) (match_dup 2))]
19149 "")
19150
19151 ;; Attempt to always use XOR for zeroing registers.
19152 (define_peephole2
19153 [(set (match_operand 0 "register_operand" "")
19154 (match_operand 1 "const0_operand" ""))]
19155 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19156 && (! TARGET_USE_MOV0 || optimize_size)
19157 && GENERAL_REG_P (operands[0])
19158 && peep2_regno_dead_p (0, FLAGS_REG)"
19159 [(parallel [(set (match_dup 0) (const_int 0))
19160 (clobber (reg:CC FLAGS_REG))])]
19161 {
19162 operands[0] = gen_lowpart (word_mode, operands[0]);
19163 })
19164
19165 (define_peephole2
19166 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19167 (const_int 0))]
19168 "(GET_MODE (operands[0]) == QImode
19169 || GET_MODE (operands[0]) == HImode)
19170 && (! TARGET_USE_MOV0 || optimize_size)
19171 && peep2_regno_dead_p (0, FLAGS_REG)"
19172 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19173 (clobber (reg:CC FLAGS_REG))])])
19174
19175 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19176 (define_peephole2
19177 [(set (match_operand 0 "register_operand" "")
19178 (const_int -1))]
19179 "(GET_MODE (operands[0]) == HImode
19180 || GET_MODE (operands[0]) == SImode
19181 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19182 && (optimize_size || TARGET_PENTIUM)
19183 && peep2_regno_dead_p (0, FLAGS_REG)"
19184 [(parallel [(set (match_dup 0) (const_int -1))
19185 (clobber (reg:CC FLAGS_REG))])]
19186 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19187 operands[0]);")
19188
19189 ;; Attempt to convert simple leas to adds. These can be created by
19190 ;; move expanders.
19191 (define_peephole2
19192 [(set (match_operand:SI 0 "register_operand" "")
19193 (plus:SI (match_dup 0)
19194 (match_operand:SI 1 "nonmemory_operand" "")))]
19195 "peep2_regno_dead_p (0, FLAGS_REG)"
19196 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19197 (clobber (reg:CC FLAGS_REG))])]
19198 "")
19199
19200 (define_peephole2
19201 [(set (match_operand:SI 0 "register_operand" "")
19202 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19203 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19204 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19205 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19206 (clobber (reg:CC FLAGS_REG))])]
19207 "operands[2] = gen_lowpart (SImode, operands[2]);")
19208
19209 (define_peephole2
19210 [(set (match_operand:DI 0 "register_operand" "")
19211 (plus:DI (match_dup 0)
19212 (match_operand:DI 1 "x86_64_general_operand" "")))]
19213 "peep2_regno_dead_p (0, FLAGS_REG)"
19214 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19215 (clobber (reg:CC FLAGS_REG))])]
19216 "")
19217
19218 (define_peephole2
19219 [(set (match_operand:SI 0 "register_operand" "")
19220 (mult:SI (match_dup 0)
19221 (match_operand:SI 1 "const_int_operand" "")))]
19222 "exact_log2 (INTVAL (operands[1])) >= 0
19223 && peep2_regno_dead_p (0, FLAGS_REG)"
19224 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19225 (clobber (reg:CC FLAGS_REG))])]
19226 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19227
19228 (define_peephole2
19229 [(set (match_operand:DI 0 "register_operand" "")
19230 (mult:DI (match_dup 0)
19231 (match_operand:DI 1 "const_int_operand" "")))]
19232 "exact_log2 (INTVAL (operands[1])) >= 0
19233 && peep2_regno_dead_p (0, FLAGS_REG)"
19234 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19235 (clobber (reg:CC FLAGS_REG))])]
19236 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19237
19238 (define_peephole2
19239 [(set (match_operand:SI 0 "register_operand" "")
19240 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19241 (match_operand:DI 2 "const_int_operand" "")) 0))]
19242 "exact_log2 (INTVAL (operands[2])) >= 0
19243 && REGNO (operands[0]) == REGNO (operands[1])
19244 && peep2_regno_dead_p (0, FLAGS_REG)"
19245 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19246 (clobber (reg:CC FLAGS_REG))])]
19247 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19248
19249 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19250 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19251 ;; many CPUs it is also faster, since special hardware to avoid esp
19252 ;; dependencies is present.
19253
19254 ;; While some of these conversions may be done using splitters, we use peepholes
19255 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19256
19257 ;; Convert prologue esp subtractions to push.
19258 ;; We need register to push. In order to keep verify_flow_info happy we have
19259 ;; two choices
19260 ;; - use scratch and clobber it in order to avoid dependencies
19261 ;; - use already live register
19262 ;; We can't use the second way right now, since there is no reliable way how to
19263 ;; verify that given register is live. First choice will also most likely in
19264 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19265 ;; call clobbered registers are dead. We may want to use base pointer as an
19266 ;; alternative when no register is available later.
19267
19268 (define_peephole2
19269 [(match_scratch:SI 0 "r")
19270 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19271 (clobber (reg:CC FLAGS_REG))
19272 (clobber (mem:BLK (scratch)))])]
19273 "optimize_size || !TARGET_SUB_ESP_4"
19274 [(clobber (match_dup 0))
19275 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19276 (clobber (mem:BLK (scratch)))])])
19277
19278 (define_peephole2
19279 [(match_scratch:SI 0 "r")
19280 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19281 (clobber (reg:CC FLAGS_REG))
19282 (clobber (mem:BLK (scratch)))])]
19283 "optimize_size || !TARGET_SUB_ESP_8"
19284 [(clobber (match_dup 0))
19285 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19286 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19287 (clobber (mem:BLK (scratch)))])])
19288
19289 ;; Convert esp subtractions to push.
19290 (define_peephole2
19291 [(match_scratch:SI 0 "r")
19292 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19293 (clobber (reg:CC FLAGS_REG))])]
19294 "optimize_size || !TARGET_SUB_ESP_4"
19295 [(clobber (match_dup 0))
19296 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19297
19298 (define_peephole2
19299 [(match_scratch:SI 0 "r")
19300 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19301 (clobber (reg:CC FLAGS_REG))])]
19302 "optimize_size || !TARGET_SUB_ESP_8"
19303 [(clobber (match_dup 0))
19304 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19305 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19306
19307 ;; Convert epilogue deallocator to pop.
19308 (define_peephole2
19309 [(match_scratch:SI 0 "r")
19310 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19311 (clobber (reg:CC FLAGS_REG))
19312 (clobber (mem:BLK (scratch)))])]
19313 "optimize_size || !TARGET_ADD_ESP_4"
19314 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19315 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19316 (clobber (mem:BLK (scratch)))])]
19317 "")
19318
19319 ;; Two pops case is tricky, since pop causes dependency on destination register.
19320 ;; We use two registers if available.
19321 (define_peephole2
19322 [(match_scratch:SI 0 "r")
19323 (match_scratch:SI 1 "r")
19324 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19325 (clobber (reg:CC FLAGS_REG))
19326 (clobber (mem:BLK (scratch)))])]
19327 "optimize_size || !TARGET_ADD_ESP_8"
19328 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19329 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19330 (clobber (mem:BLK (scratch)))])
19331 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19332 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19333 "")
19334
19335 (define_peephole2
19336 [(match_scratch:SI 0 "r")
19337 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19338 (clobber (reg:CC FLAGS_REG))
19339 (clobber (mem:BLK (scratch)))])]
19340 "optimize_size"
19341 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19342 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19343 (clobber (mem:BLK (scratch)))])
19344 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19345 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19346 "")
19347
19348 ;; Convert esp additions to pop.
19349 (define_peephole2
19350 [(match_scratch:SI 0 "r")
19351 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19352 (clobber (reg:CC FLAGS_REG))])]
19353 ""
19354 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19355 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19356 "")
19357
19358 ;; Two pops case is tricky, since pop causes dependency on destination register.
19359 ;; We use two registers if available.
19360 (define_peephole2
19361 [(match_scratch:SI 0 "r")
19362 (match_scratch:SI 1 "r")
19363 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19364 (clobber (reg:CC FLAGS_REG))])]
19365 ""
19366 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19367 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19368 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19369 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19370 "")
19371
19372 (define_peephole2
19373 [(match_scratch:SI 0 "r")
19374 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19375 (clobber (reg:CC FLAGS_REG))])]
19376 "optimize_size"
19377 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19378 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19379 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19380 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19381 "")
19382 \f
19383 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19384 ;; required and register dies. Similarly for 128 to plus -128.
19385 (define_peephole2
19386 [(set (match_operand 0 "flags_reg_operand" "")
19387 (match_operator 1 "compare_operator"
19388 [(match_operand 2 "register_operand" "")
19389 (match_operand 3 "const_int_operand" "")]))]
19390 "(INTVAL (operands[3]) == -1
19391 || INTVAL (operands[3]) == 1
19392 || INTVAL (operands[3]) == 128)
19393 && ix86_match_ccmode (insn, CCGCmode)
19394 && peep2_reg_dead_p (1, operands[2])"
19395 [(parallel [(set (match_dup 0)
19396 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19397 (clobber (match_dup 2))])]
19398 "")
19399 \f
19400 (define_peephole2
19401 [(match_scratch:DI 0 "r")
19402 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19403 (clobber (reg:CC FLAGS_REG))
19404 (clobber (mem:BLK (scratch)))])]
19405 "optimize_size || !TARGET_SUB_ESP_4"
19406 [(clobber (match_dup 0))
19407 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19408 (clobber (mem:BLK (scratch)))])])
19409
19410 (define_peephole2
19411 [(match_scratch:DI 0 "r")
19412 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19413 (clobber (reg:CC FLAGS_REG))
19414 (clobber (mem:BLK (scratch)))])]
19415 "optimize_size || !TARGET_SUB_ESP_8"
19416 [(clobber (match_dup 0))
19417 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19418 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19419 (clobber (mem:BLK (scratch)))])])
19420
19421 ;; Convert esp subtractions to push.
19422 (define_peephole2
19423 [(match_scratch:DI 0 "r")
19424 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19425 (clobber (reg:CC FLAGS_REG))])]
19426 "optimize_size || !TARGET_SUB_ESP_4"
19427 [(clobber (match_dup 0))
19428 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19429
19430 (define_peephole2
19431 [(match_scratch:DI 0 "r")
19432 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19433 (clobber (reg:CC FLAGS_REG))])]
19434 "optimize_size || !TARGET_SUB_ESP_8"
19435 [(clobber (match_dup 0))
19436 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19437 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19438
19439 ;; Convert epilogue deallocator to pop.
19440 (define_peephole2
19441 [(match_scratch:DI 0 "r")
19442 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19443 (clobber (reg:CC FLAGS_REG))
19444 (clobber (mem:BLK (scratch)))])]
19445 "optimize_size || !TARGET_ADD_ESP_4"
19446 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19447 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19448 (clobber (mem:BLK (scratch)))])]
19449 "")
19450
19451 ;; Two pops case is tricky, since pop causes dependency on destination register.
19452 ;; We use two registers if available.
19453 (define_peephole2
19454 [(match_scratch:DI 0 "r")
19455 (match_scratch:DI 1 "r")
19456 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19457 (clobber (reg:CC FLAGS_REG))
19458 (clobber (mem:BLK (scratch)))])]
19459 "optimize_size || !TARGET_ADD_ESP_8"
19460 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19461 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19462 (clobber (mem:BLK (scratch)))])
19463 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19464 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19465 "")
19466
19467 (define_peephole2
19468 [(match_scratch:DI 0 "r")
19469 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19470 (clobber (reg:CC FLAGS_REG))
19471 (clobber (mem:BLK (scratch)))])]
19472 "optimize_size"
19473 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19474 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19475 (clobber (mem:BLK (scratch)))])
19476 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19477 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19478 "")
19479
19480 ;; Convert esp additions to pop.
19481 (define_peephole2
19482 [(match_scratch:DI 0 "r")
19483 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19484 (clobber (reg:CC FLAGS_REG))])]
19485 ""
19486 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19487 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19488 "")
19489
19490 ;; Two pops case is tricky, since pop causes dependency on destination register.
19491 ;; We use two registers if available.
19492 (define_peephole2
19493 [(match_scratch:DI 0 "r")
19494 (match_scratch:DI 1 "r")
19495 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19496 (clobber (reg:CC FLAGS_REG))])]
19497 ""
19498 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19499 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19500 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19501 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19502 "")
19503
19504 (define_peephole2
19505 [(match_scratch:DI 0 "r")
19506 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19507 (clobber (reg:CC FLAGS_REG))])]
19508 "optimize_size"
19509 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19510 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19511 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19512 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19513 "")
19514 \f
19515 ;; Convert imul by three, five and nine into lea
19516 (define_peephole2
19517 [(parallel
19518 [(set (match_operand:SI 0 "register_operand" "")
19519 (mult:SI (match_operand:SI 1 "register_operand" "")
19520 (match_operand:SI 2 "const_int_operand" "")))
19521 (clobber (reg:CC FLAGS_REG))])]
19522 "INTVAL (operands[2]) == 3
19523 || INTVAL (operands[2]) == 5
19524 || INTVAL (operands[2]) == 9"
19525 [(set (match_dup 0)
19526 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19527 (match_dup 1)))]
19528 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19529
19530 (define_peephole2
19531 [(parallel
19532 [(set (match_operand:SI 0 "register_operand" "")
19533 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19534 (match_operand:SI 2 "const_int_operand" "")))
19535 (clobber (reg:CC FLAGS_REG))])]
19536 "!optimize_size
19537 && (INTVAL (operands[2]) == 3
19538 || INTVAL (operands[2]) == 5
19539 || INTVAL (operands[2]) == 9)"
19540 [(set (match_dup 0) (match_dup 1))
19541 (set (match_dup 0)
19542 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19543 (match_dup 0)))]
19544 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19545
19546 (define_peephole2
19547 [(parallel
19548 [(set (match_operand:DI 0 "register_operand" "")
19549 (mult:DI (match_operand:DI 1 "register_operand" "")
19550 (match_operand:DI 2 "const_int_operand" "")))
19551 (clobber (reg:CC FLAGS_REG))])]
19552 "TARGET_64BIT
19553 && (INTVAL (operands[2]) == 3
19554 || INTVAL (operands[2]) == 5
19555 || INTVAL (operands[2]) == 9)"
19556 [(set (match_dup 0)
19557 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19558 (match_dup 1)))]
19559 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19560
19561 (define_peephole2
19562 [(parallel
19563 [(set (match_operand:DI 0 "register_operand" "")
19564 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19565 (match_operand:DI 2 "const_int_operand" "")))
19566 (clobber (reg:CC FLAGS_REG))])]
19567 "TARGET_64BIT
19568 && !optimize_size
19569 && (INTVAL (operands[2]) == 3
19570 || INTVAL (operands[2]) == 5
19571 || INTVAL (operands[2]) == 9)"
19572 [(set (match_dup 0) (match_dup 1))
19573 (set (match_dup 0)
19574 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19575 (match_dup 0)))]
19576 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19577
19578 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19579 ;; imul $32bit_imm, reg, reg is direct decoded.
19580 (define_peephole2
19581 [(match_scratch:DI 3 "r")
19582 (parallel [(set (match_operand:DI 0 "register_operand" "")
19583 (mult:DI (match_operand:DI 1 "memory_operand" "")
19584 (match_operand:DI 2 "immediate_operand" "")))
19585 (clobber (reg:CC FLAGS_REG))])]
19586 "TARGET_K8 && !optimize_size
19587 && (GET_CODE (operands[2]) != CONST_INT
19588 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19589 [(set (match_dup 3) (match_dup 1))
19590 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19591 (clobber (reg:CC FLAGS_REG))])]
19592 "")
19593
19594 (define_peephole2
19595 [(match_scratch:SI 3 "r")
19596 (parallel [(set (match_operand:SI 0 "register_operand" "")
19597 (mult:SI (match_operand:SI 1 "memory_operand" "")
19598 (match_operand:SI 2 "immediate_operand" "")))
19599 (clobber (reg:CC FLAGS_REG))])]
19600 "TARGET_K8 && !optimize_size
19601 && (GET_CODE (operands[2]) != CONST_INT
19602 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19603 [(set (match_dup 3) (match_dup 1))
19604 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19605 (clobber (reg:CC FLAGS_REG))])]
19606 "")
19607
19608 (define_peephole2
19609 [(match_scratch:SI 3 "r")
19610 (parallel [(set (match_operand:DI 0 "register_operand" "")
19611 (zero_extend:DI
19612 (mult:SI (match_operand:SI 1 "memory_operand" "")
19613 (match_operand:SI 2 "immediate_operand" ""))))
19614 (clobber (reg:CC FLAGS_REG))])]
19615 "TARGET_K8 && !optimize_size
19616 && (GET_CODE (operands[2]) != CONST_INT
19617 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19618 [(set (match_dup 3) (match_dup 1))
19619 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19620 (clobber (reg:CC FLAGS_REG))])]
19621 "")
19622
19623 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19624 ;; Convert it into imul reg, reg
19625 ;; It would be better to force assembler to encode instruction using long
19626 ;; immediate, but there is apparently no way to do so.
19627 (define_peephole2
19628 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19629 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19630 (match_operand:DI 2 "const_int_operand" "")))
19631 (clobber (reg:CC FLAGS_REG))])
19632 (match_scratch:DI 3 "r")]
19633 "TARGET_K8 && !optimize_size
19634 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19635 [(set (match_dup 3) (match_dup 2))
19636 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19637 (clobber (reg:CC FLAGS_REG))])]
19638 {
19639 if (!rtx_equal_p (operands[0], operands[1]))
19640 emit_move_insn (operands[0], operands[1]);
19641 })
19642
19643 (define_peephole2
19644 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19645 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19646 (match_operand:SI 2 "const_int_operand" "")))
19647 (clobber (reg:CC FLAGS_REG))])
19648 (match_scratch:SI 3 "r")]
19649 "TARGET_K8 && !optimize_size
19650 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19651 [(set (match_dup 3) (match_dup 2))
19652 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19653 (clobber (reg:CC FLAGS_REG))])]
19654 {
19655 if (!rtx_equal_p (operands[0], operands[1]))
19656 emit_move_insn (operands[0], operands[1]);
19657 })
19658
19659 (define_peephole2
19660 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19661 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19662 (match_operand:HI 2 "immediate_operand" "")))
19663 (clobber (reg:CC FLAGS_REG))])
19664 (match_scratch:HI 3 "r")]
19665 "TARGET_K8 && !optimize_size"
19666 [(set (match_dup 3) (match_dup 2))
19667 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19668 (clobber (reg:CC FLAGS_REG))])]
19669 {
19670 if (!rtx_equal_p (operands[0], operands[1]))
19671 emit_move_insn (operands[0], operands[1]);
19672 })
19673 \f
19674 ;; Call-value patterns last so that the wildcard operand does not
19675 ;; disrupt insn-recog's switch tables.
19676
19677 (define_insn "*call_value_pop_0"
19678 [(set (match_operand 0 "" "")
19679 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19680 (match_operand:SI 2 "" "")))
19681 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19682 (match_operand:SI 3 "immediate_operand" "")))]
19683 "!TARGET_64BIT"
19684 {
19685 if (SIBLING_CALL_P (insn))
19686 return "jmp\t%P1";
19687 else
19688 return "call\t%P1";
19689 }
19690 [(set_attr "type" "callv")])
19691
19692 (define_insn "*call_value_pop_1"
19693 [(set (match_operand 0 "" "")
19694 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19695 (match_operand:SI 2 "" "")))
19696 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19697 (match_operand:SI 3 "immediate_operand" "i")))]
19698 "!TARGET_64BIT"
19699 {
19700 if (constant_call_address_operand (operands[1], Pmode))
19701 {
19702 if (SIBLING_CALL_P (insn))
19703 return "jmp\t%P1";
19704 else
19705 return "call\t%P1";
19706 }
19707 if (SIBLING_CALL_P (insn))
19708 return "jmp\t%A1";
19709 else
19710 return "call\t%A1";
19711 }
19712 [(set_attr "type" "callv")])
19713
19714 (define_insn "*call_value_0"
19715 [(set (match_operand 0 "" "")
19716 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19717 (match_operand:SI 2 "" "")))]
19718 "!TARGET_64BIT"
19719 {
19720 if (SIBLING_CALL_P (insn))
19721 return "jmp\t%P1";
19722 else
19723 return "call\t%P1";
19724 }
19725 [(set_attr "type" "callv")])
19726
19727 (define_insn "*call_value_0_rex64"
19728 [(set (match_operand 0 "" "")
19729 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19730 (match_operand:DI 2 "const_int_operand" "")))]
19731 "TARGET_64BIT"
19732 {
19733 if (SIBLING_CALL_P (insn))
19734 return "jmp\t%P1";
19735 else
19736 return "call\t%P1";
19737 }
19738 [(set_attr "type" "callv")])
19739
19740 (define_insn "*call_value_1"
19741 [(set (match_operand 0 "" "")
19742 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19743 (match_operand:SI 2 "" "")))]
19744 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19745 {
19746 if (constant_call_address_operand (operands[1], Pmode))
19747 return "call\t%P1";
19748 return "call\t%A1";
19749 }
19750 [(set_attr "type" "callv")])
19751
19752 (define_insn "*sibcall_value_1"
19753 [(set (match_operand 0 "" "")
19754 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19755 (match_operand:SI 2 "" "")))]
19756 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19757 {
19758 if (constant_call_address_operand (operands[1], Pmode))
19759 return "jmp\t%P1";
19760 return "jmp\t%A1";
19761 }
19762 [(set_attr "type" "callv")])
19763
19764 (define_insn "*call_value_1_rex64"
19765 [(set (match_operand 0 "" "")
19766 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19767 (match_operand:DI 2 "" "")))]
19768 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19769 {
19770 if (constant_call_address_operand (operands[1], Pmode))
19771 return "call\t%P1";
19772 return "call\t%A1";
19773 }
19774 [(set_attr "type" "callv")])
19775
19776 (define_insn "*sibcall_value_1_rex64"
19777 [(set (match_operand 0 "" "")
19778 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19779 (match_operand:DI 2 "" "")))]
19780 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19781 "jmp\t%P1"
19782 [(set_attr "type" "callv")])
19783
19784 (define_insn "*sibcall_value_1_rex64_v"
19785 [(set (match_operand 0 "" "")
19786 (call (mem:QI (reg:DI 40))
19787 (match_operand:DI 1 "" "")))]
19788 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19789 "jmp\t*%%r11"
19790 [(set_attr "type" "callv")])
19791 \f
19792 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19793 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19794 ;; caught for use by garbage collectors and the like. Using an insn that
19795 ;; maps to SIGILL makes it more likely the program will rightfully die.
19796 ;; Keeping with tradition, "6" is in honor of #UD.
19797 (define_insn "trap"
19798 [(trap_if (const_int 1) (const_int 6))]
19799 ""
19800 ".word\t0x0b0f"
19801 [(set_attr "length" "2")])
19802
19803 (define_expand "sse_prologue_save"
19804 [(parallel [(set (match_operand:BLK 0 "" "")
19805 (unspec:BLK [(reg:DI 21)
19806 (reg:DI 22)
19807 (reg:DI 23)
19808 (reg:DI 24)
19809 (reg:DI 25)
19810 (reg:DI 26)
19811 (reg:DI 27)
19812 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19813 (use (match_operand:DI 1 "register_operand" ""))
19814 (use (match_operand:DI 2 "immediate_operand" ""))
19815 (use (label_ref:DI (match_operand 3 "" "")))])]
19816 "TARGET_64BIT"
19817 "")
19818
19819 (define_insn "*sse_prologue_save_insn"
19820 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19821 (match_operand:DI 4 "const_int_operand" "n")))
19822 (unspec:BLK [(reg:DI 21)
19823 (reg:DI 22)
19824 (reg:DI 23)
19825 (reg:DI 24)
19826 (reg:DI 25)
19827 (reg:DI 26)
19828 (reg:DI 27)
19829 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19830 (use (match_operand:DI 1 "register_operand" "r"))
19831 (use (match_operand:DI 2 "const_int_operand" "i"))
19832 (use (label_ref:DI (match_operand 3 "" "X")))]
19833 "TARGET_64BIT
19834 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19835 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19836 "*
19837 {
19838 int i;
19839 operands[0] = gen_rtx_MEM (Pmode,
19840 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19841 output_asm_insn (\"jmp\\t%A1\", operands);
19842 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19843 {
19844 operands[4] = adjust_address (operands[0], DImode, i*16);
19845 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19846 PUT_MODE (operands[4], TImode);
19847 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19848 output_asm_insn (\"rex\", operands);
19849 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19850 }
19851 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19852 CODE_LABEL_NUMBER (operands[3]));
19853 RET;
19854 }
19855 "
19856 [(set_attr "type" "other")
19857 (set_attr "length_immediate" "0")
19858 (set_attr "length_address" "0")
19859 (set_attr "length" "135")
19860 (set_attr "memory" "store")
19861 (set_attr "modrm" "0")
19862 (set_attr "mode" "DI")])
19863
19864 (define_expand "prefetch"
19865 [(prefetch (match_operand 0 "address_operand" "")
19866 (match_operand:SI 1 "const_int_operand" "")
19867 (match_operand:SI 2 "const_int_operand" ""))]
19868 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19869 {
19870 int rw = INTVAL (operands[1]);
19871 int locality = INTVAL (operands[2]);
19872
19873 gcc_assert (rw == 0 || rw == 1);
19874 gcc_assert (locality >= 0 && locality <= 3);
19875 gcc_assert (GET_MODE (operands[0]) == Pmode
19876 || GET_MODE (operands[0]) == VOIDmode);
19877
19878 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19879 supported by SSE counterpart or the SSE prefetch is not available
19880 (K6 machines). Otherwise use SSE prefetch as it allows specifying
19881 of locality. */
19882 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19883 operands[2] = GEN_INT (3);
19884 else
19885 operands[1] = const0_rtx;
19886 })
19887
19888 (define_insn "*prefetch_sse"
19889 [(prefetch (match_operand:SI 0 "address_operand" "p")
19890 (const_int 0)
19891 (match_operand:SI 1 "const_int_operand" ""))]
19892 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19893 {
19894 static const char * const patterns[4] = {
19895 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19896 };
19897
19898 int locality = INTVAL (operands[1]);
19899 gcc_assert (locality >= 0 && locality <= 3);
19900
19901 return patterns[locality];
19902 }
19903 [(set_attr "type" "sse")
19904 (set_attr "memory" "none")])
19905
19906 (define_insn "*prefetch_sse_rex"
19907 [(prefetch (match_operand:DI 0 "address_operand" "p")
19908 (const_int 0)
19909 (match_operand:SI 1 "const_int_operand" ""))]
19910 "TARGET_PREFETCH_SSE && TARGET_64BIT"
19911 {
19912 static const char * const patterns[4] = {
19913 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19914 };
19915
19916 int locality = INTVAL (operands[1]);
19917 gcc_assert (locality >= 0 && locality <= 3);
19918
19919 return patterns[locality];
19920 }
19921 [(set_attr "type" "sse")
19922 (set_attr "memory" "none")])
19923
19924 (define_insn "*prefetch_3dnow"
19925 [(prefetch (match_operand:SI 0 "address_operand" "p")
19926 (match_operand:SI 1 "const_int_operand" "n")
19927 (const_int 3))]
19928 "TARGET_3DNOW && !TARGET_64BIT"
19929 {
19930 if (INTVAL (operands[1]) == 0)
19931 return "prefetch\t%a0";
19932 else
19933 return "prefetchw\t%a0";
19934 }
19935 [(set_attr "type" "mmx")
19936 (set_attr "memory" "none")])
19937
19938 (define_insn "*prefetch_3dnow_rex"
19939 [(prefetch (match_operand:DI 0 "address_operand" "p")
19940 (match_operand:SI 1 "const_int_operand" "n")
19941 (const_int 3))]
19942 "TARGET_3DNOW && TARGET_64BIT"
19943 {
19944 if (INTVAL (operands[1]) == 0)
19945 return "prefetch\t%a0";
19946 else
19947 return "prefetchw\t%a0";
19948 }
19949 [(set_attr "type" "mmx")
19950 (set_attr "memory" "none")])
19951
19952 (define_expand "stack_protect_set"
19953 [(match_operand 0 "memory_operand" "")
19954 (match_operand 1 "memory_operand" "")]
19955 ""
19956 {
19957 #ifdef TARGET_THREAD_SSP_OFFSET
19958 if (TARGET_64BIT)
19959 emit_insn (gen_stack_tls_protect_set_di (operands[0],
19960 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19961 else
19962 emit_insn (gen_stack_tls_protect_set_si (operands[0],
19963 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19964 #else
19965 if (TARGET_64BIT)
19966 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
19967 else
19968 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
19969 #endif
19970 DONE;
19971 })
19972
19973 (define_insn "stack_protect_set_si"
19974 [(set (match_operand:SI 0 "memory_operand" "=m")
19975 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19976 (set (match_scratch:SI 2 "=&r") (const_int 0))
19977 (clobber (reg:CC FLAGS_REG))]
19978 ""
19979 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19980 [(set_attr "type" "multi")])
19981
19982 (define_insn "stack_protect_set_di"
19983 [(set (match_operand:DI 0 "memory_operand" "=m")
19984 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19985 (set (match_scratch:DI 2 "=&r") (const_int 0))
19986 (clobber (reg:CC FLAGS_REG))]
19987 "TARGET_64BIT"
19988 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19989 [(set_attr "type" "multi")])
19990
19991 (define_insn "stack_tls_protect_set_si"
19992 [(set (match_operand:SI 0 "memory_operand" "=m")
19993 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19994 (set (match_scratch:SI 2 "=&r") (const_int 0))
19995 (clobber (reg:CC FLAGS_REG))]
19996 ""
19997 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19998 [(set_attr "type" "multi")])
19999
20000 (define_insn "stack_tls_protect_set_di"
20001 [(set (match_operand:DI 0 "memory_operand" "=m")
20002 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20003 (set (match_scratch:DI 2 "=&r") (const_int 0))
20004 (clobber (reg:CC FLAGS_REG))]
20005 "TARGET_64BIT"
20006 "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20007 [(set_attr "type" "multi")])
20008
20009 (define_expand "stack_protect_test"
20010 [(match_operand 0 "memory_operand" "")
20011 (match_operand 1 "memory_operand" "")
20012 (match_operand 2 "" "")]
20013 ""
20014 {
20015 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20016 ix86_compare_op0 = operands[0];
20017 ix86_compare_op1 = operands[1];
20018 ix86_compare_emitted = flags;
20019
20020 #ifdef TARGET_THREAD_SSP_OFFSET
20021 if (TARGET_64BIT)
20022 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20023 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20024 else
20025 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20026 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20027 #else
20028 if (TARGET_64BIT)
20029 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20030 else
20031 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20032 #endif
20033 emit_jump_insn (gen_beq (operands[2]));
20034 DONE;
20035 })
20036
20037 (define_insn "stack_protect_test_si"
20038 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20039 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20040 (match_operand:SI 2 "memory_operand" "m")]
20041 UNSPEC_SP_TEST))
20042 (clobber (match_scratch:SI 3 "=&r"))]
20043 ""
20044 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20045 [(set_attr "type" "multi")])
20046
20047 (define_insn "stack_protect_test_di"
20048 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20049 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20050 (match_operand:DI 2 "memory_operand" "m")]
20051 UNSPEC_SP_TEST))
20052 (clobber (match_scratch:DI 3 "=&r"))]
20053 "TARGET_64BIT"
20054 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20055 [(set_attr "type" "multi")])
20056
20057 (define_insn "stack_tls_protect_test_si"
20058 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20059 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20060 (match_operand:SI 2 "const_int_operand" "i")]
20061 UNSPEC_SP_TLS_TEST))
20062 (clobber (match_scratch:SI 3 "=r"))]
20063 ""
20064 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20065 [(set_attr "type" "multi")])
20066
20067 (define_insn "stack_tls_protect_test_di"
20068 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20069 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20070 (match_operand:DI 2 "const_int_operand" "i")]
20071 UNSPEC_SP_TLS_TEST))
20072 (clobber (match_scratch:DI 3 "=r"))]
20073 "TARGET_64BIT"
20074 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20075 [(set_attr "type" "multi")])
20076
20077 (include "sse.md")
20078 (include "mmx.md")
20079 (include "sync.md")