i386.c (ix86_expand_fp_absneg_operator): When SSE isn't available...
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;; operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
66 (UNSPEC_STACK_ALLOC 11)
67 (UNSPEC_SET_GOT 12)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_REG_SAVE 14)
70 (UNSPEC_DEF_CFA 15)
71
72 ; TLS support
73 (UNSPEC_TP 16)
74 (UNSPEC_TLS_GD 17)
75 (UNSPEC_TLS_LD_BASE 18)
76 (UNSPEC_TLSDESC 19)
77
78 ; Other random patterns
79 (UNSPEC_SCAS 20)
80 (UNSPEC_FNSTSW 21)
81 (UNSPEC_SAHF 22)
82 (UNSPEC_FSTCW 23)
83 (UNSPEC_ADD_CARRY 24)
84 (UNSPEC_FLDCW 25)
85 (UNSPEC_REP 26)
86 (UNSPEC_EH_RETURN 27)
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 30)
91 (UNSPEC_MASKMOV 31)
92 (UNSPEC_MOVMSK 32)
93 (UNSPEC_MOVNT 33)
94 (UNSPEC_MOVU 34)
95 (UNSPEC_RCP 35)
96 (UNSPEC_RSQRT 36)
97 (UNSPEC_SFENCE 37)
98 (UNSPEC_NOP 38) ; prevents combiner cleverness
99 (UNSPEC_PFRCP 39)
100 (UNSPEC_PFRCPIT1 40)
101 (UNSPEC_PFRCPIT2 41)
102 (UNSPEC_PFRSQRT 42)
103 (UNSPEC_PFRSQIT1 43)
104 (UNSPEC_MFENCE 44)
105 (UNSPEC_LFENCE 45)
106 (UNSPEC_PSADBW 46)
107 (UNSPEC_LDQQU 47)
108
109 ; Generic math support
110 (UNSPEC_COPYSIGN 50)
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
113
114 ; x87 Floating point
115 (UNSPEC_SIN 60)
116 (UNSPEC_COS 61)
117 (UNSPEC_FPATAN 62)
118 (UNSPEC_FYL2X 63)
119 (UNSPEC_FYL2XP1 64)
120 (UNSPEC_FRNDINT 65)
121 (UNSPEC_FIST 66)
122 (UNSPEC_F2XM1 67)
123
124 ; x87 Rounding
125 (UNSPEC_FRNDINT_FLOOR 70)
126 (UNSPEC_FRNDINT_CEIL 71)
127 (UNSPEC_FRNDINT_TRUNC 72)
128 (UNSPEC_FRNDINT_MASK_PM 73)
129 (UNSPEC_FIST_FLOOR 74)
130 (UNSPEC_FIST_CEIL 75)
131
132 ; x87 Double output FP
133 (UNSPEC_SINCOS_COS 80)
134 (UNSPEC_SINCOS_SIN 81)
135 (UNSPEC_TAN_ONE 82)
136 (UNSPEC_TAN_TAN 83)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
141 (UNSPEC_FPREM_F 88)
142 (UNSPEC_FPREM_U 89)
143 (UNSPEC_FPREM1_F 90)
144 (UNSPEC_FPREM1_U 91)
145
146 ; SSP patterns
147 (UNSPEC_SP_SET 100)
148 (UNSPEC_SP_TEST 101)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
151 ])
152
153 (define_constants
154 [(UNSPECV_BLOCKAGE 0)
155 (UNSPECV_STACK_PROBE 1)
156 (UNSPECV_EMMS 2)
157 (UNSPECV_LDMXCSR 3)
158 (UNSPECV_STMXCSR 4)
159 (UNSPECV_FEMMS 5)
160 (UNSPECV_CLFLUSH 6)
161 (UNSPECV_ALIGN 7)
162 (UNSPECV_MONITOR 8)
163 (UNSPECV_MWAIT 9)
164 (UNSPECV_CMPXCHG_1 10)
165 (UNSPECV_CMPXCHG_2 11)
166 (UNSPECV_XCHG 12)
167 (UNSPECV_LOCK 13)
168 ])
169
170 ;; Registers by name.
171 (define_constants
172 [(BP_REG 6)
173 (SP_REG 7)
174 (FLAGS_REG 17)
175 (FPSR_REG 18)
176 (DIRFLAG_REG 19)
177 ])
178
179 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180 ;; from i386.c.
181
182 ;; In C guard expressions, put expressions which may be compile-time
183 ;; constants first. This allows for better optimization. For
184 ;; example, write "TARGET_64BIT && reload_completed", not
185 ;; "reload_completed && TARGET_64BIT".
186
187 \f
188 ;; Processor type. This attribute must exactly match the processor_type
189 ;; enumeration in i386.h.
190 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
191 (const (symbol_ref "ix86_tune")))
192
193 ;; A basic instruction type. Refinements due to arguments to be
194 ;; provided in other attributes.
195 (define_attr "type"
196 "other,multi,
197 alu,alu1,negnot,imov,imovx,lea,
198 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199 icmp,test,ibr,setcc,icmov,
200 push,pop,call,callv,leave,
201 str,cld,
202 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203 sselog,sselog1,sseiadd,sseishft,sseimul,
204 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206 (const_string "other"))
207
208 ;; Main data type used by the insn
209 (define_attr "mode"
210 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211 (const_string "unknown"))
212
213 ;; The CPU unit operations uses.
214 (define_attr "unit" "integer,i387,sse,mmx,unknown"
215 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216 (const_string "i387")
217 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
219 (const_string "sse")
220 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
221 (const_string "mmx")
222 (eq_attr "type" "other")
223 (const_string "unknown")]
224 (const_string "integer")))
225
226 ;; The (bounding maximum) length of an instruction immediate.
227 (define_attr "length_immediate" ""
228 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
229 (const_int 0)
230 (eq_attr "unit" "i387,sse,mmx")
231 (const_int 0)
232 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
233 imul,icmp,push,pop")
234 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235 (eq_attr "type" "imov,test")
236 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237 (eq_attr "type" "call")
238 (if_then_else (match_operand 0 "constant_call_address_operand" "")
239 (const_int 4)
240 (const_int 0))
241 (eq_attr "type" "callv")
242 (if_then_else (match_operand 1 "constant_call_address_operand" "")
243 (const_int 4)
244 (const_int 0))
245 ;; We don't know the size before shorten_branches. Expect
246 ;; the instruction to fit for better scheduling.
247 (eq_attr "type" "ibr")
248 (const_int 1)
249 ]
250 (symbol_ref "/* Update immediate_length and other attributes! */
251 gcc_unreachable (),1")))
252
253 ;; The (bounding maximum) length of an instruction address.
254 (define_attr "length_address" ""
255 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
256 (const_int 0)
257 (and (eq_attr "type" "call")
258 (match_operand 0 "constant_call_address_operand" ""))
259 (const_int 0)
260 (and (eq_attr "type" "callv")
261 (match_operand 1 "constant_call_address_operand" ""))
262 (const_int 0)
263 ]
264 (symbol_ref "ix86_attr_length_address_default (insn)")))
265
266 ;; Set when length prefix is used.
267 (define_attr "prefix_data16" ""
268 (if_then_else (ior (eq_attr "mode" "HI")
269 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
270 (const_int 1)
271 (const_int 0)))
272
273 ;; Set when string REP prefix is used.
274 (define_attr "prefix_rep" ""
275 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
276 (const_int 1)
277 (const_int 0)))
278
279 ;; Set when 0f opcode prefix is used.
280 (define_attr "prefix_0f" ""
281 (if_then_else
282 (ior (eq_attr "type" "imovx,setcc,icmov")
283 (eq_attr "unit" "sse,mmx"))
284 (const_int 1)
285 (const_int 0)))
286
287 ;; Set when REX opcode prefix is used.
288 (define_attr "prefix_rex" ""
289 (cond [(and (eq_attr "mode" "DI")
290 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
291 (const_int 1)
292 (and (eq_attr "mode" "QI")
293 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294 (const_int 0)))
295 (const_int 1)
296 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
297 (const_int 0))
298 (const_int 1)
299 ]
300 (const_int 0)))
301
302 ;; Set when modrm byte is used.
303 (define_attr "modrm" ""
304 (cond [(eq_attr "type" "str,cld,leave")
305 (const_int 0)
306 (eq_attr "unit" "i387")
307 (const_int 0)
308 (and (eq_attr "type" "incdec")
309 (ior (match_operand:SI 1 "register_operand" "")
310 (match_operand:HI 1 "register_operand" "")))
311 (const_int 0)
312 (and (eq_attr "type" "push")
313 (not (match_operand 1 "memory_operand" "")))
314 (const_int 0)
315 (and (eq_attr "type" "pop")
316 (not (match_operand 0 "memory_operand" "")))
317 (const_int 0)
318 (and (eq_attr "type" "imov")
319 (ior (and (match_operand 0 "register_operand" "")
320 (match_operand 1 "immediate_operand" ""))
321 (ior (and (match_operand 0 "ax_reg_operand" "")
322 (match_operand 1 "memory_displacement_only_operand" ""))
323 (and (match_operand 0 "memory_displacement_only_operand" "")
324 (match_operand 1 "ax_reg_operand" "")))))
325 (const_int 0)
326 (and (eq_attr "type" "call")
327 (match_operand 0 "constant_call_address_operand" ""))
328 (const_int 0)
329 (and (eq_attr "type" "callv")
330 (match_operand 1 "constant_call_address_operand" ""))
331 (const_int 0)
332 ]
333 (const_int 1)))
334
335 ;; The (bounding maximum) length of an instruction in bytes.
336 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337 ;; Later we may want to split them and compute proper length as for
338 ;; other insns.
339 (define_attr "length" ""
340 (cond [(eq_attr "type" "other,multi,fistp,frndint")
341 (const_int 16)
342 (eq_attr "type" "fcmp")
343 (const_int 4)
344 (eq_attr "unit" "i387")
345 (plus (const_int 2)
346 (plus (attr "prefix_data16")
347 (attr "length_address")))]
348 (plus (plus (attr "modrm")
349 (plus (attr "prefix_0f")
350 (plus (attr "prefix_rex")
351 (const_int 1))))
352 (plus (attr "prefix_rep")
353 (plus (attr "prefix_data16")
354 (plus (attr "length_immediate")
355 (attr "length_address")))))))
356
357 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
358 ;; `store' if there is a simple memory reference therein, or `unknown'
359 ;; if the instruction is complex.
360
361 (define_attr "memory" "none,load,store,both,unknown"
362 (cond [(eq_attr "type" "other,multi,str")
363 (const_string "unknown")
364 (eq_attr "type" "lea,fcmov,fpspc,cld")
365 (const_string "none")
366 (eq_attr "type" "fistp,leave")
367 (const_string "both")
368 (eq_attr "type" "frndint")
369 (const_string "load")
370 (eq_attr "type" "push")
371 (if_then_else (match_operand 1 "memory_operand" "")
372 (const_string "both")
373 (const_string "store"))
374 (eq_attr "type" "pop")
375 (if_then_else (match_operand 0 "memory_operand" "")
376 (const_string "both")
377 (const_string "load"))
378 (eq_attr "type" "setcc")
379 (if_then_else (match_operand 0 "memory_operand" "")
380 (const_string "store")
381 (const_string "none"))
382 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383 (if_then_else (ior (match_operand 0 "memory_operand" "")
384 (match_operand 1 "memory_operand" ""))
385 (const_string "load")
386 (const_string "none"))
387 (eq_attr "type" "ibr")
388 (if_then_else (match_operand 0 "memory_operand" "")
389 (const_string "load")
390 (const_string "none"))
391 (eq_attr "type" "call")
392 (if_then_else (match_operand 0 "constant_call_address_operand" "")
393 (const_string "none")
394 (const_string "load"))
395 (eq_attr "type" "callv")
396 (if_then_else (match_operand 1 "constant_call_address_operand" "")
397 (const_string "none")
398 (const_string "load"))
399 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400 (match_operand 1 "memory_operand" ""))
401 (const_string "both")
402 (and (match_operand 0 "memory_operand" "")
403 (match_operand 1 "memory_operand" ""))
404 (const_string "both")
405 (match_operand 0 "memory_operand" "")
406 (const_string "store")
407 (match_operand 1 "memory_operand" "")
408 (const_string "load")
409 (and (eq_attr "type"
410 "!alu1,negnot,ishift1,
411 imov,imovx,icmp,test,
412 fmov,fcmp,fsgn,
413 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414 mmx,mmxmov,mmxcmp,mmxcvt")
415 (match_operand 2 "memory_operand" ""))
416 (const_string "load")
417 (and (eq_attr "type" "icmov")
418 (match_operand 3 "memory_operand" ""))
419 (const_string "load")
420 ]
421 (const_string "none")))
422
423 ;; Indicates if an instruction has both an immediate and a displacement.
424
425 (define_attr "imm_disp" "false,true,unknown"
426 (cond [(eq_attr "type" "other,multi")
427 (const_string "unknown")
428 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429 (and (match_operand 0 "memory_displacement_operand" "")
430 (match_operand 1 "immediate_operand" "")))
431 (const_string "true")
432 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433 (and (match_operand 0 "memory_displacement_operand" "")
434 (match_operand 2 "immediate_operand" "")))
435 (const_string "true")
436 ]
437 (const_string "false")))
438
439 ;; Indicates if an FP operation has an integer source.
440
441 (define_attr "fp_int_src" "false,true"
442 (const_string "false"))
443
444 ;; Defines rounding mode of an FP operation.
445
446 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447 (const_string "any"))
448
449 ;; Describe a user's asm statement.
450 (define_asm_attributes
451 [(set_attr "length" "128")
452 (set_attr "type" "multi")])
453
454 ;; All x87 floating point modes
455 (define_mode_macro X87MODEF [SF DF XF])
456
457 ;; All integer modes handled by x87 fisttp operator.
458 (define_mode_macro X87MODEI [HI SI DI])
459
460 ;; All integer modes handled by integer x87 operators.
461 (define_mode_macro X87MODEI12 [HI SI])
462
463 ;; All SSE floating point modes
464 (define_mode_macro SSEMODEF [SF DF])
465
466 ;; All integer modes handled by SSE cvtts?2si* operators.
467 (define_mode_macro SSEMODEI24 [SI DI])
468
469 \f
470 ;; Scheduling descriptions
471
472 (include "pentium.md")
473 (include "ppro.md")
474 (include "k6.md")
475 (include "athlon.md")
476
477 \f
478 ;; Operand and operator predicates and constraints
479
480 (include "predicates.md")
481 (include "constraints.md")
482
483 \f
484 ;; Compare instructions.
485
486 ;; All compare insns have expanders that save the operands away without
487 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
488 ;; after the cmp) will actually emit the cmpM.
489
490 (define_expand "cmpti"
491 [(set (reg:CC FLAGS_REG)
492 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
493 (match_operand:TI 1 "x86_64_general_operand" "")))]
494 "TARGET_64BIT"
495 {
496 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
497 operands[0] = force_reg (TImode, operands[0]);
498 ix86_compare_op0 = operands[0];
499 ix86_compare_op1 = operands[1];
500 DONE;
501 })
502
503 (define_expand "cmpdi"
504 [(set (reg:CC FLAGS_REG)
505 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
506 (match_operand:DI 1 "x86_64_general_operand" "")))]
507 ""
508 {
509 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
510 operands[0] = force_reg (DImode, operands[0]);
511 ix86_compare_op0 = operands[0];
512 ix86_compare_op1 = operands[1];
513 DONE;
514 })
515
516 (define_expand "cmpsi"
517 [(set (reg:CC FLAGS_REG)
518 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
519 (match_operand:SI 1 "general_operand" "")))]
520 ""
521 {
522 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
523 operands[0] = force_reg (SImode, operands[0]);
524 ix86_compare_op0 = operands[0];
525 ix86_compare_op1 = operands[1];
526 DONE;
527 })
528
529 (define_expand "cmphi"
530 [(set (reg:CC FLAGS_REG)
531 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
532 (match_operand:HI 1 "general_operand" "")))]
533 ""
534 {
535 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
536 operands[0] = force_reg (HImode, operands[0]);
537 ix86_compare_op0 = operands[0];
538 ix86_compare_op1 = operands[1];
539 DONE;
540 })
541
542 (define_expand "cmpqi"
543 [(set (reg:CC FLAGS_REG)
544 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
545 (match_operand:QI 1 "general_operand" "")))]
546 "TARGET_QIMODE_MATH"
547 {
548 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
549 operands[0] = force_reg (QImode, operands[0]);
550 ix86_compare_op0 = operands[0];
551 ix86_compare_op1 = operands[1];
552 DONE;
553 })
554
555 (define_insn "cmpdi_ccno_1_rex64"
556 [(set (reg FLAGS_REG)
557 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
558 (match_operand:DI 1 "const0_operand" "n,n")))]
559 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
560 "@
561 test{q}\t{%0, %0|%0, %0}
562 cmp{q}\t{%1, %0|%0, %1}"
563 [(set_attr "type" "test,icmp")
564 (set_attr "length_immediate" "0,1")
565 (set_attr "mode" "DI")])
566
567 (define_insn "*cmpdi_minus_1_rex64"
568 [(set (reg FLAGS_REG)
569 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
570 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
571 (const_int 0)))]
572 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
573 "cmp{q}\t{%1, %0|%0, %1}"
574 [(set_attr "type" "icmp")
575 (set_attr "mode" "DI")])
576
577 (define_expand "cmpdi_1_rex64"
578 [(set (reg:CC FLAGS_REG)
579 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
580 (match_operand:DI 1 "general_operand" "")))]
581 "TARGET_64BIT"
582 "")
583
584 (define_insn "cmpdi_1_insn_rex64"
585 [(set (reg FLAGS_REG)
586 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
587 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
588 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
589 "cmp{q}\t{%1, %0|%0, %1}"
590 [(set_attr "type" "icmp")
591 (set_attr "mode" "DI")])
592
593
594 (define_insn "*cmpsi_ccno_1"
595 [(set (reg FLAGS_REG)
596 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
597 (match_operand:SI 1 "const0_operand" "n,n")))]
598 "ix86_match_ccmode (insn, CCNOmode)"
599 "@
600 test{l}\t{%0, %0|%0, %0}
601 cmp{l}\t{%1, %0|%0, %1}"
602 [(set_attr "type" "test,icmp")
603 (set_attr "length_immediate" "0,1")
604 (set_attr "mode" "SI")])
605
606 (define_insn "*cmpsi_minus_1"
607 [(set (reg FLAGS_REG)
608 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
609 (match_operand:SI 1 "general_operand" "ri,mr"))
610 (const_int 0)))]
611 "ix86_match_ccmode (insn, CCGOCmode)"
612 "cmp{l}\t{%1, %0|%0, %1}"
613 [(set_attr "type" "icmp")
614 (set_attr "mode" "SI")])
615
616 (define_expand "cmpsi_1"
617 [(set (reg:CC FLAGS_REG)
618 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619 (match_operand:SI 1 "general_operand" "ri,mr")))]
620 ""
621 "")
622
623 (define_insn "*cmpsi_1_insn"
624 [(set (reg FLAGS_REG)
625 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
626 (match_operand:SI 1 "general_operand" "ri,mr")))]
627 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
628 && ix86_match_ccmode (insn, CCmode)"
629 "cmp{l}\t{%1, %0|%0, %1}"
630 [(set_attr "type" "icmp")
631 (set_attr "mode" "SI")])
632
633 (define_insn "*cmphi_ccno_1"
634 [(set (reg FLAGS_REG)
635 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
636 (match_operand:HI 1 "const0_operand" "n,n")))]
637 "ix86_match_ccmode (insn, CCNOmode)"
638 "@
639 test{w}\t{%0, %0|%0, %0}
640 cmp{w}\t{%1, %0|%0, %1}"
641 [(set_attr "type" "test,icmp")
642 (set_attr "length_immediate" "0,1")
643 (set_attr "mode" "HI")])
644
645 (define_insn "*cmphi_minus_1"
646 [(set (reg FLAGS_REG)
647 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
648 (match_operand:HI 1 "general_operand" "ri,mr"))
649 (const_int 0)))]
650 "ix86_match_ccmode (insn, CCGOCmode)"
651 "cmp{w}\t{%1, %0|%0, %1}"
652 [(set_attr "type" "icmp")
653 (set_attr "mode" "HI")])
654
655 (define_insn "*cmphi_1"
656 [(set (reg FLAGS_REG)
657 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
658 (match_operand:HI 1 "general_operand" "ri,mr")))]
659 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660 && ix86_match_ccmode (insn, CCmode)"
661 "cmp{w}\t{%1, %0|%0, %1}"
662 [(set_attr "type" "icmp")
663 (set_attr "mode" "HI")])
664
665 (define_insn "*cmpqi_ccno_1"
666 [(set (reg FLAGS_REG)
667 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
668 (match_operand:QI 1 "const0_operand" "n,n")))]
669 "ix86_match_ccmode (insn, CCNOmode)"
670 "@
671 test{b}\t{%0, %0|%0, %0}
672 cmp{b}\t{$0, %0|%0, 0}"
673 [(set_attr "type" "test,icmp")
674 (set_attr "length_immediate" "0,1")
675 (set_attr "mode" "QI")])
676
677 (define_insn "*cmpqi_1"
678 [(set (reg FLAGS_REG)
679 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
680 (match_operand:QI 1 "general_operand" "qi,mq")))]
681 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
682 && ix86_match_ccmode (insn, CCmode)"
683 "cmp{b}\t{%1, %0|%0, %1}"
684 [(set_attr "type" "icmp")
685 (set_attr "mode" "QI")])
686
687 (define_insn "*cmpqi_minus_1"
688 [(set (reg FLAGS_REG)
689 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
690 (match_operand:QI 1 "general_operand" "qi,mq"))
691 (const_int 0)))]
692 "ix86_match_ccmode (insn, CCGOCmode)"
693 "cmp{b}\t{%1, %0|%0, %1}"
694 [(set_attr "type" "icmp")
695 (set_attr "mode" "QI")])
696
697 (define_insn "*cmpqi_ext_1"
698 [(set (reg FLAGS_REG)
699 (compare
700 (match_operand:QI 0 "general_operand" "Qm")
701 (subreg:QI
702 (zero_extract:SI
703 (match_operand 1 "ext_register_operand" "Q")
704 (const_int 8)
705 (const_int 8)) 0)))]
706 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
707 "cmp{b}\t{%h1, %0|%0, %h1}"
708 [(set_attr "type" "icmp")
709 (set_attr "mode" "QI")])
710
711 (define_insn "*cmpqi_ext_1_rex64"
712 [(set (reg FLAGS_REG)
713 (compare
714 (match_operand:QI 0 "register_operand" "Q")
715 (subreg:QI
716 (zero_extract:SI
717 (match_operand 1 "ext_register_operand" "Q")
718 (const_int 8)
719 (const_int 8)) 0)))]
720 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721 "cmp{b}\t{%h1, %0|%0, %h1}"
722 [(set_attr "type" "icmp")
723 (set_attr "mode" "QI")])
724
725 (define_insn "*cmpqi_ext_2"
726 [(set (reg FLAGS_REG)
727 (compare
728 (subreg:QI
729 (zero_extract:SI
730 (match_operand 0 "ext_register_operand" "Q")
731 (const_int 8)
732 (const_int 8)) 0)
733 (match_operand:QI 1 "const0_operand" "n")))]
734 "ix86_match_ccmode (insn, CCNOmode)"
735 "test{b}\t%h0, %h0"
736 [(set_attr "type" "test")
737 (set_attr "length_immediate" "0")
738 (set_attr "mode" "QI")])
739
740 (define_expand "cmpqi_ext_3"
741 [(set (reg:CC FLAGS_REG)
742 (compare:CC
743 (subreg:QI
744 (zero_extract:SI
745 (match_operand 0 "ext_register_operand" "")
746 (const_int 8)
747 (const_int 8)) 0)
748 (match_operand:QI 1 "general_operand" "")))]
749 ""
750 "")
751
752 (define_insn "cmpqi_ext_3_insn"
753 [(set (reg FLAGS_REG)
754 (compare
755 (subreg:QI
756 (zero_extract:SI
757 (match_operand 0 "ext_register_operand" "Q")
758 (const_int 8)
759 (const_int 8)) 0)
760 (match_operand:QI 1 "general_operand" "Qmn")))]
761 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
762 "cmp{b}\t{%1, %h0|%h0, %1}"
763 [(set_attr "type" "icmp")
764 (set_attr "mode" "QI")])
765
766 (define_insn "cmpqi_ext_3_insn_rex64"
767 [(set (reg FLAGS_REG)
768 (compare
769 (subreg:QI
770 (zero_extract:SI
771 (match_operand 0 "ext_register_operand" "Q")
772 (const_int 8)
773 (const_int 8)) 0)
774 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
775 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776 "cmp{b}\t{%1, %h0|%h0, %1}"
777 [(set_attr "type" "icmp")
778 (set_attr "mode" "QI")])
779
780 (define_insn "*cmpqi_ext_4"
781 [(set (reg FLAGS_REG)
782 (compare
783 (subreg:QI
784 (zero_extract:SI
785 (match_operand 0 "ext_register_operand" "Q")
786 (const_int 8)
787 (const_int 8)) 0)
788 (subreg:QI
789 (zero_extract:SI
790 (match_operand 1 "ext_register_operand" "Q")
791 (const_int 8)
792 (const_int 8)) 0)))]
793 "ix86_match_ccmode (insn, CCmode)"
794 "cmp{b}\t{%h1, %h0|%h0, %h1}"
795 [(set_attr "type" "icmp")
796 (set_attr "mode" "QI")])
797
798 ;; These implement float point compares.
799 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
800 ;; which would allow mix and match FP modes on the compares. Which is what
801 ;; the old patterns did, but with many more of them.
802
803 (define_expand "cmpxf"
804 [(set (reg:CC FLAGS_REG)
805 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
806 (match_operand:XF 1 "nonmemory_operand" "")))]
807 "TARGET_80387"
808 {
809 ix86_compare_op0 = operands[0];
810 ix86_compare_op1 = operands[1];
811 DONE;
812 })
813
814 (define_expand "cmpdf"
815 [(set (reg:CC FLAGS_REG)
816 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
817 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
818 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
819 {
820 ix86_compare_op0 = operands[0];
821 ix86_compare_op1 = operands[1];
822 DONE;
823 })
824
825 (define_expand "cmpsf"
826 [(set (reg:CC FLAGS_REG)
827 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
828 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
829 "TARGET_80387 || TARGET_SSE_MATH"
830 {
831 ix86_compare_op0 = operands[0];
832 ix86_compare_op1 = operands[1];
833 DONE;
834 })
835
836 ;; FP compares, step 1:
837 ;; Set the FP condition codes.
838 ;;
839 ;; CCFPmode compare with exceptions
840 ;; CCFPUmode compare with no exceptions
841
842 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
843 ;; used to manage the reg stack popping would not be preserved.
844
845 (define_insn "*cmpfp_0"
846 [(set (match_operand:HI 0 "register_operand" "=a")
847 (unspec:HI
848 [(compare:CCFP
849 (match_operand 1 "register_operand" "f")
850 (match_operand 2 "const0_operand" "X"))]
851 UNSPEC_FNSTSW))]
852 "TARGET_80387
853 && FLOAT_MODE_P (GET_MODE (operands[1]))
854 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
855 "* return output_fp_compare (insn, operands, 0, 0);"
856 [(set_attr "type" "multi")
857 (set_attr "unit" "i387")
858 (set (attr "mode")
859 (cond [(match_operand:SF 1 "" "")
860 (const_string "SF")
861 (match_operand:DF 1 "" "")
862 (const_string "DF")
863 ]
864 (const_string "XF")))])
865
866 (define_insn "*cmpfp_sf"
867 [(set (match_operand:HI 0 "register_operand" "=a")
868 (unspec:HI
869 [(compare:CCFP
870 (match_operand:SF 1 "register_operand" "f")
871 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
872 UNSPEC_FNSTSW))]
873 "TARGET_80387"
874 "* return output_fp_compare (insn, operands, 0, 0);"
875 [(set_attr "type" "multi")
876 (set_attr "unit" "i387")
877 (set_attr "mode" "SF")])
878
879 (define_insn "*cmpfp_df"
880 [(set (match_operand:HI 0 "register_operand" "=a")
881 (unspec:HI
882 [(compare:CCFP
883 (match_operand:DF 1 "register_operand" "f")
884 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
885 UNSPEC_FNSTSW))]
886 "TARGET_80387"
887 "* return output_fp_compare (insn, operands, 0, 0);"
888 [(set_attr "type" "multi")
889 (set_attr "unit" "i387")
890 (set_attr "mode" "DF")])
891
892 (define_insn "*cmpfp_xf"
893 [(set (match_operand:HI 0 "register_operand" "=a")
894 (unspec:HI
895 [(compare:CCFP
896 (match_operand:XF 1 "register_operand" "f")
897 (match_operand:XF 2 "register_operand" "f"))]
898 UNSPEC_FNSTSW))]
899 "TARGET_80387"
900 "* return output_fp_compare (insn, operands, 0, 0);"
901 [(set_attr "type" "multi")
902 (set_attr "unit" "i387")
903 (set_attr "mode" "XF")])
904
905 (define_insn "*cmpfp_u"
906 [(set (match_operand:HI 0 "register_operand" "=a")
907 (unspec:HI
908 [(compare:CCFPU
909 (match_operand 1 "register_operand" "f")
910 (match_operand 2 "register_operand" "f"))]
911 UNSPEC_FNSTSW))]
912 "TARGET_80387
913 && FLOAT_MODE_P (GET_MODE (operands[1]))
914 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
915 "* return output_fp_compare (insn, operands, 0, 1);"
916 [(set_attr "type" "multi")
917 (set_attr "unit" "i387")
918 (set (attr "mode")
919 (cond [(match_operand:SF 1 "" "")
920 (const_string "SF")
921 (match_operand:DF 1 "" "")
922 (const_string "DF")
923 ]
924 (const_string "XF")))])
925
926 (define_insn "*cmpfp_<mode>"
927 [(set (match_operand:HI 0 "register_operand" "=a")
928 (unspec:HI
929 [(compare:CCFP
930 (match_operand 1 "register_operand" "f")
931 (match_operator 3 "float_operator"
932 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
933 UNSPEC_FNSTSW))]
934 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
935 && FLOAT_MODE_P (GET_MODE (operands[1]))
936 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
937 "* return output_fp_compare (insn, operands, 0, 0);"
938 [(set_attr "type" "multi")
939 (set_attr "unit" "i387")
940 (set_attr "fp_int_src" "true")
941 (set_attr "mode" "<MODE>")])
942
943 ;; FP compares, step 2
944 ;; Move the fpsw to ax.
945
946 (define_insn "x86_fnstsw_1"
947 [(set (match_operand:HI 0 "register_operand" "=a")
948 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
949 "TARGET_80387"
950 "fnstsw\t%0"
951 [(set_attr "length" "2")
952 (set_attr "mode" "SI")
953 (set_attr "unit" "i387")])
954
955 ;; FP compares, step 3
956 ;; Get ax into flags, general case.
957
958 (define_insn "x86_sahf_1"
959 [(set (reg:CC FLAGS_REG)
960 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
961 "!TARGET_64BIT"
962 "sahf"
963 [(set_attr "length" "1")
964 (set_attr "athlon_decode" "vector")
965 (set_attr "mode" "SI")])
966
967 ;; Pentium Pro can do steps 1 through 3 in one go.
968
969 (define_insn "*cmpfp_i_mixed"
970 [(set (reg:CCFP FLAGS_REG)
971 (compare:CCFP (match_operand 0 "register_operand" "f,x")
972 (match_operand 1 "nonimmediate_operand" "f,xm")))]
973 "TARGET_MIX_SSE_I387
974 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
975 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976 "* return output_fp_compare (insn, operands, 1, 0);"
977 [(set_attr "type" "fcmp,ssecomi")
978 (set (attr "mode")
979 (if_then_else (match_operand:SF 1 "" "")
980 (const_string "SF")
981 (const_string "DF")))
982 (set_attr "athlon_decode" "vector")])
983
984 (define_insn "*cmpfp_i_sse"
985 [(set (reg:CCFP FLAGS_REG)
986 (compare:CCFP (match_operand 0 "register_operand" "x")
987 (match_operand 1 "nonimmediate_operand" "xm")))]
988 "TARGET_SSE_MATH
989 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991 "* return output_fp_compare (insn, operands, 1, 0);"
992 [(set_attr "type" "ssecomi")
993 (set (attr "mode")
994 (if_then_else (match_operand:SF 1 "" "")
995 (const_string "SF")
996 (const_string "DF")))
997 (set_attr "athlon_decode" "vector")])
998
999 (define_insn "*cmpfp_i_i387"
1000 [(set (reg:CCFP FLAGS_REG)
1001 (compare:CCFP (match_operand 0 "register_operand" "f")
1002 (match_operand 1 "register_operand" "f")))]
1003 "TARGET_80387 && TARGET_CMOVE
1004 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1005 && FLOAT_MODE_P (GET_MODE (operands[0]))
1006 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007 "* return output_fp_compare (insn, operands, 1, 0);"
1008 [(set_attr "type" "fcmp")
1009 (set (attr "mode")
1010 (cond [(match_operand:SF 1 "" "")
1011 (const_string "SF")
1012 (match_operand:DF 1 "" "")
1013 (const_string "DF")
1014 ]
1015 (const_string "XF")))
1016 (set_attr "athlon_decode" "vector")])
1017
1018 (define_insn "*cmpfp_iu_mixed"
1019 [(set (reg:CCFPU FLAGS_REG)
1020 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1021 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1022 "TARGET_MIX_SSE_I387
1023 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025 "* return output_fp_compare (insn, operands, 1, 1);"
1026 [(set_attr "type" "fcmp,ssecomi")
1027 (set (attr "mode")
1028 (if_then_else (match_operand:SF 1 "" "")
1029 (const_string "SF")
1030 (const_string "DF")))
1031 (set_attr "athlon_decode" "vector")])
1032
1033 (define_insn "*cmpfp_iu_sse"
1034 [(set (reg:CCFPU FLAGS_REG)
1035 (compare:CCFPU (match_operand 0 "register_operand" "x")
1036 (match_operand 1 "nonimmediate_operand" "xm")))]
1037 "TARGET_SSE_MATH
1038 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040 "* return output_fp_compare (insn, operands, 1, 1);"
1041 [(set_attr "type" "ssecomi")
1042 (set (attr "mode")
1043 (if_then_else (match_operand:SF 1 "" "")
1044 (const_string "SF")
1045 (const_string "DF")))
1046 (set_attr "athlon_decode" "vector")])
1047
1048 (define_insn "*cmpfp_iu_387"
1049 [(set (reg:CCFPU FLAGS_REG)
1050 (compare:CCFPU (match_operand 0 "register_operand" "f")
1051 (match_operand 1 "register_operand" "f")))]
1052 "TARGET_80387 && TARGET_CMOVE
1053 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1054 && FLOAT_MODE_P (GET_MODE (operands[0]))
1055 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1056 "* return output_fp_compare (insn, operands, 1, 1);"
1057 [(set_attr "type" "fcmp")
1058 (set (attr "mode")
1059 (cond [(match_operand:SF 1 "" "")
1060 (const_string "SF")
1061 (match_operand:DF 1 "" "")
1062 (const_string "DF")
1063 ]
1064 (const_string "XF")))
1065 (set_attr "athlon_decode" "vector")])
1066 \f
1067 ;; Move instructions.
1068
1069 ;; General case of fullword move.
1070
1071 (define_expand "movsi"
1072 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1073 (match_operand:SI 1 "general_operand" ""))]
1074 ""
1075 "ix86_expand_move (SImode, operands); DONE;")
1076
1077 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1078 ;; general_operand.
1079 ;;
1080 ;; %%% We don't use a post-inc memory reference because x86 is not a
1081 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1082 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1083 ;; targets without our curiosities, and it is just as easy to represent
1084 ;; this differently.
1085
1086 (define_insn "*pushsi2"
1087 [(set (match_operand:SI 0 "push_operand" "=<")
1088 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1089 "!TARGET_64BIT"
1090 "push{l}\t%1"
1091 [(set_attr "type" "push")
1092 (set_attr "mode" "SI")])
1093
1094 ;; For 64BIT abi we always round up to 8 bytes.
1095 (define_insn "*pushsi2_rex64"
1096 [(set (match_operand:SI 0 "push_operand" "=X")
1097 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1098 "TARGET_64BIT"
1099 "push{q}\t%q1"
1100 [(set_attr "type" "push")
1101 (set_attr "mode" "SI")])
1102
1103 (define_insn "*pushsi2_prologue"
1104 [(set (match_operand:SI 0 "push_operand" "=<")
1105 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1106 (clobber (mem:BLK (scratch)))]
1107 "!TARGET_64BIT"
1108 "push{l}\t%1"
1109 [(set_attr "type" "push")
1110 (set_attr "mode" "SI")])
1111
1112 (define_insn "*popsi1_epilogue"
1113 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114 (mem:SI (reg:SI SP_REG)))
1115 (set (reg:SI SP_REG)
1116 (plus:SI (reg:SI SP_REG) (const_int 4)))
1117 (clobber (mem:BLK (scratch)))]
1118 "!TARGET_64BIT"
1119 "pop{l}\t%0"
1120 [(set_attr "type" "pop")
1121 (set_attr "mode" "SI")])
1122
1123 (define_insn "popsi1"
1124 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1125 (mem:SI (reg:SI SP_REG)))
1126 (set (reg:SI SP_REG)
1127 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1128 "!TARGET_64BIT"
1129 "pop{l}\t%0"
1130 [(set_attr "type" "pop")
1131 (set_attr "mode" "SI")])
1132
1133 (define_insn "*movsi_xor"
1134 [(set (match_operand:SI 0 "register_operand" "=r")
1135 (match_operand:SI 1 "const0_operand" "i"))
1136 (clobber (reg:CC FLAGS_REG))]
1137 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1138 "xor{l}\t{%0, %0|%0, %0}"
1139 [(set_attr "type" "alu1")
1140 (set_attr "mode" "SI")
1141 (set_attr "length_immediate" "0")])
1142
1143 (define_insn "*movsi_or"
1144 [(set (match_operand:SI 0 "register_operand" "=r")
1145 (match_operand:SI 1 "immediate_operand" "i"))
1146 (clobber (reg:CC FLAGS_REG))]
1147 "reload_completed
1148 && operands[1] == constm1_rtx
1149 && (TARGET_PENTIUM || optimize_size)"
1150 {
1151 operands[1] = constm1_rtx;
1152 return "or{l}\t{%1, %0|%0, %1}";
1153 }
1154 [(set_attr "type" "alu1")
1155 (set_attr "mode" "SI")
1156 (set_attr "length_immediate" "1")])
1157
1158 (define_insn "*movsi_1"
1159 [(set (match_operand:SI 0 "nonimmediate_operand"
1160 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1161 (match_operand:SI 1 "general_operand"
1162 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1163 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1164 {
1165 switch (get_attr_type (insn))
1166 {
1167 case TYPE_SSELOG1:
1168 if (get_attr_mode (insn) == MODE_TI)
1169 return "pxor\t%0, %0";
1170 return "xorps\t%0, %0";
1171
1172 case TYPE_SSEMOV:
1173 switch (get_attr_mode (insn))
1174 {
1175 case MODE_TI:
1176 return "movdqa\t{%1, %0|%0, %1}";
1177 case MODE_V4SF:
1178 return "movaps\t{%1, %0|%0, %1}";
1179 case MODE_SI:
1180 return "movd\t{%1, %0|%0, %1}";
1181 case MODE_SF:
1182 return "movss\t{%1, %0|%0, %1}";
1183 default:
1184 gcc_unreachable ();
1185 }
1186
1187 case TYPE_MMXADD:
1188 return "pxor\t%0, %0";
1189
1190 case TYPE_MMXMOV:
1191 if (get_attr_mode (insn) == MODE_DI)
1192 return "movq\t{%1, %0|%0, %1}";
1193 return "movd\t{%1, %0|%0, %1}";
1194
1195 case TYPE_LEA:
1196 return "lea{l}\t{%1, %0|%0, %1}";
1197
1198 default:
1199 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1200 return "mov{l}\t{%1, %0|%0, %1}";
1201 }
1202 }
1203 [(set (attr "type")
1204 (cond [(eq_attr "alternative" "2")
1205 (const_string "mmxadd")
1206 (eq_attr "alternative" "3,4,5")
1207 (const_string "mmxmov")
1208 (eq_attr "alternative" "6")
1209 (const_string "sselog1")
1210 (eq_attr "alternative" "7,8,9,10,11")
1211 (const_string "ssemov")
1212 (match_operand:DI 1 "pic_32bit_operand" "")
1213 (const_string "lea")
1214 ]
1215 (const_string "imov")))
1216 (set (attr "mode")
1217 (cond [(eq_attr "alternative" "2,3")
1218 (const_string "DI")
1219 (eq_attr "alternative" "6,7")
1220 (if_then_else
1221 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1222 (const_string "V4SF")
1223 (const_string "TI"))
1224 (and (eq_attr "alternative" "8,9,10,11")
1225 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1226 (const_string "SF")
1227 ]
1228 (const_string "SI")))])
1229
1230 ;; Stores and loads of ax to arbitrary constant address.
1231 ;; We fake an second form of instruction to force reload to load address
1232 ;; into register when rax is not available
1233 (define_insn "*movabssi_1_rex64"
1234 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1235 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1236 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1237 "@
1238 movabs{l}\t{%1, %P0|%P0, %1}
1239 mov{l}\t{%1, %a0|%a0, %1}"
1240 [(set_attr "type" "imov")
1241 (set_attr "modrm" "0,*")
1242 (set_attr "length_address" "8,0")
1243 (set_attr "length_immediate" "0,*")
1244 (set_attr "memory" "store")
1245 (set_attr "mode" "SI")])
1246
1247 (define_insn "*movabssi_2_rex64"
1248 [(set (match_operand:SI 0 "register_operand" "=a,r")
1249 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1250 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1251 "@
1252 movabs{l}\t{%P1, %0|%0, %P1}
1253 mov{l}\t{%a1, %0|%0, %a1}"
1254 [(set_attr "type" "imov")
1255 (set_attr "modrm" "0,*")
1256 (set_attr "length_address" "8,0")
1257 (set_attr "length_immediate" "0")
1258 (set_attr "memory" "load")
1259 (set_attr "mode" "SI")])
1260
1261 (define_insn "*swapsi"
1262 [(set (match_operand:SI 0 "register_operand" "+r")
1263 (match_operand:SI 1 "register_operand" "+r"))
1264 (set (match_dup 1)
1265 (match_dup 0))]
1266 ""
1267 "xchg{l}\t%1, %0"
1268 [(set_attr "type" "imov")
1269 (set_attr "mode" "SI")
1270 (set_attr "pent_pair" "np")
1271 (set_attr "athlon_decode" "vector")])
1272
1273 (define_expand "movhi"
1274 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1275 (match_operand:HI 1 "general_operand" ""))]
1276 ""
1277 "ix86_expand_move (HImode, operands); DONE;")
1278
1279 (define_insn "*pushhi2"
1280 [(set (match_operand:HI 0 "push_operand" "=X")
1281 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1282 "!TARGET_64BIT"
1283 "push{l}\t%k1"
1284 [(set_attr "type" "push")
1285 (set_attr "mode" "SI")])
1286
1287 ;; For 64BIT abi we always round up to 8 bytes.
1288 (define_insn "*pushhi2_rex64"
1289 [(set (match_operand:HI 0 "push_operand" "=X")
1290 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1291 "TARGET_64BIT"
1292 "push{q}\t%q1"
1293 [(set_attr "type" "push")
1294 (set_attr "mode" "DI")])
1295
1296 (define_insn "*movhi_1"
1297 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1298 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1299 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1300 {
1301 switch (get_attr_type (insn))
1302 {
1303 case TYPE_IMOVX:
1304 /* movzwl is faster than movw on p2 due to partial word stalls,
1305 though not as fast as an aligned movl. */
1306 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1307 default:
1308 if (get_attr_mode (insn) == MODE_SI)
1309 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1310 else
1311 return "mov{w}\t{%1, %0|%0, %1}";
1312 }
1313 }
1314 [(set (attr "type")
1315 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1316 (const_string "imov")
1317 (and (eq_attr "alternative" "0")
1318 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1319 (const_int 0))
1320 (eq (symbol_ref "TARGET_HIMODE_MATH")
1321 (const_int 0))))
1322 (const_string "imov")
1323 (and (eq_attr "alternative" "1,2")
1324 (match_operand:HI 1 "aligned_operand" ""))
1325 (const_string "imov")
1326 (and (ne (symbol_ref "TARGET_MOVX")
1327 (const_int 0))
1328 (eq_attr "alternative" "0,2"))
1329 (const_string "imovx")
1330 ]
1331 (const_string "imov")))
1332 (set (attr "mode")
1333 (cond [(eq_attr "type" "imovx")
1334 (const_string "SI")
1335 (and (eq_attr "alternative" "1,2")
1336 (match_operand:HI 1 "aligned_operand" ""))
1337 (const_string "SI")
1338 (and (eq_attr "alternative" "0")
1339 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340 (const_int 0))
1341 (eq (symbol_ref "TARGET_HIMODE_MATH")
1342 (const_int 0))))
1343 (const_string "SI")
1344 ]
1345 (const_string "HI")))])
1346
1347 ;; Stores and loads of ax to arbitrary constant address.
1348 ;; We fake an second form of instruction to force reload to load address
1349 ;; into register when rax is not available
1350 (define_insn "*movabshi_1_rex64"
1351 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1352 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1353 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1354 "@
1355 movabs{w}\t{%1, %P0|%P0, %1}
1356 mov{w}\t{%1, %a0|%a0, %1}"
1357 [(set_attr "type" "imov")
1358 (set_attr "modrm" "0,*")
1359 (set_attr "length_address" "8,0")
1360 (set_attr "length_immediate" "0,*")
1361 (set_attr "memory" "store")
1362 (set_attr "mode" "HI")])
1363
1364 (define_insn "*movabshi_2_rex64"
1365 [(set (match_operand:HI 0 "register_operand" "=a,r")
1366 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1367 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1368 "@
1369 movabs{w}\t{%P1, %0|%0, %P1}
1370 mov{w}\t{%a1, %0|%0, %a1}"
1371 [(set_attr "type" "imov")
1372 (set_attr "modrm" "0,*")
1373 (set_attr "length_address" "8,0")
1374 (set_attr "length_immediate" "0")
1375 (set_attr "memory" "load")
1376 (set_attr "mode" "HI")])
1377
1378 (define_insn "*swaphi_1"
1379 [(set (match_operand:HI 0 "register_operand" "+r")
1380 (match_operand:HI 1 "register_operand" "+r"))
1381 (set (match_dup 1)
1382 (match_dup 0))]
1383 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1384 "xchg{l}\t%k1, %k0"
1385 [(set_attr "type" "imov")
1386 (set_attr "mode" "SI")
1387 (set_attr "pent_pair" "np")
1388 (set_attr "athlon_decode" "vector")])
1389
1390 (define_insn "*swaphi_2"
1391 [(set (match_operand:HI 0 "register_operand" "+r")
1392 (match_operand:HI 1 "register_operand" "+r"))
1393 (set (match_dup 1)
1394 (match_dup 0))]
1395 "TARGET_PARTIAL_REG_STALL"
1396 "xchg{w}\t%1, %0"
1397 [(set_attr "type" "imov")
1398 (set_attr "mode" "HI")
1399 (set_attr "pent_pair" "np")
1400 (set_attr "athlon_decode" "vector")])
1401
1402 (define_expand "movstricthi"
1403 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1404 (match_operand:HI 1 "general_operand" ""))]
1405 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1406 {
1407 /* Don't generate memory->memory moves, go through a register */
1408 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1409 operands[1] = force_reg (HImode, operands[1]);
1410 })
1411
1412 (define_insn "*movstricthi_1"
1413 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1414 (match_operand:HI 1 "general_operand" "rn,m"))]
1415 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1416 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1417 "mov{w}\t{%1, %0|%0, %1}"
1418 [(set_attr "type" "imov")
1419 (set_attr "mode" "HI")])
1420
1421 (define_insn "*movstricthi_xor"
1422 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1423 (match_operand:HI 1 "const0_operand" "i"))
1424 (clobber (reg:CC FLAGS_REG))]
1425 "reload_completed
1426 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1427 "xor{w}\t{%0, %0|%0, %0}"
1428 [(set_attr "type" "alu1")
1429 (set_attr "mode" "HI")
1430 (set_attr "length_immediate" "0")])
1431
1432 (define_expand "movqi"
1433 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1434 (match_operand:QI 1 "general_operand" ""))]
1435 ""
1436 "ix86_expand_move (QImode, operands); DONE;")
1437
1438 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1439 ;; "push a byte". But actually we use pushl, which has the effect
1440 ;; of rounding the amount pushed up to a word.
1441
1442 (define_insn "*pushqi2"
1443 [(set (match_operand:QI 0 "push_operand" "=X")
1444 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1445 "!TARGET_64BIT"
1446 "push{l}\t%k1"
1447 [(set_attr "type" "push")
1448 (set_attr "mode" "SI")])
1449
1450 ;; For 64BIT abi we always round up to 8 bytes.
1451 (define_insn "*pushqi2_rex64"
1452 [(set (match_operand:QI 0 "push_operand" "=X")
1453 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1454 "TARGET_64BIT"
1455 "push{q}\t%q1"
1456 [(set_attr "type" "push")
1457 (set_attr "mode" "DI")])
1458
1459 ;; Situation is quite tricky about when to choose full sized (SImode) move
1460 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1461 ;; partial register dependency machines (such as AMD Athlon), where QImode
1462 ;; moves issue extra dependency and for partial register stalls machines
1463 ;; that don't use QImode patterns (and QImode move cause stall on the next
1464 ;; instruction).
1465 ;;
1466 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1467 ;; register stall machines with, where we use QImode instructions, since
1468 ;; partial register stall can be caused there. Then we use movzx.
1469 (define_insn "*movqi_1"
1470 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1471 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1472 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1473 {
1474 switch (get_attr_type (insn))
1475 {
1476 case TYPE_IMOVX:
1477 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1478 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1479 default:
1480 if (get_attr_mode (insn) == MODE_SI)
1481 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1482 else
1483 return "mov{b}\t{%1, %0|%0, %1}";
1484 }
1485 }
1486 [(set (attr "type")
1487 (cond [(and (eq_attr "alternative" "5")
1488 (not (match_operand:QI 1 "aligned_operand" "")))
1489 (const_string "imovx")
1490 (ne (symbol_ref "optimize_size") (const_int 0))
1491 (const_string "imov")
1492 (and (eq_attr "alternative" "3")
1493 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1494 (const_int 0))
1495 (eq (symbol_ref "TARGET_QIMODE_MATH")
1496 (const_int 0))))
1497 (const_string "imov")
1498 (eq_attr "alternative" "3,5")
1499 (const_string "imovx")
1500 (and (ne (symbol_ref "TARGET_MOVX")
1501 (const_int 0))
1502 (eq_attr "alternative" "2"))
1503 (const_string "imovx")
1504 ]
1505 (const_string "imov")))
1506 (set (attr "mode")
1507 (cond [(eq_attr "alternative" "3,4,5")
1508 (const_string "SI")
1509 (eq_attr "alternative" "6")
1510 (const_string "QI")
1511 (eq_attr "type" "imovx")
1512 (const_string "SI")
1513 (and (eq_attr "type" "imov")
1514 (and (eq_attr "alternative" "0,1")
1515 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1516 (const_int 0))
1517 (and (eq (symbol_ref "optimize_size")
1518 (const_int 0))
1519 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1520 (const_int 0))))))
1521 (const_string "SI")
1522 ;; Avoid partial register stalls when not using QImode arithmetic
1523 (and (eq_attr "type" "imov")
1524 (and (eq_attr "alternative" "0,1")
1525 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526 (const_int 0))
1527 (eq (symbol_ref "TARGET_QIMODE_MATH")
1528 (const_int 0)))))
1529 (const_string "SI")
1530 ]
1531 (const_string "QI")))])
1532
1533 (define_expand "reload_outqi"
1534 [(parallel [(match_operand:QI 0 "" "=m")
1535 (match_operand:QI 1 "register_operand" "r")
1536 (match_operand:QI 2 "register_operand" "=&q")])]
1537 ""
1538 {
1539 rtx op0, op1, op2;
1540 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1541
1542 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1543 if (! q_regs_operand (op1, QImode))
1544 {
1545 emit_insn (gen_movqi (op2, op1));
1546 op1 = op2;
1547 }
1548 emit_insn (gen_movqi (op0, op1));
1549 DONE;
1550 })
1551
1552 (define_insn "*swapqi_1"
1553 [(set (match_operand:QI 0 "register_operand" "+r")
1554 (match_operand:QI 1 "register_operand" "+r"))
1555 (set (match_dup 1)
1556 (match_dup 0))]
1557 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1558 "xchg{l}\t%k1, %k0"
1559 [(set_attr "type" "imov")
1560 (set_attr "mode" "SI")
1561 (set_attr "pent_pair" "np")
1562 (set_attr "athlon_decode" "vector")])
1563
1564 (define_insn "*swapqi_2"
1565 [(set (match_operand:QI 0 "register_operand" "+q")
1566 (match_operand:QI 1 "register_operand" "+q"))
1567 (set (match_dup 1)
1568 (match_dup 0))]
1569 "TARGET_PARTIAL_REG_STALL"
1570 "xchg{b}\t%1, %0"
1571 [(set_attr "type" "imov")
1572 (set_attr "mode" "QI")
1573 (set_attr "pent_pair" "np")
1574 (set_attr "athlon_decode" "vector")])
1575
1576 (define_expand "movstrictqi"
1577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1578 (match_operand:QI 1 "general_operand" ""))]
1579 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1580 {
1581 /* Don't generate memory->memory moves, go through a register. */
1582 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1583 operands[1] = force_reg (QImode, operands[1]);
1584 })
1585
1586 (define_insn "*movstrictqi_1"
1587 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1588 (match_operand:QI 1 "general_operand" "*qn,m"))]
1589 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1590 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1591 "mov{b}\t{%1, %0|%0, %1}"
1592 [(set_attr "type" "imov")
1593 (set_attr "mode" "QI")])
1594
1595 (define_insn "*movstrictqi_xor"
1596 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1597 (match_operand:QI 1 "const0_operand" "i"))
1598 (clobber (reg:CC FLAGS_REG))]
1599 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1600 "xor{b}\t{%0, %0|%0, %0}"
1601 [(set_attr "type" "alu1")
1602 (set_attr "mode" "QI")
1603 (set_attr "length_immediate" "0")])
1604
1605 (define_insn "*movsi_extv_1"
1606 [(set (match_operand:SI 0 "register_operand" "=R")
1607 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1608 (const_int 8)
1609 (const_int 8)))]
1610 ""
1611 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1612 [(set_attr "type" "imovx")
1613 (set_attr "mode" "SI")])
1614
1615 (define_insn "*movhi_extv_1"
1616 [(set (match_operand:HI 0 "register_operand" "=R")
1617 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1618 (const_int 8)
1619 (const_int 8)))]
1620 ""
1621 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1622 [(set_attr "type" "imovx")
1623 (set_attr "mode" "SI")])
1624
1625 (define_insn "*movqi_extv_1"
1626 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1627 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1628 (const_int 8)
1629 (const_int 8)))]
1630 "!TARGET_64BIT"
1631 {
1632 switch (get_attr_type (insn))
1633 {
1634 case TYPE_IMOVX:
1635 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1636 default:
1637 return "mov{b}\t{%h1, %0|%0, %h1}";
1638 }
1639 }
1640 [(set (attr "type")
1641 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1642 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1643 (ne (symbol_ref "TARGET_MOVX")
1644 (const_int 0))))
1645 (const_string "imovx")
1646 (const_string "imov")))
1647 (set (attr "mode")
1648 (if_then_else (eq_attr "type" "imovx")
1649 (const_string "SI")
1650 (const_string "QI")))])
1651
1652 (define_insn "*movqi_extv_1_rex64"
1653 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1654 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1655 (const_int 8)
1656 (const_int 8)))]
1657 "TARGET_64BIT"
1658 {
1659 switch (get_attr_type (insn))
1660 {
1661 case TYPE_IMOVX:
1662 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1663 default:
1664 return "mov{b}\t{%h1, %0|%0, %h1}";
1665 }
1666 }
1667 [(set (attr "type")
1668 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1669 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670 (ne (symbol_ref "TARGET_MOVX")
1671 (const_int 0))))
1672 (const_string "imovx")
1673 (const_string "imov")))
1674 (set (attr "mode")
1675 (if_then_else (eq_attr "type" "imovx")
1676 (const_string "SI")
1677 (const_string "QI")))])
1678
1679 ;; Stores and loads of ax to arbitrary constant address.
1680 ;; We fake an second form of instruction to force reload to load address
1681 ;; into register when rax is not available
1682 (define_insn "*movabsqi_1_rex64"
1683 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1684 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1685 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1686 "@
1687 movabs{b}\t{%1, %P0|%P0, %1}
1688 mov{b}\t{%1, %a0|%a0, %1}"
1689 [(set_attr "type" "imov")
1690 (set_attr "modrm" "0,*")
1691 (set_attr "length_address" "8,0")
1692 (set_attr "length_immediate" "0,*")
1693 (set_attr "memory" "store")
1694 (set_attr "mode" "QI")])
1695
1696 (define_insn "*movabsqi_2_rex64"
1697 [(set (match_operand:QI 0 "register_operand" "=a,r")
1698 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1699 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1700 "@
1701 movabs{b}\t{%P1, %0|%0, %P1}
1702 mov{b}\t{%a1, %0|%0, %a1}"
1703 [(set_attr "type" "imov")
1704 (set_attr "modrm" "0,*")
1705 (set_attr "length_address" "8,0")
1706 (set_attr "length_immediate" "0")
1707 (set_attr "memory" "load")
1708 (set_attr "mode" "QI")])
1709
1710 (define_insn "*movdi_extzv_1"
1711 [(set (match_operand:DI 0 "register_operand" "=R")
1712 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1713 (const_int 8)
1714 (const_int 8)))]
1715 "TARGET_64BIT"
1716 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1717 [(set_attr "type" "imovx")
1718 (set_attr "mode" "DI")])
1719
1720 (define_insn "*movsi_extzv_1"
1721 [(set (match_operand:SI 0 "register_operand" "=R")
1722 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1723 (const_int 8)
1724 (const_int 8)))]
1725 ""
1726 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1727 [(set_attr "type" "imovx")
1728 (set_attr "mode" "SI")])
1729
1730 (define_insn "*movqi_extzv_2"
1731 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1732 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733 (const_int 8)
1734 (const_int 8)) 0))]
1735 "!TARGET_64BIT"
1736 {
1737 switch (get_attr_type (insn))
1738 {
1739 case TYPE_IMOVX:
1740 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741 default:
1742 return "mov{b}\t{%h1, %0|%0, %h1}";
1743 }
1744 }
1745 [(set (attr "type")
1746 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1747 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1748 (ne (symbol_ref "TARGET_MOVX")
1749 (const_int 0))))
1750 (const_string "imovx")
1751 (const_string "imov")))
1752 (set (attr "mode")
1753 (if_then_else (eq_attr "type" "imovx")
1754 (const_string "SI")
1755 (const_string "QI")))])
1756
1757 (define_insn "*movqi_extzv_2_rex64"
1758 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1759 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1760 (const_int 8)
1761 (const_int 8)) 0))]
1762 "TARGET_64BIT"
1763 {
1764 switch (get_attr_type (insn))
1765 {
1766 case TYPE_IMOVX:
1767 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1768 default:
1769 return "mov{b}\t{%h1, %0|%0, %h1}";
1770 }
1771 }
1772 [(set (attr "type")
1773 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774 (ne (symbol_ref "TARGET_MOVX")
1775 (const_int 0)))
1776 (const_string "imovx")
1777 (const_string "imov")))
1778 (set (attr "mode")
1779 (if_then_else (eq_attr "type" "imovx")
1780 (const_string "SI")
1781 (const_string "QI")))])
1782
1783 (define_insn "movsi_insv_1"
1784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1785 (const_int 8)
1786 (const_int 8))
1787 (match_operand:SI 1 "general_operand" "Qmn"))]
1788 "!TARGET_64BIT"
1789 "mov{b}\t{%b1, %h0|%h0, %b1}"
1790 [(set_attr "type" "imov")
1791 (set_attr "mode" "QI")])
1792
1793 (define_insn "movdi_insv_1_rex64"
1794 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1795 (const_int 8)
1796 (const_int 8))
1797 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1798 "TARGET_64BIT"
1799 "mov{b}\t{%b1, %h0|%h0, %b1}"
1800 [(set_attr "type" "imov")
1801 (set_attr "mode" "QI")])
1802
1803 (define_insn "*movqi_insv_2"
1804 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1805 (const_int 8)
1806 (const_int 8))
1807 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1808 (const_int 8)))]
1809 ""
1810 "mov{b}\t{%h1, %h0|%h0, %h1}"
1811 [(set_attr "type" "imov")
1812 (set_attr "mode" "QI")])
1813
1814 (define_expand "movdi"
1815 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1816 (match_operand:DI 1 "general_operand" ""))]
1817 ""
1818 "ix86_expand_move (DImode, operands); DONE;")
1819
1820 (define_insn "*pushdi"
1821 [(set (match_operand:DI 0 "push_operand" "=<")
1822 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1823 "!TARGET_64BIT"
1824 "#")
1825
1826 (define_insn "*pushdi2_rex64"
1827 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1828 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1829 "TARGET_64BIT"
1830 "@
1831 push{q}\t%1
1832 #"
1833 [(set_attr "type" "push,multi")
1834 (set_attr "mode" "DI")])
1835
1836 ;; Convert impossible pushes of immediate to existing instructions.
1837 ;; First try to get scratch register and go through it. In case this
1838 ;; fails, push sign extended lower part first and then overwrite
1839 ;; upper part by 32bit move.
1840 (define_peephole2
1841 [(match_scratch:DI 2 "r")
1842 (set (match_operand:DI 0 "push_operand" "")
1843 (match_operand:DI 1 "immediate_operand" ""))]
1844 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1845 && !x86_64_immediate_operand (operands[1], DImode)"
1846 [(set (match_dup 2) (match_dup 1))
1847 (set (match_dup 0) (match_dup 2))]
1848 "")
1849
1850 ;; We need to define this as both peepholer and splitter for case
1851 ;; peephole2 pass is not run.
1852 ;; "&& 1" is needed to keep it from matching the previous pattern.
1853 (define_peephole2
1854 [(set (match_operand:DI 0 "push_operand" "")
1855 (match_operand:DI 1 "immediate_operand" ""))]
1856 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1857 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1858 [(set (match_dup 0) (match_dup 1))
1859 (set (match_dup 2) (match_dup 3))]
1860 "split_di (operands + 1, 1, operands + 2, operands + 3);
1861 operands[1] = gen_lowpart (DImode, operands[2]);
1862 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1863 GEN_INT (4)));
1864 ")
1865
1866 (define_split
1867 [(set (match_operand:DI 0 "push_operand" "")
1868 (match_operand:DI 1 "immediate_operand" ""))]
1869 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1870 ? flow2_completed : reload_completed)
1871 && !symbolic_operand (operands[1], DImode)
1872 && !x86_64_immediate_operand (operands[1], DImode)"
1873 [(set (match_dup 0) (match_dup 1))
1874 (set (match_dup 2) (match_dup 3))]
1875 "split_di (operands + 1, 1, operands + 2, operands + 3);
1876 operands[1] = gen_lowpart (DImode, operands[2]);
1877 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1878 GEN_INT (4)));
1879 ")
1880
1881 (define_insn "*pushdi2_prologue_rex64"
1882 [(set (match_operand:DI 0 "push_operand" "=<")
1883 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1884 (clobber (mem:BLK (scratch)))]
1885 "TARGET_64BIT"
1886 "push{q}\t%1"
1887 [(set_attr "type" "push")
1888 (set_attr "mode" "DI")])
1889
1890 (define_insn "*popdi1_epilogue_rex64"
1891 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892 (mem:DI (reg:DI SP_REG)))
1893 (set (reg:DI SP_REG)
1894 (plus:DI (reg:DI SP_REG) (const_int 8)))
1895 (clobber (mem:BLK (scratch)))]
1896 "TARGET_64BIT"
1897 "pop{q}\t%0"
1898 [(set_attr "type" "pop")
1899 (set_attr "mode" "DI")])
1900
1901 (define_insn "popdi1"
1902 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1903 (mem:DI (reg:DI SP_REG)))
1904 (set (reg:DI SP_REG)
1905 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1906 "TARGET_64BIT"
1907 "pop{q}\t%0"
1908 [(set_attr "type" "pop")
1909 (set_attr "mode" "DI")])
1910
1911 (define_insn "*movdi_xor_rex64"
1912 [(set (match_operand:DI 0 "register_operand" "=r")
1913 (match_operand:DI 1 "const0_operand" "i"))
1914 (clobber (reg:CC FLAGS_REG))]
1915 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1916 && reload_completed"
1917 "xor{l}\t{%k0, %k0|%k0, %k0}"
1918 [(set_attr "type" "alu1")
1919 (set_attr "mode" "SI")
1920 (set_attr "length_immediate" "0")])
1921
1922 (define_insn "*movdi_or_rex64"
1923 [(set (match_operand:DI 0 "register_operand" "=r")
1924 (match_operand:DI 1 "const_int_operand" "i"))
1925 (clobber (reg:CC FLAGS_REG))]
1926 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1927 && reload_completed
1928 && operands[1] == constm1_rtx"
1929 {
1930 operands[1] = constm1_rtx;
1931 return "or{q}\t{%1, %0|%0, %1}";
1932 }
1933 [(set_attr "type" "alu1")
1934 (set_attr "mode" "DI")
1935 (set_attr "length_immediate" "1")])
1936
1937 (define_insn "*movdi_2"
1938 [(set (match_operand:DI 0 "nonimmediate_operand"
1939 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1940 (match_operand:DI 1 "general_operand"
1941 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1942 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943 "@
1944 #
1945 #
1946 pxor\t%0, %0
1947 movq\t{%1, %0|%0, %1}
1948 movq\t{%1, %0|%0, %1}
1949 pxor\t%0, %0
1950 movq\t{%1, %0|%0, %1}
1951 movdqa\t{%1, %0|%0, %1}
1952 movq\t{%1, %0|%0, %1}
1953 xorps\t%0, %0
1954 movlps\t{%1, %0|%0, %1}
1955 movaps\t{%1, %0|%0, %1}
1956 movlps\t{%1, %0|%0, %1}"
1957 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1958 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1959
1960 (define_split
1961 [(set (match_operand:DI 0 "push_operand" "")
1962 (match_operand:DI 1 "general_operand" ""))]
1963 "!TARGET_64BIT && reload_completed
1964 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1965 [(const_int 0)]
1966 "ix86_split_long_move (operands); DONE;")
1967
1968 ;; %%% This multiword shite has got to go.
1969 (define_split
1970 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1971 (match_operand:DI 1 "general_operand" ""))]
1972 "!TARGET_64BIT && reload_completed
1973 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1974 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1975 [(const_int 0)]
1976 "ix86_split_long_move (operands); DONE;")
1977
1978 (define_insn "*movdi_1_rex64"
1979 [(set (match_operand:DI 0 "nonimmediate_operand"
1980 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1981 (match_operand:DI 1 "general_operand"
1982 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1983 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1984 {
1985 switch (get_attr_type (insn))
1986 {
1987 case TYPE_SSECVT:
1988 if (which_alternative == 13)
1989 return "movq2dq\t{%1, %0|%0, %1}";
1990 else
1991 return "movdq2q\t{%1, %0|%0, %1}";
1992 case TYPE_SSEMOV:
1993 if (get_attr_mode (insn) == MODE_TI)
1994 return "movdqa\t{%1, %0|%0, %1}";
1995 /* FALLTHRU */
1996 case TYPE_MMXMOV:
1997 /* Moves from and into integer register is done using movd opcode with
1998 REX prefix. */
1999 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2000 return "movd\t{%1, %0|%0, %1}";
2001 return "movq\t{%1, %0|%0, %1}";
2002 case TYPE_SSELOG1:
2003 case TYPE_MMXADD:
2004 return "pxor\t%0, %0";
2005 case TYPE_MULTI:
2006 return "#";
2007 case TYPE_LEA:
2008 return "lea{q}\t{%a1, %0|%0, %a1}";
2009 default:
2010 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2011 if (get_attr_mode (insn) == MODE_SI)
2012 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2013 else if (which_alternative == 2)
2014 return "movabs{q}\t{%1, %0|%0, %1}";
2015 else
2016 return "mov{q}\t{%1, %0|%0, %1}";
2017 }
2018 }
2019 [(set (attr "type")
2020 (cond [(eq_attr "alternative" "5")
2021 (const_string "mmxadd")
2022 (eq_attr "alternative" "6,7,8")
2023 (const_string "mmxmov")
2024 (eq_attr "alternative" "9")
2025 (const_string "sselog1")
2026 (eq_attr "alternative" "10,11,12")
2027 (const_string "ssemov")
2028 (eq_attr "alternative" "13,14")
2029 (const_string "ssecvt")
2030 (eq_attr "alternative" "4")
2031 (const_string "multi")
2032 (match_operand:DI 1 "pic_32bit_operand" "")
2033 (const_string "lea")
2034 ]
2035 (const_string "imov")))
2036 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2037 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2038 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2039
2040 ;; Stores and loads of ax to arbitrary constant address.
2041 ;; We fake an second form of instruction to force reload to load address
2042 ;; into register when rax is not available
2043 (define_insn "*movabsdi_1_rex64"
2044 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2045 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2046 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2047 "@
2048 movabs{q}\t{%1, %P0|%P0, %1}
2049 mov{q}\t{%1, %a0|%a0, %1}"
2050 [(set_attr "type" "imov")
2051 (set_attr "modrm" "0,*")
2052 (set_attr "length_address" "8,0")
2053 (set_attr "length_immediate" "0,*")
2054 (set_attr "memory" "store")
2055 (set_attr "mode" "DI")])
2056
2057 (define_insn "*movabsdi_2_rex64"
2058 [(set (match_operand:DI 0 "register_operand" "=a,r")
2059 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2060 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2061 "@
2062 movabs{q}\t{%P1, %0|%0, %P1}
2063 mov{q}\t{%a1, %0|%0, %a1}"
2064 [(set_attr "type" "imov")
2065 (set_attr "modrm" "0,*")
2066 (set_attr "length_address" "8,0")
2067 (set_attr "length_immediate" "0")
2068 (set_attr "memory" "load")
2069 (set_attr "mode" "DI")])
2070
2071 ;; Convert impossible stores of immediate to existing instructions.
2072 ;; First try to get scratch register and go through it. In case this
2073 ;; fails, move by 32bit parts.
2074 (define_peephole2
2075 [(match_scratch:DI 2 "r")
2076 (set (match_operand:DI 0 "memory_operand" "")
2077 (match_operand:DI 1 "immediate_operand" ""))]
2078 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079 && !x86_64_immediate_operand (operands[1], DImode)"
2080 [(set (match_dup 2) (match_dup 1))
2081 (set (match_dup 0) (match_dup 2))]
2082 "")
2083
2084 ;; We need to define this as both peepholer and splitter for case
2085 ;; peephole2 pass is not run.
2086 ;; "&& 1" is needed to keep it from matching the previous pattern.
2087 (define_peephole2
2088 [(set (match_operand:DI 0 "memory_operand" "")
2089 (match_operand:DI 1 "immediate_operand" ""))]
2090 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2092 [(set (match_dup 2) (match_dup 3))
2093 (set (match_dup 4) (match_dup 5))]
2094 "split_di (operands, 2, operands + 2, operands + 4);")
2095
2096 (define_split
2097 [(set (match_operand:DI 0 "memory_operand" "")
2098 (match_operand:DI 1 "immediate_operand" ""))]
2099 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2100 ? flow2_completed : reload_completed)
2101 && !symbolic_operand (operands[1], DImode)
2102 && !x86_64_immediate_operand (operands[1], DImode)"
2103 [(set (match_dup 2) (match_dup 3))
2104 (set (match_dup 4) (match_dup 5))]
2105 "split_di (operands, 2, operands + 2, operands + 4);")
2106
2107 (define_insn "*swapdi_rex64"
2108 [(set (match_operand:DI 0 "register_operand" "+r")
2109 (match_operand:DI 1 "register_operand" "+r"))
2110 (set (match_dup 1)
2111 (match_dup 0))]
2112 "TARGET_64BIT"
2113 "xchg{q}\t%1, %0"
2114 [(set_attr "type" "imov")
2115 (set_attr "mode" "DI")
2116 (set_attr "pent_pair" "np")
2117 (set_attr "athlon_decode" "vector")])
2118
2119 (define_expand "movti"
2120 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2121 (match_operand:TI 1 "nonimmediate_operand" ""))]
2122 "TARGET_SSE || TARGET_64BIT"
2123 {
2124 if (TARGET_64BIT)
2125 ix86_expand_move (TImode, operands);
2126 else
2127 ix86_expand_vector_move (TImode, operands);
2128 DONE;
2129 })
2130
2131 (define_insn "*movti_internal"
2132 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2133 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2134 "TARGET_SSE && !TARGET_64BIT
2135 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2136 {
2137 switch (which_alternative)
2138 {
2139 case 0:
2140 if (get_attr_mode (insn) == MODE_V4SF)
2141 return "xorps\t%0, %0";
2142 else
2143 return "pxor\t%0, %0";
2144 case 1:
2145 case 2:
2146 if (get_attr_mode (insn) == MODE_V4SF)
2147 return "movaps\t{%1, %0|%0, %1}";
2148 else
2149 return "movdqa\t{%1, %0|%0, %1}";
2150 default:
2151 gcc_unreachable ();
2152 }
2153 }
2154 [(set_attr "type" "sselog1,ssemov,ssemov")
2155 (set (attr "mode")
2156 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2157 (ne (symbol_ref "optimize_size") (const_int 0)))
2158 (const_string "V4SF")
2159 (and (eq_attr "alternative" "2")
2160 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2161 (const_int 0)))
2162 (const_string "V4SF")]
2163 (const_string "TI")))])
2164
2165 (define_insn "*movti_rex64"
2166 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2167 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2168 "TARGET_64BIT
2169 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2170 {
2171 switch (which_alternative)
2172 {
2173 case 0:
2174 case 1:
2175 return "#";
2176 case 2:
2177 if (get_attr_mode (insn) == MODE_V4SF)
2178 return "xorps\t%0, %0";
2179 else
2180 return "pxor\t%0, %0";
2181 case 3:
2182 case 4:
2183 if (get_attr_mode (insn) == MODE_V4SF)
2184 return "movaps\t{%1, %0|%0, %1}";
2185 else
2186 return "movdqa\t{%1, %0|%0, %1}";
2187 default:
2188 gcc_unreachable ();
2189 }
2190 }
2191 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2192 (set (attr "mode")
2193 (cond [(eq_attr "alternative" "2,3")
2194 (if_then_else
2195 (ne (symbol_ref "optimize_size")
2196 (const_int 0))
2197 (const_string "V4SF")
2198 (const_string "TI"))
2199 (eq_attr "alternative" "4")
2200 (if_then_else
2201 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2202 (const_int 0))
2203 (ne (symbol_ref "optimize_size")
2204 (const_int 0)))
2205 (const_string "V4SF")
2206 (const_string "TI"))]
2207 (const_string "DI")))])
2208
2209 (define_split
2210 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2211 (match_operand:TI 1 "general_operand" ""))]
2212 "reload_completed && !SSE_REG_P (operands[0])
2213 && !SSE_REG_P (operands[1])"
2214 [(const_int 0)]
2215 "ix86_split_long_move (operands); DONE;")
2216
2217 (define_expand "movsf"
2218 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2219 (match_operand:SF 1 "general_operand" ""))]
2220 ""
2221 "ix86_expand_move (SFmode, operands); DONE;")
2222
2223 (define_insn "*pushsf"
2224 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2225 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2226 "!TARGET_64BIT"
2227 {
2228 /* Anything else should be already split before reg-stack. */
2229 gcc_assert (which_alternative == 1);
2230 return "push{l}\t%1";
2231 }
2232 [(set_attr "type" "multi,push,multi")
2233 (set_attr "unit" "i387,*,*")
2234 (set_attr "mode" "SF,SI,SF")])
2235
2236 (define_insn "*pushsf_rex64"
2237 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2238 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2239 "TARGET_64BIT"
2240 {
2241 /* Anything else should be already split before reg-stack. */
2242 gcc_assert (which_alternative == 1);
2243 return "push{q}\t%q1";
2244 }
2245 [(set_attr "type" "multi,push,multi")
2246 (set_attr "unit" "i387,*,*")
2247 (set_attr "mode" "SF,DI,SF")])
2248
2249 (define_split
2250 [(set (match_operand:SF 0 "push_operand" "")
2251 (match_operand:SF 1 "memory_operand" ""))]
2252 "reload_completed
2253 && GET_CODE (operands[1]) == MEM
2254 && constant_pool_reference_p (operands[1])"
2255 [(set (match_dup 0)
2256 (match_dup 1))]
2257 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2258
2259
2260 ;; %%% Kill this when call knows how to work this out.
2261 (define_split
2262 [(set (match_operand:SF 0 "push_operand" "")
2263 (match_operand:SF 1 "any_fp_register_operand" ""))]
2264 "!TARGET_64BIT"
2265 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2266 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2267
2268 (define_split
2269 [(set (match_operand:SF 0 "push_operand" "")
2270 (match_operand:SF 1 "any_fp_register_operand" ""))]
2271 "TARGET_64BIT"
2272 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2273 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2274
2275 (define_insn "*movsf_1"
2276 [(set (match_operand:SF 0 "nonimmediate_operand"
2277 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2278 (match_operand:SF 1 "general_operand"
2279 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2280 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2281 && (reload_in_progress || reload_completed
2282 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2283 || GET_CODE (operands[1]) != CONST_DOUBLE
2284 || memory_operand (operands[0], SFmode))"
2285 {
2286 switch (which_alternative)
2287 {
2288 case 0:
2289 return output_387_reg_move (insn, operands);
2290
2291 case 1:
2292 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2293 return "fstp%z0\t%y0";
2294 else
2295 return "fst%z0\t%y0";
2296
2297 case 2:
2298 return standard_80387_constant_opcode (operands[1]);
2299
2300 case 3:
2301 case 4:
2302 return "mov{l}\t{%1, %0|%0, %1}";
2303 case 5:
2304 if (get_attr_mode (insn) == MODE_TI)
2305 return "pxor\t%0, %0";
2306 else
2307 return "xorps\t%0, %0";
2308 case 6:
2309 if (get_attr_mode (insn) == MODE_V4SF)
2310 return "movaps\t{%1, %0|%0, %1}";
2311 else
2312 return "movss\t{%1, %0|%0, %1}";
2313 case 7:
2314 case 8:
2315 return "movss\t{%1, %0|%0, %1}";
2316
2317 case 9:
2318 case 10:
2319 return "movd\t{%1, %0|%0, %1}";
2320
2321 case 11:
2322 return "movq\t{%1, %0|%0, %1}";
2323
2324 default:
2325 gcc_unreachable ();
2326 }
2327 }
2328 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2329 (set (attr "mode")
2330 (cond [(eq_attr "alternative" "3,4,9,10")
2331 (const_string "SI")
2332 (eq_attr "alternative" "5")
2333 (if_then_else
2334 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2335 (const_int 0))
2336 (ne (symbol_ref "TARGET_SSE2")
2337 (const_int 0)))
2338 (eq (symbol_ref "optimize_size")
2339 (const_int 0)))
2340 (const_string "TI")
2341 (const_string "V4SF"))
2342 /* For architectures resolving dependencies on
2343 whole SSE registers use APS move to break dependency
2344 chains, otherwise use short move to avoid extra work.
2345
2346 Do the same for architectures resolving dependencies on
2347 the parts. While in DF mode it is better to always handle
2348 just register parts, the SF mode is different due to lack
2349 of instructions to load just part of the register. It is
2350 better to maintain the whole registers in single format
2351 to avoid problems on using packed logical operations. */
2352 (eq_attr "alternative" "6")
2353 (if_then_else
2354 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2355 (const_int 0))
2356 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2357 (const_int 0)))
2358 (const_string "V4SF")
2359 (const_string "SF"))
2360 (eq_attr "alternative" "11")
2361 (const_string "DI")]
2362 (const_string "SF")))])
2363
2364 (define_insn "*swapsf"
2365 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2366 (match_operand:SF 1 "fp_register_operand" "+f"))
2367 (set (match_dup 1)
2368 (match_dup 0))]
2369 "reload_completed || TARGET_80387"
2370 {
2371 if (STACK_TOP_P (operands[0]))
2372 return "fxch\t%1";
2373 else
2374 return "fxch\t%0";
2375 }
2376 [(set_attr "type" "fxch")
2377 (set_attr "mode" "SF")])
2378
2379 (define_expand "movdf"
2380 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2381 (match_operand:DF 1 "general_operand" ""))]
2382 ""
2383 "ix86_expand_move (DFmode, operands); DONE;")
2384
2385 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2386 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2387 ;; On the average, pushdf using integers can be still shorter. Allow this
2388 ;; pattern for optimize_size too.
2389
2390 (define_insn "*pushdf_nointeger"
2391 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2392 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2393 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2394 {
2395 /* This insn should be already split before reg-stack. */
2396 gcc_unreachable ();
2397 }
2398 [(set_attr "type" "multi")
2399 (set_attr "unit" "i387,*,*,*")
2400 (set_attr "mode" "DF,SI,SI,DF")])
2401
2402 (define_insn "*pushdf_integer"
2403 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2404 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2405 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2406 {
2407 /* This insn should be already split before reg-stack. */
2408 gcc_unreachable ();
2409 }
2410 [(set_attr "type" "multi")
2411 (set_attr "unit" "i387,*,*")
2412 (set_attr "mode" "DF,SI,DF")])
2413
2414 ;; %%% Kill this when call knows how to work this out.
2415 (define_split
2416 [(set (match_operand:DF 0 "push_operand" "")
2417 (match_operand:DF 1 "any_fp_register_operand" ""))]
2418 "!TARGET_64BIT && reload_completed"
2419 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2420 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2421 "")
2422
2423 (define_split
2424 [(set (match_operand:DF 0 "push_operand" "")
2425 (match_operand:DF 1 "any_fp_register_operand" ""))]
2426 "TARGET_64BIT && reload_completed"
2427 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2428 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2429 "")
2430
2431 (define_split
2432 [(set (match_operand:DF 0 "push_operand" "")
2433 (match_operand:DF 1 "general_operand" ""))]
2434 "reload_completed"
2435 [(const_int 0)]
2436 "ix86_split_long_move (operands); DONE;")
2437
2438 ;; Moving is usually shorter when only FP registers are used. This separate
2439 ;; movdf pattern avoids the use of integer registers for FP operations
2440 ;; when optimizing for size.
2441
2442 (define_insn "*movdf_nointeger"
2443 [(set (match_operand:DF 0 "nonimmediate_operand"
2444 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2445 (match_operand:DF 1 "general_operand"
2446 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2447 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2448 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2449 && (reload_in_progress || reload_completed
2450 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2451 || GET_CODE (operands[1]) != CONST_DOUBLE
2452 || memory_operand (operands[0], DFmode))"
2453 {
2454 switch (which_alternative)
2455 {
2456 case 0:
2457 return output_387_reg_move (insn, operands);
2458
2459 case 1:
2460 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2461 return "fstp%z0\t%y0";
2462 else
2463 return "fst%z0\t%y0";
2464
2465 case 2:
2466 return standard_80387_constant_opcode (operands[1]);
2467
2468 case 3:
2469 case 4:
2470 return "#";
2471 case 5:
2472 switch (get_attr_mode (insn))
2473 {
2474 case MODE_V4SF:
2475 return "xorps\t%0, %0";
2476 case MODE_V2DF:
2477 return "xorpd\t%0, %0";
2478 case MODE_TI:
2479 return "pxor\t%0, %0";
2480 default:
2481 gcc_unreachable ();
2482 }
2483 case 6:
2484 case 7:
2485 case 8:
2486 switch (get_attr_mode (insn))
2487 {
2488 case MODE_V4SF:
2489 return "movaps\t{%1, %0|%0, %1}";
2490 case MODE_V2DF:
2491 return "movapd\t{%1, %0|%0, %1}";
2492 case MODE_TI:
2493 return "movdqa\t{%1, %0|%0, %1}";
2494 case MODE_DI:
2495 return "movq\t{%1, %0|%0, %1}";
2496 case MODE_DF:
2497 return "movsd\t{%1, %0|%0, %1}";
2498 case MODE_V1DF:
2499 return "movlpd\t{%1, %0|%0, %1}";
2500 case MODE_V2SF:
2501 return "movlps\t{%1, %0|%0, %1}";
2502 default:
2503 gcc_unreachable ();
2504 }
2505
2506 default:
2507 gcc_unreachable ();
2508 }
2509 }
2510 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2511 (set (attr "mode")
2512 (cond [(eq_attr "alternative" "0,1,2")
2513 (const_string "DF")
2514 (eq_attr "alternative" "3,4")
2515 (const_string "SI")
2516
2517 /* For SSE1, we have many fewer alternatives. */
2518 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2519 (cond [(eq_attr "alternative" "5,6")
2520 (const_string "V4SF")
2521 ]
2522 (const_string "V2SF"))
2523
2524 /* xorps is one byte shorter. */
2525 (eq_attr "alternative" "5")
2526 (cond [(ne (symbol_ref "optimize_size")
2527 (const_int 0))
2528 (const_string "V4SF")
2529 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2530 (const_int 0))
2531 (const_string "TI")
2532 ]
2533 (const_string "V2DF"))
2534
2535 /* For architectures resolving dependencies on
2536 whole SSE registers use APD move to break dependency
2537 chains, otherwise use short move to avoid extra work.
2538
2539 movaps encodes one byte shorter. */
2540 (eq_attr "alternative" "6")
2541 (cond
2542 [(ne (symbol_ref "optimize_size")
2543 (const_int 0))
2544 (const_string "V4SF")
2545 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2546 (const_int 0))
2547 (const_string "V2DF")
2548 ]
2549 (const_string "DF"))
2550 /* For architectures resolving dependencies on register
2551 parts we may avoid extra work to zero out upper part
2552 of register. */
2553 (eq_attr "alternative" "7")
2554 (if_then_else
2555 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2556 (const_int 0))
2557 (const_string "V1DF")
2558 (const_string "DF"))
2559 ]
2560 (const_string "DF")))])
2561
2562 (define_insn "*movdf_integer"
2563 [(set (match_operand:DF 0 "nonimmediate_operand"
2564 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2565 (match_operand:DF 1 "general_operand"
2566 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2567 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2568 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2569 && (reload_in_progress || reload_completed
2570 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2571 || GET_CODE (operands[1]) != CONST_DOUBLE
2572 || memory_operand (operands[0], DFmode))"
2573 {
2574 switch (which_alternative)
2575 {
2576 case 0:
2577 return output_387_reg_move (insn, operands);
2578
2579 case 1:
2580 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2581 return "fstp%z0\t%y0";
2582 else
2583 return "fst%z0\t%y0";
2584
2585 case 2:
2586 return standard_80387_constant_opcode (operands[1]);
2587
2588 case 3:
2589 case 4:
2590 return "#";
2591
2592 case 5:
2593 switch (get_attr_mode (insn))
2594 {
2595 case MODE_V4SF:
2596 return "xorps\t%0, %0";
2597 case MODE_V2DF:
2598 return "xorpd\t%0, %0";
2599 case MODE_TI:
2600 return "pxor\t%0, %0";
2601 default:
2602 gcc_unreachable ();
2603 }
2604 case 6:
2605 case 7:
2606 case 8:
2607 switch (get_attr_mode (insn))
2608 {
2609 case MODE_V4SF:
2610 return "movaps\t{%1, %0|%0, %1}";
2611 case MODE_V2DF:
2612 return "movapd\t{%1, %0|%0, %1}";
2613 case MODE_TI:
2614 return "movdqa\t{%1, %0|%0, %1}";
2615 case MODE_DI:
2616 return "movq\t{%1, %0|%0, %1}";
2617 case MODE_DF:
2618 return "movsd\t{%1, %0|%0, %1}";
2619 case MODE_V1DF:
2620 return "movlpd\t{%1, %0|%0, %1}";
2621 case MODE_V2SF:
2622 return "movlps\t{%1, %0|%0, %1}";
2623 default:
2624 gcc_unreachable ();
2625 }
2626
2627 default:
2628 gcc_unreachable();
2629 }
2630 }
2631 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2632 (set (attr "mode")
2633 (cond [(eq_attr "alternative" "0,1,2")
2634 (const_string "DF")
2635 (eq_attr "alternative" "3,4")
2636 (const_string "SI")
2637
2638 /* For SSE1, we have many fewer alternatives. */
2639 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2640 (cond [(eq_attr "alternative" "5,6")
2641 (const_string "V4SF")
2642 ]
2643 (const_string "V2SF"))
2644
2645 /* xorps is one byte shorter. */
2646 (eq_attr "alternative" "5")
2647 (cond [(ne (symbol_ref "optimize_size")
2648 (const_int 0))
2649 (const_string "V4SF")
2650 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2651 (const_int 0))
2652 (const_string "TI")
2653 ]
2654 (const_string "V2DF"))
2655
2656 /* For architectures resolving dependencies on
2657 whole SSE registers use APD move to break dependency
2658 chains, otherwise use short move to avoid extra work.
2659
2660 movaps encodes one byte shorter. */
2661 (eq_attr "alternative" "6")
2662 (cond
2663 [(ne (symbol_ref "optimize_size")
2664 (const_int 0))
2665 (const_string "V4SF")
2666 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2667 (const_int 0))
2668 (const_string "V2DF")
2669 ]
2670 (const_string "DF"))
2671 /* For architectures resolving dependencies on register
2672 parts we may avoid extra work to zero out upper part
2673 of register. */
2674 (eq_attr "alternative" "7")
2675 (if_then_else
2676 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2677 (const_int 0))
2678 (const_string "V1DF")
2679 (const_string "DF"))
2680 ]
2681 (const_string "DF")))])
2682
2683 (define_split
2684 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2685 (match_operand:DF 1 "general_operand" ""))]
2686 "reload_completed
2687 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2688 && ! (ANY_FP_REG_P (operands[0]) ||
2689 (GET_CODE (operands[0]) == SUBREG
2690 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2691 && ! (ANY_FP_REG_P (operands[1]) ||
2692 (GET_CODE (operands[1]) == SUBREG
2693 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2694 [(const_int 0)]
2695 "ix86_split_long_move (operands); DONE;")
2696
2697 (define_insn "*swapdf"
2698 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2699 (match_operand:DF 1 "fp_register_operand" "+f"))
2700 (set (match_dup 1)
2701 (match_dup 0))]
2702 "reload_completed || TARGET_80387"
2703 {
2704 if (STACK_TOP_P (operands[0]))
2705 return "fxch\t%1";
2706 else
2707 return "fxch\t%0";
2708 }
2709 [(set_attr "type" "fxch")
2710 (set_attr "mode" "DF")])
2711
2712 (define_expand "movxf"
2713 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2714 (match_operand:XF 1 "general_operand" ""))]
2715 ""
2716 "ix86_expand_move (XFmode, operands); DONE;")
2717
2718 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2720 ;; Pushing using integer instructions is longer except for constants
2721 ;; and direct memory references.
2722 ;; (assuming that any given constant is pushed only once, but this ought to be
2723 ;; handled elsewhere).
2724
2725 (define_insn "*pushxf_nointeger"
2726 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2727 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2728 "optimize_size"
2729 {
2730 /* This insn should be already split before reg-stack. */
2731 gcc_unreachable ();
2732 }
2733 [(set_attr "type" "multi")
2734 (set_attr "unit" "i387,*,*")
2735 (set_attr "mode" "XF,SI,SI")])
2736
2737 (define_insn "*pushxf_integer"
2738 [(set (match_operand:XF 0 "push_operand" "=<,<")
2739 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2740 "!optimize_size"
2741 {
2742 /* This insn should be already split before reg-stack. */
2743 gcc_unreachable ();
2744 }
2745 [(set_attr "type" "multi")
2746 (set_attr "unit" "i387,*")
2747 (set_attr "mode" "XF,SI")])
2748
2749 (define_split
2750 [(set (match_operand 0 "push_operand" "")
2751 (match_operand 1 "general_operand" ""))]
2752 "reload_completed
2753 && (GET_MODE (operands[0]) == XFmode
2754 || GET_MODE (operands[0]) == DFmode)
2755 && !ANY_FP_REG_P (operands[1])"
2756 [(const_int 0)]
2757 "ix86_split_long_move (operands); DONE;")
2758
2759 (define_split
2760 [(set (match_operand:XF 0 "push_operand" "")
2761 (match_operand:XF 1 "any_fp_register_operand" ""))]
2762 "!TARGET_64BIT"
2763 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2764 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2765 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2766
2767 (define_split
2768 [(set (match_operand:XF 0 "push_operand" "")
2769 (match_operand:XF 1 "any_fp_register_operand" ""))]
2770 "TARGET_64BIT"
2771 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2772 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2773 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774
2775 ;; Do not use integer registers when optimizing for size
2776 (define_insn "*movxf_nointeger"
2777 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2779 "optimize_size
2780 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781 && (reload_in_progress || reload_completed
2782 || GET_CODE (operands[1]) != CONST_DOUBLE
2783 || memory_operand (operands[0], XFmode))"
2784 {
2785 switch (which_alternative)
2786 {
2787 case 0:
2788 return output_387_reg_move (insn, operands);
2789
2790 case 1:
2791 /* There is no non-popping store to memory for XFmode. So if
2792 we need one, follow the store with a load. */
2793 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2794 return "fstp%z0\t%y0\;fld%z0\t%y0";
2795 else
2796 return "fstp%z0\t%y0";
2797
2798 case 2:
2799 return standard_80387_constant_opcode (operands[1]);
2800
2801 case 3: case 4:
2802 return "#";
2803 default:
2804 gcc_unreachable ();
2805 }
2806 }
2807 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2808 (set_attr "mode" "XF,XF,XF,SI,SI")])
2809
2810 (define_insn "*movxf_integer"
2811 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2812 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2813 "!optimize_size
2814 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2815 && (reload_in_progress || reload_completed
2816 || GET_CODE (operands[1]) != CONST_DOUBLE
2817 || memory_operand (operands[0], XFmode))"
2818 {
2819 switch (which_alternative)
2820 {
2821 case 0:
2822 return output_387_reg_move (insn, operands);
2823
2824 case 1:
2825 /* There is no non-popping store to memory for XFmode. So if
2826 we need one, follow the store with a load. */
2827 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2828 return "fstp%z0\t%y0\;fld%z0\t%y0";
2829 else
2830 return "fstp%z0\t%y0";
2831
2832 case 2:
2833 return standard_80387_constant_opcode (operands[1]);
2834
2835 case 3: case 4:
2836 return "#";
2837
2838 default:
2839 gcc_unreachable ();
2840 }
2841 }
2842 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2843 (set_attr "mode" "XF,XF,XF,SI,SI")])
2844
2845 (define_split
2846 [(set (match_operand 0 "nonimmediate_operand" "")
2847 (match_operand 1 "general_operand" ""))]
2848 "reload_completed
2849 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2850 && GET_MODE (operands[0]) == XFmode
2851 && ! (ANY_FP_REG_P (operands[0]) ||
2852 (GET_CODE (operands[0]) == SUBREG
2853 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2854 && ! (ANY_FP_REG_P (operands[1]) ||
2855 (GET_CODE (operands[1]) == SUBREG
2856 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2857 [(const_int 0)]
2858 "ix86_split_long_move (operands); DONE;")
2859
2860 (define_split
2861 [(set (match_operand 0 "register_operand" "")
2862 (match_operand 1 "memory_operand" ""))]
2863 "reload_completed
2864 && GET_CODE (operands[1]) == MEM
2865 && (GET_MODE (operands[0]) == XFmode
2866 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2867 && constant_pool_reference_p (operands[1])"
2868 [(set (match_dup 0) (match_dup 1))]
2869 {
2870 rtx c = avoid_constant_pool_reference (operands[1]);
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" "*,*,sselog1,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 ; zero extend to SImode here to avoid partial register stalls
3036 (define_insn "*zero_extendqihi2_movzbl"
3037 [(set (match_operand:HI 0 "register_operand" "=r")
3038 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3039 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3040 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3041 [(set_attr "type" "imovx")
3042 (set_attr "mode" "SI")])
3043
3044 ;; For the movzbw case strip only the clobber
3045 (define_split
3046 [(set (match_operand:HI 0 "register_operand" "")
3047 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3048 (clobber (reg:CC FLAGS_REG))]
3049 "reload_completed
3050 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3051 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3052 [(set (match_operand:HI 0 "register_operand" "")
3053 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3054
3055 ;; When source and destination does not overlap, clear destination
3056 ;; first and then do the movb
3057 (define_split
3058 [(set (match_operand:HI 0 "register_operand" "")
3059 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3060 (clobber (reg:CC FLAGS_REG))]
3061 "reload_completed
3062 && ANY_QI_REG_P (operands[0])
3063 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3064 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3065 [(set (match_dup 0) (const_int 0))
3066 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3067 "operands[2] = gen_lowpart (QImode, operands[0]);")
3068
3069 ;; Rest is handled by single and.
3070 (define_split
3071 [(set (match_operand:HI 0 "register_operand" "")
3072 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3073 (clobber (reg:CC FLAGS_REG))]
3074 "reload_completed
3075 && true_regnum (operands[0]) == true_regnum (operands[1])"
3076 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3077 (clobber (reg:CC FLAGS_REG))])]
3078 "")
3079
3080 (define_expand "zero_extendqisi2"
3081 [(parallel
3082 [(set (match_operand:SI 0 "register_operand" "")
3083 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3084 (clobber (reg:CC FLAGS_REG))])]
3085 ""
3086 "")
3087
3088 (define_insn "*zero_extendqisi2_and"
3089 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3090 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3091 (clobber (reg:CC FLAGS_REG))]
3092 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3093 "#"
3094 [(set_attr "type" "alu1")
3095 (set_attr "mode" "SI")])
3096
3097 (define_insn "*zero_extendqisi2_movzbw_and"
3098 [(set (match_operand:SI 0 "register_operand" "=r,r")
3099 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3100 (clobber (reg:CC FLAGS_REG))]
3101 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3102 "#"
3103 [(set_attr "type" "imovx,alu1")
3104 (set_attr "mode" "SI")])
3105
3106 (define_insn "*zero_extendqisi2_movzbw"
3107 [(set (match_operand:SI 0 "register_operand" "=r")
3108 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3109 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3110 "movz{bl|x}\t{%1, %0|%0, %1}"
3111 [(set_attr "type" "imovx")
3112 (set_attr "mode" "SI")])
3113
3114 ;; For the movzbl case strip only the clobber
3115 (define_split
3116 [(set (match_operand:SI 0 "register_operand" "")
3117 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3118 (clobber (reg:CC FLAGS_REG))]
3119 "reload_completed
3120 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3121 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3122 [(set (match_dup 0)
3123 (zero_extend:SI (match_dup 1)))])
3124
3125 ;; When source and destination does not overlap, clear destination
3126 ;; first and then do the movb
3127 (define_split
3128 [(set (match_operand:SI 0 "register_operand" "")
3129 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3130 (clobber (reg:CC FLAGS_REG))]
3131 "reload_completed
3132 && ANY_QI_REG_P (operands[0])
3133 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3134 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3135 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3136 [(set (match_dup 0) (const_int 0))
3137 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3138 "operands[2] = gen_lowpart (QImode, operands[0]);")
3139
3140 ;; Rest is handled by single and.
3141 (define_split
3142 [(set (match_operand:SI 0 "register_operand" "")
3143 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3144 (clobber (reg:CC FLAGS_REG))]
3145 "reload_completed
3146 && true_regnum (operands[0]) == true_regnum (operands[1])"
3147 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3148 (clobber (reg:CC FLAGS_REG))])]
3149 "")
3150
3151 ;; %%% Kill me once multi-word ops are sane.
3152 (define_expand "zero_extendsidi2"
3153 [(set (match_operand:DI 0 "register_operand" "=r")
3154 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3155 ""
3156 "if (!TARGET_64BIT)
3157 {
3158 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3159 DONE;
3160 }
3161 ")
3162
3163 (define_insn "zero_extendsidi2_32"
3164 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3165 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3166 (clobber (reg:CC FLAGS_REG))]
3167 "!TARGET_64BIT"
3168 "@
3169 #
3170 #
3171 #
3172 movd\t{%1, %0|%0, %1}
3173 movd\t{%1, %0|%0, %1}"
3174 [(set_attr "mode" "SI,SI,SI,DI,TI")
3175 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3176
3177 (define_insn "zero_extendsidi2_rex64"
3178 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3179 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3180 "TARGET_64BIT"
3181 "@
3182 mov\t{%k1, %k0|%k0, %k1}
3183 #
3184 movd\t{%1, %0|%0, %1}
3185 movd\t{%1, %0|%0, %1}"
3186 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3187 (set_attr "mode" "SI,DI,SI,SI")])
3188
3189 (define_split
3190 [(set (match_operand:DI 0 "memory_operand" "")
3191 (zero_extend:DI (match_dup 0)))]
3192 "TARGET_64BIT"
3193 [(set (match_dup 4) (const_int 0))]
3194 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3195
3196 (define_split
3197 [(set (match_operand:DI 0 "register_operand" "")
3198 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3199 (clobber (reg:CC FLAGS_REG))]
3200 "!TARGET_64BIT && reload_completed
3201 && true_regnum (operands[0]) == true_regnum (operands[1])"
3202 [(set (match_dup 4) (const_int 0))]
3203 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3204
3205 (define_split
3206 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3207 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3208 (clobber (reg:CC FLAGS_REG))]
3209 "!TARGET_64BIT && reload_completed
3210 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3211 [(set (match_dup 3) (match_dup 1))
3212 (set (match_dup 4) (const_int 0))]
3213 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3214
3215 (define_insn "zero_extendhidi2"
3216 [(set (match_operand:DI 0 "register_operand" "=r")
3217 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3218 "TARGET_64BIT"
3219 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3220 [(set_attr "type" "imovx")
3221 (set_attr "mode" "DI")])
3222
3223 (define_insn "zero_extendqidi2"
3224 [(set (match_operand:DI 0 "register_operand" "=r")
3225 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3226 "TARGET_64BIT"
3227 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3228 [(set_attr "type" "imovx")
3229 (set_attr "mode" "DI")])
3230 \f
3231 ;; Sign extension instructions
3232
3233 (define_expand "extendsidi2"
3234 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3235 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3236 (clobber (reg:CC FLAGS_REG))
3237 (clobber (match_scratch:SI 2 ""))])]
3238 ""
3239 {
3240 if (TARGET_64BIT)
3241 {
3242 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3243 DONE;
3244 }
3245 })
3246
3247 (define_insn "*extendsidi2_1"
3248 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3249 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3250 (clobber (reg:CC FLAGS_REG))
3251 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3252 "!TARGET_64BIT"
3253 "#")
3254
3255 (define_insn "extendsidi2_rex64"
3256 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3257 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3258 "TARGET_64BIT"
3259 "@
3260 {cltq|cdqe}
3261 movs{lq|x}\t{%1,%0|%0, %1}"
3262 [(set_attr "type" "imovx")
3263 (set_attr "mode" "DI")
3264 (set_attr "prefix_0f" "0")
3265 (set_attr "modrm" "0,1")])
3266
3267 (define_insn "extendhidi2"
3268 [(set (match_operand:DI 0 "register_operand" "=r")
3269 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3270 "TARGET_64BIT"
3271 "movs{wq|x}\t{%1,%0|%0, %1}"
3272 [(set_attr "type" "imovx")
3273 (set_attr "mode" "DI")])
3274
3275 (define_insn "extendqidi2"
3276 [(set (match_operand:DI 0 "register_operand" "=r")
3277 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278 "TARGET_64BIT"
3279 "movs{bq|x}\t{%1,%0|%0, %1}"
3280 [(set_attr "type" "imovx")
3281 (set_attr "mode" "DI")])
3282
3283 ;; Extend to memory case when source register does die.
3284 (define_split
3285 [(set (match_operand:DI 0 "memory_operand" "")
3286 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3287 (clobber (reg:CC FLAGS_REG))
3288 (clobber (match_operand:SI 2 "register_operand" ""))]
3289 "(reload_completed
3290 && dead_or_set_p (insn, operands[1])
3291 && !reg_mentioned_p (operands[1], operands[0]))"
3292 [(set (match_dup 3) (match_dup 1))
3293 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3294 (clobber (reg:CC FLAGS_REG))])
3295 (set (match_dup 4) (match_dup 1))]
3296 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3297
3298 ;; Extend to memory case when source register does not die.
3299 (define_split
3300 [(set (match_operand:DI 0 "memory_operand" "")
3301 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3302 (clobber (reg:CC FLAGS_REG))
3303 (clobber (match_operand:SI 2 "register_operand" ""))]
3304 "reload_completed"
3305 [(const_int 0)]
3306 {
3307 split_di (&operands[0], 1, &operands[3], &operands[4]);
3308
3309 emit_move_insn (operands[3], operands[1]);
3310
3311 /* Generate a cltd if possible and doing so it profitable. */
3312 if (true_regnum (operands[1]) == 0
3313 && true_regnum (operands[2]) == 1
3314 && (optimize_size || TARGET_USE_CLTD))
3315 {
3316 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3317 }
3318 else
3319 {
3320 emit_move_insn (operands[2], operands[1]);
3321 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3322 }
3323 emit_move_insn (operands[4], operands[2]);
3324 DONE;
3325 })
3326
3327 ;; Extend to register case. Optimize case where source and destination
3328 ;; registers match and cases where we can use cltd.
3329 (define_split
3330 [(set (match_operand:DI 0 "register_operand" "")
3331 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3332 (clobber (reg:CC FLAGS_REG))
3333 (clobber (match_scratch:SI 2 ""))]
3334 "reload_completed"
3335 [(const_int 0)]
3336 {
3337 split_di (&operands[0], 1, &operands[3], &operands[4]);
3338
3339 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3340 emit_move_insn (operands[3], operands[1]);
3341
3342 /* Generate a cltd if possible and doing so it profitable. */
3343 if (true_regnum (operands[3]) == 0
3344 && (optimize_size || TARGET_USE_CLTD))
3345 {
3346 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3347 DONE;
3348 }
3349
3350 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3351 emit_move_insn (operands[4], operands[1]);
3352
3353 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3354 DONE;
3355 })
3356
3357 (define_insn "extendhisi2"
3358 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3359 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3360 ""
3361 {
3362 switch (get_attr_prefix_0f (insn))
3363 {
3364 case 0:
3365 return "{cwtl|cwde}";
3366 default:
3367 return "movs{wl|x}\t{%1,%0|%0, %1}";
3368 }
3369 }
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "SI")
3372 (set (attr "prefix_0f")
3373 ;; movsx is short decodable while cwtl is vector decoded.
3374 (if_then_else (and (eq_attr "cpu" "!k6")
3375 (eq_attr "alternative" "0"))
3376 (const_string "0")
3377 (const_string "1")))
3378 (set (attr "modrm")
3379 (if_then_else (eq_attr "prefix_0f" "0")
3380 (const_string "0")
3381 (const_string "1")))])
3382
3383 (define_insn "*extendhisi2_zext"
3384 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3385 (zero_extend:DI
3386 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3387 "TARGET_64BIT"
3388 {
3389 switch (get_attr_prefix_0f (insn))
3390 {
3391 case 0:
3392 return "{cwtl|cwde}";
3393 default:
3394 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3395 }
3396 }
3397 [(set_attr "type" "imovx")
3398 (set_attr "mode" "SI")
3399 (set (attr "prefix_0f")
3400 ;; movsx is short decodable while cwtl is vector decoded.
3401 (if_then_else (and (eq_attr "cpu" "!k6")
3402 (eq_attr "alternative" "0"))
3403 (const_string "0")
3404 (const_string "1")))
3405 (set (attr "modrm")
3406 (if_then_else (eq_attr "prefix_0f" "0")
3407 (const_string "0")
3408 (const_string "1")))])
3409
3410 (define_insn "extendqihi2"
3411 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3412 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3413 ""
3414 {
3415 switch (get_attr_prefix_0f (insn))
3416 {
3417 case 0:
3418 return "{cbtw|cbw}";
3419 default:
3420 return "movs{bw|x}\t{%1,%0|%0, %1}";
3421 }
3422 }
3423 [(set_attr "type" "imovx")
3424 (set_attr "mode" "HI")
3425 (set (attr "prefix_0f")
3426 ;; movsx is short decodable while cwtl is vector decoded.
3427 (if_then_else (and (eq_attr "cpu" "!k6")
3428 (eq_attr "alternative" "0"))
3429 (const_string "0")
3430 (const_string "1")))
3431 (set (attr "modrm")
3432 (if_then_else (eq_attr "prefix_0f" "0")
3433 (const_string "0")
3434 (const_string "1")))])
3435
3436 (define_insn "extendqisi2"
3437 [(set (match_operand:SI 0 "register_operand" "=r")
3438 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3439 ""
3440 "movs{bl|x}\t{%1,%0|%0, %1}"
3441 [(set_attr "type" "imovx")
3442 (set_attr "mode" "SI")])
3443
3444 (define_insn "*extendqisi2_zext"
3445 [(set (match_operand:DI 0 "register_operand" "=r")
3446 (zero_extend:DI
3447 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3448 "TARGET_64BIT"
3449 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3450 [(set_attr "type" "imovx")
3451 (set_attr "mode" "SI")])
3452 \f
3453 ;; Conversions between float and double.
3454
3455 ;; These are all no-ops in the model used for the 80387. So just
3456 ;; emit moves.
3457
3458 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3459 (define_insn "*dummy_extendsfdf2"
3460 [(set (match_operand:DF 0 "push_operand" "=<")
3461 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3462 "0"
3463 "#")
3464
3465 (define_split
3466 [(set (match_operand:DF 0 "push_operand" "")
3467 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3468 "!TARGET_64BIT"
3469 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3470 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3471
3472 (define_split
3473 [(set (match_operand:DF 0 "push_operand" "")
3474 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3475 "TARGET_64BIT"
3476 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3477 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3478
3479 (define_insn "*dummy_extendsfxf2"
3480 [(set (match_operand:XF 0 "push_operand" "=<")
3481 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3482 "0"
3483 "#")
3484
3485 (define_split
3486 [(set (match_operand:XF 0 "push_operand" "")
3487 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3488 ""
3489 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3490 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3491 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3492
3493 (define_split
3494 [(set (match_operand:XF 0 "push_operand" "")
3495 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3496 "TARGET_64BIT"
3497 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3498 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3499 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3500
3501 (define_split
3502 [(set (match_operand:XF 0 "push_operand" "")
3503 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3504 ""
3505 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3506 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3507 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3508
3509 (define_split
3510 [(set (match_operand:XF 0 "push_operand" "")
3511 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3512 "TARGET_64BIT"
3513 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3514 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3515 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3516
3517 (define_expand "extendsfdf2"
3518 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3519 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3520 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3521 {
3522 /* ??? Needed for compress_float_constant since all fp constants
3523 are LEGITIMATE_CONSTANT_P. */
3524 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3525 {
3526 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3527 && standard_80387_constant_p (operands[1]) > 0)
3528 {
3529 operands[1] = simplify_const_unary_operation
3530 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3531 emit_move_insn_1 (operands[0], operands[1]);
3532 DONE;
3533 }
3534 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3535 }
3536 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3537 operands[1] = force_reg (SFmode, operands[1]);
3538 })
3539
3540 (define_insn "*extendsfdf2_mixed"
3541 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3542 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3543 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3544 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3545 {
3546 switch (which_alternative)
3547 {
3548 case 0:
3549 return output_387_reg_move (insn, operands);
3550
3551 case 1:
3552 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3553 return "fstp%z0\t%y0";
3554 else
3555 return "fst%z0\t%y0";
3556
3557 case 2:
3558 return "cvtss2sd\t{%1, %0|%0, %1}";
3559
3560 default:
3561 gcc_unreachable ();
3562 }
3563 }
3564 [(set_attr "type" "fmov,fmov,ssecvt")
3565 (set_attr "mode" "SF,XF,DF")])
3566
3567 (define_insn "*extendsfdf2_sse"
3568 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3569 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3570 "TARGET_SSE2 && TARGET_SSE_MATH
3571 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3572 "cvtss2sd\t{%1, %0|%0, %1}"
3573 [(set_attr "type" "ssecvt")
3574 (set_attr "mode" "DF")])
3575
3576 (define_insn "*extendsfdf2_i387"
3577 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3578 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3579 "TARGET_80387
3580 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3581 {
3582 switch (which_alternative)
3583 {
3584 case 0:
3585 return output_387_reg_move (insn, operands);
3586
3587 case 1:
3588 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3589 return "fstp%z0\t%y0";
3590 else
3591 return "fst%z0\t%y0";
3592
3593 default:
3594 gcc_unreachable ();
3595 }
3596 }
3597 [(set_attr "type" "fmov")
3598 (set_attr "mode" "SF,XF")])
3599
3600 (define_expand "extendsfxf2"
3601 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3602 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3603 "TARGET_80387"
3604 {
3605 /* ??? Needed for compress_float_constant since all fp constants
3606 are LEGITIMATE_CONSTANT_P. */
3607 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3608 {
3609 if (standard_80387_constant_p (operands[1]) > 0)
3610 {
3611 operands[1] = simplify_const_unary_operation
3612 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3613 emit_move_insn_1 (operands[0], operands[1]);
3614 DONE;
3615 }
3616 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3617 }
3618 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3619 operands[1] = force_reg (SFmode, operands[1]);
3620 })
3621
3622 (define_insn "*extendsfxf2_i387"
3623 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3624 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3625 "TARGET_80387
3626 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3627 {
3628 switch (which_alternative)
3629 {
3630 case 0:
3631 return output_387_reg_move (insn, operands);
3632
3633 case 1:
3634 /* There is no non-popping store to memory for XFmode. So if
3635 we need one, follow the store with a load. */
3636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637 return "fstp%z0\t%y0";
3638 else
3639 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3640
3641 default:
3642 gcc_unreachable ();
3643 }
3644 }
3645 [(set_attr "type" "fmov")
3646 (set_attr "mode" "SF,XF")])
3647
3648 (define_expand "extenddfxf2"
3649 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3650 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3651 "TARGET_80387"
3652 {
3653 /* ??? Needed for compress_float_constant since all fp constants
3654 are LEGITIMATE_CONSTANT_P. */
3655 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3656 {
3657 if (standard_80387_constant_p (operands[1]) > 0)
3658 {
3659 operands[1] = simplify_const_unary_operation
3660 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3661 emit_move_insn_1 (operands[0], operands[1]);
3662 DONE;
3663 }
3664 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3665 }
3666 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3667 operands[1] = force_reg (DFmode, operands[1]);
3668 })
3669
3670 (define_insn "*extenddfxf2_i387"
3671 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3672 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3673 "TARGET_80387
3674 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3675 {
3676 switch (which_alternative)
3677 {
3678 case 0:
3679 return output_387_reg_move (insn, operands);
3680
3681 case 1:
3682 /* There is no non-popping store to memory for XFmode. So if
3683 we need one, follow the store with a load. */
3684 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3686 else
3687 return "fstp%z0\t%y0";
3688
3689 default:
3690 gcc_unreachable ();
3691 }
3692 }
3693 [(set_attr "type" "fmov")
3694 (set_attr "mode" "DF,XF")])
3695
3696 ;; %%% This seems bad bad news.
3697 ;; This cannot output into an f-reg because there is no way to be sure
3698 ;; of truncating in that case. Otherwise this is just like a simple move
3699 ;; insn. So we pretend we can output to a reg in order to get better
3700 ;; register preferencing, but we really use a stack slot.
3701
3702 ;; Conversion from DFmode to SFmode.
3703
3704 (define_expand "truncdfsf2"
3705 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3706 (float_truncate:SF
3707 (match_operand:DF 1 "nonimmediate_operand" "")))]
3708 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3709 {
3710 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3711 operands[1] = force_reg (DFmode, operands[1]);
3712
3713 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3714 ;
3715 else if (flag_unsafe_math_optimizations)
3716 ;
3717 else
3718 {
3719 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3720 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3721 DONE;
3722 }
3723 })
3724
3725 (define_expand "truncdfsf2_with_temp"
3726 [(parallel [(set (match_operand:SF 0 "" "")
3727 (float_truncate:SF (match_operand:DF 1 "" "")))
3728 (clobber (match_operand:SF 2 "" ""))])]
3729 "")
3730
3731 (define_insn "*truncdfsf_fast_mixed"
3732 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3733 (float_truncate:SF
3734 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3735 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3736 {
3737 switch (which_alternative)
3738 {
3739 case 0:
3740 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3741 return "fstp%z0\t%y0";
3742 else
3743 return "fst%z0\t%y0";
3744 case 1:
3745 return output_387_reg_move (insn, operands);
3746 case 2:
3747 return "cvtsd2ss\t{%1, %0|%0, %1}";
3748 default:
3749 gcc_unreachable ();
3750 }
3751 }
3752 [(set_attr "type" "fmov,fmov,ssecvt")
3753 (set_attr "mode" "SF")])
3754
3755 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3756 ;; because nothing we do here is unsafe.
3757 (define_insn "*truncdfsf_fast_sse"
3758 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3759 (float_truncate:SF
3760 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3761 "TARGET_SSE2 && TARGET_SSE_MATH"
3762 "cvtsd2ss\t{%1, %0|%0, %1}"
3763 [(set_attr "type" "ssecvt")
3764 (set_attr "mode" "SF")])
3765
3766 (define_insn "*truncdfsf_fast_i387"
3767 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3768 (float_truncate:SF
3769 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3770 "TARGET_80387 && flag_unsafe_math_optimizations"
3771 "* return output_387_reg_move (insn, operands);"
3772 [(set_attr "type" "fmov")
3773 (set_attr "mode" "SF")])
3774
3775 (define_insn "*truncdfsf_mixed"
3776 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3777 (float_truncate:SF
3778 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3779 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3780 "TARGET_MIX_SSE_I387"
3781 {
3782 switch (which_alternative)
3783 {
3784 case 0:
3785 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786 return "fstp%z0\t%y0";
3787 else
3788 return "fst%z0\t%y0";
3789 case 1:
3790 return "#";
3791 case 2:
3792 return "cvtsd2ss\t{%1, %0|%0, %1}";
3793 default:
3794 gcc_unreachable ();
3795 }
3796 }
3797 [(set_attr "type" "fmov,multi,ssecvt")
3798 (set_attr "unit" "*,i387,*")
3799 (set_attr "mode" "SF")])
3800
3801 (define_insn "*truncdfsf_i387"
3802 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3803 (float_truncate:SF
3804 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3805 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3806 "TARGET_80387"
3807 {
3808 switch (which_alternative)
3809 {
3810 case 0:
3811 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3812 return "fstp%z0\t%y0";
3813 else
3814 return "fst%z0\t%y0";
3815 case 1:
3816 return "#";
3817 default:
3818 gcc_unreachable ();
3819 }
3820 }
3821 [(set_attr "type" "fmov,multi")
3822 (set_attr "unit" "*,i387")
3823 (set_attr "mode" "SF")])
3824
3825 (define_insn "*truncdfsf2_i387_1"
3826 [(set (match_operand:SF 0 "memory_operand" "=m")
3827 (float_truncate:SF
3828 (match_operand:DF 1 "register_operand" "f")))]
3829 "TARGET_80387
3830 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3831 && !TARGET_MIX_SSE_I387"
3832 {
3833 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834 return "fstp%z0\t%y0";
3835 else
3836 return "fst%z0\t%y0";
3837 }
3838 [(set_attr "type" "fmov")
3839 (set_attr "mode" "SF")])
3840
3841 (define_split
3842 [(set (match_operand:SF 0 "register_operand" "")
3843 (float_truncate:SF
3844 (match_operand:DF 1 "fp_register_operand" "")))
3845 (clobber (match_operand 2 "" ""))]
3846 "reload_completed"
3847 [(set (match_dup 2) (match_dup 1))
3848 (set (match_dup 0) (match_dup 2))]
3849 {
3850 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3851 })
3852
3853 ;; Conversion from XFmode to SFmode.
3854
3855 (define_expand "truncxfsf2"
3856 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3857 (float_truncate:SF
3858 (match_operand:XF 1 "register_operand" "")))
3859 (clobber (match_dup 2))])]
3860 "TARGET_80387"
3861 {
3862 if (flag_unsafe_math_optimizations)
3863 {
3864 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3865 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3866 if (reg != operands[0])
3867 emit_move_insn (operands[0], reg);
3868 DONE;
3869 }
3870 else
3871 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3872 })
3873
3874 (define_insn "*truncxfsf2_mixed"
3875 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3876 (float_truncate:SF
3877 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3878 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3879 "TARGET_MIX_SSE_I387"
3880 {
3881 gcc_assert (!which_alternative);
3882 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3883 return "fstp%z0\t%y0";
3884 else
3885 return "fst%z0\t%y0";
3886 }
3887 [(set_attr "type" "fmov,multi,multi,multi")
3888 (set_attr "unit" "*,i387,i387,i387")
3889 (set_attr "mode" "SF")])
3890
3891 (define_insn "truncxfsf2_i387_noop"
3892 [(set (match_operand:SF 0 "register_operand" "=f")
3893 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3894 "TARGET_80387 && flag_unsafe_math_optimizations"
3895 {
3896 return output_387_reg_move (insn, operands);
3897 }
3898 [(set_attr "type" "fmov")
3899 (set_attr "mode" "SF")])
3900
3901 (define_insn "*truncxfsf2_i387"
3902 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3903 (float_truncate:SF
3904 (match_operand:XF 1 "register_operand" "f,f,f")))
3905 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3906 "TARGET_80387"
3907 {
3908 gcc_assert (!which_alternative);
3909 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910 return "fstp%z0\t%y0";
3911 else
3912 return "fst%z0\t%y0";
3913 }
3914 [(set_attr "type" "fmov,multi,multi")
3915 (set_attr "unit" "*,i387,i387")
3916 (set_attr "mode" "SF")])
3917
3918 (define_insn "*truncxfsf2_i387_1"
3919 [(set (match_operand:SF 0 "memory_operand" "=m")
3920 (float_truncate:SF
3921 (match_operand:XF 1 "register_operand" "f")))]
3922 "TARGET_80387"
3923 {
3924 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3925 return "fstp%z0\t%y0";
3926 else
3927 return "fst%z0\t%y0";
3928 }
3929 [(set_attr "type" "fmov")
3930 (set_attr "mode" "SF")])
3931
3932 (define_split
3933 [(set (match_operand:SF 0 "register_operand" "")
3934 (float_truncate:SF
3935 (match_operand:XF 1 "register_operand" "")))
3936 (clobber (match_operand:SF 2 "memory_operand" ""))]
3937 "TARGET_80387 && reload_completed"
3938 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3939 (set (match_dup 0) (match_dup 2))]
3940 "")
3941
3942 (define_split
3943 [(set (match_operand:SF 0 "memory_operand" "")
3944 (float_truncate:SF
3945 (match_operand:XF 1 "register_operand" "")))
3946 (clobber (match_operand:SF 2 "memory_operand" ""))]
3947 "TARGET_80387"
3948 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3949 "")
3950
3951 ;; Conversion from XFmode to DFmode.
3952
3953 (define_expand "truncxfdf2"
3954 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3955 (float_truncate:DF
3956 (match_operand:XF 1 "register_operand" "")))
3957 (clobber (match_dup 2))])]
3958 "TARGET_80387"
3959 {
3960 if (flag_unsafe_math_optimizations)
3961 {
3962 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3963 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3964 if (reg != operands[0])
3965 emit_move_insn (operands[0], reg);
3966 DONE;
3967 }
3968 else
3969 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3970 })
3971
3972 (define_insn "*truncxfdf2_mixed"
3973 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3974 (float_truncate:DF
3975 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3976 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3977 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3978 {
3979 gcc_assert (!which_alternative);
3980 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3981 return "fstp%z0\t%y0";
3982 else
3983 return "fst%z0\t%y0";
3984 }
3985 [(set_attr "type" "fmov,multi,multi,multi")
3986 (set_attr "unit" "*,i387,i387,i387")
3987 (set_attr "mode" "DF")])
3988
3989 (define_insn "truncxfdf2_i387_noop"
3990 [(set (match_operand:DF 0 "register_operand" "=f")
3991 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3992 "TARGET_80387 && flag_unsafe_math_optimizations"
3993 {
3994 return output_387_reg_move (insn, operands);
3995 }
3996 [(set_attr "type" "fmov")
3997 (set_attr "mode" "DF")])
3998
3999 (define_insn "*truncxfdf2_i387"
4000 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4001 (float_truncate:DF
4002 (match_operand:XF 1 "register_operand" "f,f,f")))
4003 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4004 "TARGET_80387"
4005 {
4006 gcc_assert (!which_alternative);
4007 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008 return "fstp%z0\t%y0";
4009 else
4010 return "fst%z0\t%y0";
4011 }
4012 [(set_attr "type" "fmov,multi,multi")
4013 (set_attr "unit" "*,i387,i387")
4014 (set_attr "mode" "DF")])
4015
4016 (define_insn "*truncxfdf2_i387_1"
4017 [(set (match_operand:DF 0 "memory_operand" "=m")
4018 (float_truncate:DF
4019 (match_operand:XF 1 "register_operand" "f")))]
4020 "TARGET_80387"
4021 {
4022 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4023 return "fstp%z0\t%y0";
4024 else
4025 return "fst%z0\t%y0";
4026 }
4027 [(set_attr "type" "fmov")
4028 (set_attr "mode" "DF")])
4029
4030 (define_split
4031 [(set (match_operand:DF 0 "register_operand" "")
4032 (float_truncate:DF
4033 (match_operand:XF 1 "register_operand" "")))
4034 (clobber (match_operand:DF 2 "memory_operand" ""))]
4035 "TARGET_80387 && reload_completed"
4036 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4037 (set (match_dup 0) (match_dup 2))]
4038 "")
4039
4040 (define_split
4041 [(set (match_operand:DF 0 "memory_operand" "")
4042 (float_truncate:DF
4043 (match_operand:XF 1 "register_operand" "")))
4044 (clobber (match_operand:DF 2 "memory_operand" ""))]
4045 "TARGET_80387"
4046 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4047 "")
4048 \f
4049 ;; Signed conversion to DImode.
4050
4051 (define_expand "fix_truncxfdi2"
4052 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4053 (fix:DI (match_operand:XF 1 "register_operand" "")))
4054 (clobber (reg:CC FLAGS_REG))])]
4055 "TARGET_80387"
4056 {
4057 if (TARGET_FISTTP)
4058 {
4059 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4060 DONE;
4061 }
4062 })
4063
4064 (define_expand "fix_trunc<mode>di2"
4065 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4066 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4067 (clobber (reg:CC FLAGS_REG))])]
4068 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4069 {
4070 if (TARGET_FISTTP
4071 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4072 {
4073 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4074 DONE;
4075 }
4076 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4077 {
4078 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4079 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4080 if (out != operands[0])
4081 emit_move_insn (operands[0], out);
4082 DONE;
4083 }
4084 })
4085
4086 ;; Signed conversion to SImode.
4087
4088 (define_expand "fix_truncxfsi2"
4089 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4090 (fix:SI (match_operand:XF 1 "register_operand" "")))
4091 (clobber (reg:CC FLAGS_REG))])]
4092 "TARGET_80387"
4093 {
4094 if (TARGET_FISTTP)
4095 {
4096 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4097 DONE;
4098 }
4099 })
4100
4101 (define_expand "fix_trunc<mode>si2"
4102 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4103 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4104 (clobber (reg:CC FLAGS_REG))])]
4105 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4106 {
4107 if (TARGET_FISTTP
4108 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4109 {
4110 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4111 DONE;
4112 }
4113 if (SSE_FLOAT_MODE_P (<MODE>mode))
4114 {
4115 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4116 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4117 if (out != operands[0])
4118 emit_move_insn (operands[0], out);
4119 DONE;
4120 }
4121 })
4122
4123 ;; Signed conversion to HImode.
4124
4125 (define_expand "fix_trunc<mode>hi2"
4126 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4127 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4128 (clobber (reg:CC FLAGS_REG))])]
4129 "TARGET_80387
4130 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4131 {
4132 if (TARGET_FISTTP)
4133 {
4134 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4135 DONE;
4136 }
4137 })
4138
4139 ;; When SSE is available, it is always faster to use it!
4140 (define_insn "fix_truncsfdi_sse"
4141 [(set (match_operand:DI 0 "register_operand" "=r,r")
4142 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4143 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4144 "cvttss2si{q}\t{%1, %0|%0, %1}"
4145 [(set_attr "type" "sseicvt")
4146 (set_attr "mode" "SF")
4147 (set_attr "athlon_decode" "double,vector")])
4148
4149 (define_insn "fix_truncdfdi_sse"
4150 [(set (match_operand:DI 0 "register_operand" "=r,r")
4151 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4152 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4153 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4154 [(set_attr "type" "sseicvt")
4155 (set_attr "mode" "DF")
4156 (set_attr "athlon_decode" "double,vector")])
4157
4158 (define_insn "fix_truncsfsi_sse"
4159 [(set (match_operand:SI 0 "register_operand" "=r,r")
4160 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4161 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4162 "cvttss2si\t{%1, %0|%0, %1}"
4163 [(set_attr "type" "sseicvt")
4164 (set_attr "mode" "DF")
4165 (set_attr "athlon_decode" "double,vector")])
4166
4167 (define_insn "fix_truncdfsi_sse"
4168 [(set (match_operand:SI 0 "register_operand" "=r,r")
4169 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4170 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4171 "cvttsd2si\t{%1, %0|%0, %1}"
4172 [(set_attr "type" "sseicvt")
4173 (set_attr "mode" "DF")
4174 (set_attr "athlon_decode" "double,vector")])
4175
4176 ;; Avoid vector decoded forms of the instruction.
4177 (define_peephole2
4178 [(match_scratch:DF 2 "Y")
4179 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4180 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4181 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4182 [(set (match_dup 2) (match_dup 1))
4183 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4184 "")
4185
4186 (define_peephole2
4187 [(match_scratch:SF 2 "x")
4188 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4189 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4190 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4191 [(set (match_dup 2) (match_dup 1))
4192 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4193 "")
4194
4195 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4196 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4197 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4198 "TARGET_FISTTP
4199 && FLOAT_MODE_P (GET_MODE (operands[1]))
4200 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4201 && (TARGET_64BIT || <MODE>mode != DImode))
4202 && TARGET_SSE_MATH)
4203 && !(reload_completed || reload_in_progress)"
4204 "#"
4205 "&& 1"
4206 [(const_int 0)]
4207 {
4208 if (memory_operand (operands[0], VOIDmode))
4209 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4210 else
4211 {
4212 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4213 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4214 operands[1],
4215 operands[2]));
4216 }
4217 DONE;
4218 }
4219 [(set_attr "type" "fisttp")
4220 (set_attr "mode" "<MODE>")])
4221
4222 (define_insn "fix_trunc<mode>_i387_fisttp"
4223 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4224 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4225 (clobber (match_scratch:XF 2 "=&1f"))]
4226 "TARGET_FISTTP
4227 && FLOAT_MODE_P (GET_MODE (operands[1]))
4228 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4229 && (TARGET_64BIT || <MODE>mode != DImode))
4230 && TARGET_SSE_MATH)"
4231 "* return output_fix_trunc (insn, operands, 1);"
4232 [(set_attr "type" "fisttp")
4233 (set_attr "mode" "<MODE>")])
4234
4235 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4236 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4237 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4238 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4239 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4240 "TARGET_FISTTP
4241 && FLOAT_MODE_P (GET_MODE (operands[1]))
4242 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4243 && (TARGET_64BIT || <MODE>mode != DImode))
4244 && TARGET_SSE_MATH)"
4245 "#"
4246 [(set_attr "type" "fisttp")
4247 (set_attr "mode" "<MODE>")])
4248
4249 (define_split
4250 [(set (match_operand:X87MODEI 0 "register_operand" "")
4251 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4252 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4253 (clobber (match_scratch 3 ""))]
4254 "reload_completed"
4255 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4256 (clobber (match_dup 3))])
4257 (set (match_dup 0) (match_dup 2))]
4258 "")
4259
4260 (define_split
4261 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4262 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4263 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4264 (clobber (match_scratch 3 ""))]
4265 "reload_completed"
4266 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4267 (clobber (match_dup 3))])]
4268 "")
4269
4270 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4271 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4272 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4273 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4274 ;; function in i386.c.
4275 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4276 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4277 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4278 (clobber (reg:CC FLAGS_REG))]
4279 "TARGET_80387 && !TARGET_FISTTP
4280 && FLOAT_MODE_P (GET_MODE (operands[1]))
4281 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4282 && (TARGET_64BIT || <MODE>mode != DImode))
4283 && !(reload_completed || reload_in_progress)"
4284 "#"
4285 "&& 1"
4286 [(const_int 0)]
4287 {
4288 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4289
4290 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4291 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4292 if (memory_operand (operands[0], VOIDmode))
4293 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4294 operands[2], operands[3]));
4295 else
4296 {
4297 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4298 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4299 operands[2], operands[3],
4300 operands[4]));
4301 }
4302 DONE;
4303 }
4304 [(set_attr "type" "fistp")
4305 (set_attr "i387_cw" "trunc")
4306 (set_attr "mode" "<MODE>")])
4307
4308 (define_insn "fix_truncdi_i387"
4309 [(set (match_operand:DI 0 "memory_operand" "=m")
4310 (fix:DI (match_operand 1 "register_operand" "f")))
4311 (use (match_operand:HI 2 "memory_operand" "m"))
4312 (use (match_operand:HI 3 "memory_operand" "m"))
4313 (clobber (match_scratch:XF 4 "=&1f"))]
4314 "TARGET_80387 && !TARGET_FISTTP
4315 && FLOAT_MODE_P (GET_MODE (operands[1]))
4316 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4317 "* return output_fix_trunc (insn, operands, 0);"
4318 [(set_attr "type" "fistp")
4319 (set_attr "i387_cw" "trunc")
4320 (set_attr "mode" "DI")])
4321
4322 (define_insn "fix_truncdi_i387_with_temp"
4323 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4324 (fix:DI (match_operand 1 "register_operand" "f,f")))
4325 (use (match_operand:HI 2 "memory_operand" "m,m"))
4326 (use (match_operand:HI 3 "memory_operand" "m,m"))
4327 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4328 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4329 "TARGET_80387 && !TARGET_FISTTP
4330 && FLOAT_MODE_P (GET_MODE (operands[1]))
4331 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4332 "#"
4333 [(set_attr "type" "fistp")
4334 (set_attr "i387_cw" "trunc")
4335 (set_attr "mode" "DI")])
4336
4337 (define_split
4338 [(set (match_operand:DI 0 "register_operand" "")
4339 (fix:DI (match_operand 1 "register_operand" "")))
4340 (use (match_operand:HI 2 "memory_operand" ""))
4341 (use (match_operand:HI 3 "memory_operand" ""))
4342 (clobber (match_operand:DI 4 "memory_operand" ""))
4343 (clobber (match_scratch 5 ""))]
4344 "reload_completed"
4345 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4346 (use (match_dup 2))
4347 (use (match_dup 3))
4348 (clobber (match_dup 5))])
4349 (set (match_dup 0) (match_dup 4))]
4350 "")
4351
4352 (define_split
4353 [(set (match_operand:DI 0 "memory_operand" "")
4354 (fix:DI (match_operand 1 "register_operand" "")))
4355 (use (match_operand:HI 2 "memory_operand" ""))
4356 (use (match_operand:HI 3 "memory_operand" ""))
4357 (clobber (match_operand:DI 4 "memory_operand" ""))
4358 (clobber (match_scratch 5 ""))]
4359 "reload_completed"
4360 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4361 (use (match_dup 2))
4362 (use (match_dup 3))
4363 (clobber (match_dup 5))])]
4364 "")
4365
4366 (define_insn "fix_trunc<mode>_i387"
4367 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4368 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4369 (use (match_operand:HI 2 "memory_operand" "m"))
4370 (use (match_operand:HI 3 "memory_operand" "m"))]
4371 "TARGET_80387 && !TARGET_FISTTP
4372 && FLOAT_MODE_P (GET_MODE (operands[1]))
4373 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4374 "* return output_fix_trunc (insn, operands, 0);"
4375 [(set_attr "type" "fistp")
4376 (set_attr "i387_cw" "trunc")
4377 (set_attr "mode" "<MODE>")])
4378
4379 (define_insn "fix_trunc<mode>_i387_with_temp"
4380 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4381 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4382 (use (match_operand:HI 2 "memory_operand" "m,m"))
4383 (use (match_operand:HI 3 "memory_operand" "m,m"))
4384 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4385 "TARGET_80387 && !TARGET_FISTTP
4386 && FLOAT_MODE_P (GET_MODE (operands[1]))
4387 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4388 "#"
4389 [(set_attr "type" "fistp")
4390 (set_attr "i387_cw" "trunc")
4391 (set_attr "mode" "<MODE>")])
4392
4393 (define_split
4394 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4395 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4396 (use (match_operand:HI 2 "memory_operand" ""))
4397 (use (match_operand:HI 3 "memory_operand" ""))
4398 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4399 "reload_completed"
4400 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4401 (use (match_dup 2))
4402 (use (match_dup 3))])
4403 (set (match_dup 0) (match_dup 4))]
4404 "")
4405
4406 (define_split
4407 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4408 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4409 (use (match_operand:HI 2 "memory_operand" ""))
4410 (use (match_operand:HI 3 "memory_operand" ""))
4411 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4412 "reload_completed"
4413 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4414 (use (match_dup 2))
4415 (use (match_dup 3))])]
4416 "")
4417
4418 (define_insn "x86_fnstcw_1"
4419 [(set (match_operand:HI 0 "memory_operand" "=m")
4420 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4421 "TARGET_80387"
4422 "fnstcw\t%0"
4423 [(set_attr "length" "2")
4424 (set_attr "mode" "HI")
4425 (set_attr "unit" "i387")])
4426
4427 (define_insn "x86_fldcw_1"
4428 [(set (reg:HI FPSR_REG)
4429 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4430 "TARGET_80387"
4431 "fldcw\t%0"
4432 [(set_attr "length" "2")
4433 (set_attr "mode" "HI")
4434 (set_attr "unit" "i387")
4435 (set_attr "athlon_decode" "vector")])
4436 \f
4437 ;; Conversion between fixed point and floating point.
4438
4439 ;; Even though we only accept memory inputs, the backend _really_
4440 ;; wants to be able to do this between registers.
4441
4442 (define_expand "floathisf2"
4443 [(set (match_operand:SF 0 "register_operand" "")
4444 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4445 "TARGET_80387 || TARGET_SSE_MATH"
4446 {
4447 if (TARGET_SSE_MATH)
4448 {
4449 emit_insn (gen_floatsisf2 (operands[0],
4450 convert_to_mode (SImode, operands[1], 0)));
4451 DONE;
4452 }
4453 })
4454
4455 (define_insn "*floathisf2_i387"
4456 [(set (match_operand:SF 0 "register_operand" "=f,f")
4457 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4458 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4459 "@
4460 fild%z1\t%1
4461 #"
4462 [(set_attr "type" "fmov,multi")
4463 (set_attr "mode" "SF")
4464 (set_attr "unit" "*,i387")
4465 (set_attr "fp_int_src" "true")])
4466
4467 (define_expand "floatsisf2"
4468 [(set (match_operand:SF 0 "register_operand" "")
4469 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4470 "TARGET_80387 || TARGET_SSE_MATH"
4471 "")
4472
4473 (define_insn "*floatsisf2_mixed"
4474 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4475 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4476 "TARGET_MIX_SSE_I387"
4477 "@
4478 fild%z1\t%1
4479 #
4480 cvtsi2ss\t{%1, %0|%0, %1}
4481 cvtsi2ss\t{%1, %0|%0, %1}"
4482 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4483 (set_attr "mode" "SF")
4484 (set_attr "unit" "*,i387,*,*")
4485 (set_attr "athlon_decode" "*,*,vector,double")
4486 (set_attr "fp_int_src" "true")])
4487
4488 (define_insn "*floatsisf2_sse"
4489 [(set (match_operand:SF 0 "register_operand" "=x,x")
4490 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4491 "TARGET_SSE_MATH"
4492 "cvtsi2ss\t{%1, %0|%0, %1}"
4493 [(set_attr "type" "sseicvt")
4494 (set_attr "mode" "SF")
4495 (set_attr "athlon_decode" "vector,double")
4496 (set_attr "fp_int_src" "true")])
4497
4498 (define_insn "*floatsisf2_i387"
4499 [(set (match_operand:SF 0 "register_operand" "=f,f")
4500 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4501 "TARGET_80387"
4502 "@
4503 fild%z1\t%1
4504 #"
4505 [(set_attr "type" "fmov,multi")
4506 (set_attr "mode" "SF")
4507 (set_attr "unit" "*,i387")
4508 (set_attr "fp_int_src" "true")])
4509
4510 (define_expand "floatdisf2"
4511 [(set (match_operand:SF 0 "register_operand" "")
4512 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4513 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4514 "")
4515
4516 (define_insn "*floatdisf2_mixed"
4517 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4518 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4519 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4520 "@
4521 fild%z1\t%1
4522 #
4523 cvtsi2ss{q}\t{%1, %0|%0, %1}
4524 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4525 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4526 (set_attr "mode" "SF")
4527 (set_attr "unit" "*,i387,*,*")
4528 (set_attr "athlon_decode" "*,*,vector,double")
4529 (set_attr "fp_int_src" "true")])
4530
4531 (define_insn "*floatdisf2_sse"
4532 [(set (match_operand:SF 0 "register_operand" "=x,x")
4533 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4534 "TARGET_64BIT && TARGET_SSE_MATH"
4535 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4536 [(set_attr "type" "sseicvt")
4537 (set_attr "mode" "SF")
4538 (set_attr "athlon_decode" "vector,double")
4539 (set_attr "fp_int_src" "true")])
4540
4541 (define_insn "*floatdisf2_i387"
4542 [(set (match_operand:SF 0 "register_operand" "=f,f")
4543 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4544 "TARGET_80387"
4545 "@
4546 fild%z1\t%1
4547 #"
4548 [(set_attr "type" "fmov,multi")
4549 (set_attr "mode" "SF")
4550 (set_attr "unit" "*,i387")
4551 (set_attr "fp_int_src" "true")])
4552
4553 (define_expand "floathidf2"
4554 [(set (match_operand:DF 0 "register_operand" "")
4555 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4556 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4557 {
4558 if (TARGET_SSE2 && TARGET_SSE_MATH)
4559 {
4560 emit_insn (gen_floatsidf2 (operands[0],
4561 convert_to_mode (SImode, operands[1], 0)));
4562 DONE;
4563 }
4564 })
4565
4566 (define_insn "*floathidf2_i387"
4567 [(set (match_operand:DF 0 "register_operand" "=f,f")
4568 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4569 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4570 "@
4571 fild%z1\t%1
4572 #"
4573 [(set_attr "type" "fmov,multi")
4574 (set_attr "mode" "DF")
4575 (set_attr "unit" "*,i387")
4576 (set_attr "fp_int_src" "true")])
4577
4578 (define_expand "floatsidf2"
4579 [(set (match_operand:DF 0 "register_operand" "")
4580 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4581 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4582 "")
4583
4584 (define_insn "*floatsidf2_mixed"
4585 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4586 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4587 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4588 "@
4589 fild%z1\t%1
4590 #
4591 cvtsi2sd\t{%1, %0|%0, %1}
4592 cvtsi2sd\t{%1, %0|%0, %1}"
4593 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4594 (set_attr "mode" "DF")
4595 (set_attr "unit" "*,i387,*,*")
4596 (set_attr "athlon_decode" "*,*,double,direct")
4597 (set_attr "fp_int_src" "true")])
4598
4599 (define_insn "*floatsidf2_sse"
4600 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4601 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4602 "TARGET_SSE2 && TARGET_SSE_MATH"
4603 "cvtsi2sd\t{%1, %0|%0, %1}"
4604 [(set_attr "type" "sseicvt")
4605 (set_attr "mode" "DF")
4606 (set_attr "athlon_decode" "double,direct")
4607 (set_attr "fp_int_src" "true")])
4608
4609 (define_insn "*floatsidf2_i387"
4610 [(set (match_operand:DF 0 "register_operand" "=f,f")
4611 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4612 "TARGET_80387"
4613 "@
4614 fild%z1\t%1
4615 #"
4616 [(set_attr "type" "fmov,multi")
4617 (set_attr "mode" "DF")
4618 (set_attr "unit" "*,i387")
4619 (set_attr "fp_int_src" "true")])
4620
4621 (define_expand "floatdidf2"
4622 [(set (match_operand:DF 0 "register_operand" "")
4623 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4624 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4625 "")
4626
4627 (define_insn "*floatdidf2_mixed"
4628 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4629 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4630 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4631 "@
4632 fild%z1\t%1
4633 #
4634 cvtsi2sd{q}\t{%1, %0|%0, %1}
4635 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4636 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4637 (set_attr "mode" "DF")
4638 (set_attr "unit" "*,i387,*,*")
4639 (set_attr "athlon_decode" "*,*,double,direct")
4640 (set_attr "fp_int_src" "true")])
4641
4642 (define_insn "*floatdidf2_sse"
4643 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4644 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4645 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4646 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4647 [(set_attr "type" "sseicvt")
4648 (set_attr "mode" "DF")
4649 (set_attr "athlon_decode" "double,direct")
4650 (set_attr "fp_int_src" "true")])
4651
4652 (define_insn "*floatdidf2_i387"
4653 [(set (match_operand:DF 0 "register_operand" "=f,f")
4654 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4655 "TARGET_80387"
4656 "@
4657 fild%z1\t%1
4658 #"
4659 [(set_attr "type" "fmov,multi")
4660 (set_attr "mode" "DF")
4661 (set_attr "unit" "*,i387")
4662 (set_attr "fp_int_src" "true")])
4663
4664 (define_insn "floathixf2"
4665 [(set (match_operand:XF 0 "register_operand" "=f,f")
4666 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4667 "TARGET_80387"
4668 "@
4669 fild%z1\t%1
4670 #"
4671 [(set_attr "type" "fmov,multi")
4672 (set_attr "mode" "XF")
4673 (set_attr "unit" "*,i387")
4674 (set_attr "fp_int_src" "true")])
4675
4676 (define_insn "floatsixf2"
4677 [(set (match_operand:XF 0 "register_operand" "=f,f")
4678 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4679 "TARGET_80387"
4680 "@
4681 fild%z1\t%1
4682 #"
4683 [(set_attr "type" "fmov,multi")
4684 (set_attr "mode" "XF")
4685 (set_attr "unit" "*,i387")
4686 (set_attr "fp_int_src" "true")])
4687
4688 (define_insn "floatdixf2"
4689 [(set (match_operand:XF 0 "register_operand" "=f,f")
4690 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4691 "TARGET_80387"
4692 "@
4693 fild%z1\t%1
4694 #"
4695 [(set_attr "type" "fmov,multi")
4696 (set_attr "mode" "XF")
4697 (set_attr "unit" "*,i387")
4698 (set_attr "fp_int_src" "true")])
4699
4700 ;; %%% Kill these when reload knows how to do it.
4701 (define_split
4702 [(set (match_operand 0 "fp_register_operand" "")
4703 (float (match_operand 1 "register_operand" "")))]
4704 "reload_completed
4705 && TARGET_80387
4706 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4707 [(const_int 0)]
4708 {
4709 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4710 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4711 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4712 ix86_free_from_memory (GET_MODE (operands[1]));
4713 DONE;
4714 })
4715
4716 (define_expand "floatunssisf2"
4717 [(use (match_operand:SF 0 "register_operand" ""))
4718 (use (match_operand:SI 1 "register_operand" ""))]
4719 "!TARGET_64BIT && TARGET_SSE_MATH"
4720 "x86_emit_floatuns (operands); DONE;")
4721
4722 (define_expand "floatunsdisf2"
4723 [(use (match_operand:SF 0 "register_operand" ""))
4724 (use (match_operand:DI 1 "register_operand" ""))]
4725 "TARGET_64BIT && TARGET_SSE_MATH"
4726 "x86_emit_floatuns (operands); DONE;")
4727
4728 (define_expand "floatunsdidf2"
4729 [(use (match_operand:DF 0 "register_operand" ""))
4730 (use (match_operand:DI 1 "register_operand" ""))]
4731 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4732 "x86_emit_floatuns (operands); DONE;")
4733 \f
4734 ;; SSE extract/set expanders
4735
4736 \f
4737 ;; Add instructions
4738
4739 ;; %%% splits for addditi3
4740
4741 (define_expand "addti3"
4742 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4743 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4744 (match_operand:TI 2 "x86_64_general_operand" "")))
4745 (clobber (reg:CC FLAGS_REG))]
4746 "TARGET_64BIT"
4747 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4748
4749 (define_insn "*addti3_1"
4750 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4751 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4752 (match_operand:TI 2 "general_operand" "roiF,riF")))
4753 (clobber (reg:CC FLAGS_REG))]
4754 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4755 "#")
4756
4757 (define_split
4758 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4759 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4760 (match_operand:TI 2 "general_operand" "")))
4761 (clobber (reg:CC FLAGS_REG))]
4762 "TARGET_64BIT && reload_completed"
4763 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4764 UNSPEC_ADD_CARRY))
4765 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4766 (parallel [(set (match_dup 3)
4767 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4768 (match_dup 4))
4769 (match_dup 5)))
4770 (clobber (reg:CC FLAGS_REG))])]
4771 "split_ti (operands+0, 1, operands+0, operands+3);
4772 split_ti (operands+1, 1, operands+1, operands+4);
4773 split_ti (operands+2, 1, operands+2, operands+5);")
4774
4775 ;; %%% splits for addsidi3
4776 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4777 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4778 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4779
4780 (define_expand "adddi3"
4781 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4782 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4783 (match_operand:DI 2 "x86_64_general_operand" "")))
4784 (clobber (reg:CC FLAGS_REG))]
4785 ""
4786 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4787
4788 (define_insn "*adddi3_1"
4789 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4790 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4791 (match_operand:DI 2 "general_operand" "roiF,riF")))
4792 (clobber (reg:CC FLAGS_REG))]
4793 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4794 "#")
4795
4796 (define_split
4797 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4798 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4799 (match_operand:DI 2 "general_operand" "")))
4800 (clobber (reg:CC FLAGS_REG))]
4801 "!TARGET_64BIT && reload_completed"
4802 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4803 UNSPEC_ADD_CARRY))
4804 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4805 (parallel [(set (match_dup 3)
4806 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4807 (match_dup 4))
4808 (match_dup 5)))
4809 (clobber (reg:CC FLAGS_REG))])]
4810 "split_di (operands+0, 1, operands+0, operands+3);
4811 split_di (operands+1, 1, operands+1, operands+4);
4812 split_di (operands+2, 1, operands+2, operands+5);")
4813
4814 (define_insn "adddi3_carry_rex64"
4815 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4816 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4817 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4818 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4819 (clobber (reg:CC FLAGS_REG))]
4820 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4821 "adc{q}\t{%2, %0|%0, %2}"
4822 [(set_attr "type" "alu")
4823 (set_attr "pent_pair" "pu")
4824 (set_attr "mode" "DI")])
4825
4826 (define_insn "*adddi3_cc_rex64"
4827 [(set (reg:CC FLAGS_REG)
4828 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4829 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4830 UNSPEC_ADD_CARRY))
4831 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4832 (plus:DI (match_dup 1) (match_dup 2)))]
4833 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4834 "add{q}\t{%2, %0|%0, %2}"
4835 [(set_attr "type" "alu")
4836 (set_attr "mode" "DI")])
4837
4838 (define_insn "addqi3_carry"
4839 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4840 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4841 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4842 (match_operand:QI 2 "general_operand" "qi,qm")))
4843 (clobber (reg:CC FLAGS_REG))]
4844 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4845 "adc{b}\t{%2, %0|%0, %2}"
4846 [(set_attr "type" "alu")
4847 (set_attr "pent_pair" "pu")
4848 (set_attr "mode" "QI")])
4849
4850 (define_insn "addhi3_carry"
4851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4852 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4853 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4854 (match_operand:HI 2 "general_operand" "ri,rm")))
4855 (clobber (reg:CC FLAGS_REG))]
4856 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4857 "adc{w}\t{%2, %0|%0, %2}"
4858 [(set_attr "type" "alu")
4859 (set_attr "pent_pair" "pu")
4860 (set_attr "mode" "HI")])
4861
4862 (define_insn "addsi3_carry"
4863 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4865 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4866 (match_operand:SI 2 "general_operand" "ri,rm")))
4867 (clobber (reg:CC FLAGS_REG))]
4868 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4869 "adc{l}\t{%2, %0|%0, %2}"
4870 [(set_attr "type" "alu")
4871 (set_attr "pent_pair" "pu")
4872 (set_attr "mode" "SI")])
4873
4874 (define_insn "*addsi3_carry_zext"
4875 [(set (match_operand:DI 0 "register_operand" "=r")
4876 (zero_extend:DI
4877 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4878 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4879 (match_operand:SI 2 "general_operand" "rim"))))
4880 (clobber (reg:CC FLAGS_REG))]
4881 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4882 "adc{l}\t{%2, %k0|%k0, %2}"
4883 [(set_attr "type" "alu")
4884 (set_attr "pent_pair" "pu")
4885 (set_attr "mode" "SI")])
4886
4887 (define_insn "*addsi3_cc"
4888 [(set (reg:CC FLAGS_REG)
4889 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4890 (match_operand:SI 2 "general_operand" "ri,rm")]
4891 UNSPEC_ADD_CARRY))
4892 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4893 (plus:SI (match_dup 1) (match_dup 2)))]
4894 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4895 "add{l}\t{%2, %0|%0, %2}"
4896 [(set_attr "type" "alu")
4897 (set_attr "mode" "SI")])
4898
4899 (define_insn "addqi3_cc"
4900 [(set (reg:CC FLAGS_REG)
4901 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4902 (match_operand:QI 2 "general_operand" "qi,qm")]
4903 UNSPEC_ADD_CARRY))
4904 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4905 (plus:QI (match_dup 1) (match_dup 2)))]
4906 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4907 "add{b}\t{%2, %0|%0, %2}"
4908 [(set_attr "type" "alu")
4909 (set_attr "mode" "QI")])
4910
4911 (define_expand "addsi3"
4912 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4913 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4914 (match_operand:SI 2 "general_operand" "")))
4915 (clobber (reg:CC FLAGS_REG))])]
4916 ""
4917 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4918
4919 (define_insn "*lea_1"
4920 [(set (match_operand:SI 0 "register_operand" "=r")
4921 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4922 "!TARGET_64BIT"
4923 "lea{l}\t{%a1, %0|%0, %a1}"
4924 [(set_attr "type" "lea")
4925 (set_attr "mode" "SI")])
4926
4927 (define_insn "*lea_1_rex64"
4928 [(set (match_operand:SI 0 "register_operand" "=r")
4929 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4930 "TARGET_64BIT"
4931 "lea{l}\t{%a1, %0|%0, %a1}"
4932 [(set_attr "type" "lea")
4933 (set_attr "mode" "SI")])
4934
4935 (define_insn "*lea_1_zext"
4936 [(set (match_operand:DI 0 "register_operand" "=r")
4937 (zero_extend:DI
4938 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4939 "TARGET_64BIT"
4940 "lea{l}\t{%a1, %k0|%k0, %a1}"
4941 [(set_attr "type" "lea")
4942 (set_attr "mode" "SI")])
4943
4944 (define_insn "*lea_2_rex64"
4945 [(set (match_operand:DI 0 "register_operand" "=r")
4946 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4947 "TARGET_64BIT"
4948 "lea{q}\t{%a1, %0|%0, %a1}"
4949 [(set_attr "type" "lea")
4950 (set_attr "mode" "DI")])
4951
4952 ;; The lea patterns for non-Pmodes needs to be matched by several
4953 ;; insns converted to real lea by splitters.
4954
4955 (define_insn_and_split "*lea_general_1"
4956 [(set (match_operand 0 "register_operand" "=r")
4957 (plus (plus (match_operand 1 "index_register_operand" "l")
4958 (match_operand 2 "register_operand" "r"))
4959 (match_operand 3 "immediate_operand" "i")))]
4960 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4961 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4962 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4963 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4964 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4965 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4966 || GET_MODE (operands[3]) == VOIDmode)"
4967 "#"
4968 "&& reload_completed"
4969 [(const_int 0)]
4970 {
4971 rtx pat;
4972 operands[0] = gen_lowpart (SImode, operands[0]);
4973 operands[1] = gen_lowpart (Pmode, operands[1]);
4974 operands[2] = gen_lowpart (Pmode, operands[2]);
4975 operands[3] = gen_lowpart (Pmode, operands[3]);
4976 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4977 operands[3]);
4978 if (Pmode != SImode)
4979 pat = gen_rtx_SUBREG (SImode, pat, 0);
4980 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4981 DONE;
4982 }
4983 [(set_attr "type" "lea")
4984 (set_attr "mode" "SI")])
4985
4986 (define_insn_and_split "*lea_general_1_zext"
4987 [(set (match_operand:DI 0 "register_operand" "=r")
4988 (zero_extend:DI
4989 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4990 (match_operand:SI 2 "register_operand" "r"))
4991 (match_operand:SI 3 "immediate_operand" "i"))))]
4992 "TARGET_64BIT"
4993 "#"
4994 "&& reload_completed"
4995 [(set (match_dup 0)
4996 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4997 (match_dup 2))
4998 (match_dup 3)) 0)))]
4999 {
5000 operands[1] = gen_lowpart (Pmode, operands[1]);
5001 operands[2] = gen_lowpart (Pmode, operands[2]);
5002 operands[3] = gen_lowpart (Pmode, operands[3]);
5003 }
5004 [(set_attr "type" "lea")
5005 (set_attr "mode" "SI")])
5006
5007 (define_insn_and_split "*lea_general_2"
5008 [(set (match_operand 0 "register_operand" "=r")
5009 (plus (mult (match_operand 1 "index_register_operand" "l")
5010 (match_operand 2 "const248_operand" "i"))
5011 (match_operand 3 "nonmemory_operand" "ri")))]
5012 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5013 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5014 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5015 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5016 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5017 || GET_MODE (operands[3]) == VOIDmode)"
5018 "#"
5019 "&& reload_completed"
5020 [(const_int 0)]
5021 {
5022 rtx pat;
5023 operands[0] = gen_lowpart (SImode, operands[0]);
5024 operands[1] = gen_lowpart (Pmode, operands[1]);
5025 operands[3] = gen_lowpart (Pmode, operands[3]);
5026 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5027 operands[3]);
5028 if (Pmode != SImode)
5029 pat = gen_rtx_SUBREG (SImode, pat, 0);
5030 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5031 DONE;
5032 }
5033 [(set_attr "type" "lea")
5034 (set_attr "mode" "SI")])
5035
5036 (define_insn_and_split "*lea_general_2_zext"
5037 [(set (match_operand:DI 0 "register_operand" "=r")
5038 (zero_extend:DI
5039 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5040 (match_operand:SI 2 "const248_operand" "n"))
5041 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5042 "TARGET_64BIT"
5043 "#"
5044 "&& reload_completed"
5045 [(set (match_dup 0)
5046 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5047 (match_dup 2))
5048 (match_dup 3)) 0)))]
5049 {
5050 operands[1] = gen_lowpart (Pmode, operands[1]);
5051 operands[3] = gen_lowpart (Pmode, operands[3]);
5052 }
5053 [(set_attr "type" "lea")
5054 (set_attr "mode" "SI")])
5055
5056 (define_insn_and_split "*lea_general_3"
5057 [(set (match_operand 0 "register_operand" "=r")
5058 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5059 (match_operand 2 "const248_operand" "i"))
5060 (match_operand 3 "register_operand" "r"))
5061 (match_operand 4 "immediate_operand" "i")))]
5062 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5063 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5064 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5065 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5066 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5067 "#"
5068 "&& reload_completed"
5069 [(const_int 0)]
5070 {
5071 rtx pat;
5072 operands[0] = gen_lowpart (SImode, operands[0]);
5073 operands[1] = gen_lowpart (Pmode, operands[1]);
5074 operands[3] = gen_lowpart (Pmode, operands[3]);
5075 operands[4] = gen_lowpart (Pmode, operands[4]);
5076 pat = gen_rtx_PLUS (Pmode,
5077 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5078 operands[2]),
5079 operands[3]),
5080 operands[4]);
5081 if (Pmode != SImode)
5082 pat = gen_rtx_SUBREG (SImode, pat, 0);
5083 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5084 DONE;
5085 }
5086 [(set_attr "type" "lea")
5087 (set_attr "mode" "SI")])
5088
5089 (define_insn_and_split "*lea_general_3_zext"
5090 [(set (match_operand:DI 0 "register_operand" "=r")
5091 (zero_extend:DI
5092 (plus:SI (plus:SI (mult:SI
5093 (match_operand:SI 1 "index_register_operand" "l")
5094 (match_operand:SI 2 "const248_operand" "n"))
5095 (match_operand:SI 3 "register_operand" "r"))
5096 (match_operand:SI 4 "immediate_operand" "i"))))]
5097 "TARGET_64BIT"
5098 "#"
5099 "&& reload_completed"
5100 [(set (match_dup 0)
5101 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5102 (match_dup 2))
5103 (match_dup 3))
5104 (match_dup 4)) 0)))]
5105 {
5106 operands[1] = gen_lowpart (Pmode, operands[1]);
5107 operands[3] = gen_lowpart (Pmode, operands[3]);
5108 operands[4] = gen_lowpart (Pmode, operands[4]);
5109 }
5110 [(set_attr "type" "lea")
5111 (set_attr "mode" "SI")])
5112
5113 (define_insn "*adddi_1_rex64"
5114 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5115 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5116 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5117 (clobber (reg:CC FLAGS_REG))]
5118 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5119 {
5120 switch (get_attr_type (insn))
5121 {
5122 case TYPE_LEA:
5123 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5124 return "lea{q}\t{%a2, %0|%0, %a2}";
5125
5126 case TYPE_INCDEC:
5127 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5128 if (operands[2] == const1_rtx)
5129 return "inc{q}\t%0";
5130 else
5131 {
5132 gcc_assert (operands[2] == constm1_rtx);
5133 return "dec{q}\t%0";
5134 }
5135
5136 default:
5137 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5138
5139 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5140 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5141 if (GET_CODE (operands[2]) == CONST_INT
5142 /* Avoid overflows. */
5143 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5144 && (INTVAL (operands[2]) == 128
5145 || (INTVAL (operands[2]) < 0
5146 && INTVAL (operands[2]) != -128)))
5147 {
5148 operands[2] = GEN_INT (-INTVAL (operands[2]));
5149 return "sub{q}\t{%2, %0|%0, %2}";
5150 }
5151 return "add{q}\t{%2, %0|%0, %2}";
5152 }
5153 }
5154 [(set (attr "type")
5155 (cond [(eq_attr "alternative" "2")
5156 (const_string "lea")
5157 ; Current assemblers are broken and do not allow @GOTOFF in
5158 ; ought but a memory context.
5159 (match_operand:DI 2 "pic_symbolic_operand" "")
5160 (const_string "lea")
5161 (match_operand:DI 2 "incdec_operand" "")
5162 (const_string "incdec")
5163 ]
5164 (const_string "alu")))
5165 (set_attr "mode" "DI")])
5166
5167 ;; Convert lea to the lea pattern to avoid flags dependency.
5168 (define_split
5169 [(set (match_operand:DI 0 "register_operand" "")
5170 (plus:DI (match_operand:DI 1 "register_operand" "")
5171 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5172 (clobber (reg:CC FLAGS_REG))]
5173 "TARGET_64BIT && reload_completed
5174 && true_regnum (operands[0]) != true_regnum (operands[1])"
5175 [(set (match_dup 0)
5176 (plus:DI (match_dup 1)
5177 (match_dup 2)))]
5178 "")
5179
5180 (define_insn "*adddi_2_rex64"
5181 [(set (reg FLAGS_REG)
5182 (compare
5183 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5184 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5185 (const_int 0)))
5186 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5187 (plus:DI (match_dup 1) (match_dup 2)))]
5188 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5189 && ix86_binary_operator_ok (PLUS, DImode, operands)
5190 /* Current assemblers are broken and do not allow @GOTOFF in
5191 ought but a memory context. */
5192 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5193 {
5194 switch (get_attr_type (insn))
5195 {
5196 case TYPE_INCDEC:
5197 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5198 if (operands[2] == const1_rtx)
5199 return "inc{q}\t%0";
5200 else
5201 {
5202 gcc_assert (operands[2] == constm1_rtx);
5203 return "dec{q}\t%0";
5204 }
5205
5206 default:
5207 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5208 /* ???? We ought to handle there the 32bit case too
5209 - do we need new constraint? */
5210 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5211 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5212 if (GET_CODE (operands[2]) == CONST_INT
5213 /* Avoid overflows. */
5214 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5215 && (INTVAL (operands[2]) == 128
5216 || (INTVAL (operands[2]) < 0
5217 && INTVAL (operands[2]) != -128)))
5218 {
5219 operands[2] = GEN_INT (-INTVAL (operands[2]));
5220 return "sub{q}\t{%2, %0|%0, %2}";
5221 }
5222 return "add{q}\t{%2, %0|%0, %2}";
5223 }
5224 }
5225 [(set (attr "type")
5226 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5227 (const_string "incdec")
5228 (const_string "alu")))
5229 (set_attr "mode" "DI")])
5230
5231 (define_insn "*adddi_3_rex64"
5232 [(set (reg FLAGS_REG)
5233 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5234 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5235 (clobber (match_scratch:DI 0 "=r"))]
5236 "TARGET_64BIT
5237 && ix86_match_ccmode (insn, CCZmode)
5238 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5239 /* Current assemblers are broken and do not allow @GOTOFF in
5240 ought but a memory context. */
5241 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5242 {
5243 switch (get_attr_type (insn))
5244 {
5245 case TYPE_INCDEC:
5246 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5247 if (operands[2] == const1_rtx)
5248 return "inc{q}\t%0";
5249 else
5250 {
5251 gcc_assert (operands[2] == constm1_rtx);
5252 return "dec{q}\t%0";
5253 }
5254
5255 default:
5256 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5257 /* ???? We ought to handle there the 32bit case too
5258 - do we need new constraint? */
5259 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5260 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5261 if (GET_CODE (operands[2]) == CONST_INT
5262 /* Avoid overflows. */
5263 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5264 && (INTVAL (operands[2]) == 128
5265 || (INTVAL (operands[2]) < 0
5266 && INTVAL (operands[2]) != -128)))
5267 {
5268 operands[2] = GEN_INT (-INTVAL (operands[2]));
5269 return "sub{q}\t{%2, %0|%0, %2}";
5270 }
5271 return "add{q}\t{%2, %0|%0, %2}";
5272 }
5273 }
5274 [(set (attr "type")
5275 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5276 (const_string "incdec")
5277 (const_string "alu")))
5278 (set_attr "mode" "DI")])
5279
5280 ; For comparisons against 1, -1 and 128, we may generate better code
5281 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5282 ; is matched then. We can't accept general immediate, because for
5283 ; case of overflows, the result is messed up.
5284 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5285 ; when negated.
5286 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5287 ; only for comparisons not depending on it.
5288 (define_insn "*adddi_4_rex64"
5289 [(set (reg FLAGS_REG)
5290 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5291 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5292 (clobber (match_scratch:DI 0 "=rm"))]
5293 "TARGET_64BIT
5294 && ix86_match_ccmode (insn, CCGCmode)"
5295 {
5296 switch (get_attr_type (insn))
5297 {
5298 case TYPE_INCDEC:
5299 if (operands[2] == constm1_rtx)
5300 return "inc{q}\t%0";
5301 else
5302 {
5303 gcc_assert (operands[2] == const1_rtx);
5304 return "dec{q}\t%0";
5305 }
5306
5307 default:
5308 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5309 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5310 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5311 if ((INTVAL (operands[2]) == -128
5312 || (INTVAL (operands[2]) > 0
5313 && INTVAL (operands[2]) != 128))
5314 /* Avoid overflows. */
5315 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5316 return "sub{q}\t{%2, %0|%0, %2}";
5317 operands[2] = GEN_INT (-INTVAL (operands[2]));
5318 return "add{q}\t{%2, %0|%0, %2}";
5319 }
5320 }
5321 [(set (attr "type")
5322 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5323 (const_string "incdec")
5324 (const_string "alu")))
5325 (set_attr "mode" "DI")])
5326
5327 (define_insn "*adddi_5_rex64"
5328 [(set (reg FLAGS_REG)
5329 (compare
5330 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5331 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5332 (const_int 0)))
5333 (clobber (match_scratch:DI 0 "=r"))]
5334 "TARGET_64BIT
5335 && ix86_match_ccmode (insn, CCGOCmode)
5336 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5337 /* Current assemblers are broken and do not allow @GOTOFF in
5338 ought but a memory context. */
5339 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5340 {
5341 switch (get_attr_type (insn))
5342 {
5343 case TYPE_INCDEC:
5344 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5345 if (operands[2] == const1_rtx)
5346 return "inc{q}\t%0";
5347 else
5348 {
5349 gcc_assert (operands[2] == constm1_rtx);
5350 return "dec{q}\t%0";
5351 }
5352
5353 default:
5354 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5355 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5356 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5357 if (GET_CODE (operands[2]) == CONST_INT
5358 /* Avoid overflows. */
5359 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5360 && (INTVAL (operands[2]) == 128
5361 || (INTVAL (operands[2]) < 0
5362 && INTVAL (operands[2]) != -128)))
5363 {
5364 operands[2] = GEN_INT (-INTVAL (operands[2]));
5365 return "sub{q}\t{%2, %0|%0, %2}";
5366 }
5367 return "add{q}\t{%2, %0|%0, %2}";
5368 }
5369 }
5370 [(set (attr "type")
5371 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5372 (const_string "incdec")
5373 (const_string "alu")))
5374 (set_attr "mode" "DI")])
5375
5376
5377 (define_insn "*addsi_1"
5378 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5379 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5380 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5381 (clobber (reg:CC FLAGS_REG))]
5382 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5383 {
5384 switch (get_attr_type (insn))
5385 {
5386 case TYPE_LEA:
5387 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5388 return "lea{l}\t{%a2, %0|%0, %a2}";
5389
5390 case TYPE_INCDEC:
5391 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5392 if (operands[2] == const1_rtx)
5393 return "inc{l}\t%0";
5394 else
5395 {
5396 gcc_assert (operands[2] == constm1_rtx);
5397 return "dec{l}\t%0";
5398 }
5399
5400 default:
5401 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5402
5403 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5404 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5405 if (GET_CODE (operands[2]) == CONST_INT
5406 && (INTVAL (operands[2]) == 128
5407 || (INTVAL (operands[2]) < 0
5408 && INTVAL (operands[2]) != -128)))
5409 {
5410 operands[2] = GEN_INT (-INTVAL (operands[2]));
5411 return "sub{l}\t{%2, %0|%0, %2}";
5412 }
5413 return "add{l}\t{%2, %0|%0, %2}";
5414 }
5415 }
5416 [(set (attr "type")
5417 (cond [(eq_attr "alternative" "2")
5418 (const_string "lea")
5419 ; Current assemblers are broken and do not allow @GOTOFF in
5420 ; ought but a memory context.
5421 (match_operand:SI 2 "pic_symbolic_operand" "")
5422 (const_string "lea")
5423 (match_operand:SI 2 "incdec_operand" "")
5424 (const_string "incdec")
5425 ]
5426 (const_string "alu")))
5427 (set_attr "mode" "SI")])
5428
5429 ;; Convert lea to the lea pattern to avoid flags dependency.
5430 (define_split
5431 [(set (match_operand 0 "register_operand" "")
5432 (plus (match_operand 1 "register_operand" "")
5433 (match_operand 2 "nonmemory_operand" "")))
5434 (clobber (reg:CC FLAGS_REG))]
5435 "reload_completed
5436 && true_regnum (operands[0]) != true_regnum (operands[1])"
5437 [(const_int 0)]
5438 {
5439 rtx pat;
5440 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5441 may confuse gen_lowpart. */
5442 if (GET_MODE (operands[0]) != Pmode)
5443 {
5444 operands[1] = gen_lowpart (Pmode, operands[1]);
5445 operands[2] = gen_lowpart (Pmode, operands[2]);
5446 }
5447 operands[0] = gen_lowpart (SImode, operands[0]);
5448 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5449 if (Pmode != SImode)
5450 pat = gen_rtx_SUBREG (SImode, pat, 0);
5451 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5452 DONE;
5453 })
5454
5455 ;; It may seem that nonimmediate operand is proper one for operand 1.
5456 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5457 ;; we take care in ix86_binary_operator_ok to not allow two memory
5458 ;; operands so proper swapping will be done in reload. This allow
5459 ;; patterns constructed from addsi_1 to match.
5460 (define_insn "addsi_1_zext"
5461 [(set (match_operand:DI 0 "register_operand" "=r,r")
5462 (zero_extend:DI
5463 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5464 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5465 (clobber (reg:CC FLAGS_REG))]
5466 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5467 {
5468 switch (get_attr_type (insn))
5469 {
5470 case TYPE_LEA:
5471 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5472 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5473
5474 case TYPE_INCDEC:
5475 if (operands[2] == const1_rtx)
5476 return "inc{l}\t%k0";
5477 else
5478 {
5479 gcc_assert (operands[2] == constm1_rtx);
5480 return "dec{l}\t%k0";
5481 }
5482
5483 default:
5484 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5485 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5486 if (GET_CODE (operands[2]) == CONST_INT
5487 && (INTVAL (operands[2]) == 128
5488 || (INTVAL (operands[2]) < 0
5489 && INTVAL (operands[2]) != -128)))
5490 {
5491 operands[2] = GEN_INT (-INTVAL (operands[2]));
5492 return "sub{l}\t{%2, %k0|%k0, %2}";
5493 }
5494 return "add{l}\t{%2, %k0|%k0, %2}";
5495 }
5496 }
5497 [(set (attr "type")
5498 (cond [(eq_attr "alternative" "1")
5499 (const_string "lea")
5500 ; Current assemblers are broken and do not allow @GOTOFF in
5501 ; ought but a memory context.
5502 (match_operand:SI 2 "pic_symbolic_operand" "")
5503 (const_string "lea")
5504 (match_operand:SI 2 "incdec_operand" "")
5505 (const_string "incdec")
5506 ]
5507 (const_string "alu")))
5508 (set_attr "mode" "SI")])
5509
5510 ;; Convert lea to the lea pattern to avoid flags dependency.
5511 (define_split
5512 [(set (match_operand:DI 0 "register_operand" "")
5513 (zero_extend:DI
5514 (plus:SI (match_operand:SI 1 "register_operand" "")
5515 (match_operand:SI 2 "nonmemory_operand" ""))))
5516 (clobber (reg:CC FLAGS_REG))]
5517 "TARGET_64BIT && reload_completed
5518 && true_regnum (operands[0]) != true_regnum (operands[1])"
5519 [(set (match_dup 0)
5520 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5521 {
5522 operands[1] = gen_lowpart (Pmode, operands[1]);
5523 operands[2] = gen_lowpart (Pmode, operands[2]);
5524 })
5525
5526 (define_insn "*addsi_2"
5527 [(set (reg FLAGS_REG)
5528 (compare
5529 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5530 (match_operand:SI 2 "general_operand" "rmni,rni"))
5531 (const_int 0)))
5532 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5533 (plus:SI (match_dup 1) (match_dup 2)))]
5534 "ix86_match_ccmode (insn, CCGOCmode)
5535 && ix86_binary_operator_ok (PLUS, SImode, operands)
5536 /* Current assemblers are broken and do not allow @GOTOFF in
5537 ought but a memory context. */
5538 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5539 {
5540 switch (get_attr_type (insn))
5541 {
5542 case TYPE_INCDEC:
5543 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5544 if (operands[2] == const1_rtx)
5545 return "inc{l}\t%0";
5546 else
5547 {
5548 gcc_assert (operands[2] == constm1_rtx);
5549 return "dec{l}\t%0";
5550 }
5551
5552 default:
5553 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5554 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5555 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5556 if (GET_CODE (operands[2]) == CONST_INT
5557 && (INTVAL (operands[2]) == 128
5558 || (INTVAL (operands[2]) < 0
5559 && INTVAL (operands[2]) != -128)))
5560 {
5561 operands[2] = GEN_INT (-INTVAL (operands[2]));
5562 return "sub{l}\t{%2, %0|%0, %2}";
5563 }
5564 return "add{l}\t{%2, %0|%0, %2}";
5565 }
5566 }
5567 [(set (attr "type")
5568 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5569 (const_string "incdec")
5570 (const_string "alu")))
5571 (set_attr "mode" "SI")])
5572
5573 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5574 (define_insn "*addsi_2_zext"
5575 [(set (reg FLAGS_REG)
5576 (compare
5577 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5578 (match_operand:SI 2 "general_operand" "rmni"))
5579 (const_int 0)))
5580 (set (match_operand:DI 0 "register_operand" "=r")
5581 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5582 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5583 && ix86_binary_operator_ok (PLUS, SImode, operands)
5584 /* Current assemblers are broken and do not allow @GOTOFF in
5585 ought but a memory context. */
5586 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5587 {
5588 switch (get_attr_type (insn))
5589 {
5590 case TYPE_INCDEC:
5591 if (operands[2] == const1_rtx)
5592 return "inc{l}\t%k0";
5593 else
5594 {
5595 gcc_assert (operands[2] == constm1_rtx);
5596 return "dec{l}\t%k0";
5597 }
5598
5599 default:
5600 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5601 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5602 if (GET_CODE (operands[2]) == CONST_INT
5603 && (INTVAL (operands[2]) == 128
5604 || (INTVAL (operands[2]) < 0
5605 && INTVAL (operands[2]) != -128)))
5606 {
5607 operands[2] = GEN_INT (-INTVAL (operands[2]));
5608 return "sub{l}\t{%2, %k0|%k0, %2}";
5609 }
5610 return "add{l}\t{%2, %k0|%k0, %2}";
5611 }
5612 }
5613 [(set (attr "type")
5614 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5615 (const_string "incdec")
5616 (const_string "alu")))
5617 (set_attr "mode" "SI")])
5618
5619 (define_insn "*addsi_3"
5620 [(set (reg FLAGS_REG)
5621 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5622 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5623 (clobber (match_scratch:SI 0 "=r"))]
5624 "ix86_match_ccmode (insn, CCZmode)
5625 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5626 /* Current assemblers are broken and do not allow @GOTOFF in
5627 ought but a memory context. */
5628 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5629 {
5630 switch (get_attr_type (insn))
5631 {
5632 case TYPE_INCDEC:
5633 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634 if (operands[2] == const1_rtx)
5635 return "inc{l}\t%0";
5636 else
5637 {
5638 gcc_assert (operands[2] == constm1_rtx);
5639 return "dec{l}\t%0";
5640 }
5641
5642 default:
5643 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5645 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5646 if (GET_CODE (operands[2]) == CONST_INT
5647 && (INTVAL (operands[2]) == 128
5648 || (INTVAL (operands[2]) < 0
5649 && INTVAL (operands[2]) != -128)))
5650 {
5651 operands[2] = GEN_INT (-INTVAL (operands[2]));
5652 return "sub{l}\t{%2, %0|%0, %2}";
5653 }
5654 return "add{l}\t{%2, %0|%0, %2}";
5655 }
5656 }
5657 [(set (attr "type")
5658 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5659 (const_string "incdec")
5660 (const_string "alu")))
5661 (set_attr "mode" "SI")])
5662
5663 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5664 (define_insn "*addsi_3_zext"
5665 [(set (reg FLAGS_REG)
5666 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5667 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5668 (set (match_operand:DI 0 "register_operand" "=r")
5669 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5670 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5671 && ix86_binary_operator_ok (PLUS, SImode, operands)
5672 /* Current assemblers are broken and do not allow @GOTOFF in
5673 ought but a memory context. */
5674 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5675 {
5676 switch (get_attr_type (insn))
5677 {
5678 case TYPE_INCDEC:
5679 if (operands[2] == const1_rtx)
5680 return "inc{l}\t%k0";
5681 else
5682 {
5683 gcc_assert (operands[2] == constm1_rtx);
5684 return "dec{l}\t%k0";
5685 }
5686
5687 default:
5688 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5689 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5690 if (GET_CODE (operands[2]) == CONST_INT
5691 && (INTVAL (operands[2]) == 128
5692 || (INTVAL (operands[2]) < 0
5693 && INTVAL (operands[2]) != -128)))
5694 {
5695 operands[2] = GEN_INT (-INTVAL (operands[2]));
5696 return "sub{l}\t{%2, %k0|%k0, %2}";
5697 }
5698 return "add{l}\t{%2, %k0|%k0, %2}";
5699 }
5700 }
5701 [(set (attr "type")
5702 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5703 (const_string "incdec")
5704 (const_string "alu")))
5705 (set_attr "mode" "SI")])
5706
5707 ; For comparisons against 1, -1 and 128, we may generate better code
5708 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5709 ; is matched then. We can't accept general immediate, because for
5710 ; case of overflows, the result is messed up.
5711 ; This pattern also don't hold of 0x80000000, since the value overflows
5712 ; when negated.
5713 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5714 ; only for comparisons not depending on it.
5715 (define_insn "*addsi_4"
5716 [(set (reg FLAGS_REG)
5717 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5718 (match_operand:SI 2 "const_int_operand" "n")))
5719 (clobber (match_scratch:SI 0 "=rm"))]
5720 "ix86_match_ccmode (insn, CCGCmode)
5721 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5722 {
5723 switch (get_attr_type (insn))
5724 {
5725 case TYPE_INCDEC:
5726 if (operands[2] == constm1_rtx)
5727 return "inc{l}\t%0";
5728 else
5729 {
5730 gcc_assert (operands[2] == const1_rtx);
5731 return "dec{l}\t%0";
5732 }
5733
5734 default:
5735 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5737 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5738 if ((INTVAL (operands[2]) == -128
5739 || (INTVAL (operands[2]) > 0
5740 && INTVAL (operands[2]) != 128)))
5741 return "sub{l}\t{%2, %0|%0, %2}";
5742 operands[2] = GEN_INT (-INTVAL (operands[2]));
5743 return "add{l}\t{%2, %0|%0, %2}";
5744 }
5745 }
5746 [(set (attr "type")
5747 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5748 (const_string "incdec")
5749 (const_string "alu")))
5750 (set_attr "mode" "SI")])
5751
5752 (define_insn "*addsi_5"
5753 [(set (reg FLAGS_REG)
5754 (compare
5755 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5756 (match_operand:SI 2 "general_operand" "rmni"))
5757 (const_int 0)))
5758 (clobber (match_scratch:SI 0 "=r"))]
5759 "ix86_match_ccmode (insn, CCGOCmode)
5760 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5761 /* Current assemblers are broken and do not allow @GOTOFF in
5762 ought but a memory context. */
5763 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5764 {
5765 switch (get_attr_type (insn))
5766 {
5767 case TYPE_INCDEC:
5768 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5769 if (operands[2] == const1_rtx)
5770 return "inc{l}\t%0";
5771 else
5772 {
5773 gcc_assert (operands[2] == constm1_rtx);
5774 return "dec{l}\t%0";
5775 }
5776
5777 default:
5778 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5779 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5780 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5781 if (GET_CODE (operands[2]) == CONST_INT
5782 && (INTVAL (operands[2]) == 128
5783 || (INTVAL (operands[2]) < 0
5784 && INTVAL (operands[2]) != -128)))
5785 {
5786 operands[2] = GEN_INT (-INTVAL (operands[2]));
5787 return "sub{l}\t{%2, %0|%0, %2}";
5788 }
5789 return "add{l}\t{%2, %0|%0, %2}";
5790 }
5791 }
5792 [(set (attr "type")
5793 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5794 (const_string "incdec")
5795 (const_string "alu")))
5796 (set_attr "mode" "SI")])
5797
5798 (define_expand "addhi3"
5799 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5800 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5801 (match_operand:HI 2 "general_operand" "")))
5802 (clobber (reg:CC FLAGS_REG))])]
5803 "TARGET_HIMODE_MATH"
5804 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5805
5806 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5807 ;; type optimizations enabled by define-splits. This is not important
5808 ;; for PII, and in fact harmful because of partial register stalls.
5809
5810 (define_insn "*addhi_1_lea"
5811 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5812 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5813 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5814 (clobber (reg:CC FLAGS_REG))]
5815 "!TARGET_PARTIAL_REG_STALL
5816 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5817 {
5818 switch (get_attr_type (insn))
5819 {
5820 case TYPE_LEA:
5821 return "#";
5822 case TYPE_INCDEC:
5823 if (operands[2] == const1_rtx)
5824 return "inc{w}\t%0";
5825 else
5826 {
5827 gcc_assert (operands[2] == constm1_rtx);
5828 return "dec{w}\t%0";
5829 }
5830
5831 default:
5832 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5833 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5834 if (GET_CODE (operands[2]) == CONST_INT
5835 && (INTVAL (operands[2]) == 128
5836 || (INTVAL (operands[2]) < 0
5837 && INTVAL (operands[2]) != -128)))
5838 {
5839 operands[2] = GEN_INT (-INTVAL (operands[2]));
5840 return "sub{w}\t{%2, %0|%0, %2}";
5841 }
5842 return "add{w}\t{%2, %0|%0, %2}";
5843 }
5844 }
5845 [(set (attr "type")
5846 (if_then_else (eq_attr "alternative" "2")
5847 (const_string "lea")
5848 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5849 (const_string "incdec")
5850 (const_string "alu"))))
5851 (set_attr "mode" "HI,HI,SI")])
5852
5853 (define_insn "*addhi_1"
5854 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5855 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5856 (match_operand:HI 2 "general_operand" "ri,rm")))
5857 (clobber (reg:CC FLAGS_REG))]
5858 "TARGET_PARTIAL_REG_STALL
5859 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5860 {
5861 switch (get_attr_type (insn))
5862 {
5863 case TYPE_INCDEC:
5864 if (operands[2] == const1_rtx)
5865 return "inc{w}\t%0";
5866 else
5867 {
5868 gcc_assert (operands[2] == constm1_rtx);
5869 return "dec{w}\t%0";
5870 }
5871
5872 default:
5873 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5875 if (GET_CODE (operands[2]) == CONST_INT
5876 && (INTVAL (operands[2]) == 128
5877 || (INTVAL (operands[2]) < 0
5878 && INTVAL (operands[2]) != -128)))
5879 {
5880 operands[2] = GEN_INT (-INTVAL (operands[2]));
5881 return "sub{w}\t{%2, %0|%0, %2}";
5882 }
5883 return "add{w}\t{%2, %0|%0, %2}";
5884 }
5885 }
5886 [(set (attr "type")
5887 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5888 (const_string "incdec")
5889 (const_string "alu")))
5890 (set_attr "mode" "HI")])
5891
5892 (define_insn "*addhi_2"
5893 [(set (reg FLAGS_REG)
5894 (compare
5895 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896 (match_operand:HI 2 "general_operand" "rmni,rni"))
5897 (const_int 0)))
5898 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5899 (plus:HI (match_dup 1) (match_dup 2)))]
5900 "ix86_match_ccmode (insn, CCGOCmode)
5901 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5902 {
5903 switch (get_attr_type (insn))
5904 {
5905 case TYPE_INCDEC:
5906 if (operands[2] == const1_rtx)
5907 return "inc{w}\t%0";
5908 else
5909 {
5910 gcc_assert (operands[2] == constm1_rtx);
5911 return "dec{w}\t%0";
5912 }
5913
5914 default:
5915 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5917 if (GET_CODE (operands[2]) == CONST_INT
5918 && (INTVAL (operands[2]) == 128
5919 || (INTVAL (operands[2]) < 0
5920 && INTVAL (operands[2]) != -128)))
5921 {
5922 operands[2] = GEN_INT (-INTVAL (operands[2]));
5923 return "sub{w}\t{%2, %0|%0, %2}";
5924 }
5925 return "add{w}\t{%2, %0|%0, %2}";
5926 }
5927 }
5928 [(set (attr "type")
5929 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5930 (const_string "incdec")
5931 (const_string "alu")))
5932 (set_attr "mode" "HI")])
5933
5934 (define_insn "*addhi_3"
5935 [(set (reg FLAGS_REG)
5936 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5937 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5938 (clobber (match_scratch:HI 0 "=r"))]
5939 "ix86_match_ccmode (insn, CCZmode)
5940 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5941 {
5942 switch (get_attr_type (insn))
5943 {
5944 case TYPE_INCDEC:
5945 if (operands[2] == const1_rtx)
5946 return "inc{w}\t%0";
5947 else
5948 {
5949 gcc_assert (operands[2] == constm1_rtx);
5950 return "dec{w}\t%0";
5951 }
5952
5953 default:
5954 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5955 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5956 if (GET_CODE (operands[2]) == CONST_INT
5957 && (INTVAL (operands[2]) == 128
5958 || (INTVAL (operands[2]) < 0
5959 && INTVAL (operands[2]) != -128)))
5960 {
5961 operands[2] = GEN_INT (-INTVAL (operands[2]));
5962 return "sub{w}\t{%2, %0|%0, %2}";
5963 }
5964 return "add{w}\t{%2, %0|%0, %2}";
5965 }
5966 }
5967 [(set (attr "type")
5968 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5969 (const_string "incdec")
5970 (const_string "alu")))
5971 (set_attr "mode" "HI")])
5972
5973 ; See comments above addsi_4 for details.
5974 (define_insn "*addhi_4"
5975 [(set (reg FLAGS_REG)
5976 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5977 (match_operand:HI 2 "const_int_operand" "n")))
5978 (clobber (match_scratch:HI 0 "=rm"))]
5979 "ix86_match_ccmode (insn, CCGCmode)
5980 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5981 {
5982 switch (get_attr_type (insn))
5983 {
5984 case TYPE_INCDEC:
5985 if (operands[2] == constm1_rtx)
5986 return "inc{w}\t%0";
5987 else
5988 {
5989 gcc_assert (operands[2] == const1_rtx);
5990 return "dec{w}\t%0";
5991 }
5992
5993 default:
5994 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5995 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5996 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5997 if ((INTVAL (operands[2]) == -128
5998 || (INTVAL (operands[2]) > 0
5999 && INTVAL (operands[2]) != 128)))
6000 return "sub{w}\t{%2, %0|%0, %2}";
6001 operands[2] = GEN_INT (-INTVAL (operands[2]));
6002 return "add{w}\t{%2, %0|%0, %2}";
6003 }
6004 }
6005 [(set (attr "type")
6006 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6007 (const_string "incdec")
6008 (const_string "alu")))
6009 (set_attr "mode" "SI")])
6010
6011
6012 (define_insn "*addhi_5"
6013 [(set (reg FLAGS_REG)
6014 (compare
6015 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6016 (match_operand:HI 2 "general_operand" "rmni"))
6017 (const_int 0)))
6018 (clobber (match_scratch:HI 0 "=r"))]
6019 "ix86_match_ccmode (insn, CCGOCmode)
6020 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6021 {
6022 switch (get_attr_type (insn))
6023 {
6024 case TYPE_INCDEC:
6025 if (operands[2] == const1_rtx)
6026 return "inc{w}\t%0";
6027 else
6028 {
6029 gcc_assert (operands[2] == constm1_rtx);
6030 return "dec{w}\t%0";
6031 }
6032
6033 default:
6034 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6035 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6036 if (GET_CODE (operands[2]) == CONST_INT
6037 && (INTVAL (operands[2]) == 128
6038 || (INTVAL (operands[2]) < 0
6039 && INTVAL (operands[2]) != -128)))
6040 {
6041 operands[2] = GEN_INT (-INTVAL (operands[2]));
6042 return "sub{w}\t{%2, %0|%0, %2}";
6043 }
6044 return "add{w}\t{%2, %0|%0, %2}";
6045 }
6046 }
6047 [(set (attr "type")
6048 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6049 (const_string "incdec")
6050 (const_string "alu")))
6051 (set_attr "mode" "HI")])
6052
6053 (define_expand "addqi3"
6054 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6055 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6056 (match_operand:QI 2 "general_operand" "")))
6057 (clobber (reg:CC FLAGS_REG))])]
6058 "TARGET_QIMODE_MATH"
6059 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6060
6061 ;; %%% Potential partial reg stall on alternative 2. What to do?
6062 (define_insn "*addqi_1_lea"
6063 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6064 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6065 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6066 (clobber (reg:CC FLAGS_REG))]
6067 "!TARGET_PARTIAL_REG_STALL
6068 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6069 {
6070 int widen = (which_alternative == 2);
6071 switch (get_attr_type (insn))
6072 {
6073 case TYPE_LEA:
6074 return "#";
6075 case TYPE_INCDEC:
6076 if (operands[2] == const1_rtx)
6077 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6078 else
6079 {
6080 gcc_assert (operands[2] == constm1_rtx);
6081 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6082 }
6083
6084 default:
6085 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6087 if (GET_CODE (operands[2]) == CONST_INT
6088 && (INTVAL (operands[2]) == 128
6089 || (INTVAL (operands[2]) < 0
6090 && INTVAL (operands[2]) != -128)))
6091 {
6092 operands[2] = GEN_INT (-INTVAL (operands[2]));
6093 if (widen)
6094 return "sub{l}\t{%2, %k0|%k0, %2}";
6095 else
6096 return "sub{b}\t{%2, %0|%0, %2}";
6097 }
6098 if (widen)
6099 return "add{l}\t{%k2, %k0|%k0, %k2}";
6100 else
6101 return "add{b}\t{%2, %0|%0, %2}";
6102 }
6103 }
6104 [(set (attr "type")
6105 (if_then_else (eq_attr "alternative" "3")
6106 (const_string "lea")
6107 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6108 (const_string "incdec")
6109 (const_string "alu"))))
6110 (set_attr "mode" "QI,QI,SI,SI")])
6111
6112 (define_insn "*addqi_1"
6113 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6114 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6115 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6116 (clobber (reg:CC FLAGS_REG))]
6117 "TARGET_PARTIAL_REG_STALL
6118 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6119 {
6120 int widen = (which_alternative == 2);
6121 switch (get_attr_type (insn))
6122 {
6123 case TYPE_INCDEC:
6124 if (operands[2] == const1_rtx)
6125 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6126 else
6127 {
6128 gcc_assert (operands[2] == constm1_rtx);
6129 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6130 }
6131
6132 default:
6133 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6134 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6135 if (GET_CODE (operands[2]) == CONST_INT
6136 && (INTVAL (operands[2]) == 128
6137 || (INTVAL (operands[2]) < 0
6138 && INTVAL (operands[2]) != -128)))
6139 {
6140 operands[2] = GEN_INT (-INTVAL (operands[2]));
6141 if (widen)
6142 return "sub{l}\t{%2, %k0|%k0, %2}";
6143 else
6144 return "sub{b}\t{%2, %0|%0, %2}";
6145 }
6146 if (widen)
6147 return "add{l}\t{%k2, %k0|%k0, %k2}";
6148 else
6149 return "add{b}\t{%2, %0|%0, %2}";
6150 }
6151 }
6152 [(set (attr "type")
6153 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6154 (const_string "incdec")
6155 (const_string "alu")))
6156 (set_attr "mode" "QI,QI,SI")])
6157
6158 (define_insn "*addqi_1_slp"
6159 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6160 (plus:QI (match_dup 0)
6161 (match_operand:QI 1 "general_operand" "qn,qnm")))
6162 (clobber (reg:CC FLAGS_REG))]
6163 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6164 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6165 {
6166 switch (get_attr_type (insn))
6167 {
6168 case TYPE_INCDEC:
6169 if (operands[1] == const1_rtx)
6170 return "inc{b}\t%0";
6171 else
6172 {
6173 gcc_assert (operands[1] == constm1_rtx);
6174 return "dec{b}\t%0";
6175 }
6176
6177 default:
6178 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6179 if (GET_CODE (operands[1]) == CONST_INT
6180 && INTVAL (operands[1]) < 0)
6181 {
6182 operands[1] = GEN_INT (-INTVAL (operands[1]));
6183 return "sub{b}\t{%1, %0|%0, %1}";
6184 }
6185 return "add{b}\t{%1, %0|%0, %1}";
6186 }
6187 }
6188 [(set (attr "type")
6189 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6190 (const_string "incdec")
6191 (const_string "alu1")))
6192 (set (attr "memory")
6193 (if_then_else (match_operand 1 "memory_operand" "")
6194 (const_string "load")
6195 (const_string "none")))
6196 (set_attr "mode" "QI")])
6197
6198 (define_insn "*addqi_2"
6199 [(set (reg FLAGS_REG)
6200 (compare
6201 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6202 (match_operand:QI 2 "general_operand" "qmni,qni"))
6203 (const_int 0)))
6204 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6205 (plus:QI (match_dup 1) (match_dup 2)))]
6206 "ix86_match_ccmode (insn, CCGOCmode)
6207 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6208 {
6209 switch (get_attr_type (insn))
6210 {
6211 case TYPE_INCDEC:
6212 if (operands[2] == const1_rtx)
6213 return "inc{b}\t%0";
6214 else
6215 {
6216 gcc_assert (operands[2] == constm1_rtx
6217 || (GET_CODE (operands[2]) == CONST_INT
6218 && INTVAL (operands[2]) == 255));
6219 return "dec{b}\t%0";
6220 }
6221
6222 default:
6223 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6224 if (GET_CODE (operands[2]) == CONST_INT
6225 && INTVAL (operands[2]) < 0)
6226 {
6227 operands[2] = GEN_INT (-INTVAL (operands[2]));
6228 return "sub{b}\t{%2, %0|%0, %2}";
6229 }
6230 return "add{b}\t{%2, %0|%0, %2}";
6231 }
6232 }
6233 [(set (attr "type")
6234 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6235 (const_string "incdec")
6236 (const_string "alu")))
6237 (set_attr "mode" "QI")])
6238
6239 (define_insn "*addqi_3"
6240 [(set (reg FLAGS_REG)
6241 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6242 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6243 (clobber (match_scratch:QI 0 "=q"))]
6244 "ix86_match_ccmode (insn, CCZmode)
6245 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6246 {
6247 switch (get_attr_type (insn))
6248 {
6249 case TYPE_INCDEC:
6250 if (operands[2] == const1_rtx)
6251 return "inc{b}\t%0";
6252 else
6253 {
6254 gcc_assert (operands[2] == constm1_rtx
6255 || (GET_CODE (operands[2]) == CONST_INT
6256 && INTVAL (operands[2]) == 255));
6257 return "dec{b}\t%0";
6258 }
6259
6260 default:
6261 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6262 if (GET_CODE (operands[2]) == CONST_INT
6263 && INTVAL (operands[2]) < 0)
6264 {
6265 operands[2] = GEN_INT (-INTVAL (operands[2]));
6266 return "sub{b}\t{%2, %0|%0, %2}";
6267 }
6268 return "add{b}\t{%2, %0|%0, %2}";
6269 }
6270 }
6271 [(set (attr "type")
6272 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6273 (const_string "incdec")
6274 (const_string "alu")))
6275 (set_attr "mode" "QI")])
6276
6277 ; See comments above addsi_4 for details.
6278 (define_insn "*addqi_4"
6279 [(set (reg FLAGS_REG)
6280 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6281 (match_operand:QI 2 "const_int_operand" "n")))
6282 (clobber (match_scratch:QI 0 "=qm"))]
6283 "ix86_match_ccmode (insn, CCGCmode)
6284 && (INTVAL (operands[2]) & 0xff) != 0x80"
6285 {
6286 switch (get_attr_type (insn))
6287 {
6288 case TYPE_INCDEC:
6289 if (operands[2] == constm1_rtx
6290 || (GET_CODE (operands[2]) == CONST_INT
6291 && INTVAL (operands[2]) == 255))
6292 return "inc{b}\t%0";
6293 else
6294 {
6295 gcc_assert (operands[2] == const1_rtx);
6296 return "dec{b}\t%0";
6297 }
6298
6299 default:
6300 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6301 if (INTVAL (operands[2]) < 0)
6302 {
6303 operands[2] = GEN_INT (-INTVAL (operands[2]));
6304 return "add{b}\t{%2, %0|%0, %2}";
6305 }
6306 return "sub{b}\t{%2, %0|%0, %2}";
6307 }
6308 }
6309 [(set (attr "type")
6310 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6311 (const_string "incdec")
6312 (const_string "alu")))
6313 (set_attr "mode" "QI")])
6314
6315
6316 (define_insn "*addqi_5"
6317 [(set (reg FLAGS_REG)
6318 (compare
6319 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6320 (match_operand:QI 2 "general_operand" "qmni"))
6321 (const_int 0)))
6322 (clobber (match_scratch:QI 0 "=q"))]
6323 "ix86_match_ccmode (insn, CCGOCmode)
6324 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6325 {
6326 switch (get_attr_type (insn))
6327 {
6328 case TYPE_INCDEC:
6329 if (operands[2] == const1_rtx)
6330 return "inc{b}\t%0";
6331 else
6332 {
6333 gcc_assert (operands[2] == constm1_rtx
6334 || (GET_CODE (operands[2]) == CONST_INT
6335 && INTVAL (operands[2]) == 255));
6336 return "dec{b}\t%0";
6337 }
6338
6339 default:
6340 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6341 if (GET_CODE (operands[2]) == CONST_INT
6342 && INTVAL (operands[2]) < 0)
6343 {
6344 operands[2] = GEN_INT (-INTVAL (operands[2]));
6345 return "sub{b}\t{%2, %0|%0, %2}";
6346 }
6347 return "add{b}\t{%2, %0|%0, %2}";
6348 }
6349 }
6350 [(set (attr "type")
6351 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352 (const_string "incdec")
6353 (const_string "alu")))
6354 (set_attr "mode" "QI")])
6355
6356
6357 (define_insn "addqi_ext_1"
6358 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6359 (const_int 8)
6360 (const_int 8))
6361 (plus:SI
6362 (zero_extract:SI
6363 (match_operand 1 "ext_register_operand" "0")
6364 (const_int 8)
6365 (const_int 8))
6366 (match_operand:QI 2 "general_operand" "Qmn")))
6367 (clobber (reg:CC FLAGS_REG))]
6368 "!TARGET_64BIT"
6369 {
6370 switch (get_attr_type (insn))
6371 {
6372 case TYPE_INCDEC:
6373 if (operands[2] == const1_rtx)
6374 return "inc{b}\t%h0";
6375 else
6376 {
6377 gcc_assert (operands[2] == constm1_rtx
6378 || (GET_CODE (operands[2]) == CONST_INT
6379 && INTVAL (operands[2]) == 255));
6380 return "dec{b}\t%h0";
6381 }
6382
6383 default:
6384 return "add{b}\t{%2, %h0|%h0, %2}";
6385 }
6386 }
6387 [(set (attr "type")
6388 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389 (const_string "incdec")
6390 (const_string "alu")))
6391 (set_attr "mode" "QI")])
6392
6393 (define_insn "*addqi_ext_1_rex64"
6394 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6395 (const_int 8)
6396 (const_int 8))
6397 (plus:SI
6398 (zero_extract:SI
6399 (match_operand 1 "ext_register_operand" "0")
6400 (const_int 8)
6401 (const_int 8))
6402 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6403 (clobber (reg:CC FLAGS_REG))]
6404 "TARGET_64BIT"
6405 {
6406 switch (get_attr_type (insn))
6407 {
6408 case TYPE_INCDEC:
6409 if (operands[2] == const1_rtx)
6410 return "inc{b}\t%h0";
6411 else
6412 {
6413 gcc_assert (operands[2] == constm1_rtx
6414 || (GET_CODE (operands[2]) == CONST_INT
6415 && INTVAL (operands[2]) == 255));
6416 return "dec{b}\t%h0";
6417 }
6418
6419 default:
6420 return "add{b}\t{%2, %h0|%h0, %2}";
6421 }
6422 }
6423 [(set (attr "type")
6424 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6425 (const_string "incdec")
6426 (const_string "alu")))
6427 (set_attr "mode" "QI")])
6428
6429 (define_insn "*addqi_ext_2"
6430 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6431 (const_int 8)
6432 (const_int 8))
6433 (plus:SI
6434 (zero_extract:SI
6435 (match_operand 1 "ext_register_operand" "%0")
6436 (const_int 8)
6437 (const_int 8))
6438 (zero_extract:SI
6439 (match_operand 2 "ext_register_operand" "Q")
6440 (const_int 8)
6441 (const_int 8))))
6442 (clobber (reg:CC FLAGS_REG))]
6443 ""
6444 "add{b}\t{%h2, %h0|%h0, %h2}"
6445 [(set_attr "type" "alu")
6446 (set_attr "mode" "QI")])
6447
6448 ;; The patterns that match these are at the end of this file.
6449
6450 (define_expand "addxf3"
6451 [(set (match_operand:XF 0 "register_operand" "")
6452 (plus:XF (match_operand:XF 1 "register_operand" "")
6453 (match_operand:XF 2 "register_operand" "")))]
6454 "TARGET_80387"
6455 "")
6456
6457 (define_expand "adddf3"
6458 [(set (match_operand:DF 0 "register_operand" "")
6459 (plus:DF (match_operand:DF 1 "register_operand" "")
6460 (match_operand:DF 2 "nonimmediate_operand" "")))]
6461 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6462 "")
6463
6464 (define_expand "addsf3"
6465 [(set (match_operand:SF 0 "register_operand" "")
6466 (plus:SF (match_operand:SF 1 "register_operand" "")
6467 (match_operand:SF 2 "nonimmediate_operand" "")))]
6468 "TARGET_80387 || TARGET_SSE_MATH"
6469 "")
6470 \f
6471 ;; Subtract instructions
6472
6473 ;; %%% splits for subditi3
6474
6475 (define_expand "subti3"
6476 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6477 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6478 (match_operand:TI 2 "x86_64_general_operand" "")))
6479 (clobber (reg:CC FLAGS_REG))])]
6480 "TARGET_64BIT"
6481 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6482
6483 (define_insn "*subti3_1"
6484 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6485 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6486 (match_operand:TI 2 "general_operand" "roiF,riF")))
6487 (clobber (reg:CC FLAGS_REG))]
6488 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6489 "#")
6490
6491 (define_split
6492 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6493 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6494 (match_operand:TI 2 "general_operand" "")))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "TARGET_64BIT && reload_completed"
6497 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6498 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6499 (parallel [(set (match_dup 3)
6500 (minus:DI (match_dup 4)
6501 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6502 (match_dup 5))))
6503 (clobber (reg:CC FLAGS_REG))])]
6504 "split_ti (operands+0, 1, operands+0, operands+3);
6505 split_ti (operands+1, 1, operands+1, operands+4);
6506 split_ti (operands+2, 1, operands+2, operands+5);")
6507
6508 ;; %%% splits for subsidi3
6509
6510 (define_expand "subdi3"
6511 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6512 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6513 (match_operand:DI 2 "x86_64_general_operand" "")))
6514 (clobber (reg:CC FLAGS_REG))])]
6515 ""
6516 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6517
6518 (define_insn "*subdi3_1"
6519 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6520 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6521 (match_operand:DI 2 "general_operand" "roiF,riF")))
6522 (clobber (reg:CC FLAGS_REG))]
6523 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6524 "#")
6525
6526 (define_split
6527 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6528 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6529 (match_operand:DI 2 "general_operand" "")))
6530 (clobber (reg:CC FLAGS_REG))]
6531 "!TARGET_64BIT && reload_completed"
6532 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6533 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6534 (parallel [(set (match_dup 3)
6535 (minus:SI (match_dup 4)
6536 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6537 (match_dup 5))))
6538 (clobber (reg:CC FLAGS_REG))])]
6539 "split_di (operands+0, 1, operands+0, operands+3);
6540 split_di (operands+1, 1, operands+1, operands+4);
6541 split_di (operands+2, 1, operands+2, operands+5);")
6542
6543 (define_insn "subdi3_carry_rex64"
6544 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6545 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6546 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6547 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6548 (clobber (reg:CC FLAGS_REG))]
6549 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6550 "sbb{q}\t{%2, %0|%0, %2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "pent_pair" "pu")
6553 (set_attr "mode" "DI")])
6554
6555 (define_insn "*subdi_1_rex64"
6556 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6557 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6558 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6559 (clobber (reg:CC FLAGS_REG))]
6560 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6561 "sub{q}\t{%2, %0|%0, %2}"
6562 [(set_attr "type" "alu")
6563 (set_attr "mode" "DI")])
6564
6565 (define_insn "*subdi_2_rex64"
6566 [(set (reg FLAGS_REG)
6567 (compare
6568 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6569 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6570 (const_int 0)))
6571 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6572 (minus:DI (match_dup 1) (match_dup 2)))]
6573 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6574 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6575 "sub{q}\t{%2, %0|%0, %2}"
6576 [(set_attr "type" "alu")
6577 (set_attr "mode" "DI")])
6578
6579 (define_insn "*subdi_3_rex63"
6580 [(set (reg FLAGS_REG)
6581 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6582 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6583 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6584 (minus:DI (match_dup 1) (match_dup 2)))]
6585 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6586 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6587 "sub{q}\t{%2, %0|%0, %2}"
6588 [(set_attr "type" "alu")
6589 (set_attr "mode" "DI")])
6590
6591 (define_insn "subqi3_carry"
6592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6593 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6594 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6595 (match_operand:QI 2 "general_operand" "qi,qm"))))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6598 "sbb{b}\t{%2, %0|%0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "pent_pair" "pu")
6601 (set_attr "mode" "QI")])
6602
6603 (define_insn "subhi3_carry"
6604 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6605 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6606 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6607 (match_operand:HI 2 "general_operand" "ri,rm"))))
6608 (clobber (reg:CC FLAGS_REG))]
6609 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6610 "sbb{w}\t{%2, %0|%0, %2}"
6611 [(set_attr "type" "alu")
6612 (set_attr "pent_pair" "pu")
6613 (set_attr "mode" "HI")])
6614
6615 (define_insn "subsi3_carry"
6616 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6618 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6619 (match_operand:SI 2 "general_operand" "ri,rm"))))
6620 (clobber (reg:CC FLAGS_REG))]
6621 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6622 "sbb{l}\t{%2, %0|%0, %2}"
6623 [(set_attr "type" "alu")
6624 (set_attr "pent_pair" "pu")
6625 (set_attr "mode" "SI")])
6626
6627 (define_insn "subsi3_carry_zext"
6628 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6629 (zero_extend:DI
6630 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6631 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6632 (match_operand:SI 2 "general_operand" "ri,rm")))))
6633 (clobber (reg:CC FLAGS_REG))]
6634 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6635 "sbb{l}\t{%2, %k0|%k0, %2}"
6636 [(set_attr "type" "alu")
6637 (set_attr "pent_pair" "pu")
6638 (set_attr "mode" "SI")])
6639
6640 (define_expand "subsi3"
6641 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6642 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6643 (match_operand:SI 2 "general_operand" "")))
6644 (clobber (reg:CC FLAGS_REG))])]
6645 ""
6646 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6647
6648 (define_insn "*subsi_1"
6649 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6650 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6651 (match_operand:SI 2 "general_operand" "ri,rm")))
6652 (clobber (reg:CC FLAGS_REG))]
6653 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6654 "sub{l}\t{%2, %0|%0, %2}"
6655 [(set_attr "type" "alu")
6656 (set_attr "mode" "SI")])
6657
6658 (define_insn "*subsi_1_zext"
6659 [(set (match_operand:DI 0 "register_operand" "=r")
6660 (zero_extend:DI
6661 (minus:SI (match_operand:SI 1 "register_operand" "0")
6662 (match_operand:SI 2 "general_operand" "rim"))))
6663 (clobber (reg:CC FLAGS_REG))]
6664 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6665 "sub{l}\t{%2, %k0|%k0, %2}"
6666 [(set_attr "type" "alu")
6667 (set_attr "mode" "SI")])
6668
6669 (define_insn "*subsi_2"
6670 [(set (reg FLAGS_REG)
6671 (compare
6672 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673 (match_operand:SI 2 "general_operand" "ri,rm"))
6674 (const_int 0)))
6675 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6676 (minus:SI (match_dup 1) (match_dup 2)))]
6677 "ix86_match_ccmode (insn, CCGOCmode)
6678 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6679 "sub{l}\t{%2, %0|%0, %2}"
6680 [(set_attr "type" "alu")
6681 (set_attr "mode" "SI")])
6682
6683 (define_insn "*subsi_2_zext"
6684 [(set (reg FLAGS_REG)
6685 (compare
6686 (minus:SI (match_operand:SI 1 "register_operand" "0")
6687 (match_operand:SI 2 "general_operand" "rim"))
6688 (const_int 0)))
6689 (set (match_operand:DI 0 "register_operand" "=r")
6690 (zero_extend:DI
6691 (minus:SI (match_dup 1)
6692 (match_dup 2))))]
6693 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6694 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6695 "sub{l}\t{%2, %k0|%k0, %2}"
6696 [(set_attr "type" "alu")
6697 (set_attr "mode" "SI")])
6698
6699 (define_insn "*subsi_3"
6700 [(set (reg FLAGS_REG)
6701 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6702 (match_operand:SI 2 "general_operand" "ri,rm")))
6703 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6704 (minus:SI (match_dup 1) (match_dup 2)))]
6705 "ix86_match_ccmode (insn, CCmode)
6706 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707 "sub{l}\t{%2, %0|%0, %2}"
6708 [(set_attr "type" "alu")
6709 (set_attr "mode" "SI")])
6710
6711 (define_insn "*subsi_3_zext"
6712 [(set (reg FLAGS_REG)
6713 (compare (match_operand:SI 1 "register_operand" "0")
6714 (match_operand:SI 2 "general_operand" "rim")))
6715 (set (match_operand:DI 0 "register_operand" "=r")
6716 (zero_extend:DI
6717 (minus:SI (match_dup 1)
6718 (match_dup 2))))]
6719 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6720 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721 "sub{q}\t{%2, %0|%0, %2}"
6722 [(set_attr "type" "alu")
6723 (set_attr "mode" "DI")])
6724
6725 (define_expand "subhi3"
6726 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6727 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6728 (match_operand:HI 2 "general_operand" "")))
6729 (clobber (reg:CC FLAGS_REG))])]
6730 "TARGET_HIMODE_MATH"
6731 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6732
6733 (define_insn "*subhi_1"
6734 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6735 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6736 (match_operand:HI 2 "general_operand" "ri,rm")))
6737 (clobber (reg:CC FLAGS_REG))]
6738 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6739 "sub{w}\t{%2, %0|%0, %2}"
6740 [(set_attr "type" "alu")
6741 (set_attr "mode" "HI")])
6742
6743 (define_insn "*subhi_2"
6744 [(set (reg FLAGS_REG)
6745 (compare
6746 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6747 (match_operand:HI 2 "general_operand" "ri,rm"))
6748 (const_int 0)))
6749 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6750 (minus:HI (match_dup 1) (match_dup 2)))]
6751 "ix86_match_ccmode (insn, CCGOCmode)
6752 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6753 "sub{w}\t{%2, %0|%0, %2}"
6754 [(set_attr "type" "alu")
6755 (set_attr "mode" "HI")])
6756
6757 (define_insn "*subhi_3"
6758 [(set (reg FLAGS_REG)
6759 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6760 (match_operand:HI 2 "general_operand" "ri,rm")))
6761 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6762 (minus:HI (match_dup 1) (match_dup 2)))]
6763 "ix86_match_ccmode (insn, CCmode)
6764 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6765 "sub{w}\t{%2, %0|%0, %2}"
6766 [(set_attr "type" "alu")
6767 (set_attr "mode" "HI")])
6768
6769 (define_expand "subqi3"
6770 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6771 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6772 (match_operand:QI 2 "general_operand" "")))
6773 (clobber (reg:CC FLAGS_REG))])]
6774 "TARGET_QIMODE_MATH"
6775 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6776
6777 (define_insn "*subqi_1"
6778 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6779 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6780 (match_operand:QI 2 "general_operand" "qn,qmn")))
6781 (clobber (reg:CC FLAGS_REG))]
6782 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6783 "sub{b}\t{%2, %0|%0, %2}"
6784 [(set_attr "type" "alu")
6785 (set_attr "mode" "QI")])
6786
6787 (define_insn "*subqi_1_slp"
6788 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6789 (minus:QI (match_dup 0)
6790 (match_operand:QI 1 "general_operand" "qn,qmn")))
6791 (clobber (reg:CC FLAGS_REG))]
6792 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6793 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6794 "sub{b}\t{%1, %0|%0, %1}"
6795 [(set_attr "type" "alu1")
6796 (set_attr "mode" "QI")])
6797
6798 (define_insn "*subqi_2"
6799 [(set (reg FLAGS_REG)
6800 (compare
6801 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6802 (match_operand:QI 2 "general_operand" "qi,qm"))
6803 (const_int 0)))
6804 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6805 (minus:HI (match_dup 1) (match_dup 2)))]
6806 "ix86_match_ccmode (insn, CCGOCmode)
6807 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6808 "sub{b}\t{%2, %0|%0, %2}"
6809 [(set_attr "type" "alu")
6810 (set_attr "mode" "QI")])
6811
6812 (define_insn "*subqi_3"
6813 [(set (reg FLAGS_REG)
6814 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6815 (match_operand:QI 2 "general_operand" "qi,qm")))
6816 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6817 (minus:HI (match_dup 1) (match_dup 2)))]
6818 "ix86_match_ccmode (insn, CCmode)
6819 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6820 "sub{b}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "mode" "QI")])
6823
6824 ;; The patterns that match these are at the end of this file.
6825
6826 (define_expand "subxf3"
6827 [(set (match_operand:XF 0 "register_operand" "")
6828 (minus:XF (match_operand:XF 1 "register_operand" "")
6829 (match_operand:XF 2 "register_operand" "")))]
6830 "TARGET_80387"
6831 "")
6832
6833 (define_expand "subdf3"
6834 [(set (match_operand:DF 0 "register_operand" "")
6835 (minus:DF (match_operand:DF 1 "register_operand" "")
6836 (match_operand:DF 2 "nonimmediate_operand" "")))]
6837 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6838 "")
6839
6840 (define_expand "subsf3"
6841 [(set (match_operand:SF 0 "register_operand" "")
6842 (minus:SF (match_operand:SF 1 "register_operand" "")
6843 (match_operand:SF 2 "nonimmediate_operand" "")))]
6844 "TARGET_80387 || TARGET_SSE_MATH"
6845 "")
6846 \f
6847 ;; Multiply instructions
6848
6849 (define_expand "muldi3"
6850 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6851 (mult:DI (match_operand:DI 1 "register_operand" "")
6852 (match_operand:DI 2 "x86_64_general_operand" "")))
6853 (clobber (reg:CC FLAGS_REG))])]
6854 "TARGET_64BIT"
6855 "")
6856
6857 (define_insn "*muldi3_1_rex64"
6858 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6859 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6860 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6861 (clobber (reg:CC FLAGS_REG))]
6862 "TARGET_64BIT
6863 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6864 "@
6865 imul{q}\t{%2, %1, %0|%0, %1, %2}
6866 imul{q}\t{%2, %1, %0|%0, %1, %2}
6867 imul{q}\t{%2, %0|%0, %2}"
6868 [(set_attr "type" "imul")
6869 (set_attr "prefix_0f" "0,0,1")
6870 (set (attr "athlon_decode")
6871 (cond [(eq_attr "cpu" "athlon")
6872 (const_string "vector")
6873 (eq_attr "alternative" "1")
6874 (const_string "vector")
6875 (and (eq_attr "alternative" "2")
6876 (match_operand 1 "memory_operand" ""))
6877 (const_string "vector")]
6878 (const_string "direct")))
6879 (set_attr "mode" "DI")])
6880
6881 (define_expand "mulsi3"
6882 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6883 (mult:SI (match_operand:SI 1 "register_operand" "")
6884 (match_operand:SI 2 "general_operand" "")))
6885 (clobber (reg:CC FLAGS_REG))])]
6886 ""
6887 "")
6888
6889 (define_insn "*mulsi3_1"
6890 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6891 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6892 (match_operand:SI 2 "general_operand" "K,i,mr")))
6893 (clobber (reg:CC FLAGS_REG))]
6894 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6895 "@
6896 imul{l}\t{%2, %1, %0|%0, %1, %2}
6897 imul{l}\t{%2, %1, %0|%0, %1, %2}
6898 imul{l}\t{%2, %0|%0, %2}"
6899 [(set_attr "type" "imul")
6900 (set_attr "prefix_0f" "0,0,1")
6901 (set (attr "athlon_decode")
6902 (cond [(eq_attr "cpu" "athlon")
6903 (const_string "vector")
6904 (eq_attr "alternative" "1")
6905 (const_string "vector")
6906 (and (eq_attr "alternative" "2")
6907 (match_operand 1 "memory_operand" ""))
6908 (const_string "vector")]
6909 (const_string "direct")))
6910 (set_attr "mode" "SI")])
6911
6912 (define_insn "*mulsi3_1_zext"
6913 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6914 (zero_extend:DI
6915 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6916 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6917 (clobber (reg:CC FLAGS_REG))]
6918 "TARGET_64BIT
6919 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6920 "@
6921 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6922 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6923 imul{l}\t{%2, %k0|%k0, %2}"
6924 [(set_attr "type" "imul")
6925 (set_attr "prefix_0f" "0,0,1")
6926 (set (attr "athlon_decode")
6927 (cond [(eq_attr "cpu" "athlon")
6928 (const_string "vector")
6929 (eq_attr "alternative" "1")
6930 (const_string "vector")
6931 (and (eq_attr "alternative" "2")
6932 (match_operand 1 "memory_operand" ""))
6933 (const_string "vector")]
6934 (const_string "direct")))
6935 (set_attr "mode" "SI")])
6936
6937 (define_expand "mulhi3"
6938 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6939 (mult:HI (match_operand:HI 1 "register_operand" "")
6940 (match_operand:HI 2 "general_operand" "")))
6941 (clobber (reg:CC FLAGS_REG))])]
6942 "TARGET_HIMODE_MATH"
6943 "")
6944
6945 (define_insn "*mulhi3_1"
6946 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6947 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6948 (match_operand:HI 2 "general_operand" "K,i,mr")))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6951 "@
6952 imul{w}\t{%2, %1, %0|%0, %1, %2}
6953 imul{w}\t{%2, %1, %0|%0, %1, %2}
6954 imul{w}\t{%2, %0|%0, %2}"
6955 [(set_attr "type" "imul")
6956 (set_attr "prefix_0f" "0,0,1")
6957 (set (attr "athlon_decode")
6958 (cond [(eq_attr "cpu" "athlon")
6959 (const_string "vector")
6960 (eq_attr "alternative" "1,2")
6961 (const_string "vector")]
6962 (const_string "direct")))
6963 (set_attr "mode" "HI")])
6964
6965 (define_expand "mulqi3"
6966 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6967 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6968 (match_operand:QI 2 "register_operand" "")))
6969 (clobber (reg:CC FLAGS_REG))])]
6970 "TARGET_QIMODE_MATH"
6971 "")
6972
6973 (define_insn "*mulqi3_1"
6974 [(set (match_operand:QI 0 "register_operand" "=a")
6975 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6976 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6977 (clobber (reg:CC FLAGS_REG))]
6978 "TARGET_QIMODE_MATH
6979 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6980 "mul{b}\t%2"
6981 [(set_attr "type" "imul")
6982 (set_attr "length_immediate" "0")
6983 (set (attr "athlon_decode")
6984 (if_then_else (eq_attr "cpu" "athlon")
6985 (const_string "vector")
6986 (const_string "direct")))
6987 (set_attr "mode" "QI")])
6988
6989 (define_expand "umulqihi3"
6990 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6991 (mult:HI (zero_extend:HI
6992 (match_operand:QI 1 "nonimmediate_operand" ""))
6993 (zero_extend:HI
6994 (match_operand:QI 2 "register_operand" ""))))
6995 (clobber (reg:CC FLAGS_REG))])]
6996 "TARGET_QIMODE_MATH"
6997 "")
6998
6999 (define_insn "*umulqihi3_1"
7000 [(set (match_operand:HI 0 "register_operand" "=a")
7001 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7002 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7003 (clobber (reg:CC FLAGS_REG))]
7004 "TARGET_QIMODE_MATH
7005 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7006 "mul{b}\t%2"
7007 [(set_attr "type" "imul")
7008 (set_attr "length_immediate" "0")
7009 (set (attr "athlon_decode")
7010 (if_then_else (eq_attr "cpu" "athlon")
7011 (const_string "vector")
7012 (const_string "direct")))
7013 (set_attr "mode" "QI")])
7014
7015 (define_expand "mulqihi3"
7016 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7017 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7018 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7019 (clobber (reg:CC FLAGS_REG))])]
7020 "TARGET_QIMODE_MATH"
7021 "")
7022
7023 (define_insn "*mulqihi3_insn"
7024 [(set (match_operand:HI 0 "register_operand" "=a")
7025 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7026 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7027 (clobber (reg:CC FLAGS_REG))]
7028 "TARGET_QIMODE_MATH
7029 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7030 "imul{b}\t%2"
7031 [(set_attr "type" "imul")
7032 (set_attr "length_immediate" "0")
7033 (set (attr "athlon_decode")
7034 (if_then_else (eq_attr "cpu" "athlon")
7035 (const_string "vector")
7036 (const_string "direct")))
7037 (set_attr "mode" "QI")])
7038
7039 (define_expand "umulditi3"
7040 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7041 (mult:TI (zero_extend:TI
7042 (match_operand:DI 1 "nonimmediate_operand" ""))
7043 (zero_extend:TI
7044 (match_operand:DI 2 "register_operand" ""))))
7045 (clobber (reg:CC FLAGS_REG))])]
7046 "TARGET_64BIT"
7047 "")
7048
7049 (define_insn "*umulditi3_insn"
7050 [(set (match_operand:TI 0 "register_operand" "=A")
7051 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7052 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7053 (clobber (reg:CC FLAGS_REG))]
7054 "TARGET_64BIT
7055 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7056 "mul{q}\t%2"
7057 [(set_attr "type" "imul")
7058 (set_attr "length_immediate" "0")
7059 (set (attr "athlon_decode")
7060 (if_then_else (eq_attr "cpu" "athlon")
7061 (const_string "vector")
7062 (const_string "double")))
7063 (set_attr "mode" "DI")])
7064
7065 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7066 (define_expand "umulsidi3"
7067 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7068 (mult:DI (zero_extend:DI
7069 (match_operand:SI 1 "nonimmediate_operand" ""))
7070 (zero_extend:DI
7071 (match_operand:SI 2 "register_operand" ""))))
7072 (clobber (reg:CC FLAGS_REG))])]
7073 "!TARGET_64BIT"
7074 "")
7075
7076 (define_insn "*umulsidi3_insn"
7077 [(set (match_operand:DI 0 "register_operand" "=A")
7078 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7079 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7080 (clobber (reg:CC FLAGS_REG))]
7081 "!TARGET_64BIT
7082 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7083 "mul{l}\t%2"
7084 [(set_attr "type" "imul")
7085 (set_attr "length_immediate" "0")
7086 (set (attr "athlon_decode")
7087 (if_then_else (eq_attr "cpu" "athlon")
7088 (const_string "vector")
7089 (const_string "double")))
7090 (set_attr "mode" "SI")])
7091
7092 (define_expand "mulditi3"
7093 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7094 (mult:TI (sign_extend:TI
7095 (match_operand:DI 1 "nonimmediate_operand" ""))
7096 (sign_extend:TI
7097 (match_operand:DI 2 "register_operand" ""))))
7098 (clobber (reg:CC FLAGS_REG))])]
7099 "TARGET_64BIT"
7100 "")
7101
7102 (define_insn "*mulditi3_insn"
7103 [(set (match_operand:TI 0 "register_operand" "=A")
7104 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7105 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7106 (clobber (reg:CC FLAGS_REG))]
7107 "TARGET_64BIT
7108 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7109 "imul{q}\t%2"
7110 [(set_attr "type" "imul")
7111 (set_attr "length_immediate" "0")
7112 (set (attr "athlon_decode")
7113 (if_then_else (eq_attr "cpu" "athlon")
7114 (const_string "vector")
7115 (const_string "double")))
7116 (set_attr "mode" "DI")])
7117
7118 (define_expand "mulsidi3"
7119 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7120 (mult:DI (sign_extend:DI
7121 (match_operand:SI 1 "nonimmediate_operand" ""))
7122 (sign_extend:DI
7123 (match_operand:SI 2 "register_operand" ""))))
7124 (clobber (reg:CC FLAGS_REG))])]
7125 "!TARGET_64BIT"
7126 "")
7127
7128 (define_insn "*mulsidi3_insn"
7129 [(set (match_operand:DI 0 "register_operand" "=A")
7130 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7131 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7132 (clobber (reg:CC FLAGS_REG))]
7133 "!TARGET_64BIT
7134 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7135 "imul{l}\t%2"
7136 [(set_attr "type" "imul")
7137 (set_attr "length_immediate" "0")
7138 (set (attr "athlon_decode")
7139 (if_then_else (eq_attr "cpu" "athlon")
7140 (const_string "vector")
7141 (const_string "double")))
7142 (set_attr "mode" "SI")])
7143
7144 (define_expand "umuldi3_highpart"
7145 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7146 (truncate:DI
7147 (lshiftrt:TI
7148 (mult:TI (zero_extend:TI
7149 (match_operand:DI 1 "nonimmediate_operand" ""))
7150 (zero_extend:TI
7151 (match_operand:DI 2 "register_operand" "")))
7152 (const_int 64))))
7153 (clobber (match_scratch:DI 3 ""))
7154 (clobber (reg:CC FLAGS_REG))])]
7155 "TARGET_64BIT"
7156 "")
7157
7158 (define_insn "*umuldi3_highpart_rex64"
7159 [(set (match_operand:DI 0 "register_operand" "=d")
7160 (truncate:DI
7161 (lshiftrt:TI
7162 (mult:TI (zero_extend:TI
7163 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7164 (zero_extend:TI
7165 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7166 (const_int 64))))
7167 (clobber (match_scratch:DI 3 "=1"))
7168 (clobber (reg:CC FLAGS_REG))]
7169 "TARGET_64BIT
7170 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7171 "mul{q}\t%2"
7172 [(set_attr "type" "imul")
7173 (set_attr "length_immediate" "0")
7174 (set (attr "athlon_decode")
7175 (if_then_else (eq_attr "cpu" "athlon")
7176 (const_string "vector")
7177 (const_string "double")))
7178 (set_attr "mode" "DI")])
7179
7180 (define_expand "umulsi3_highpart"
7181 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7182 (truncate:SI
7183 (lshiftrt:DI
7184 (mult:DI (zero_extend:DI
7185 (match_operand:SI 1 "nonimmediate_operand" ""))
7186 (zero_extend:DI
7187 (match_operand:SI 2 "register_operand" "")))
7188 (const_int 32))))
7189 (clobber (match_scratch:SI 3 ""))
7190 (clobber (reg:CC FLAGS_REG))])]
7191 ""
7192 "")
7193
7194 (define_insn "*umulsi3_highpart_insn"
7195 [(set (match_operand:SI 0 "register_operand" "=d")
7196 (truncate:SI
7197 (lshiftrt:DI
7198 (mult:DI (zero_extend:DI
7199 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7200 (zero_extend:DI
7201 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7202 (const_int 32))))
7203 (clobber (match_scratch:SI 3 "=1"))
7204 (clobber (reg:CC FLAGS_REG))]
7205 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7206 "mul{l}\t%2"
7207 [(set_attr "type" "imul")
7208 (set_attr "length_immediate" "0")
7209 (set (attr "athlon_decode")
7210 (if_then_else (eq_attr "cpu" "athlon")
7211 (const_string "vector")
7212 (const_string "double")))
7213 (set_attr "mode" "SI")])
7214
7215 (define_insn "*umulsi3_highpart_zext"
7216 [(set (match_operand:DI 0 "register_operand" "=d")
7217 (zero_extend:DI (truncate:SI
7218 (lshiftrt:DI
7219 (mult:DI (zero_extend:DI
7220 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7221 (zero_extend:DI
7222 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7223 (const_int 32)))))
7224 (clobber (match_scratch:SI 3 "=1"))
7225 (clobber (reg:CC FLAGS_REG))]
7226 "TARGET_64BIT
7227 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7228 "mul{l}\t%2"
7229 [(set_attr "type" "imul")
7230 (set_attr "length_immediate" "0")
7231 (set (attr "athlon_decode")
7232 (if_then_else (eq_attr "cpu" "athlon")
7233 (const_string "vector")
7234 (const_string "double")))
7235 (set_attr "mode" "SI")])
7236
7237 (define_expand "smuldi3_highpart"
7238 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7239 (truncate:DI
7240 (lshiftrt:TI
7241 (mult:TI (sign_extend:TI
7242 (match_operand:DI 1 "nonimmediate_operand" ""))
7243 (sign_extend:TI
7244 (match_operand:DI 2 "register_operand" "")))
7245 (const_int 64))))
7246 (clobber (match_scratch:DI 3 ""))
7247 (clobber (reg:CC FLAGS_REG))])]
7248 "TARGET_64BIT"
7249 "")
7250
7251 (define_insn "*smuldi3_highpart_rex64"
7252 [(set (match_operand:DI 0 "register_operand" "=d")
7253 (truncate:DI
7254 (lshiftrt:TI
7255 (mult:TI (sign_extend:TI
7256 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7257 (sign_extend:TI
7258 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7259 (const_int 64))))
7260 (clobber (match_scratch:DI 3 "=1"))
7261 (clobber (reg:CC FLAGS_REG))]
7262 "TARGET_64BIT
7263 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7264 "imul{q}\t%2"
7265 [(set_attr "type" "imul")
7266 (set (attr "athlon_decode")
7267 (if_then_else (eq_attr "cpu" "athlon")
7268 (const_string "vector")
7269 (const_string "double")))
7270 (set_attr "mode" "DI")])
7271
7272 (define_expand "smulsi3_highpart"
7273 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7274 (truncate:SI
7275 (lshiftrt:DI
7276 (mult:DI (sign_extend:DI
7277 (match_operand:SI 1 "nonimmediate_operand" ""))
7278 (sign_extend:DI
7279 (match_operand:SI 2 "register_operand" "")))
7280 (const_int 32))))
7281 (clobber (match_scratch:SI 3 ""))
7282 (clobber (reg:CC FLAGS_REG))])]
7283 ""
7284 "")
7285
7286 (define_insn "*smulsi3_highpart_insn"
7287 [(set (match_operand:SI 0 "register_operand" "=d")
7288 (truncate:SI
7289 (lshiftrt:DI
7290 (mult:DI (sign_extend:DI
7291 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7292 (sign_extend:DI
7293 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7294 (const_int 32))))
7295 (clobber (match_scratch:SI 3 "=1"))
7296 (clobber (reg:CC FLAGS_REG))]
7297 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7298 "imul{l}\t%2"
7299 [(set_attr "type" "imul")
7300 (set (attr "athlon_decode")
7301 (if_then_else (eq_attr "cpu" "athlon")
7302 (const_string "vector")
7303 (const_string "double")))
7304 (set_attr "mode" "SI")])
7305
7306 (define_insn "*smulsi3_highpart_zext"
7307 [(set (match_operand:DI 0 "register_operand" "=d")
7308 (zero_extend:DI (truncate:SI
7309 (lshiftrt:DI
7310 (mult:DI (sign_extend:DI
7311 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7312 (sign_extend:DI
7313 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7314 (const_int 32)))))
7315 (clobber (match_scratch:SI 3 "=1"))
7316 (clobber (reg:CC FLAGS_REG))]
7317 "TARGET_64BIT
7318 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7319 "imul{l}\t%2"
7320 [(set_attr "type" "imul")
7321 (set (attr "athlon_decode")
7322 (if_then_else (eq_attr "cpu" "athlon")
7323 (const_string "vector")
7324 (const_string "double")))
7325 (set_attr "mode" "SI")])
7326
7327 ;; The patterns that match these are at the end of this file.
7328
7329 (define_expand "mulxf3"
7330 [(set (match_operand:XF 0 "register_operand" "")
7331 (mult:XF (match_operand:XF 1 "register_operand" "")
7332 (match_operand:XF 2 "register_operand" "")))]
7333 "TARGET_80387"
7334 "")
7335
7336 (define_expand "muldf3"
7337 [(set (match_operand:DF 0 "register_operand" "")
7338 (mult:DF (match_operand:DF 1 "register_operand" "")
7339 (match_operand:DF 2 "nonimmediate_operand" "")))]
7340 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7341 "")
7342
7343 (define_expand "mulsf3"
7344 [(set (match_operand:SF 0 "register_operand" "")
7345 (mult:SF (match_operand:SF 1 "register_operand" "")
7346 (match_operand:SF 2 "nonimmediate_operand" "")))]
7347 "TARGET_80387 || TARGET_SSE_MATH"
7348 "")
7349 \f
7350 ;; Divide instructions
7351
7352 (define_insn "divqi3"
7353 [(set (match_operand:QI 0 "register_operand" "=a")
7354 (div:QI (match_operand:HI 1 "register_operand" "0")
7355 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7356 (clobber (reg:CC FLAGS_REG))]
7357 "TARGET_QIMODE_MATH"
7358 "idiv{b}\t%2"
7359 [(set_attr "type" "idiv")
7360 (set_attr "mode" "QI")])
7361
7362 (define_insn "udivqi3"
7363 [(set (match_operand:QI 0 "register_operand" "=a")
7364 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7365 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7366 (clobber (reg:CC FLAGS_REG))]
7367 "TARGET_QIMODE_MATH"
7368 "div{b}\t%2"
7369 [(set_attr "type" "idiv")
7370 (set_attr "mode" "QI")])
7371
7372 ;; The patterns that match these are at the end of this file.
7373
7374 (define_expand "divxf3"
7375 [(set (match_operand:XF 0 "register_operand" "")
7376 (div:XF (match_operand:XF 1 "register_operand" "")
7377 (match_operand:XF 2 "register_operand" "")))]
7378 "TARGET_80387"
7379 "")
7380
7381 (define_expand "divdf3"
7382 [(set (match_operand:DF 0 "register_operand" "")
7383 (div:DF (match_operand:DF 1 "register_operand" "")
7384 (match_operand:DF 2 "nonimmediate_operand" "")))]
7385 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7386 "")
7387
7388 (define_expand "divsf3"
7389 [(set (match_operand:SF 0 "register_operand" "")
7390 (div:SF (match_operand:SF 1 "register_operand" "")
7391 (match_operand:SF 2 "nonimmediate_operand" "")))]
7392 "TARGET_80387 || TARGET_SSE_MATH"
7393 "")
7394 \f
7395 ;; Remainder instructions.
7396
7397 (define_expand "divmoddi4"
7398 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7399 (div:DI (match_operand:DI 1 "register_operand" "")
7400 (match_operand:DI 2 "nonimmediate_operand" "")))
7401 (set (match_operand:DI 3 "register_operand" "")
7402 (mod:DI (match_dup 1) (match_dup 2)))
7403 (clobber (reg:CC FLAGS_REG))])]
7404 "TARGET_64BIT"
7405 "")
7406
7407 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7408 ;; Penalize eax case slightly because it results in worse scheduling
7409 ;; of code.
7410 (define_insn "*divmoddi4_nocltd_rex64"
7411 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7412 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7413 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7414 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7415 (mod:DI (match_dup 2) (match_dup 3)))
7416 (clobber (reg:CC FLAGS_REG))]
7417 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7418 "#"
7419 [(set_attr "type" "multi")])
7420
7421 (define_insn "*divmoddi4_cltd_rex64"
7422 [(set (match_operand:DI 0 "register_operand" "=a")
7423 (div:DI (match_operand:DI 2 "register_operand" "a")
7424 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7425 (set (match_operand:DI 1 "register_operand" "=&d")
7426 (mod:DI (match_dup 2) (match_dup 3)))
7427 (clobber (reg:CC FLAGS_REG))]
7428 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7429 "#"
7430 [(set_attr "type" "multi")])
7431
7432 (define_insn "*divmoddi_noext_rex64"
7433 [(set (match_operand:DI 0 "register_operand" "=a")
7434 (div:DI (match_operand:DI 1 "register_operand" "0")
7435 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7436 (set (match_operand:DI 3 "register_operand" "=d")
7437 (mod:DI (match_dup 1) (match_dup 2)))
7438 (use (match_operand:DI 4 "register_operand" "3"))
7439 (clobber (reg:CC FLAGS_REG))]
7440 "TARGET_64BIT"
7441 "idiv{q}\t%2"
7442 [(set_attr "type" "idiv")
7443 (set_attr "mode" "DI")])
7444
7445 (define_split
7446 [(set (match_operand:DI 0 "register_operand" "")
7447 (div:DI (match_operand:DI 1 "register_operand" "")
7448 (match_operand:DI 2 "nonimmediate_operand" "")))
7449 (set (match_operand:DI 3 "register_operand" "")
7450 (mod:DI (match_dup 1) (match_dup 2)))
7451 (clobber (reg:CC FLAGS_REG))]
7452 "TARGET_64BIT && reload_completed"
7453 [(parallel [(set (match_dup 3)
7454 (ashiftrt:DI (match_dup 4) (const_int 63)))
7455 (clobber (reg:CC FLAGS_REG))])
7456 (parallel [(set (match_dup 0)
7457 (div:DI (reg:DI 0) (match_dup 2)))
7458 (set (match_dup 3)
7459 (mod:DI (reg:DI 0) (match_dup 2)))
7460 (use (match_dup 3))
7461 (clobber (reg:CC FLAGS_REG))])]
7462 {
7463 /* Avoid use of cltd in favor of a mov+shift. */
7464 if (!TARGET_USE_CLTD && !optimize_size)
7465 {
7466 if (true_regnum (operands[1]))
7467 emit_move_insn (operands[0], operands[1]);
7468 else
7469 emit_move_insn (operands[3], operands[1]);
7470 operands[4] = operands[3];
7471 }
7472 else
7473 {
7474 gcc_assert (!true_regnum (operands[1]));
7475 operands[4] = operands[1];
7476 }
7477 })
7478
7479
7480 (define_expand "divmodsi4"
7481 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7482 (div:SI (match_operand:SI 1 "register_operand" "")
7483 (match_operand:SI 2 "nonimmediate_operand" "")))
7484 (set (match_operand:SI 3 "register_operand" "")
7485 (mod:SI (match_dup 1) (match_dup 2)))
7486 (clobber (reg:CC FLAGS_REG))])]
7487 ""
7488 "")
7489
7490 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7491 ;; Penalize eax case slightly because it results in worse scheduling
7492 ;; of code.
7493 (define_insn "*divmodsi4_nocltd"
7494 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7495 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7496 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7497 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7498 (mod:SI (match_dup 2) (match_dup 3)))
7499 (clobber (reg:CC FLAGS_REG))]
7500 "!optimize_size && !TARGET_USE_CLTD"
7501 "#"
7502 [(set_attr "type" "multi")])
7503
7504 (define_insn "*divmodsi4_cltd"
7505 [(set (match_operand:SI 0 "register_operand" "=a")
7506 (div:SI (match_operand:SI 2 "register_operand" "a")
7507 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7508 (set (match_operand:SI 1 "register_operand" "=&d")
7509 (mod:SI (match_dup 2) (match_dup 3)))
7510 (clobber (reg:CC FLAGS_REG))]
7511 "optimize_size || TARGET_USE_CLTD"
7512 "#"
7513 [(set_attr "type" "multi")])
7514
7515 (define_insn "*divmodsi_noext"
7516 [(set (match_operand:SI 0 "register_operand" "=a")
7517 (div:SI (match_operand:SI 1 "register_operand" "0")
7518 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7519 (set (match_operand:SI 3 "register_operand" "=d")
7520 (mod:SI (match_dup 1) (match_dup 2)))
7521 (use (match_operand:SI 4 "register_operand" "3"))
7522 (clobber (reg:CC FLAGS_REG))]
7523 ""
7524 "idiv{l}\t%2"
7525 [(set_attr "type" "idiv")
7526 (set_attr "mode" "SI")])
7527
7528 (define_split
7529 [(set (match_operand:SI 0 "register_operand" "")
7530 (div:SI (match_operand:SI 1 "register_operand" "")
7531 (match_operand:SI 2 "nonimmediate_operand" "")))
7532 (set (match_operand:SI 3 "register_operand" "")
7533 (mod:SI (match_dup 1) (match_dup 2)))
7534 (clobber (reg:CC FLAGS_REG))]
7535 "reload_completed"
7536 [(parallel [(set (match_dup 3)
7537 (ashiftrt:SI (match_dup 4) (const_int 31)))
7538 (clobber (reg:CC FLAGS_REG))])
7539 (parallel [(set (match_dup 0)
7540 (div:SI (reg:SI 0) (match_dup 2)))
7541 (set (match_dup 3)
7542 (mod:SI (reg:SI 0) (match_dup 2)))
7543 (use (match_dup 3))
7544 (clobber (reg:CC FLAGS_REG))])]
7545 {
7546 /* Avoid use of cltd in favor of a mov+shift. */
7547 if (!TARGET_USE_CLTD && !optimize_size)
7548 {
7549 if (true_regnum (operands[1]))
7550 emit_move_insn (operands[0], operands[1]);
7551 else
7552 emit_move_insn (operands[3], operands[1]);
7553 operands[4] = operands[3];
7554 }
7555 else
7556 {
7557 gcc_assert (!true_regnum (operands[1]));
7558 operands[4] = operands[1];
7559 }
7560 })
7561 ;; %%% Split me.
7562 (define_insn "divmodhi4"
7563 [(set (match_operand:HI 0 "register_operand" "=a")
7564 (div:HI (match_operand:HI 1 "register_operand" "0")
7565 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7566 (set (match_operand:HI 3 "register_operand" "=&d")
7567 (mod:HI (match_dup 1) (match_dup 2)))
7568 (clobber (reg:CC FLAGS_REG))]
7569 "TARGET_HIMODE_MATH"
7570 "cwtd\;idiv{w}\t%2"
7571 [(set_attr "type" "multi")
7572 (set_attr "length_immediate" "0")
7573 (set_attr "mode" "SI")])
7574
7575 (define_insn "udivmoddi4"
7576 [(set (match_operand:DI 0 "register_operand" "=a")
7577 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7578 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7579 (set (match_operand:DI 3 "register_operand" "=&d")
7580 (umod:DI (match_dup 1) (match_dup 2)))
7581 (clobber (reg:CC FLAGS_REG))]
7582 "TARGET_64BIT"
7583 "xor{q}\t%3, %3\;div{q}\t%2"
7584 [(set_attr "type" "multi")
7585 (set_attr "length_immediate" "0")
7586 (set_attr "mode" "DI")])
7587
7588 (define_insn "*udivmoddi4_noext"
7589 [(set (match_operand:DI 0 "register_operand" "=a")
7590 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7591 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7592 (set (match_operand:DI 3 "register_operand" "=d")
7593 (umod:DI (match_dup 1) (match_dup 2)))
7594 (use (match_dup 3))
7595 (clobber (reg:CC FLAGS_REG))]
7596 "TARGET_64BIT"
7597 "div{q}\t%2"
7598 [(set_attr "type" "idiv")
7599 (set_attr "mode" "DI")])
7600
7601 (define_split
7602 [(set (match_operand:DI 0 "register_operand" "")
7603 (udiv:DI (match_operand:DI 1 "register_operand" "")
7604 (match_operand:DI 2 "nonimmediate_operand" "")))
7605 (set (match_operand:DI 3 "register_operand" "")
7606 (umod:DI (match_dup 1) (match_dup 2)))
7607 (clobber (reg:CC FLAGS_REG))]
7608 "TARGET_64BIT && reload_completed"
7609 [(set (match_dup 3) (const_int 0))
7610 (parallel [(set (match_dup 0)
7611 (udiv:DI (match_dup 1) (match_dup 2)))
7612 (set (match_dup 3)
7613 (umod:DI (match_dup 1) (match_dup 2)))
7614 (use (match_dup 3))
7615 (clobber (reg:CC FLAGS_REG))])]
7616 "")
7617
7618 (define_insn "udivmodsi4"
7619 [(set (match_operand:SI 0 "register_operand" "=a")
7620 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7621 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7622 (set (match_operand:SI 3 "register_operand" "=&d")
7623 (umod:SI (match_dup 1) (match_dup 2)))
7624 (clobber (reg:CC FLAGS_REG))]
7625 ""
7626 "xor{l}\t%3, %3\;div{l}\t%2"
7627 [(set_attr "type" "multi")
7628 (set_attr "length_immediate" "0")
7629 (set_attr "mode" "SI")])
7630
7631 (define_insn "*udivmodsi4_noext"
7632 [(set (match_operand:SI 0 "register_operand" "=a")
7633 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7634 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7635 (set (match_operand:SI 3 "register_operand" "=d")
7636 (umod:SI (match_dup 1) (match_dup 2)))
7637 (use (match_dup 3))
7638 (clobber (reg:CC FLAGS_REG))]
7639 ""
7640 "div{l}\t%2"
7641 [(set_attr "type" "idiv")
7642 (set_attr "mode" "SI")])
7643
7644 (define_split
7645 [(set (match_operand:SI 0 "register_operand" "")
7646 (udiv:SI (match_operand:SI 1 "register_operand" "")
7647 (match_operand:SI 2 "nonimmediate_operand" "")))
7648 (set (match_operand:SI 3 "register_operand" "")
7649 (umod:SI (match_dup 1) (match_dup 2)))
7650 (clobber (reg:CC FLAGS_REG))]
7651 "reload_completed"
7652 [(set (match_dup 3) (const_int 0))
7653 (parallel [(set (match_dup 0)
7654 (udiv:SI (match_dup 1) (match_dup 2)))
7655 (set (match_dup 3)
7656 (umod:SI (match_dup 1) (match_dup 2)))
7657 (use (match_dup 3))
7658 (clobber (reg:CC FLAGS_REG))])]
7659 "")
7660
7661 (define_expand "udivmodhi4"
7662 [(set (match_dup 4) (const_int 0))
7663 (parallel [(set (match_operand:HI 0 "register_operand" "")
7664 (udiv:HI (match_operand:HI 1 "register_operand" "")
7665 (match_operand:HI 2 "nonimmediate_operand" "")))
7666 (set (match_operand:HI 3 "register_operand" "")
7667 (umod:HI (match_dup 1) (match_dup 2)))
7668 (use (match_dup 4))
7669 (clobber (reg:CC FLAGS_REG))])]
7670 "TARGET_HIMODE_MATH"
7671 "operands[4] = gen_reg_rtx (HImode);")
7672
7673 (define_insn "*udivmodhi_noext"
7674 [(set (match_operand:HI 0 "register_operand" "=a")
7675 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7676 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7677 (set (match_operand:HI 3 "register_operand" "=d")
7678 (umod:HI (match_dup 1) (match_dup 2)))
7679 (use (match_operand:HI 4 "register_operand" "3"))
7680 (clobber (reg:CC FLAGS_REG))]
7681 ""
7682 "div{w}\t%2"
7683 [(set_attr "type" "idiv")
7684 (set_attr "mode" "HI")])
7685
7686 ;; We cannot use div/idiv for double division, because it causes
7687 ;; "division by zero" on the overflow and that's not what we expect
7688 ;; from truncate. Because true (non truncating) double division is
7689 ;; never generated, we can't create this insn anyway.
7690 ;
7691 ;(define_insn ""
7692 ; [(set (match_operand:SI 0 "register_operand" "=a")
7693 ; (truncate:SI
7694 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7695 ; (zero_extend:DI
7696 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7697 ; (set (match_operand:SI 3 "register_operand" "=d")
7698 ; (truncate:SI
7699 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7700 ; (clobber (reg:CC FLAGS_REG))]
7701 ; ""
7702 ; "div{l}\t{%2, %0|%0, %2}"
7703 ; [(set_attr "type" "idiv")])
7704 \f
7705 ;;- Logical AND instructions
7706
7707 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7708 ;; Note that this excludes ah.
7709
7710 (define_insn "*testdi_1_rex64"
7711 [(set (reg FLAGS_REG)
7712 (compare
7713 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7714 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7715 (const_int 0)))]
7716 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7717 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7718 "@
7719 test{l}\t{%k1, %k0|%k0, %k1}
7720 test{l}\t{%k1, %k0|%k0, %k1}
7721 test{q}\t{%1, %0|%0, %1}
7722 test{q}\t{%1, %0|%0, %1}
7723 test{q}\t{%1, %0|%0, %1}"
7724 [(set_attr "type" "test")
7725 (set_attr "modrm" "0,1,0,1,1")
7726 (set_attr "mode" "SI,SI,DI,DI,DI")
7727 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7728
7729 (define_insn "testsi_1"
7730 [(set (reg FLAGS_REG)
7731 (compare
7732 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7733 (match_operand:SI 1 "general_operand" "in,in,rin"))
7734 (const_int 0)))]
7735 "ix86_match_ccmode (insn, CCNOmode)
7736 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7737 "test{l}\t{%1, %0|%0, %1}"
7738 [(set_attr "type" "test")
7739 (set_attr "modrm" "0,1,1")
7740 (set_attr "mode" "SI")
7741 (set_attr "pent_pair" "uv,np,uv")])
7742
7743 (define_expand "testsi_ccno_1"
7744 [(set (reg:CCNO FLAGS_REG)
7745 (compare:CCNO
7746 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7747 (match_operand:SI 1 "nonmemory_operand" ""))
7748 (const_int 0)))]
7749 ""
7750 "")
7751
7752 (define_insn "*testhi_1"
7753 [(set (reg FLAGS_REG)
7754 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7755 (match_operand:HI 1 "general_operand" "n,n,rn"))
7756 (const_int 0)))]
7757 "ix86_match_ccmode (insn, CCNOmode)
7758 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7759 "test{w}\t{%1, %0|%0, %1}"
7760 [(set_attr "type" "test")
7761 (set_attr "modrm" "0,1,1")
7762 (set_attr "mode" "HI")
7763 (set_attr "pent_pair" "uv,np,uv")])
7764
7765 (define_expand "testqi_ccz_1"
7766 [(set (reg:CCZ FLAGS_REG)
7767 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7768 (match_operand:QI 1 "nonmemory_operand" ""))
7769 (const_int 0)))]
7770 ""
7771 "")
7772
7773 (define_insn "*testqi_1_maybe_si"
7774 [(set (reg FLAGS_REG)
7775 (compare
7776 (and:QI
7777 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7778 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7779 (const_int 0)))]
7780 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7781 && ix86_match_ccmode (insn,
7782 GET_CODE (operands[1]) == CONST_INT
7783 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7784 {
7785 if (which_alternative == 3)
7786 {
7787 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7788 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7789 return "test{l}\t{%1, %k0|%k0, %1}";
7790 }
7791 return "test{b}\t{%1, %0|%0, %1}";
7792 }
7793 [(set_attr "type" "test")
7794 (set_attr "modrm" "0,1,1,1")
7795 (set_attr "mode" "QI,QI,QI,SI")
7796 (set_attr "pent_pair" "uv,np,uv,np")])
7797
7798 (define_insn "*testqi_1"
7799 [(set (reg FLAGS_REG)
7800 (compare
7801 (and:QI
7802 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7803 (match_operand:QI 1 "general_operand" "n,n,qn"))
7804 (const_int 0)))]
7805 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7806 && ix86_match_ccmode (insn, CCNOmode)"
7807 "test{b}\t{%1, %0|%0, %1}"
7808 [(set_attr "type" "test")
7809 (set_attr "modrm" "0,1,1")
7810 (set_attr "mode" "QI")
7811 (set_attr "pent_pair" "uv,np,uv")])
7812
7813 (define_expand "testqi_ext_ccno_0"
7814 [(set (reg:CCNO FLAGS_REG)
7815 (compare:CCNO
7816 (and:SI
7817 (zero_extract:SI
7818 (match_operand 0 "ext_register_operand" "")
7819 (const_int 8)
7820 (const_int 8))
7821 (match_operand 1 "const_int_operand" ""))
7822 (const_int 0)))]
7823 ""
7824 "")
7825
7826 (define_insn "*testqi_ext_0"
7827 [(set (reg FLAGS_REG)
7828 (compare
7829 (and:SI
7830 (zero_extract:SI
7831 (match_operand 0 "ext_register_operand" "Q")
7832 (const_int 8)
7833 (const_int 8))
7834 (match_operand 1 "const_int_operand" "n"))
7835 (const_int 0)))]
7836 "ix86_match_ccmode (insn, CCNOmode)"
7837 "test{b}\t{%1, %h0|%h0, %1}"
7838 [(set_attr "type" "test")
7839 (set_attr "mode" "QI")
7840 (set_attr "length_immediate" "1")
7841 (set_attr "pent_pair" "np")])
7842
7843 (define_insn "*testqi_ext_1"
7844 [(set (reg FLAGS_REG)
7845 (compare
7846 (and:SI
7847 (zero_extract:SI
7848 (match_operand 0 "ext_register_operand" "Q")
7849 (const_int 8)
7850 (const_int 8))
7851 (zero_extend:SI
7852 (match_operand:QI 1 "general_operand" "Qm")))
7853 (const_int 0)))]
7854 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7855 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7856 "test{b}\t{%1, %h0|%h0, %1}"
7857 [(set_attr "type" "test")
7858 (set_attr "mode" "QI")])
7859
7860 (define_insn "*testqi_ext_1_rex64"
7861 [(set (reg FLAGS_REG)
7862 (compare
7863 (and:SI
7864 (zero_extract:SI
7865 (match_operand 0 "ext_register_operand" "Q")
7866 (const_int 8)
7867 (const_int 8))
7868 (zero_extend:SI
7869 (match_operand:QI 1 "register_operand" "Q")))
7870 (const_int 0)))]
7871 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7872 "test{b}\t{%1, %h0|%h0, %1}"
7873 [(set_attr "type" "test")
7874 (set_attr "mode" "QI")])
7875
7876 (define_insn "*testqi_ext_2"
7877 [(set (reg FLAGS_REG)
7878 (compare
7879 (and:SI
7880 (zero_extract:SI
7881 (match_operand 0 "ext_register_operand" "Q")
7882 (const_int 8)
7883 (const_int 8))
7884 (zero_extract:SI
7885 (match_operand 1 "ext_register_operand" "Q")
7886 (const_int 8)
7887 (const_int 8)))
7888 (const_int 0)))]
7889 "ix86_match_ccmode (insn, CCNOmode)"
7890 "test{b}\t{%h1, %h0|%h0, %h1}"
7891 [(set_attr "type" "test")
7892 (set_attr "mode" "QI")])
7893
7894 ;; Combine likes to form bit extractions for some tests. Humor it.
7895 (define_insn "*testqi_ext_3"
7896 [(set (reg FLAGS_REG)
7897 (compare (zero_extract:SI
7898 (match_operand 0 "nonimmediate_operand" "rm")
7899 (match_operand:SI 1 "const_int_operand" "")
7900 (match_operand:SI 2 "const_int_operand" ""))
7901 (const_int 0)))]
7902 "ix86_match_ccmode (insn, CCNOmode)
7903 && INTVAL (operands[1]) > 0
7904 && INTVAL (operands[2]) >= 0
7905 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7906 && (GET_MODE (operands[0]) == SImode
7907 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7908 || GET_MODE (operands[0]) == HImode
7909 || GET_MODE (operands[0]) == QImode)"
7910 "#")
7911
7912 (define_insn "*testqi_ext_3_rex64"
7913 [(set (reg FLAGS_REG)
7914 (compare (zero_extract:DI
7915 (match_operand 0 "nonimmediate_operand" "rm")
7916 (match_operand:DI 1 "const_int_operand" "")
7917 (match_operand:DI 2 "const_int_operand" ""))
7918 (const_int 0)))]
7919 "TARGET_64BIT
7920 && ix86_match_ccmode (insn, CCNOmode)
7921 && INTVAL (operands[1]) > 0
7922 && INTVAL (operands[2]) >= 0
7923 /* Ensure that resulting mask is zero or sign extended operand. */
7924 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7925 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7926 && INTVAL (operands[1]) > 32))
7927 && (GET_MODE (operands[0]) == SImode
7928 || GET_MODE (operands[0]) == DImode
7929 || GET_MODE (operands[0]) == HImode
7930 || GET_MODE (operands[0]) == QImode)"
7931 "#")
7932
7933 (define_split
7934 [(set (match_operand 0 "flags_reg_operand" "")
7935 (match_operator 1 "compare_operator"
7936 [(zero_extract
7937 (match_operand 2 "nonimmediate_operand" "")
7938 (match_operand 3 "const_int_operand" "")
7939 (match_operand 4 "const_int_operand" ""))
7940 (const_int 0)]))]
7941 "ix86_match_ccmode (insn, CCNOmode)"
7942 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7943 {
7944 rtx val = operands[2];
7945 HOST_WIDE_INT len = INTVAL (operands[3]);
7946 HOST_WIDE_INT pos = INTVAL (operands[4]);
7947 HOST_WIDE_INT mask;
7948 enum machine_mode mode, submode;
7949
7950 mode = GET_MODE (val);
7951 if (GET_CODE (val) == MEM)
7952 {
7953 /* ??? Combine likes to put non-volatile mem extractions in QImode
7954 no matter the size of the test. So find a mode that works. */
7955 if (! MEM_VOLATILE_P (val))
7956 {
7957 mode = smallest_mode_for_size (pos + len, MODE_INT);
7958 val = adjust_address (val, mode, 0);
7959 }
7960 }
7961 else if (GET_CODE (val) == SUBREG
7962 && (submode = GET_MODE (SUBREG_REG (val)),
7963 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7964 && pos + len <= GET_MODE_BITSIZE (submode))
7965 {
7966 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7967 mode = submode;
7968 val = SUBREG_REG (val);
7969 }
7970 else if (mode == HImode && pos + len <= 8)
7971 {
7972 /* Small HImode tests can be converted to QImode. */
7973 mode = QImode;
7974 val = gen_lowpart (QImode, val);
7975 }
7976
7977 if (len == HOST_BITS_PER_WIDE_INT)
7978 mask = -1;
7979 else
7980 mask = ((HOST_WIDE_INT)1 << len) - 1;
7981 mask <<= pos;
7982
7983 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7984 })
7985
7986 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7987 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7988 ;; this is relatively important trick.
7989 ;; Do the conversion only post-reload to avoid limiting of the register class
7990 ;; to QI regs.
7991 (define_split
7992 [(set (match_operand 0 "flags_reg_operand" "")
7993 (match_operator 1 "compare_operator"
7994 [(and (match_operand 2 "register_operand" "")
7995 (match_operand 3 "const_int_operand" ""))
7996 (const_int 0)]))]
7997 "reload_completed
7998 && QI_REG_P (operands[2])
7999 && GET_MODE (operands[2]) != QImode
8000 && ((ix86_match_ccmode (insn, CCZmode)
8001 && !(INTVAL (operands[3]) & ~(255 << 8)))
8002 || (ix86_match_ccmode (insn, CCNOmode)
8003 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8004 [(set (match_dup 0)
8005 (match_op_dup 1
8006 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8007 (match_dup 3))
8008 (const_int 0)]))]
8009 "operands[2] = gen_lowpart (SImode, operands[2]);
8010 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8011
8012 (define_split
8013 [(set (match_operand 0 "flags_reg_operand" "")
8014 (match_operator 1 "compare_operator"
8015 [(and (match_operand 2 "nonimmediate_operand" "")
8016 (match_operand 3 "const_int_operand" ""))
8017 (const_int 0)]))]
8018 "reload_completed
8019 && GET_MODE (operands[2]) != QImode
8020 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8021 && ((ix86_match_ccmode (insn, CCZmode)
8022 && !(INTVAL (operands[3]) & ~255))
8023 || (ix86_match_ccmode (insn, CCNOmode)
8024 && !(INTVAL (operands[3]) & ~127)))"
8025 [(set (match_dup 0)
8026 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8027 (const_int 0)]))]
8028 "operands[2] = gen_lowpart (QImode, operands[2]);
8029 operands[3] = gen_lowpart (QImode, operands[3]);")
8030
8031
8032 ;; %%% This used to optimize known byte-wide and operations to memory,
8033 ;; and sometimes to QImode registers. If this is considered useful,
8034 ;; it should be done with splitters.
8035
8036 (define_expand "anddi3"
8037 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8038 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8039 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8040 (clobber (reg:CC FLAGS_REG))]
8041 "TARGET_64BIT"
8042 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8043
8044 (define_insn "*anddi_1_rex64"
8045 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8046 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8047 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8048 (clobber (reg:CC FLAGS_REG))]
8049 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8050 {
8051 switch (get_attr_type (insn))
8052 {
8053 case TYPE_IMOVX:
8054 {
8055 enum machine_mode mode;
8056
8057 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8058 if (INTVAL (operands[2]) == 0xff)
8059 mode = QImode;
8060 else
8061 {
8062 gcc_assert (INTVAL (operands[2]) == 0xffff);
8063 mode = HImode;
8064 }
8065
8066 operands[1] = gen_lowpart (mode, operands[1]);
8067 if (mode == QImode)
8068 return "movz{bq|x}\t{%1,%0|%0, %1}";
8069 else
8070 return "movz{wq|x}\t{%1,%0|%0, %1}";
8071 }
8072
8073 default:
8074 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8075 if (get_attr_mode (insn) == MODE_SI)
8076 return "and{l}\t{%k2, %k0|%k0, %k2}";
8077 else
8078 return "and{q}\t{%2, %0|%0, %2}";
8079 }
8080 }
8081 [(set_attr "type" "alu,alu,alu,imovx")
8082 (set_attr "length_immediate" "*,*,*,0")
8083 (set_attr "mode" "SI,DI,DI,DI")])
8084
8085 (define_insn "*anddi_2"
8086 [(set (reg FLAGS_REG)
8087 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8088 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8089 (const_int 0)))
8090 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8091 (and:DI (match_dup 1) (match_dup 2)))]
8092 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8093 && ix86_binary_operator_ok (AND, DImode, operands)"
8094 "@
8095 and{l}\t{%k2, %k0|%k0, %k2}
8096 and{q}\t{%2, %0|%0, %2}
8097 and{q}\t{%2, %0|%0, %2}"
8098 [(set_attr "type" "alu")
8099 (set_attr "mode" "SI,DI,DI")])
8100
8101 (define_expand "andsi3"
8102 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8103 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8104 (match_operand:SI 2 "general_operand" "")))
8105 (clobber (reg:CC FLAGS_REG))]
8106 ""
8107 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8108
8109 (define_insn "*andsi_1"
8110 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8111 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8112 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8113 (clobber (reg:CC FLAGS_REG))]
8114 "ix86_binary_operator_ok (AND, SImode, operands)"
8115 {
8116 switch (get_attr_type (insn))
8117 {
8118 case TYPE_IMOVX:
8119 {
8120 enum machine_mode mode;
8121
8122 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8123 if (INTVAL (operands[2]) == 0xff)
8124 mode = QImode;
8125 else
8126 {
8127 gcc_assert (INTVAL (operands[2]) == 0xffff);
8128 mode = HImode;
8129 }
8130
8131 operands[1] = gen_lowpart (mode, operands[1]);
8132 if (mode == QImode)
8133 return "movz{bl|x}\t{%1,%0|%0, %1}";
8134 else
8135 return "movz{wl|x}\t{%1,%0|%0, %1}";
8136 }
8137
8138 default:
8139 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8140 return "and{l}\t{%2, %0|%0, %2}";
8141 }
8142 }
8143 [(set_attr "type" "alu,alu,imovx")
8144 (set_attr "length_immediate" "*,*,0")
8145 (set_attr "mode" "SI")])
8146
8147 (define_split
8148 [(set (match_operand 0 "register_operand" "")
8149 (and (match_dup 0)
8150 (const_int -65536)))
8151 (clobber (reg:CC FLAGS_REG))]
8152 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8153 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8154 "operands[1] = gen_lowpart (HImode, operands[0]);")
8155
8156 (define_split
8157 [(set (match_operand 0 "ext_register_operand" "")
8158 (and (match_dup 0)
8159 (const_int -256)))
8160 (clobber (reg:CC FLAGS_REG))]
8161 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8162 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8163 "operands[1] = gen_lowpart (QImode, operands[0]);")
8164
8165 (define_split
8166 [(set (match_operand 0 "ext_register_operand" "")
8167 (and (match_dup 0)
8168 (const_int -65281)))
8169 (clobber (reg:CC FLAGS_REG))]
8170 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8171 [(parallel [(set (zero_extract:SI (match_dup 0)
8172 (const_int 8)
8173 (const_int 8))
8174 (xor:SI
8175 (zero_extract:SI (match_dup 0)
8176 (const_int 8)
8177 (const_int 8))
8178 (zero_extract:SI (match_dup 0)
8179 (const_int 8)
8180 (const_int 8))))
8181 (clobber (reg:CC FLAGS_REG))])]
8182 "operands[0] = gen_lowpart (SImode, operands[0]);")
8183
8184 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8185 (define_insn "*andsi_1_zext"
8186 [(set (match_operand:DI 0 "register_operand" "=r")
8187 (zero_extend:DI
8188 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8189 (match_operand:SI 2 "general_operand" "rim"))))
8190 (clobber (reg:CC FLAGS_REG))]
8191 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8192 "and{l}\t{%2, %k0|%k0, %2}"
8193 [(set_attr "type" "alu")
8194 (set_attr "mode" "SI")])
8195
8196 (define_insn "*andsi_2"
8197 [(set (reg FLAGS_REG)
8198 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8199 (match_operand:SI 2 "general_operand" "rim,ri"))
8200 (const_int 0)))
8201 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8202 (and:SI (match_dup 1) (match_dup 2)))]
8203 "ix86_match_ccmode (insn, CCNOmode)
8204 && ix86_binary_operator_ok (AND, SImode, operands)"
8205 "and{l}\t{%2, %0|%0, %2}"
8206 [(set_attr "type" "alu")
8207 (set_attr "mode" "SI")])
8208
8209 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8210 (define_insn "*andsi_2_zext"
8211 [(set (reg FLAGS_REG)
8212 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8213 (match_operand:SI 2 "general_operand" "rim"))
8214 (const_int 0)))
8215 (set (match_operand:DI 0 "register_operand" "=r")
8216 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8217 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8218 && ix86_binary_operator_ok (AND, SImode, operands)"
8219 "and{l}\t{%2, %k0|%k0, %2}"
8220 [(set_attr "type" "alu")
8221 (set_attr "mode" "SI")])
8222
8223 (define_expand "andhi3"
8224 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8225 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8226 (match_operand:HI 2 "general_operand" "")))
8227 (clobber (reg:CC FLAGS_REG))]
8228 "TARGET_HIMODE_MATH"
8229 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8230
8231 (define_insn "*andhi_1"
8232 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8233 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8234 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8235 (clobber (reg:CC FLAGS_REG))]
8236 "ix86_binary_operator_ok (AND, HImode, operands)"
8237 {
8238 switch (get_attr_type (insn))
8239 {
8240 case TYPE_IMOVX:
8241 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8242 gcc_assert (INTVAL (operands[2]) == 0xff);
8243 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8244
8245 default:
8246 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8247
8248 return "and{w}\t{%2, %0|%0, %2}";
8249 }
8250 }
8251 [(set_attr "type" "alu,alu,imovx")
8252 (set_attr "length_immediate" "*,*,0")
8253 (set_attr "mode" "HI,HI,SI")])
8254
8255 (define_insn "*andhi_2"
8256 [(set (reg FLAGS_REG)
8257 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8258 (match_operand:HI 2 "general_operand" "rim,ri"))
8259 (const_int 0)))
8260 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8261 (and:HI (match_dup 1) (match_dup 2)))]
8262 "ix86_match_ccmode (insn, CCNOmode)
8263 && ix86_binary_operator_ok (AND, HImode, operands)"
8264 "and{w}\t{%2, %0|%0, %2}"
8265 [(set_attr "type" "alu")
8266 (set_attr "mode" "HI")])
8267
8268 (define_expand "andqi3"
8269 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8270 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8271 (match_operand:QI 2 "general_operand" "")))
8272 (clobber (reg:CC FLAGS_REG))]
8273 "TARGET_QIMODE_MATH"
8274 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8275
8276 ;; %%% Potential partial reg stall on alternative 2. What to do?
8277 (define_insn "*andqi_1"
8278 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8279 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8280 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8281 (clobber (reg:CC FLAGS_REG))]
8282 "ix86_binary_operator_ok (AND, QImode, operands)"
8283 "@
8284 and{b}\t{%2, %0|%0, %2}
8285 and{b}\t{%2, %0|%0, %2}
8286 and{l}\t{%k2, %k0|%k0, %k2}"
8287 [(set_attr "type" "alu")
8288 (set_attr "mode" "QI,QI,SI")])
8289
8290 (define_insn "*andqi_1_slp"
8291 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8292 (and:QI (match_dup 0)
8293 (match_operand:QI 1 "general_operand" "qi,qmi")))
8294 (clobber (reg:CC FLAGS_REG))]
8295 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8296 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8297 "and{b}\t{%1, %0|%0, %1}"
8298 [(set_attr "type" "alu1")
8299 (set_attr "mode" "QI")])
8300
8301 (define_insn "*andqi_2_maybe_si"
8302 [(set (reg FLAGS_REG)
8303 (compare (and:QI
8304 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8305 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8306 (const_int 0)))
8307 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8308 (and:QI (match_dup 1) (match_dup 2)))]
8309 "ix86_binary_operator_ok (AND, QImode, operands)
8310 && ix86_match_ccmode (insn,
8311 GET_CODE (operands[2]) == CONST_INT
8312 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8313 {
8314 if (which_alternative == 2)
8315 {
8316 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8317 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8318 return "and{l}\t{%2, %k0|%k0, %2}";
8319 }
8320 return "and{b}\t{%2, %0|%0, %2}";
8321 }
8322 [(set_attr "type" "alu")
8323 (set_attr "mode" "QI,QI,SI")])
8324
8325 (define_insn "*andqi_2"
8326 [(set (reg FLAGS_REG)
8327 (compare (and:QI
8328 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8329 (match_operand:QI 2 "general_operand" "qim,qi"))
8330 (const_int 0)))
8331 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8332 (and:QI (match_dup 1) (match_dup 2)))]
8333 "ix86_match_ccmode (insn, CCNOmode)
8334 && ix86_binary_operator_ok (AND, QImode, operands)"
8335 "and{b}\t{%2, %0|%0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "mode" "QI")])
8338
8339 (define_insn "*andqi_2_slp"
8340 [(set (reg FLAGS_REG)
8341 (compare (and:QI
8342 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8343 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8344 (const_int 0)))
8345 (set (strict_low_part (match_dup 0))
8346 (and:QI (match_dup 0) (match_dup 1)))]
8347 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8348 && ix86_match_ccmode (insn, CCNOmode)
8349 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8350 "and{b}\t{%1, %0|%0, %1}"
8351 [(set_attr "type" "alu1")
8352 (set_attr "mode" "QI")])
8353
8354 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8355 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8356 ;; for a QImode operand, which of course failed.
8357
8358 (define_insn "andqi_ext_0"
8359 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8360 (const_int 8)
8361 (const_int 8))
8362 (and:SI
8363 (zero_extract:SI
8364 (match_operand 1 "ext_register_operand" "0")
8365 (const_int 8)
8366 (const_int 8))
8367 (match_operand 2 "const_int_operand" "n")))
8368 (clobber (reg:CC FLAGS_REG))]
8369 ""
8370 "and{b}\t{%2, %h0|%h0, %2}"
8371 [(set_attr "type" "alu")
8372 (set_attr "length_immediate" "1")
8373 (set_attr "mode" "QI")])
8374
8375 ;; Generated by peephole translating test to and. This shows up
8376 ;; often in fp comparisons.
8377
8378 (define_insn "*andqi_ext_0_cc"
8379 [(set (reg FLAGS_REG)
8380 (compare
8381 (and:SI
8382 (zero_extract:SI
8383 (match_operand 1 "ext_register_operand" "0")
8384 (const_int 8)
8385 (const_int 8))
8386 (match_operand 2 "const_int_operand" "n"))
8387 (const_int 0)))
8388 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8389 (const_int 8)
8390 (const_int 8))
8391 (and:SI
8392 (zero_extract:SI
8393 (match_dup 1)
8394 (const_int 8)
8395 (const_int 8))
8396 (match_dup 2)))]
8397 "ix86_match_ccmode (insn, CCNOmode)"
8398 "and{b}\t{%2, %h0|%h0, %2}"
8399 [(set_attr "type" "alu")
8400 (set_attr "length_immediate" "1")
8401 (set_attr "mode" "QI")])
8402
8403 (define_insn "*andqi_ext_1"
8404 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8405 (const_int 8)
8406 (const_int 8))
8407 (and:SI
8408 (zero_extract:SI
8409 (match_operand 1 "ext_register_operand" "0")
8410 (const_int 8)
8411 (const_int 8))
8412 (zero_extend:SI
8413 (match_operand:QI 2 "general_operand" "Qm"))))
8414 (clobber (reg:CC FLAGS_REG))]
8415 "!TARGET_64BIT"
8416 "and{b}\t{%2, %h0|%h0, %2}"
8417 [(set_attr "type" "alu")
8418 (set_attr "length_immediate" "0")
8419 (set_attr "mode" "QI")])
8420
8421 (define_insn "*andqi_ext_1_rex64"
8422 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8423 (const_int 8)
8424 (const_int 8))
8425 (and:SI
8426 (zero_extract:SI
8427 (match_operand 1 "ext_register_operand" "0")
8428 (const_int 8)
8429 (const_int 8))
8430 (zero_extend:SI
8431 (match_operand 2 "ext_register_operand" "Q"))))
8432 (clobber (reg:CC FLAGS_REG))]
8433 "TARGET_64BIT"
8434 "and{b}\t{%2, %h0|%h0, %2}"
8435 [(set_attr "type" "alu")
8436 (set_attr "length_immediate" "0")
8437 (set_attr "mode" "QI")])
8438
8439 (define_insn "*andqi_ext_2"
8440 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8441 (const_int 8)
8442 (const_int 8))
8443 (and:SI
8444 (zero_extract:SI
8445 (match_operand 1 "ext_register_operand" "%0")
8446 (const_int 8)
8447 (const_int 8))
8448 (zero_extract:SI
8449 (match_operand 2 "ext_register_operand" "Q")
8450 (const_int 8)
8451 (const_int 8))))
8452 (clobber (reg:CC FLAGS_REG))]
8453 ""
8454 "and{b}\t{%h2, %h0|%h0, %h2}"
8455 [(set_attr "type" "alu")
8456 (set_attr "length_immediate" "0")
8457 (set_attr "mode" "QI")])
8458
8459 ;; Convert wide AND instructions with immediate operand to shorter QImode
8460 ;; equivalents when possible.
8461 ;; Don't do the splitting with memory operands, since it introduces risk
8462 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8463 ;; for size, but that can (should?) be handled by generic code instead.
8464 (define_split
8465 [(set (match_operand 0 "register_operand" "")
8466 (and (match_operand 1 "register_operand" "")
8467 (match_operand 2 "const_int_operand" "")))
8468 (clobber (reg:CC FLAGS_REG))]
8469 "reload_completed
8470 && QI_REG_P (operands[0])
8471 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8472 && !(~INTVAL (operands[2]) & ~(255 << 8))
8473 && GET_MODE (operands[0]) != QImode"
8474 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8475 (and:SI (zero_extract:SI (match_dup 1)
8476 (const_int 8) (const_int 8))
8477 (match_dup 2)))
8478 (clobber (reg:CC FLAGS_REG))])]
8479 "operands[0] = gen_lowpart (SImode, operands[0]);
8480 operands[1] = gen_lowpart (SImode, operands[1]);
8481 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8482
8483 ;; Since AND can be encoded with sign extended immediate, this is only
8484 ;; profitable when 7th bit is not set.
8485 (define_split
8486 [(set (match_operand 0 "register_operand" "")
8487 (and (match_operand 1 "general_operand" "")
8488 (match_operand 2 "const_int_operand" "")))
8489 (clobber (reg:CC FLAGS_REG))]
8490 "reload_completed
8491 && ANY_QI_REG_P (operands[0])
8492 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8493 && !(~INTVAL (operands[2]) & ~255)
8494 && !(INTVAL (operands[2]) & 128)
8495 && GET_MODE (operands[0]) != QImode"
8496 [(parallel [(set (strict_low_part (match_dup 0))
8497 (and:QI (match_dup 1)
8498 (match_dup 2)))
8499 (clobber (reg:CC FLAGS_REG))])]
8500 "operands[0] = gen_lowpart (QImode, operands[0]);
8501 operands[1] = gen_lowpart (QImode, operands[1]);
8502 operands[2] = gen_lowpart (QImode, operands[2]);")
8503 \f
8504 ;; Logical inclusive OR instructions
8505
8506 ;; %%% This used to optimize known byte-wide and operations to memory.
8507 ;; If this is considered useful, it should be done with splitters.
8508
8509 (define_expand "iordi3"
8510 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8511 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8512 (match_operand:DI 2 "x86_64_general_operand" "")))
8513 (clobber (reg:CC FLAGS_REG))]
8514 "TARGET_64BIT"
8515 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8516
8517 (define_insn "*iordi_1_rex64"
8518 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8519 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8520 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8521 (clobber (reg:CC FLAGS_REG))]
8522 "TARGET_64BIT
8523 && ix86_binary_operator_ok (IOR, DImode, operands)"
8524 "or{q}\t{%2, %0|%0, %2}"
8525 [(set_attr "type" "alu")
8526 (set_attr "mode" "DI")])
8527
8528 (define_insn "*iordi_2_rex64"
8529 [(set (reg FLAGS_REG)
8530 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8531 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8532 (const_int 0)))
8533 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8534 (ior:DI (match_dup 1) (match_dup 2)))]
8535 "TARGET_64BIT
8536 && ix86_match_ccmode (insn, CCNOmode)
8537 && ix86_binary_operator_ok (IOR, DImode, operands)"
8538 "or{q}\t{%2, %0|%0, %2}"
8539 [(set_attr "type" "alu")
8540 (set_attr "mode" "DI")])
8541
8542 (define_insn "*iordi_3_rex64"
8543 [(set (reg FLAGS_REG)
8544 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8545 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8546 (const_int 0)))
8547 (clobber (match_scratch:DI 0 "=r"))]
8548 "TARGET_64BIT
8549 && ix86_match_ccmode (insn, CCNOmode)
8550 && ix86_binary_operator_ok (IOR, DImode, operands)"
8551 "or{q}\t{%2, %0|%0, %2}"
8552 [(set_attr "type" "alu")
8553 (set_attr "mode" "DI")])
8554
8555
8556 (define_expand "iorsi3"
8557 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8558 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8559 (match_operand:SI 2 "general_operand" "")))
8560 (clobber (reg:CC FLAGS_REG))]
8561 ""
8562 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8563
8564 (define_insn "*iorsi_1"
8565 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8566 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8567 (match_operand:SI 2 "general_operand" "ri,rmi")))
8568 (clobber (reg:CC FLAGS_REG))]
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 (define_insn "*iorsi_1_zext"
8576 [(set (match_operand:DI 0 "register_operand" "=rm")
8577 (zero_extend:DI
8578 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8579 (match_operand:SI 2 "general_operand" "rim"))))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8582 "or{l}\t{%2, %k0|%k0, %2}"
8583 [(set_attr "type" "alu")
8584 (set_attr "mode" "SI")])
8585
8586 (define_insn "*iorsi_1_zext_imm"
8587 [(set (match_operand:DI 0 "register_operand" "=rm")
8588 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8589 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8590 (clobber (reg:CC FLAGS_REG))]
8591 "TARGET_64BIT"
8592 "or{l}\t{%2, %k0|%k0, %2}"
8593 [(set_attr "type" "alu")
8594 (set_attr "mode" "SI")])
8595
8596 (define_insn "*iorsi_2"
8597 [(set (reg FLAGS_REG)
8598 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8599 (match_operand:SI 2 "general_operand" "rim,ri"))
8600 (const_int 0)))
8601 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8602 (ior:SI (match_dup 1) (match_dup 2)))]
8603 "ix86_match_ccmode (insn, CCNOmode)
8604 && ix86_binary_operator_ok (IOR, SImode, operands)"
8605 "or{l}\t{%2, %0|%0, %2}"
8606 [(set_attr "type" "alu")
8607 (set_attr "mode" "SI")])
8608
8609 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8610 ;; ??? Special case for immediate operand is missing - it is tricky.
8611 (define_insn "*iorsi_2_zext"
8612 [(set (reg FLAGS_REG)
8613 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8614 (match_operand:SI 2 "general_operand" "rim"))
8615 (const_int 0)))
8616 (set (match_operand:DI 0 "register_operand" "=r")
8617 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8618 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8619 && ix86_binary_operator_ok (IOR, SImode, operands)"
8620 "or{l}\t{%2, %k0|%k0, %2}"
8621 [(set_attr "type" "alu")
8622 (set_attr "mode" "SI")])
8623
8624 (define_insn "*iorsi_2_zext_imm"
8625 [(set (reg FLAGS_REG)
8626 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8627 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8628 (const_int 0)))
8629 (set (match_operand:DI 0 "register_operand" "=r")
8630 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8631 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8632 && ix86_binary_operator_ok (IOR, SImode, operands)"
8633 "or{l}\t{%2, %k0|%k0, %2}"
8634 [(set_attr "type" "alu")
8635 (set_attr "mode" "SI")])
8636
8637 (define_insn "*iorsi_3"
8638 [(set (reg FLAGS_REG)
8639 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8640 (match_operand:SI 2 "general_operand" "rim"))
8641 (const_int 0)))
8642 (clobber (match_scratch:SI 0 "=r"))]
8643 "ix86_match_ccmode (insn, CCNOmode)
8644 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8645 "or{l}\t{%2, %0|%0, %2}"
8646 [(set_attr "type" "alu")
8647 (set_attr "mode" "SI")])
8648
8649 (define_expand "iorhi3"
8650 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8651 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8652 (match_operand:HI 2 "general_operand" "")))
8653 (clobber (reg:CC FLAGS_REG))]
8654 "TARGET_HIMODE_MATH"
8655 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8656
8657 (define_insn "*iorhi_1"
8658 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8659 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8660 (match_operand:HI 2 "general_operand" "rmi,ri")))
8661 (clobber (reg:CC FLAGS_REG))]
8662 "ix86_binary_operator_ok (IOR, HImode, operands)"
8663 "or{w}\t{%2, %0|%0, %2}"
8664 [(set_attr "type" "alu")
8665 (set_attr "mode" "HI")])
8666
8667 (define_insn "*iorhi_2"
8668 [(set (reg FLAGS_REG)
8669 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8670 (match_operand:HI 2 "general_operand" "rim,ri"))
8671 (const_int 0)))
8672 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8673 (ior:HI (match_dup 1) (match_dup 2)))]
8674 "ix86_match_ccmode (insn, CCNOmode)
8675 && ix86_binary_operator_ok (IOR, HImode, operands)"
8676 "or{w}\t{%2, %0|%0, %2}"
8677 [(set_attr "type" "alu")
8678 (set_attr "mode" "HI")])
8679
8680 (define_insn "*iorhi_3"
8681 [(set (reg FLAGS_REG)
8682 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8683 (match_operand:HI 2 "general_operand" "rim"))
8684 (const_int 0)))
8685 (clobber (match_scratch:HI 0 "=r"))]
8686 "ix86_match_ccmode (insn, CCNOmode)
8687 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8688 "or{w}\t{%2, %0|%0, %2}"
8689 [(set_attr "type" "alu")
8690 (set_attr "mode" "HI")])
8691
8692 (define_expand "iorqi3"
8693 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8694 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8695 (match_operand:QI 2 "general_operand" "")))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "TARGET_QIMODE_MATH"
8698 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8699
8700 ;; %%% Potential partial reg stall on alternative 2. What to do?
8701 (define_insn "*iorqi_1"
8702 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8703 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8704 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8705 (clobber (reg:CC FLAGS_REG))]
8706 "ix86_binary_operator_ok (IOR, QImode, operands)"
8707 "@
8708 or{b}\t{%2, %0|%0, %2}
8709 or{b}\t{%2, %0|%0, %2}
8710 or{l}\t{%k2, %k0|%k0, %k2}"
8711 [(set_attr "type" "alu")
8712 (set_attr "mode" "QI,QI,SI")])
8713
8714 (define_insn "*iorqi_1_slp"
8715 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8716 (ior:QI (match_dup 0)
8717 (match_operand:QI 1 "general_operand" "qmi,qi")))
8718 (clobber (reg:CC FLAGS_REG))]
8719 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8720 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8721 "or{b}\t{%1, %0|%0, %1}"
8722 [(set_attr "type" "alu1")
8723 (set_attr "mode" "QI")])
8724
8725 (define_insn "*iorqi_2"
8726 [(set (reg FLAGS_REG)
8727 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8728 (match_operand:QI 2 "general_operand" "qim,qi"))
8729 (const_int 0)))
8730 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8731 (ior:QI (match_dup 1) (match_dup 2)))]
8732 "ix86_match_ccmode (insn, CCNOmode)
8733 && ix86_binary_operator_ok (IOR, QImode, operands)"
8734 "or{b}\t{%2, %0|%0, %2}"
8735 [(set_attr "type" "alu")
8736 (set_attr "mode" "QI")])
8737
8738 (define_insn "*iorqi_2_slp"
8739 [(set (reg FLAGS_REG)
8740 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8741 (match_operand:QI 1 "general_operand" "qim,qi"))
8742 (const_int 0)))
8743 (set (strict_low_part (match_dup 0))
8744 (ior:QI (match_dup 0) (match_dup 1)))]
8745 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8746 && ix86_match_ccmode (insn, CCNOmode)
8747 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8748 "or{b}\t{%1, %0|%0, %1}"
8749 [(set_attr "type" "alu1")
8750 (set_attr "mode" "QI")])
8751
8752 (define_insn "*iorqi_3"
8753 [(set (reg FLAGS_REG)
8754 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8755 (match_operand:QI 2 "general_operand" "qim"))
8756 (const_int 0)))
8757 (clobber (match_scratch:QI 0 "=q"))]
8758 "ix86_match_ccmode (insn, CCNOmode)
8759 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8760 "or{b}\t{%2, %0|%0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "mode" "QI")])
8763
8764 (define_insn "iorqi_ext_0"
8765 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8766 (const_int 8)
8767 (const_int 8))
8768 (ior:SI
8769 (zero_extract:SI
8770 (match_operand 1 "ext_register_operand" "0")
8771 (const_int 8)
8772 (const_int 8))
8773 (match_operand 2 "const_int_operand" "n")))
8774 (clobber (reg:CC FLAGS_REG))]
8775 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8776 "or{b}\t{%2, %h0|%h0, %2}"
8777 [(set_attr "type" "alu")
8778 (set_attr "length_immediate" "1")
8779 (set_attr "mode" "QI")])
8780
8781 (define_insn "*iorqi_ext_1"
8782 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8783 (const_int 8)
8784 (const_int 8))
8785 (ior:SI
8786 (zero_extract:SI
8787 (match_operand 1 "ext_register_operand" "0")
8788 (const_int 8)
8789 (const_int 8))
8790 (zero_extend:SI
8791 (match_operand:QI 2 "general_operand" "Qm"))))
8792 (clobber (reg:CC FLAGS_REG))]
8793 "!TARGET_64BIT
8794 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8795 "or{b}\t{%2, %h0|%h0, %2}"
8796 [(set_attr "type" "alu")
8797 (set_attr "length_immediate" "0")
8798 (set_attr "mode" "QI")])
8799
8800 (define_insn "*iorqi_ext_1_rex64"
8801 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8802 (const_int 8)
8803 (const_int 8))
8804 (ior:SI
8805 (zero_extract:SI
8806 (match_operand 1 "ext_register_operand" "0")
8807 (const_int 8)
8808 (const_int 8))
8809 (zero_extend:SI
8810 (match_operand 2 "ext_register_operand" "Q"))))
8811 (clobber (reg:CC FLAGS_REG))]
8812 "TARGET_64BIT
8813 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8814 "or{b}\t{%2, %h0|%h0, %2}"
8815 [(set_attr "type" "alu")
8816 (set_attr "length_immediate" "0")
8817 (set_attr "mode" "QI")])
8818
8819 (define_insn "*iorqi_ext_2"
8820 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8821 (const_int 8)
8822 (const_int 8))
8823 (ior:SI
8824 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8825 (const_int 8)
8826 (const_int 8))
8827 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8828 (const_int 8)
8829 (const_int 8))))
8830 (clobber (reg:CC FLAGS_REG))]
8831 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8832 "ior{b}\t{%h2, %h0|%h0, %h2}"
8833 [(set_attr "type" "alu")
8834 (set_attr "length_immediate" "0")
8835 (set_attr "mode" "QI")])
8836
8837 (define_split
8838 [(set (match_operand 0 "register_operand" "")
8839 (ior (match_operand 1 "register_operand" "")
8840 (match_operand 2 "const_int_operand" "")))
8841 (clobber (reg:CC FLAGS_REG))]
8842 "reload_completed
8843 && QI_REG_P (operands[0])
8844 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8845 && !(INTVAL (operands[2]) & ~(255 << 8))
8846 && GET_MODE (operands[0]) != QImode"
8847 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8848 (ior:SI (zero_extract:SI (match_dup 1)
8849 (const_int 8) (const_int 8))
8850 (match_dup 2)))
8851 (clobber (reg:CC FLAGS_REG))])]
8852 "operands[0] = gen_lowpart (SImode, operands[0]);
8853 operands[1] = gen_lowpart (SImode, operands[1]);
8854 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8855
8856 ;; Since OR can be encoded with sign extended immediate, this is only
8857 ;; profitable when 7th bit is set.
8858 (define_split
8859 [(set (match_operand 0 "register_operand" "")
8860 (ior (match_operand 1 "general_operand" "")
8861 (match_operand 2 "const_int_operand" "")))
8862 (clobber (reg:CC FLAGS_REG))]
8863 "reload_completed
8864 && ANY_QI_REG_P (operands[0])
8865 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8866 && !(INTVAL (operands[2]) & ~255)
8867 && (INTVAL (operands[2]) & 128)
8868 && GET_MODE (operands[0]) != QImode"
8869 [(parallel [(set (strict_low_part (match_dup 0))
8870 (ior:QI (match_dup 1)
8871 (match_dup 2)))
8872 (clobber (reg:CC FLAGS_REG))])]
8873 "operands[0] = gen_lowpart (QImode, operands[0]);
8874 operands[1] = gen_lowpart (QImode, operands[1]);
8875 operands[2] = gen_lowpart (QImode, operands[2]);")
8876 \f
8877 ;; Logical XOR instructions
8878
8879 ;; %%% This used to optimize known byte-wide and operations to memory.
8880 ;; If this is considered useful, it should be done with splitters.
8881
8882 (define_expand "xordi3"
8883 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8884 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8885 (match_operand:DI 2 "x86_64_general_operand" "")))
8886 (clobber (reg:CC FLAGS_REG))]
8887 "TARGET_64BIT"
8888 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8889
8890 (define_insn "*xordi_1_rex64"
8891 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8892 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8893 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8894 (clobber (reg:CC FLAGS_REG))]
8895 "TARGET_64BIT
8896 && ix86_binary_operator_ok (XOR, DImode, operands)"
8897 "@
8898 xor{q}\t{%2, %0|%0, %2}
8899 xor{q}\t{%2, %0|%0, %2}"
8900 [(set_attr "type" "alu")
8901 (set_attr "mode" "DI,DI")])
8902
8903 (define_insn "*xordi_2_rex64"
8904 [(set (reg FLAGS_REG)
8905 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8906 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8907 (const_int 0)))
8908 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8909 (xor:DI (match_dup 1) (match_dup 2)))]
8910 "TARGET_64BIT
8911 && ix86_match_ccmode (insn, CCNOmode)
8912 && ix86_binary_operator_ok (XOR, DImode, operands)"
8913 "@
8914 xor{q}\t{%2, %0|%0, %2}
8915 xor{q}\t{%2, %0|%0, %2}"
8916 [(set_attr "type" "alu")
8917 (set_attr "mode" "DI,DI")])
8918
8919 (define_insn "*xordi_3_rex64"
8920 [(set (reg FLAGS_REG)
8921 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8922 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8923 (const_int 0)))
8924 (clobber (match_scratch:DI 0 "=r"))]
8925 "TARGET_64BIT
8926 && ix86_match_ccmode (insn, CCNOmode)
8927 && ix86_binary_operator_ok (XOR, DImode, operands)"
8928 "xor{q}\t{%2, %0|%0, %2}"
8929 [(set_attr "type" "alu")
8930 (set_attr "mode" "DI")])
8931
8932 (define_expand "xorsi3"
8933 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8934 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8935 (match_operand:SI 2 "general_operand" "")))
8936 (clobber (reg:CC FLAGS_REG))]
8937 ""
8938 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8939
8940 (define_insn "*xorsi_1"
8941 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8942 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8943 (match_operand:SI 2 "general_operand" "ri,rm")))
8944 (clobber (reg:CC FLAGS_REG))]
8945 "ix86_binary_operator_ok (XOR, SImode, operands)"
8946 "xor{l}\t{%2, %0|%0, %2}"
8947 [(set_attr "type" "alu")
8948 (set_attr "mode" "SI")])
8949
8950 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8951 ;; Add speccase for immediates
8952 (define_insn "*xorsi_1_zext"
8953 [(set (match_operand:DI 0 "register_operand" "=r")
8954 (zero_extend:DI
8955 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956 (match_operand:SI 2 "general_operand" "rim"))))
8957 (clobber (reg:CC FLAGS_REG))]
8958 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8959 "xor{l}\t{%2, %k0|%k0, %2}"
8960 [(set_attr "type" "alu")
8961 (set_attr "mode" "SI")])
8962
8963 (define_insn "*xorsi_1_zext_imm"
8964 [(set (match_operand:DI 0 "register_operand" "=r")
8965 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8966 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8967 (clobber (reg:CC FLAGS_REG))]
8968 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8969 "xor{l}\t{%2, %k0|%k0, %2}"
8970 [(set_attr "type" "alu")
8971 (set_attr "mode" "SI")])
8972
8973 (define_insn "*xorsi_2"
8974 [(set (reg FLAGS_REG)
8975 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8976 (match_operand:SI 2 "general_operand" "rim,ri"))
8977 (const_int 0)))
8978 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8979 (xor:SI (match_dup 1) (match_dup 2)))]
8980 "ix86_match_ccmode (insn, CCNOmode)
8981 && ix86_binary_operator_ok (XOR, SImode, operands)"
8982 "xor{l}\t{%2, %0|%0, %2}"
8983 [(set_attr "type" "alu")
8984 (set_attr "mode" "SI")])
8985
8986 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8987 ;; ??? Special case for immediate operand is missing - it is tricky.
8988 (define_insn "*xorsi_2_zext"
8989 [(set (reg FLAGS_REG)
8990 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8991 (match_operand:SI 2 "general_operand" "rim"))
8992 (const_int 0)))
8993 (set (match_operand:DI 0 "register_operand" "=r")
8994 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8995 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8996 && ix86_binary_operator_ok (XOR, SImode, operands)"
8997 "xor{l}\t{%2, %k0|%k0, %2}"
8998 [(set_attr "type" "alu")
8999 (set_attr "mode" "SI")])
9000
9001 (define_insn "*xorsi_2_zext_imm"
9002 [(set (reg FLAGS_REG)
9003 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9004 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9005 (const_int 0)))
9006 (set (match_operand:DI 0 "register_operand" "=r")
9007 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9008 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9009 && ix86_binary_operator_ok (XOR, SImode, operands)"
9010 "xor{l}\t{%2, %k0|%k0, %2}"
9011 [(set_attr "type" "alu")
9012 (set_attr "mode" "SI")])
9013
9014 (define_insn "*xorsi_3"
9015 [(set (reg FLAGS_REG)
9016 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9017 (match_operand:SI 2 "general_operand" "rim"))
9018 (const_int 0)))
9019 (clobber (match_scratch:SI 0 "=r"))]
9020 "ix86_match_ccmode (insn, CCNOmode)
9021 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9022 "xor{l}\t{%2, %0|%0, %2}"
9023 [(set_attr "type" "alu")
9024 (set_attr "mode" "SI")])
9025
9026 (define_expand "xorhi3"
9027 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9028 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9029 (match_operand:HI 2 "general_operand" "")))
9030 (clobber (reg:CC FLAGS_REG))]
9031 "TARGET_HIMODE_MATH"
9032 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9033
9034 (define_insn "*xorhi_1"
9035 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9036 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9037 (match_operand:HI 2 "general_operand" "rmi,ri")))
9038 (clobber (reg:CC FLAGS_REG))]
9039 "ix86_binary_operator_ok (XOR, HImode, operands)"
9040 "xor{w}\t{%2, %0|%0, %2}"
9041 [(set_attr "type" "alu")
9042 (set_attr "mode" "HI")])
9043
9044 (define_insn "*xorhi_2"
9045 [(set (reg FLAGS_REG)
9046 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9047 (match_operand:HI 2 "general_operand" "rim,ri"))
9048 (const_int 0)))
9049 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9050 (xor:HI (match_dup 1) (match_dup 2)))]
9051 "ix86_match_ccmode (insn, CCNOmode)
9052 && ix86_binary_operator_ok (XOR, HImode, operands)"
9053 "xor{w}\t{%2, %0|%0, %2}"
9054 [(set_attr "type" "alu")
9055 (set_attr "mode" "HI")])
9056
9057 (define_insn "*xorhi_3"
9058 [(set (reg FLAGS_REG)
9059 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9060 (match_operand:HI 2 "general_operand" "rim"))
9061 (const_int 0)))
9062 (clobber (match_scratch:HI 0 "=r"))]
9063 "ix86_match_ccmode (insn, CCNOmode)
9064 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9065 "xor{w}\t{%2, %0|%0, %2}"
9066 [(set_attr "type" "alu")
9067 (set_attr "mode" "HI")])
9068
9069 (define_expand "xorqi3"
9070 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9071 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9072 (match_operand:QI 2 "general_operand" "")))
9073 (clobber (reg:CC FLAGS_REG))]
9074 "TARGET_QIMODE_MATH"
9075 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9076
9077 ;; %%% Potential partial reg stall on alternative 2. What to do?
9078 (define_insn "*xorqi_1"
9079 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9080 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9081 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9082 (clobber (reg:CC FLAGS_REG))]
9083 "ix86_binary_operator_ok (XOR, QImode, operands)"
9084 "@
9085 xor{b}\t{%2, %0|%0, %2}
9086 xor{b}\t{%2, %0|%0, %2}
9087 xor{l}\t{%k2, %k0|%k0, %k2}"
9088 [(set_attr "type" "alu")
9089 (set_attr "mode" "QI,QI,SI")])
9090
9091 (define_insn "*xorqi_1_slp"
9092 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9093 (xor:QI (match_dup 0)
9094 (match_operand:QI 1 "general_operand" "qi,qmi")))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9097 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9098 "xor{b}\t{%1, %0|%0, %1}"
9099 [(set_attr "type" "alu1")
9100 (set_attr "mode" "QI")])
9101
9102 (define_insn "xorqi_ext_0"
9103 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9104 (const_int 8)
9105 (const_int 8))
9106 (xor:SI
9107 (zero_extract:SI
9108 (match_operand 1 "ext_register_operand" "0")
9109 (const_int 8)
9110 (const_int 8))
9111 (match_operand 2 "const_int_operand" "n")))
9112 (clobber (reg:CC FLAGS_REG))]
9113 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9114 "xor{b}\t{%2, %h0|%h0, %2}"
9115 [(set_attr "type" "alu")
9116 (set_attr "length_immediate" "1")
9117 (set_attr "mode" "QI")])
9118
9119 (define_insn "*xorqi_ext_1"
9120 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9121 (const_int 8)
9122 (const_int 8))
9123 (xor:SI
9124 (zero_extract:SI
9125 (match_operand 1 "ext_register_operand" "0")
9126 (const_int 8)
9127 (const_int 8))
9128 (zero_extend:SI
9129 (match_operand:QI 2 "general_operand" "Qm"))))
9130 (clobber (reg:CC FLAGS_REG))]
9131 "!TARGET_64BIT
9132 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9133 "xor{b}\t{%2, %h0|%h0, %2}"
9134 [(set_attr "type" "alu")
9135 (set_attr "length_immediate" "0")
9136 (set_attr "mode" "QI")])
9137
9138 (define_insn "*xorqi_ext_1_rex64"
9139 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9140 (const_int 8)
9141 (const_int 8))
9142 (xor:SI
9143 (zero_extract:SI
9144 (match_operand 1 "ext_register_operand" "0")
9145 (const_int 8)
9146 (const_int 8))
9147 (zero_extend:SI
9148 (match_operand 2 "ext_register_operand" "Q"))))
9149 (clobber (reg:CC FLAGS_REG))]
9150 "TARGET_64BIT
9151 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9152 "xor{b}\t{%2, %h0|%h0, %2}"
9153 [(set_attr "type" "alu")
9154 (set_attr "length_immediate" "0")
9155 (set_attr "mode" "QI")])
9156
9157 (define_insn "*xorqi_ext_2"
9158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159 (const_int 8)
9160 (const_int 8))
9161 (xor:SI
9162 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9163 (const_int 8)
9164 (const_int 8))
9165 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9166 (const_int 8)
9167 (const_int 8))))
9168 (clobber (reg:CC FLAGS_REG))]
9169 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170 "xor{b}\t{%h2, %h0|%h0, %h2}"
9171 [(set_attr "type" "alu")
9172 (set_attr "length_immediate" "0")
9173 (set_attr "mode" "QI")])
9174
9175 (define_insn "*xorqi_cc_1"
9176 [(set (reg FLAGS_REG)
9177 (compare
9178 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9179 (match_operand:QI 2 "general_operand" "qim,qi"))
9180 (const_int 0)))
9181 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9182 (xor:QI (match_dup 1) (match_dup 2)))]
9183 "ix86_match_ccmode (insn, CCNOmode)
9184 && ix86_binary_operator_ok (XOR, QImode, operands)"
9185 "xor{b}\t{%2, %0|%0, %2}"
9186 [(set_attr "type" "alu")
9187 (set_attr "mode" "QI")])
9188
9189 (define_insn "*xorqi_2_slp"
9190 [(set (reg FLAGS_REG)
9191 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9192 (match_operand:QI 1 "general_operand" "qim,qi"))
9193 (const_int 0)))
9194 (set (strict_low_part (match_dup 0))
9195 (xor:QI (match_dup 0) (match_dup 1)))]
9196 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9197 && ix86_match_ccmode (insn, CCNOmode)
9198 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9199 "xor{b}\t{%1, %0|%0, %1}"
9200 [(set_attr "type" "alu1")
9201 (set_attr "mode" "QI")])
9202
9203 (define_insn "*xorqi_cc_2"
9204 [(set (reg FLAGS_REG)
9205 (compare
9206 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9207 (match_operand:QI 2 "general_operand" "qim"))
9208 (const_int 0)))
9209 (clobber (match_scratch:QI 0 "=q"))]
9210 "ix86_match_ccmode (insn, CCNOmode)
9211 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9212 "xor{b}\t{%2, %0|%0, %2}"
9213 [(set_attr "type" "alu")
9214 (set_attr "mode" "QI")])
9215
9216 (define_insn "*xorqi_cc_ext_1"
9217 [(set (reg FLAGS_REG)
9218 (compare
9219 (xor:SI
9220 (zero_extract:SI
9221 (match_operand 1 "ext_register_operand" "0")
9222 (const_int 8)
9223 (const_int 8))
9224 (match_operand:QI 2 "general_operand" "qmn"))
9225 (const_int 0)))
9226 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9227 (const_int 8)
9228 (const_int 8))
9229 (xor:SI
9230 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9231 (match_dup 2)))]
9232 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9233 "xor{b}\t{%2, %h0|%h0, %2}"
9234 [(set_attr "type" "alu")
9235 (set_attr "mode" "QI")])
9236
9237 (define_insn "*xorqi_cc_ext_1_rex64"
9238 [(set (reg FLAGS_REG)
9239 (compare
9240 (xor:SI
9241 (zero_extract:SI
9242 (match_operand 1 "ext_register_operand" "0")
9243 (const_int 8)
9244 (const_int 8))
9245 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9246 (const_int 0)))
9247 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9248 (const_int 8)
9249 (const_int 8))
9250 (xor:SI
9251 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9252 (match_dup 2)))]
9253 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9254 "xor{b}\t{%2, %h0|%h0, %2}"
9255 [(set_attr "type" "alu")
9256 (set_attr "mode" "QI")])
9257
9258 (define_expand "xorqi_cc_ext_1"
9259 [(parallel [
9260 (set (reg:CCNO FLAGS_REG)
9261 (compare:CCNO
9262 (xor:SI
9263 (zero_extract:SI
9264 (match_operand 1 "ext_register_operand" "")
9265 (const_int 8)
9266 (const_int 8))
9267 (match_operand:QI 2 "general_operand" ""))
9268 (const_int 0)))
9269 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9270 (const_int 8)
9271 (const_int 8))
9272 (xor:SI
9273 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9274 (match_dup 2)))])]
9275 ""
9276 "")
9277
9278 (define_split
9279 [(set (match_operand 0 "register_operand" "")
9280 (xor (match_operand 1 "register_operand" "")
9281 (match_operand 2 "const_int_operand" "")))
9282 (clobber (reg:CC FLAGS_REG))]
9283 "reload_completed
9284 && QI_REG_P (operands[0])
9285 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9286 && !(INTVAL (operands[2]) & ~(255 << 8))
9287 && GET_MODE (operands[0]) != QImode"
9288 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9289 (xor:SI (zero_extract:SI (match_dup 1)
9290 (const_int 8) (const_int 8))
9291 (match_dup 2)))
9292 (clobber (reg:CC FLAGS_REG))])]
9293 "operands[0] = gen_lowpart (SImode, operands[0]);
9294 operands[1] = gen_lowpart (SImode, operands[1]);
9295 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9296
9297 ;; Since XOR can be encoded with sign extended immediate, this is only
9298 ;; profitable when 7th bit is set.
9299 (define_split
9300 [(set (match_operand 0 "register_operand" "")
9301 (xor (match_operand 1 "general_operand" "")
9302 (match_operand 2 "const_int_operand" "")))
9303 (clobber (reg:CC FLAGS_REG))]
9304 "reload_completed
9305 && ANY_QI_REG_P (operands[0])
9306 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9307 && !(INTVAL (operands[2]) & ~255)
9308 && (INTVAL (operands[2]) & 128)
9309 && GET_MODE (operands[0]) != QImode"
9310 [(parallel [(set (strict_low_part (match_dup 0))
9311 (xor:QI (match_dup 1)
9312 (match_dup 2)))
9313 (clobber (reg:CC FLAGS_REG))])]
9314 "operands[0] = gen_lowpart (QImode, operands[0]);
9315 operands[1] = gen_lowpart (QImode, operands[1]);
9316 operands[2] = gen_lowpart (QImode, operands[2]);")
9317 \f
9318 ;; Negation instructions
9319
9320 (define_expand "negti2"
9321 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9322 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9323 (clobber (reg:CC FLAGS_REG))])]
9324 "TARGET_64BIT"
9325 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9326
9327 (define_insn "*negti2_1"
9328 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9329 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9330 (clobber (reg:CC FLAGS_REG))]
9331 "TARGET_64BIT
9332 && ix86_unary_operator_ok (NEG, TImode, operands)"
9333 "#")
9334
9335 (define_split
9336 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9337 (neg:TI (match_operand:TI 1 "general_operand" "")))
9338 (clobber (reg:CC FLAGS_REG))]
9339 "TARGET_64BIT && reload_completed"
9340 [(parallel
9341 [(set (reg:CCZ FLAGS_REG)
9342 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9343 (set (match_dup 0) (neg:DI (match_dup 2)))])
9344 (parallel
9345 [(set (match_dup 1)
9346 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9347 (match_dup 3))
9348 (const_int 0)))
9349 (clobber (reg:CC FLAGS_REG))])
9350 (parallel
9351 [(set (match_dup 1)
9352 (neg:DI (match_dup 1)))
9353 (clobber (reg:CC FLAGS_REG))])]
9354 "split_ti (operands+1, 1, operands+2, operands+3);
9355 split_ti (operands+0, 1, operands+0, operands+1);")
9356
9357 (define_expand "negdi2"
9358 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9359 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))])]
9361 ""
9362 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9363
9364 (define_insn "*negdi2_1"
9365 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9366 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9367 (clobber (reg:CC FLAGS_REG))]
9368 "!TARGET_64BIT
9369 && ix86_unary_operator_ok (NEG, DImode, operands)"
9370 "#")
9371
9372 (define_split
9373 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9374 (neg:DI (match_operand:DI 1 "general_operand" "")))
9375 (clobber (reg:CC FLAGS_REG))]
9376 "!TARGET_64BIT && reload_completed"
9377 [(parallel
9378 [(set (reg:CCZ FLAGS_REG)
9379 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9380 (set (match_dup 0) (neg:SI (match_dup 2)))])
9381 (parallel
9382 [(set (match_dup 1)
9383 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9384 (match_dup 3))
9385 (const_int 0)))
9386 (clobber (reg:CC FLAGS_REG))])
9387 (parallel
9388 [(set (match_dup 1)
9389 (neg:SI (match_dup 1)))
9390 (clobber (reg:CC FLAGS_REG))])]
9391 "split_di (operands+1, 1, operands+2, operands+3);
9392 split_di (operands+0, 1, operands+0, operands+1);")
9393
9394 (define_insn "*negdi2_1_rex64"
9395 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9396 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9397 (clobber (reg:CC FLAGS_REG))]
9398 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9399 "neg{q}\t%0"
9400 [(set_attr "type" "negnot")
9401 (set_attr "mode" "DI")])
9402
9403 ;; The problem with neg is that it does not perform (compare x 0),
9404 ;; it really performs (compare 0 x), which leaves us with the zero
9405 ;; flag being the only useful item.
9406
9407 (define_insn "*negdi2_cmpz_rex64"
9408 [(set (reg:CCZ FLAGS_REG)
9409 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9410 (const_int 0)))
9411 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9412 (neg:DI (match_dup 1)))]
9413 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9414 "neg{q}\t%0"
9415 [(set_attr "type" "negnot")
9416 (set_attr "mode" "DI")])
9417
9418
9419 (define_expand "negsi2"
9420 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9421 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9422 (clobber (reg:CC FLAGS_REG))])]
9423 ""
9424 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9425
9426 (define_insn "*negsi2_1"
9427 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9428 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9429 (clobber (reg:CC FLAGS_REG))]
9430 "ix86_unary_operator_ok (NEG, SImode, operands)"
9431 "neg{l}\t%0"
9432 [(set_attr "type" "negnot")
9433 (set_attr "mode" "SI")])
9434
9435 ;; Combine is quite creative about this pattern.
9436 (define_insn "*negsi2_1_zext"
9437 [(set (match_operand:DI 0 "register_operand" "=r")
9438 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9439 (const_int 32)))
9440 (const_int 32)))
9441 (clobber (reg:CC FLAGS_REG))]
9442 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9443 "neg{l}\t%k0"
9444 [(set_attr "type" "negnot")
9445 (set_attr "mode" "SI")])
9446
9447 ;; The problem with neg is that it does not perform (compare x 0),
9448 ;; it really performs (compare 0 x), which leaves us with the zero
9449 ;; flag being the only useful item.
9450
9451 (define_insn "*negsi2_cmpz"
9452 [(set (reg:CCZ FLAGS_REG)
9453 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9454 (const_int 0)))
9455 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9456 (neg:SI (match_dup 1)))]
9457 "ix86_unary_operator_ok (NEG, SImode, operands)"
9458 "neg{l}\t%0"
9459 [(set_attr "type" "negnot")
9460 (set_attr "mode" "SI")])
9461
9462 (define_insn "*negsi2_cmpz_zext"
9463 [(set (reg:CCZ FLAGS_REG)
9464 (compare:CCZ (lshiftrt:DI
9465 (neg:DI (ashift:DI
9466 (match_operand:DI 1 "register_operand" "0")
9467 (const_int 32)))
9468 (const_int 32))
9469 (const_int 0)))
9470 (set (match_operand:DI 0 "register_operand" "=r")
9471 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9472 (const_int 32)))
9473 (const_int 32)))]
9474 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9475 "neg{l}\t%k0"
9476 [(set_attr "type" "negnot")
9477 (set_attr "mode" "SI")])
9478
9479 (define_expand "neghi2"
9480 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9481 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9482 (clobber (reg:CC FLAGS_REG))])]
9483 "TARGET_HIMODE_MATH"
9484 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9485
9486 (define_insn "*neghi2_1"
9487 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9488 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9489 (clobber (reg:CC FLAGS_REG))]
9490 "ix86_unary_operator_ok (NEG, HImode, operands)"
9491 "neg{w}\t%0"
9492 [(set_attr "type" "negnot")
9493 (set_attr "mode" "HI")])
9494
9495 (define_insn "*neghi2_cmpz"
9496 [(set (reg:CCZ FLAGS_REG)
9497 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9498 (const_int 0)))
9499 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9500 (neg:HI (match_dup 1)))]
9501 "ix86_unary_operator_ok (NEG, HImode, operands)"
9502 "neg{w}\t%0"
9503 [(set_attr "type" "negnot")
9504 (set_attr "mode" "HI")])
9505
9506 (define_expand "negqi2"
9507 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9508 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9509 (clobber (reg:CC FLAGS_REG))])]
9510 "TARGET_QIMODE_MATH"
9511 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9512
9513 (define_insn "*negqi2_1"
9514 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9515 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9516 (clobber (reg:CC FLAGS_REG))]
9517 "ix86_unary_operator_ok (NEG, QImode, operands)"
9518 "neg{b}\t%0"
9519 [(set_attr "type" "negnot")
9520 (set_attr "mode" "QI")])
9521
9522 (define_insn "*negqi2_cmpz"
9523 [(set (reg:CCZ FLAGS_REG)
9524 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9525 (const_int 0)))
9526 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9527 (neg:QI (match_dup 1)))]
9528 "ix86_unary_operator_ok (NEG, QImode, operands)"
9529 "neg{b}\t%0"
9530 [(set_attr "type" "negnot")
9531 (set_attr "mode" "QI")])
9532
9533 ;; Changing of sign for FP values is doable using integer unit too.
9534
9535 (define_expand "negsf2"
9536 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9537 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9538 "TARGET_80387 || TARGET_SSE_MATH"
9539 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9540
9541 (define_expand "abssf2"
9542 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9543 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9544 "TARGET_80387 || TARGET_SSE_MATH"
9545 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9546
9547 (define_insn "*absnegsf2_mixed"
9548 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9549 (match_operator:SF 3 "absneg_operator"
9550 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9551 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9552 (clobber (reg:CC FLAGS_REG))]
9553 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9554 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9555 "#")
9556
9557 (define_insn "*absnegsf2_sse"
9558 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9559 (match_operator:SF 3 "absneg_operator"
9560 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9561 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9562 (clobber (reg:CC FLAGS_REG))]
9563 "TARGET_SSE_MATH
9564 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9565 "#")
9566
9567 (define_insn "*absnegsf2_i387"
9568 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9569 (match_operator:SF 3 "absneg_operator"
9570 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9571 (use (match_operand 2 "" ""))
9572 (clobber (reg:CC FLAGS_REG))]
9573 "TARGET_80387 && !TARGET_SSE_MATH
9574 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9575 "#")
9576
9577 (define_expand "copysignsf3"
9578 [(match_operand:SF 0 "register_operand" "")
9579 (match_operand:SF 1 "nonmemory_operand" "")
9580 (match_operand:SF 2 "register_operand" "")]
9581 "TARGET_SSE_MATH"
9582 {
9583 ix86_expand_copysign (operands);
9584 DONE;
9585 })
9586
9587 (define_insn_and_split "copysignsf3_const"
9588 [(set (match_operand:SF 0 "register_operand" "=x")
9589 (unspec:SF
9590 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9591 (match_operand:SF 2 "register_operand" "0")
9592 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9593 UNSPEC_COPYSIGN))]
9594 "TARGET_SSE_MATH"
9595 "#"
9596 "&& reload_completed"
9597 [(const_int 0)]
9598 {
9599 ix86_split_copysign_const (operands);
9600 DONE;
9601 })
9602
9603 (define_insn "copysignsf3_var"
9604 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9605 (unspec:SF
9606 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9607 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9608 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9609 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9610 UNSPEC_COPYSIGN))
9611 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9612 "TARGET_SSE_MATH"
9613 "#")
9614
9615 (define_split
9616 [(set (match_operand:SF 0 "register_operand" "")
9617 (unspec:SF
9618 [(match_operand:SF 2 "register_operand" "")
9619 (match_operand:SF 3 "register_operand" "")
9620 (match_operand:V4SF 4 "" "")
9621 (match_operand:V4SF 5 "" "")]
9622 UNSPEC_COPYSIGN))
9623 (clobber (match_scratch:V4SF 1 ""))]
9624 "TARGET_SSE_MATH && reload_completed"
9625 [(const_int 0)]
9626 {
9627 ix86_split_copysign_var (operands);
9628 DONE;
9629 })
9630
9631 (define_expand "negdf2"
9632 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9633 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9634 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9635 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9636
9637 (define_expand "absdf2"
9638 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9639 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9640 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9641 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9642
9643 (define_insn "*absnegdf2_mixed"
9644 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9645 (match_operator:DF 3 "absneg_operator"
9646 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9647 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9648 (clobber (reg:CC FLAGS_REG))]
9649 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9650 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9651 "#")
9652
9653 (define_insn "*absnegdf2_sse"
9654 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9655 (match_operator:DF 3 "absneg_operator"
9656 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9657 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9658 (clobber (reg:CC FLAGS_REG))]
9659 "TARGET_SSE2 && TARGET_SSE_MATH
9660 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9661 "#")
9662
9663 (define_insn "*absnegdf2_i387"
9664 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9665 (match_operator:DF 3 "absneg_operator"
9666 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9667 (use (match_operand 2 "" ""))
9668 (clobber (reg:CC FLAGS_REG))]
9669 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9670 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9671 "#")
9672
9673 (define_expand "copysigndf3"
9674 [(match_operand:DF 0 "register_operand" "")
9675 (match_operand:DF 1 "nonmemory_operand" "")
9676 (match_operand:DF 2 "register_operand" "")]
9677 "TARGET_SSE2 && TARGET_SSE_MATH"
9678 {
9679 ix86_expand_copysign (operands);
9680 DONE;
9681 })
9682
9683 (define_insn_and_split "copysigndf3_const"
9684 [(set (match_operand:DF 0 "register_operand" "=x")
9685 (unspec:DF
9686 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9687 (match_operand:DF 2 "register_operand" "0")
9688 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9689 UNSPEC_COPYSIGN))]
9690 "TARGET_SSE2 && TARGET_SSE_MATH"
9691 "#"
9692 "&& reload_completed"
9693 [(const_int 0)]
9694 {
9695 ix86_split_copysign_const (operands);
9696 DONE;
9697 })
9698
9699 (define_insn "copysigndf3_var"
9700 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9701 (unspec:DF
9702 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9703 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9704 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9705 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9706 UNSPEC_COPYSIGN))
9707 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9708 "TARGET_SSE2 && TARGET_SSE_MATH"
9709 "#")
9710
9711 (define_split
9712 [(set (match_operand:DF 0 "register_operand" "")
9713 (unspec:DF
9714 [(match_operand:DF 2 "register_operand" "")
9715 (match_operand:DF 3 "register_operand" "")
9716 (match_operand:V2DF 4 "" "")
9717 (match_operand:V2DF 5 "" "")]
9718 UNSPEC_COPYSIGN))
9719 (clobber (match_scratch:V2DF 1 ""))]
9720 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9721 [(const_int 0)]
9722 {
9723 ix86_split_copysign_var (operands);
9724 DONE;
9725 })
9726
9727 (define_expand "negxf2"
9728 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9729 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9730 "TARGET_80387"
9731 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9732
9733 (define_expand "absxf2"
9734 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9735 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9736 "TARGET_80387"
9737 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9738
9739 (define_insn "*absnegxf2_i387"
9740 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9741 (match_operator:XF 3 "absneg_operator"
9742 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9743 (use (match_operand 2 "" ""))
9744 (clobber (reg:CC FLAGS_REG))]
9745 "TARGET_80387
9746 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9747 "#")
9748
9749 ;; Splitters for fp abs and neg.
9750
9751 (define_split
9752 [(set (match_operand 0 "fp_register_operand" "")
9753 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9754 (use (match_operand 2 "" ""))
9755 (clobber (reg:CC FLAGS_REG))]
9756 "reload_completed"
9757 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9758
9759 (define_split
9760 [(set (match_operand 0 "register_operand" "")
9761 (match_operator 3 "absneg_operator"
9762 [(match_operand 1 "register_operand" "")]))
9763 (use (match_operand 2 "nonimmediate_operand" ""))
9764 (clobber (reg:CC FLAGS_REG))]
9765 "reload_completed && SSE_REG_P (operands[0])"
9766 [(set (match_dup 0) (match_dup 3))]
9767 {
9768 enum machine_mode mode = GET_MODE (operands[0]);
9769 enum machine_mode vmode = GET_MODE (operands[2]);
9770 rtx tmp;
9771
9772 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9773 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9774 if (operands_match_p (operands[0], operands[2]))
9775 {
9776 tmp = operands[1];
9777 operands[1] = operands[2];
9778 operands[2] = tmp;
9779 }
9780 if (GET_CODE (operands[3]) == ABS)
9781 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9782 else
9783 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9784 operands[3] = tmp;
9785 })
9786
9787 (define_split
9788 [(set (match_operand:SF 0 "register_operand" "")
9789 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9790 (use (match_operand:V4SF 2 "" ""))
9791 (clobber (reg:CC FLAGS_REG))]
9792 "reload_completed"
9793 [(parallel [(set (match_dup 0) (match_dup 1))
9794 (clobber (reg:CC FLAGS_REG))])]
9795 {
9796 rtx tmp;
9797 operands[0] = gen_lowpart (SImode, operands[0]);
9798 if (GET_CODE (operands[1]) == ABS)
9799 {
9800 tmp = gen_int_mode (0x7fffffff, SImode);
9801 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9802 }
9803 else
9804 {
9805 tmp = gen_int_mode (0x80000000, SImode);
9806 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9807 }
9808 operands[1] = tmp;
9809 })
9810
9811 (define_split
9812 [(set (match_operand:DF 0 "register_operand" "")
9813 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9814 (use (match_operand 2 "" ""))
9815 (clobber (reg:CC FLAGS_REG))]
9816 "reload_completed"
9817 [(parallel [(set (match_dup 0) (match_dup 1))
9818 (clobber (reg:CC FLAGS_REG))])]
9819 {
9820 rtx tmp;
9821 if (TARGET_64BIT)
9822 {
9823 tmp = gen_lowpart (DImode, operands[0]);
9824 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9825 operands[0] = tmp;
9826
9827 if (GET_CODE (operands[1]) == ABS)
9828 tmp = const0_rtx;
9829 else
9830 tmp = gen_rtx_NOT (DImode, tmp);
9831 }
9832 else
9833 {
9834 operands[0] = gen_highpart (SImode, operands[0]);
9835 if (GET_CODE (operands[1]) == ABS)
9836 {
9837 tmp = gen_int_mode (0x7fffffff, SImode);
9838 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9839 }
9840 else
9841 {
9842 tmp = gen_int_mode (0x80000000, SImode);
9843 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9844 }
9845 }
9846 operands[1] = tmp;
9847 })
9848
9849 (define_split
9850 [(set (match_operand:XF 0 "register_operand" "")
9851 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9852 (use (match_operand 2 "" ""))
9853 (clobber (reg:CC FLAGS_REG))]
9854 "reload_completed"
9855 [(parallel [(set (match_dup 0) (match_dup 1))
9856 (clobber (reg:CC FLAGS_REG))])]
9857 {
9858 rtx tmp;
9859 operands[0] = gen_rtx_REG (SImode,
9860 true_regnum (operands[0])
9861 + (TARGET_64BIT ? 1 : 2));
9862 if (GET_CODE (operands[1]) == ABS)
9863 {
9864 tmp = GEN_INT (0x7fff);
9865 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9866 }
9867 else
9868 {
9869 tmp = GEN_INT (0x8000);
9870 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9871 }
9872 operands[1] = tmp;
9873 })
9874
9875 (define_split
9876 [(set (match_operand 0 "memory_operand" "")
9877 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9878 (use (match_operand 2 "" ""))
9879 (clobber (reg:CC FLAGS_REG))]
9880 "reload_completed"
9881 [(parallel [(set (match_dup 0) (match_dup 1))
9882 (clobber (reg:CC FLAGS_REG))])]
9883 {
9884 enum machine_mode mode = GET_MODE (operands[0]);
9885 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9886 rtx tmp;
9887
9888 operands[0] = adjust_address (operands[0], QImode, size - 1);
9889 if (GET_CODE (operands[1]) == ABS)
9890 {
9891 tmp = gen_int_mode (0x7f, QImode);
9892 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9893 }
9894 else
9895 {
9896 tmp = gen_int_mode (0x80, QImode);
9897 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9898 }
9899 operands[1] = tmp;
9900 })
9901
9902 ;; Conditionalize these after reload. If they match before reload, we
9903 ;; lose the clobber and ability to use integer instructions.
9904
9905 (define_insn "*negsf2_1"
9906 [(set (match_operand:SF 0 "register_operand" "=f")
9907 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9908 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9909 "fchs"
9910 [(set_attr "type" "fsgn")
9911 (set_attr "mode" "SF")])
9912
9913 (define_insn "*negdf2_1"
9914 [(set (match_operand:DF 0 "register_operand" "=f")
9915 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9916 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9917 "fchs"
9918 [(set_attr "type" "fsgn")
9919 (set_attr "mode" "DF")])
9920
9921 (define_insn "*negxf2_1"
9922 [(set (match_operand:XF 0 "register_operand" "=f")
9923 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9924 "TARGET_80387"
9925 "fchs"
9926 [(set_attr "type" "fsgn")
9927 (set_attr "mode" "XF")])
9928
9929 (define_insn "*abssf2_1"
9930 [(set (match_operand:SF 0 "register_operand" "=f")
9931 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9932 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9933 "fabs"
9934 [(set_attr "type" "fsgn")
9935 (set_attr "mode" "SF")])
9936
9937 (define_insn "*absdf2_1"
9938 [(set (match_operand:DF 0 "register_operand" "=f")
9939 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9940 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9941 "fabs"
9942 [(set_attr "type" "fsgn")
9943 (set_attr "mode" "DF")])
9944
9945 (define_insn "*absxf2_1"
9946 [(set (match_operand:XF 0 "register_operand" "=f")
9947 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9948 "TARGET_80387"
9949 "fabs"
9950 [(set_attr "type" "fsgn")
9951 (set_attr "mode" "DF")])
9952
9953 (define_insn "*negextendsfdf2"
9954 [(set (match_operand:DF 0 "register_operand" "=f")
9955 (neg:DF (float_extend:DF
9956 (match_operand:SF 1 "register_operand" "0"))))]
9957 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9958 "fchs"
9959 [(set_attr "type" "fsgn")
9960 (set_attr "mode" "DF")])
9961
9962 (define_insn "*negextenddfxf2"
9963 [(set (match_operand:XF 0 "register_operand" "=f")
9964 (neg:XF (float_extend:XF
9965 (match_operand:DF 1 "register_operand" "0"))))]
9966 "TARGET_80387"
9967 "fchs"
9968 [(set_attr "type" "fsgn")
9969 (set_attr "mode" "XF")])
9970
9971 (define_insn "*negextendsfxf2"
9972 [(set (match_operand:XF 0 "register_operand" "=f")
9973 (neg:XF (float_extend:XF
9974 (match_operand:SF 1 "register_operand" "0"))))]
9975 "TARGET_80387"
9976 "fchs"
9977 [(set_attr "type" "fsgn")
9978 (set_attr "mode" "XF")])
9979
9980 (define_insn "*absextendsfdf2"
9981 [(set (match_operand:DF 0 "register_operand" "=f")
9982 (abs:DF (float_extend:DF
9983 (match_operand:SF 1 "register_operand" "0"))))]
9984 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9985 "fabs"
9986 [(set_attr "type" "fsgn")
9987 (set_attr "mode" "DF")])
9988
9989 (define_insn "*absextenddfxf2"
9990 [(set (match_operand:XF 0 "register_operand" "=f")
9991 (abs:XF (float_extend:XF
9992 (match_operand:DF 1 "register_operand" "0"))))]
9993 "TARGET_80387"
9994 "fabs"
9995 [(set_attr "type" "fsgn")
9996 (set_attr "mode" "XF")])
9997
9998 (define_insn "*absextendsfxf2"
9999 [(set (match_operand:XF 0 "register_operand" "=f")
10000 (abs:XF (float_extend:XF
10001 (match_operand:SF 1 "register_operand" "0"))))]
10002 "TARGET_80387"
10003 "fabs"
10004 [(set_attr "type" "fsgn")
10005 (set_attr "mode" "XF")])
10006 \f
10007 ;; One complement instructions
10008
10009 (define_expand "one_cmpldi2"
10010 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10011 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10012 "TARGET_64BIT"
10013 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10014
10015 (define_insn "*one_cmpldi2_1_rex64"
10016 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10017 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10018 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10019 "not{q}\t%0"
10020 [(set_attr "type" "negnot")
10021 (set_attr "mode" "DI")])
10022
10023 (define_insn "*one_cmpldi2_2_rex64"
10024 [(set (reg FLAGS_REG)
10025 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10026 (const_int 0)))
10027 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10028 (not:DI (match_dup 1)))]
10029 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10030 && ix86_unary_operator_ok (NOT, DImode, operands)"
10031 "#"
10032 [(set_attr "type" "alu1")
10033 (set_attr "mode" "DI")])
10034
10035 (define_split
10036 [(set (match_operand 0 "flags_reg_operand" "")
10037 (match_operator 2 "compare_operator"
10038 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10039 (const_int 0)]))
10040 (set (match_operand:DI 1 "nonimmediate_operand" "")
10041 (not:DI (match_dup 3)))]
10042 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10043 [(parallel [(set (match_dup 0)
10044 (match_op_dup 2
10045 [(xor:DI (match_dup 3) (const_int -1))
10046 (const_int 0)]))
10047 (set (match_dup 1)
10048 (xor:DI (match_dup 3) (const_int -1)))])]
10049 "")
10050
10051 (define_expand "one_cmplsi2"
10052 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10053 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10054 ""
10055 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10056
10057 (define_insn "*one_cmplsi2_1"
10058 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10059 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10060 "ix86_unary_operator_ok (NOT, SImode, operands)"
10061 "not{l}\t%0"
10062 [(set_attr "type" "negnot")
10063 (set_attr "mode" "SI")])
10064
10065 ;; ??? Currently never generated - xor is used instead.
10066 (define_insn "*one_cmplsi2_1_zext"
10067 [(set (match_operand:DI 0 "register_operand" "=r")
10068 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10069 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10070 "not{l}\t%k0"
10071 [(set_attr "type" "negnot")
10072 (set_attr "mode" "SI")])
10073
10074 (define_insn "*one_cmplsi2_2"
10075 [(set (reg FLAGS_REG)
10076 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10077 (const_int 0)))
10078 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10079 (not:SI (match_dup 1)))]
10080 "ix86_match_ccmode (insn, CCNOmode)
10081 && ix86_unary_operator_ok (NOT, SImode, operands)"
10082 "#"
10083 [(set_attr "type" "alu1")
10084 (set_attr "mode" "SI")])
10085
10086 (define_split
10087 [(set (match_operand 0 "flags_reg_operand" "")
10088 (match_operator 2 "compare_operator"
10089 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10090 (const_int 0)]))
10091 (set (match_operand:SI 1 "nonimmediate_operand" "")
10092 (not:SI (match_dup 3)))]
10093 "ix86_match_ccmode (insn, CCNOmode)"
10094 [(parallel [(set (match_dup 0)
10095 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10096 (const_int 0)]))
10097 (set (match_dup 1)
10098 (xor:SI (match_dup 3) (const_int -1)))])]
10099 "")
10100
10101 ;; ??? Currently never generated - xor is used instead.
10102 (define_insn "*one_cmplsi2_2_zext"
10103 [(set (reg FLAGS_REG)
10104 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10105 (const_int 0)))
10106 (set (match_operand:DI 0 "register_operand" "=r")
10107 (zero_extend:DI (not:SI (match_dup 1))))]
10108 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10109 && ix86_unary_operator_ok (NOT, SImode, operands)"
10110 "#"
10111 [(set_attr "type" "alu1")
10112 (set_attr "mode" "SI")])
10113
10114 (define_split
10115 [(set (match_operand 0 "flags_reg_operand" "")
10116 (match_operator 2 "compare_operator"
10117 [(not:SI (match_operand:SI 3 "register_operand" ""))
10118 (const_int 0)]))
10119 (set (match_operand:DI 1 "register_operand" "")
10120 (zero_extend:DI (not:SI (match_dup 3))))]
10121 "ix86_match_ccmode (insn, CCNOmode)"
10122 [(parallel [(set (match_dup 0)
10123 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10124 (const_int 0)]))
10125 (set (match_dup 1)
10126 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10127 "")
10128
10129 (define_expand "one_cmplhi2"
10130 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10131 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10132 "TARGET_HIMODE_MATH"
10133 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10134
10135 (define_insn "*one_cmplhi2_1"
10136 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10137 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10138 "ix86_unary_operator_ok (NOT, HImode, operands)"
10139 "not{w}\t%0"
10140 [(set_attr "type" "negnot")
10141 (set_attr "mode" "HI")])
10142
10143 (define_insn "*one_cmplhi2_2"
10144 [(set (reg FLAGS_REG)
10145 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10146 (const_int 0)))
10147 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10148 (not:HI (match_dup 1)))]
10149 "ix86_match_ccmode (insn, CCNOmode)
10150 && ix86_unary_operator_ok (NEG, HImode, operands)"
10151 "#"
10152 [(set_attr "type" "alu1")
10153 (set_attr "mode" "HI")])
10154
10155 (define_split
10156 [(set (match_operand 0 "flags_reg_operand" "")
10157 (match_operator 2 "compare_operator"
10158 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10159 (const_int 0)]))
10160 (set (match_operand:HI 1 "nonimmediate_operand" "")
10161 (not:HI (match_dup 3)))]
10162 "ix86_match_ccmode (insn, CCNOmode)"
10163 [(parallel [(set (match_dup 0)
10164 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10165 (const_int 0)]))
10166 (set (match_dup 1)
10167 (xor:HI (match_dup 3) (const_int -1)))])]
10168 "")
10169
10170 ;; %%% Potential partial reg stall on alternative 1. What to do?
10171 (define_expand "one_cmplqi2"
10172 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10173 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10174 "TARGET_QIMODE_MATH"
10175 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10176
10177 (define_insn "*one_cmplqi2_1"
10178 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10179 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10180 "ix86_unary_operator_ok (NOT, QImode, operands)"
10181 "@
10182 not{b}\t%0
10183 not{l}\t%k0"
10184 [(set_attr "type" "negnot")
10185 (set_attr "mode" "QI,SI")])
10186
10187 (define_insn "*one_cmplqi2_2"
10188 [(set (reg FLAGS_REG)
10189 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10190 (const_int 0)))
10191 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10192 (not:QI (match_dup 1)))]
10193 "ix86_match_ccmode (insn, CCNOmode)
10194 && ix86_unary_operator_ok (NOT, QImode, operands)"
10195 "#"
10196 [(set_attr "type" "alu1")
10197 (set_attr "mode" "QI")])
10198
10199 (define_split
10200 [(set (match_operand 0 "flags_reg_operand" "")
10201 (match_operator 2 "compare_operator"
10202 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10203 (const_int 0)]))
10204 (set (match_operand:QI 1 "nonimmediate_operand" "")
10205 (not:QI (match_dup 3)))]
10206 "ix86_match_ccmode (insn, CCNOmode)"
10207 [(parallel [(set (match_dup 0)
10208 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10209 (const_int 0)]))
10210 (set (match_dup 1)
10211 (xor:QI (match_dup 3) (const_int -1)))])]
10212 "")
10213 \f
10214 ;; Arithmetic shift instructions
10215
10216 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10217 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10218 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10219 ;; from the assembler input.
10220 ;;
10221 ;; This instruction shifts the target reg/mem as usual, but instead of
10222 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10223 ;; is a left shift double, bits are taken from the high order bits of
10224 ;; reg, else if the insn is a shift right double, bits are taken from the
10225 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10226 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10227 ;;
10228 ;; Since sh[lr]d does not change the `reg' operand, that is done
10229 ;; separately, making all shifts emit pairs of shift double and normal
10230 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10231 ;; support a 63 bit shift, each shift where the count is in a reg expands
10232 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10233 ;;
10234 ;; If the shift count is a constant, we need never emit more than one
10235 ;; shift pair, instead using moves and sign extension for counts greater
10236 ;; than 31.
10237
10238 (define_expand "ashlti3"
10239 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10240 (ashift:TI (match_operand:TI 1 "register_operand" "")
10241 (match_operand:QI 2 "nonmemory_operand" "")))
10242 (clobber (reg:CC FLAGS_REG))])]
10243 "TARGET_64BIT"
10244 {
10245 if (! immediate_operand (operands[2], QImode))
10246 {
10247 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10248 DONE;
10249 }
10250 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10251 DONE;
10252 })
10253
10254 (define_insn "ashlti3_1"
10255 [(set (match_operand:TI 0 "register_operand" "=r")
10256 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10257 (match_operand:QI 2 "register_operand" "c")))
10258 (clobber (match_scratch:DI 3 "=&r"))
10259 (clobber (reg:CC FLAGS_REG))]
10260 "TARGET_64BIT"
10261 "#"
10262 [(set_attr "type" "multi")])
10263
10264 (define_insn "*ashlti3_2"
10265 [(set (match_operand:TI 0 "register_operand" "=r")
10266 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10267 (match_operand:QI 2 "immediate_operand" "O")))
10268 (clobber (reg:CC FLAGS_REG))]
10269 "TARGET_64BIT"
10270 "#"
10271 [(set_attr "type" "multi")])
10272
10273 (define_split
10274 [(set (match_operand:TI 0 "register_operand" "")
10275 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10276 (match_operand:QI 2 "register_operand" "")))
10277 (clobber (match_scratch:DI 3 ""))
10278 (clobber (reg:CC FLAGS_REG))]
10279 "TARGET_64BIT && reload_completed"
10280 [(const_int 0)]
10281 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10282
10283 (define_split
10284 [(set (match_operand:TI 0 "register_operand" "")
10285 (ashift:TI (match_operand:TI 1 "register_operand" "")
10286 (match_operand:QI 2 "immediate_operand" "")))
10287 (clobber (reg:CC FLAGS_REG))]
10288 "TARGET_64BIT && reload_completed"
10289 [(const_int 0)]
10290 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10291
10292 (define_insn "x86_64_shld"
10293 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10294 (ior:DI (ashift:DI (match_dup 0)
10295 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10296 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10297 (minus:QI (const_int 64) (match_dup 2)))))
10298 (clobber (reg:CC FLAGS_REG))]
10299 "TARGET_64BIT"
10300 "@
10301 shld{q}\t{%2, %1, %0|%0, %1, %2}
10302 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10303 [(set_attr "type" "ishift")
10304 (set_attr "prefix_0f" "1")
10305 (set_attr "mode" "DI")
10306 (set_attr "athlon_decode" "vector")])
10307
10308 (define_expand "x86_64_shift_adj"
10309 [(set (reg:CCZ FLAGS_REG)
10310 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10311 (const_int 64))
10312 (const_int 0)))
10313 (set (match_operand:DI 0 "register_operand" "")
10314 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10315 (match_operand:DI 1 "register_operand" "")
10316 (match_dup 0)))
10317 (set (match_dup 1)
10318 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10319 (match_operand:DI 3 "register_operand" "r")
10320 (match_dup 1)))]
10321 "TARGET_64BIT"
10322 "")
10323
10324 (define_expand "ashldi3"
10325 [(set (match_operand:DI 0 "shiftdi_operand" "")
10326 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10327 (match_operand:QI 2 "nonmemory_operand" "")))]
10328 ""
10329 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10330
10331 (define_insn "*ashldi3_1_rex64"
10332 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10333 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10334 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10335 (clobber (reg:CC FLAGS_REG))]
10336 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10337 {
10338 switch (get_attr_type (insn))
10339 {
10340 case TYPE_ALU:
10341 gcc_assert (operands[2] == const1_rtx);
10342 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10343 return "add{q}\t{%0, %0|%0, %0}";
10344
10345 case TYPE_LEA:
10346 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10347 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10348 operands[1] = gen_rtx_MULT (DImode, operands[1],
10349 GEN_INT (1 << INTVAL (operands[2])));
10350 return "lea{q}\t{%a1, %0|%0, %a1}";
10351
10352 default:
10353 if (REG_P (operands[2]))
10354 return "sal{q}\t{%b2, %0|%0, %b2}";
10355 else if (operands[2] == const1_rtx
10356 && (TARGET_SHIFT1 || optimize_size))
10357 return "sal{q}\t%0";
10358 else
10359 return "sal{q}\t{%2, %0|%0, %2}";
10360 }
10361 }
10362 [(set (attr "type")
10363 (cond [(eq_attr "alternative" "1")
10364 (const_string "lea")
10365 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10366 (const_int 0))
10367 (match_operand 0 "register_operand" ""))
10368 (match_operand 2 "const1_operand" ""))
10369 (const_string "alu")
10370 ]
10371 (const_string "ishift")))
10372 (set_attr "mode" "DI")])
10373
10374 ;; Convert lea to the lea pattern to avoid flags dependency.
10375 (define_split
10376 [(set (match_operand:DI 0 "register_operand" "")
10377 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10378 (match_operand:QI 2 "immediate_operand" "")))
10379 (clobber (reg:CC FLAGS_REG))]
10380 "TARGET_64BIT && reload_completed
10381 && true_regnum (operands[0]) != true_regnum (operands[1])"
10382 [(set (match_dup 0)
10383 (mult:DI (match_dup 1)
10384 (match_dup 2)))]
10385 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10386
10387 ;; This pattern can't accept a variable shift count, since shifts by
10388 ;; zero don't affect the flags. We assume that shifts by constant
10389 ;; zero are optimized away.
10390 (define_insn "*ashldi3_cmp_rex64"
10391 [(set (reg FLAGS_REG)
10392 (compare
10393 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10394 (match_operand:QI 2 "immediate_operand" "e"))
10395 (const_int 0)))
10396 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10397 (ashift:DI (match_dup 1) (match_dup 2)))]
10398 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10399 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10400 {
10401 switch (get_attr_type (insn))
10402 {
10403 case TYPE_ALU:
10404 gcc_assert (operands[2] == const1_rtx);
10405 return "add{q}\t{%0, %0|%0, %0}";
10406
10407 default:
10408 if (REG_P (operands[2]))
10409 return "sal{q}\t{%b2, %0|%0, %b2}";
10410 else if (operands[2] == const1_rtx
10411 && (TARGET_SHIFT1 || optimize_size))
10412 return "sal{q}\t%0";
10413 else
10414 return "sal{q}\t{%2, %0|%0, %2}";
10415 }
10416 }
10417 [(set (attr "type")
10418 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10419 (const_int 0))
10420 (match_operand 0 "register_operand" ""))
10421 (match_operand 2 "const1_operand" ""))
10422 (const_string "alu")
10423 ]
10424 (const_string "ishift")))
10425 (set_attr "mode" "DI")])
10426
10427 (define_insn "*ashldi3_1"
10428 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10429 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10430 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10431 (clobber (reg:CC FLAGS_REG))]
10432 "!TARGET_64BIT"
10433 "#"
10434 [(set_attr "type" "multi")])
10435
10436 ;; By default we don't ask for a scratch register, because when DImode
10437 ;; values are manipulated, registers are already at a premium. But if
10438 ;; we have one handy, we won't turn it away.
10439 (define_peephole2
10440 [(match_scratch:SI 3 "r")
10441 (parallel [(set (match_operand:DI 0 "register_operand" "")
10442 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10443 (match_operand:QI 2 "nonmemory_operand" "")))
10444 (clobber (reg:CC FLAGS_REG))])
10445 (match_dup 3)]
10446 "!TARGET_64BIT && TARGET_CMOVE"
10447 [(const_int 0)]
10448 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10449
10450 (define_split
10451 [(set (match_operand:DI 0 "register_operand" "")
10452 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10453 (match_operand:QI 2 "nonmemory_operand" "")))
10454 (clobber (reg:CC FLAGS_REG))]
10455 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10456 ? flow2_completed : reload_completed)"
10457 [(const_int 0)]
10458 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10459
10460 (define_insn "x86_shld_1"
10461 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10462 (ior:SI (ashift:SI (match_dup 0)
10463 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10464 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10465 (minus:QI (const_int 32) (match_dup 2)))))
10466 (clobber (reg:CC FLAGS_REG))]
10467 ""
10468 "@
10469 shld{l}\t{%2, %1, %0|%0, %1, %2}
10470 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10471 [(set_attr "type" "ishift")
10472 (set_attr "prefix_0f" "1")
10473 (set_attr "mode" "SI")
10474 (set_attr "pent_pair" "np")
10475 (set_attr "athlon_decode" "vector")])
10476
10477 (define_expand "x86_shift_adj_1"
10478 [(set (reg:CCZ FLAGS_REG)
10479 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10480 (const_int 32))
10481 (const_int 0)))
10482 (set (match_operand:SI 0 "register_operand" "")
10483 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10484 (match_operand:SI 1 "register_operand" "")
10485 (match_dup 0)))
10486 (set (match_dup 1)
10487 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10488 (match_operand:SI 3 "register_operand" "r")
10489 (match_dup 1)))]
10490 "TARGET_CMOVE"
10491 "")
10492
10493 (define_expand "x86_shift_adj_2"
10494 [(use (match_operand:SI 0 "register_operand" ""))
10495 (use (match_operand:SI 1 "register_operand" ""))
10496 (use (match_operand:QI 2 "register_operand" ""))]
10497 ""
10498 {
10499 rtx label = gen_label_rtx ();
10500 rtx tmp;
10501
10502 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10503
10504 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10505 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10506 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10507 gen_rtx_LABEL_REF (VOIDmode, label),
10508 pc_rtx);
10509 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10510 JUMP_LABEL (tmp) = label;
10511
10512 emit_move_insn (operands[0], operands[1]);
10513 ix86_expand_clear (operands[1]);
10514
10515 emit_label (label);
10516 LABEL_NUSES (label) = 1;
10517
10518 DONE;
10519 })
10520
10521 (define_expand "ashlsi3"
10522 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10523 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10524 (match_operand:QI 2 "nonmemory_operand" "")))
10525 (clobber (reg:CC FLAGS_REG))]
10526 ""
10527 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10528
10529 (define_insn "*ashlsi3_1"
10530 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10531 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10532 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10533 (clobber (reg:CC FLAGS_REG))]
10534 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10535 {
10536 switch (get_attr_type (insn))
10537 {
10538 case TYPE_ALU:
10539 gcc_assert (operands[2] == const1_rtx);
10540 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10541 return "add{l}\t{%0, %0|%0, %0}";
10542
10543 case TYPE_LEA:
10544 return "#";
10545
10546 default:
10547 if (REG_P (operands[2]))
10548 return "sal{l}\t{%b2, %0|%0, %b2}";
10549 else if (operands[2] == const1_rtx
10550 && (TARGET_SHIFT1 || optimize_size))
10551 return "sal{l}\t%0";
10552 else
10553 return "sal{l}\t{%2, %0|%0, %2}";
10554 }
10555 }
10556 [(set (attr "type")
10557 (cond [(eq_attr "alternative" "1")
10558 (const_string "lea")
10559 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10560 (const_int 0))
10561 (match_operand 0 "register_operand" ""))
10562 (match_operand 2 "const1_operand" ""))
10563 (const_string "alu")
10564 ]
10565 (const_string "ishift")))
10566 (set_attr "mode" "SI")])
10567
10568 ;; Convert lea to the lea pattern to avoid flags dependency.
10569 (define_split
10570 [(set (match_operand 0 "register_operand" "")
10571 (ashift (match_operand 1 "index_register_operand" "")
10572 (match_operand:QI 2 "const_int_operand" "")))
10573 (clobber (reg:CC FLAGS_REG))]
10574 "reload_completed
10575 && true_regnum (operands[0]) != true_regnum (operands[1])
10576 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10577 [(const_int 0)]
10578 {
10579 rtx pat;
10580 enum machine_mode mode = GET_MODE (operands[0]);
10581
10582 if (GET_MODE_SIZE (mode) < 4)
10583 operands[0] = gen_lowpart (SImode, operands[0]);
10584 if (mode != Pmode)
10585 operands[1] = gen_lowpart (Pmode, operands[1]);
10586 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10587
10588 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10589 if (Pmode != SImode)
10590 pat = gen_rtx_SUBREG (SImode, pat, 0);
10591 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10592 DONE;
10593 })
10594
10595 ;; Rare case of shifting RSP is handled by generating move and shift
10596 (define_split
10597 [(set (match_operand 0 "register_operand" "")
10598 (ashift (match_operand 1 "register_operand" "")
10599 (match_operand:QI 2 "const_int_operand" "")))
10600 (clobber (reg:CC FLAGS_REG))]
10601 "reload_completed
10602 && true_regnum (operands[0]) != true_regnum (operands[1])"
10603 [(const_int 0)]
10604 {
10605 rtx pat, clob;
10606 emit_move_insn (operands[0], operands[1]);
10607 pat = gen_rtx_SET (VOIDmode, operands[0],
10608 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10609 operands[0], operands[2]));
10610 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10611 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10612 DONE;
10613 })
10614
10615 (define_insn "*ashlsi3_1_zext"
10616 [(set (match_operand:DI 0 "register_operand" "=r,r")
10617 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10618 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10619 (clobber (reg:CC FLAGS_REG))]
10620 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10621 {
10622 switch (get_attr_type (insn))
10623 {
10624 case TYPE_ALU:
10625 gcc_assert (operands[2] == const1_rtx);
10626 return "add{l}\t{%k0, %k0|%k0, %k0}";
10627
10628 case TYPE_LEA:
10629 return "#";
10630
10631 default:
10632 if (REG_P (operands[2]))
10633 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10634 else if (operands[2] == const1_rtx
10635 && (TARGET_SHIFT1 || optimize_size))
10636 return "sal{l}\t%k0";
10637 else
10638 return "sal{l}\t{%2, %k0|%k0, %2}";
10639 }
10640 }
10641 [(set (attr "type")
10642 (cond [(eq_attr "alternative" "1")
10643 (const_string "lea")
10644 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10645 (const_int 0))
10646 (match_operand 2 "const1_operand" ""))
10647 (const_string "alu")
10648 ]
10649 (const_string "ishift")))
10650 (set_attr "mode" "SI")])
10651
10652 ;; Convert lea to the lea pattern to avoid flags dependency.
10653 (define_split
10654 [(set (match_operand:DI 0 "register_operand" "")
10655 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10656 (match_operand:QI 2 "const_int_operand" ""))))
10657 (clobber (reg:CC FLAGS_REG))]
10658 "TARGET_64BIT && reload_completed
10659 && true_regnum (operands[0]) != true_regnum (operands[1])"
10660 [(set (match_dup 0) (zero_extend:DI
10661 (subreg:SI (mult:SI (match_dup 1)
10662 (match_dup 2)) 0)))]
10663 {
10664 operands[1] = gen_lowpart (Pmode, operands[1]);
10665 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10666 })
10667
10668 ;; This pattern can't accept a variable shift count, since shifts by
10669 ;; zero don't affect the flags. We assume that shifts by constant
10670 ;; zero are optimized away.
10671 (define_insn "*ashlsi3_cmp"
10672 [(set (reg FLAGS_REG)
10673 (compare
10674 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10675 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10676 (const_int 0)))
10677 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10678 (ashift:SI (match_dup 1) (match_dup 2)))]
10679 "ix86_match_ccmode (insn, CCGOCmode)
10680 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10681 {
10682 switch (get_attr_type (insn))
10683 {
10684 case TYPE_ALU:
10685 gcc_assert (operands[2] == const1_rtx);
10686 return "add{l}\t{%0, %0|%0, %0}";
10687
10688 default:
10689 if (REG_P (operands[2]))
10690 return "sal{l}\t{%b2, %0|%0, %b2}";
10691 else if (operands[2] == const1_rtx
10692 && (TARGET_SHIFT1 || optimize_size))
10693 return "sal{l}\t%0";
10694 else
10695 return "sal{l}\t{%2, %0|%0, %2}";
10696 }
10697 }
10698 [(set (attr "type")
10699 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10700 (const_int 0))
10701 (match_operand 0 "register_operand" ""))
10702 (match_operand 2 "const1_operand" ""))
10703 (const_string "alu")
10704 ]
10705 (const_string "ishift")))
10706 (set_attr "mode" "SI")])
10707
10708 (define_insn "*ashlsi3_cmp_zext"
10709 [(set (reg FLAGS_REG)
10710 (compare
10711 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10712 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10713 (const_int 0)))
10714 (set (match_operand:DI 0 "register_operand" "=r")
10715 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10716 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10717 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10718 {
10719 switch (get_attr_type (insn))
10720 {
10721 case TYPE_ALU:
10722 gcc_assert (operands[2] == const1_rtx);
10723 return "add{l}\t{%k0, %k0|%k0, %k0}";
10724
10725 default:
10726 if (REG_P (operands[2]))
10727 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10728 else if (operands[2] == const1_rtx
10729 && (TARGET_SHIFT1 || optimize_size))
10730 return "sal{l}\t%k0";
10731 else
10732 return "sal{l}\t{%2, %k0|%k0, %2}";
10733 }
10734 }
10735 [(set (attr "type")
10736 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10737 (const_int 0))
10738 (match_operand 2 "const1_operand" ""))
10739 (const_string "alu")
10740 ]
10741 (const_string "ishift")))
10742 (set_attr "mode" "SI")])
10743
10744 (define_expand "ashlhi3"
10745 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10746 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10747 (match_operand:QI 2 "nonmemory_operand" "")))
10748 (clobber (reg:CC FLAGS_REG))]
10749 "TARGET_HIMODE_MATH"
10750 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10751
10752 (define_insn "*ashlhi3_1_lea"
10753 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10754 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10755 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10756 (clobber (reg:CC FLAGS_REG))]
10757 "!TARGET_PARTIAL_REG_STALL
10758 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10759 {
10760 switch (get_attr_type (insn))
10761 {
10762 case TYPE_LEA:
10763 return "#";
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 [(eq_attr "alternative" "1")
10780 (const_string "lea")
10781 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10782 (const_int 0))
10783 (match_operand 0 "register_operand" ""))
10784 (match_operand 2 "const1_operand" ""))
10785 (const_string "alu")
10786 ]
10787 (const_string "ishift")))
10788 (set_attr "mode" "HI,SI")])
10789
10790 (define_insn "*ashlhi3_1"
10791 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10792 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10793 (match_operand:QI 2 "nonmemory_operand" "cI")))
10794 (clobber (reg:CC FLAGS_REG))]
10795 "TARGET_PARTIAL_REG_STALL
10796 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10797 {
10798 switch (get_attr_type (insn))
10799 {
10800 case TYPE_ALU:
10801 gcc_assert (operands[2] == const1_rtx);
10802 return "add{w}\t{%0, %0|%0, %0}";
10803
10804 default:
10805 if (REG_P (operands[2]))
10806 return "sal{w}\t{%b2, %0|%0, %b2}";
10807 else if (operands[2] == const1_rtx
10808 && (TARGET_SHIFT1 || optimize_size))
10809 return "sal{w}\t%0";
10810 else
10811 return "sal{w}\t{%2, %0|%0, %2}";
10812 }
10813 }
10814 [(set (attr "type")
10815 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10816 (const_int 0))
10817 (match_operand 0 "register_operand" ""))
10818 (match_operand 2 "const1_operand" ""))
10819 (const_string "alu")
10820 ]
10821 (const_string "ishift")))
10822 (set_attr "mode" "HI")])
10823
10824 ;; This pattern can't accept a variable shift count, since shifts by
10825 ;; zero don't affect the flags. We assume that shifts by constant
10826 ;; zero are optimized away.
10827 (define_insn "*ashlhi3_cmp"
10828 [(set (reg FLAGS_REG)
10829 (compare
10830 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10831 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10832 (const_int 0)))
10833 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10834 (ashift:HI (match_dup 1) (match_dup 2)))]
10835 "ix86_match_ccmode (insn, CCGOCmode)
10836 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10837 {
10838 switch (get_attr_type (insn))
10839 {
10840 case TYPE_ALU:
10841 gcc_assert (operands[2] == const1_rtx);
10842 return "add{w}\t{%0, %0|%0, %0}";
10843
10844 default:
10845 if (REG_P (operands[2]))
10846 return "sal{w}\t{%b2, %0|%0, %b2}";
10847 else if (operands[2] == const1_rtx
10848 && (TARGET_SHIFT1 || optimize_size))
10849 return "sal{w}\t%0";
10850 else
10851 return "sal{w}\t{%2, %0|%0, %2}";
10852 }
10853 }
10854 [(set (attr "type")
10855 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10856 (const_int 0))
10857 (match_operand 0 "register_operand" ""))
10858 (match_operand 2 "const1_operand" ""))
10859 (const_string "alu")
10860 ]
10861 (const_string "ishift")))
10862 (set_attr "mode" "HI")])
10863
10864 (define_expand "ashlqi3"
10865 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10866 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10867 (match_operand:QI 2 "nonmemory_operand" "")))
10868 (clobber (reg:CC FLAGS_REG))]
10869 "TARGET_QIMODE_MATH"
10870 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10871
10872 ;; %%% Potential partial reg stall on alternative 2. What to do?
10873
10874 (define_insn "*ashlqi3_1_lea"
10875 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10876 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10877 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10878 (clobber (reg:CC FLAGS_REG))]
10879 "!TARGET_PARTIAL_REG_STALL
10880 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10881 {
10882 switch (get_attr_type (insn))
10883 {
10884 case TYPE_LEA:
10885 return "#";
10886 case TYPE_ALU:
10887 gcc_assert (operands[2] == const1_rtx);
10888 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10889 return "add{l}\t{%k0, %k0|%k0, %k0}";
10890 else
10891 return "add{b}\t{%0, %0|%0, %0}";
10892
10893 default:
10894 if (REG_P (operands[2]))
10895 {
10896 if (get_attr_mode (insn) == MODE_SI)
10897 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10898 else
10899 return "sal{b}\t{%b2, %0|%0, %b2}";
10900 }
10901 else if (operands[2] == const1_rtx
10902 && (TARGET_SHIFT1 || optimize_size))
10903 {
10904 if (get_attr_mode (insn) == MODE_SI)
10905 return "sal{l}\t%0";
10906 else
10907 return "sal{b}\t%0";
10908 }
10909 else
10910 {
10911 if (get_attr_mode (insn) == MODE_SI)
10912 return "sal{l}\t{%2, %k0|%k0, %2}";
10913 else
10914 return "sal{b}\t{%2, %0|%0, %2}";
10915 }
10916 }
10917 }
10918 [(set (attr "type")
10919 (cond [(eq_attr "alternative" "2")
10920 (const_string "lea")
10921 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10922 (const_int 0))
10923 (match_operand 0 "register_operand" ""))
10924 (match_operand 2 "const1_operand" ""))
10925 (const_string "alu")
10926 ]
10927 (const_string "ishift")))
10928 (set_attr "mode" "QI,SI,SI")])
10929
10930 (define_insn "*ashlqi3_1"
10931 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10932 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10933 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10934 (clobber (reg:CC FLAGS_REG))]
10935 "TARGET_PARTIAL_REG_STALL
10936 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10937 {
10938 switch (get_attr_type (insn))
10939 {
10940 case TYPE_ALU:
10941 gcc_assert (operands[2] == const1_rtx);
10942 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10943 return "add{l}\t{%k0, %k0|%k0, %k0}";
10944 else
10945 return "add{b}\t{%0, %0|%0, %0}";
10946
10947 default:
10948 if (REG_P (operands[2]))
10949 {
10950 if (get_attr_mode (insn) == MODE_SI)
10951 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10952 else
10953 return "sal{b}\t{%b2, %0|%0, %b2}";
10954 }
10955 else if (operands[2] == const1_rtx
10956 && (TARGET_SHIFT1 || optimize_size))
10957 {
10958 if (get_attr_mode (insn) == MODE_SI)
10959 return "sal{l}\t%0";
10960 else
10961 return "sal{b}\t%0";
10962 }
10963 else
10964 {
10965 if (get_attr_mode (insn) == MODE_SI)
10966 return "sal{l}\t{%2, %k0|%k0, %2}";
10967 else
10968 return "sal{b}\t{%2, %0|%0, %2}";
10969 }
10970 }
10971 }
10972 [(set (attr "type")
10973 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974 (const_int 0))
10975 (match_operand 0 "register_operand" ""))
10976 (match_operand 2 "const1_operand" ""))
10977 (const_string "alu")
10978 ]
10979 (const_string "ishift")))
10980 (set_attr "mode" "QI,SI")])
10981
10982 ;; This pattern can't accept a variable shift count, since shifts by
10983 ;; zero don't affect the flags. We assume that shifts by constant
10984 ;; zero are optimized away.
10985 (define_insn "*ashlqi3_cmp"
10986 [(set (reg FLAGS_REG)
10987 (compare
10988 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10989 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10990 (const_int 0)))
10991 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10992 (ashift:QI (match_dup 1) (match_dup 2)))]
10993 "ix86_match_ccmode (insn, CCGOCmode)
10994 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10995 {
10996 switch (get_attr_type (insn))
10997 {
10998 case TYPE_ALU:
10999 gcc_assert (operands[2] == const1_rtx);
11000 return "add{b}\t{%0, %0|%0, %0}";
11001
11002 default:
11003 if (REG_P (operands[2]))
11004 return "sal{b}\t{%b2, %0|%0, %b2}";
11005 else if (operands[2] == const1_rtx
11006 && (TARGET_SHIFT1 || optimize_size))
11007 return "sal{b}\t%0";
11008 else
11009 return "sal{b}\t{%2, %0|%0, %2}";
11010 }
11011 }
11012 [(set (attr "type")
11013 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014 (const_int 0))
11015 (match_operand 0 "register_operand" ""))
11016 (match_operand 2 "const1_operand" ""))
11017 (const_string "alu")
11018 ]
11019 (const_string "ishift")))
11020 (set_attr "mode" "QI")])
11021
11022 ;; See comment above `ashldi3' about how this works.
11023
11024 (define_expand "ashrti3"
11025 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11026 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11027 (match_operand:QI 2 "nonmemory_operand" "")))
11028 (clobber (reg:CC FLAGS_REG))])]
11029 "TARGET_64BIT"
11030 {
11031 if (! immediate_operand (operands[2], QImode))
11032 {
11033 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11034 DONE;
11035 }
11036 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11037 DONE;
11038 })
11039
11040 (define_insn "ashrti3_1"
11041 [(set (match_operand:TI 0 "register_operand" "=r")
11042 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11043 (match_operand:QI 2 "register_operand" "c")))
11044 (clobber (match_scratch:DI 3 "=&r"))
11045 (clobber (reg:CC FLAGS_REG))]
11046 "TARGET_64BIT"
11047 "#"
11048 [(set_attr "type" "multi")])
11049
11050 (define_insn "*ashrti3_2"
11051 [(set (match_operand:TI 0 "register_operand" "=r")
11052 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11053 (match_operand:QI 2 "immediate_operand" "O")))
11054 (clobber (reg:CC FLAGS_REG))]
11055 "TARGET_64BIT"
11056 "#"
11057 [(set_attr "type" "multi")])
11058
11059 (define_split
11060 [(set (match_operand:TI 0 "register_operand" "")
11061 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11062 (match_operand:QI 2 "register_operand" "")))
11063 (clobber (match_scratch:DI 3 ""))
11064 (clobber (reg:CC FLAGS_REG))]
11065 "TARGET_64BIT && reload_completed"
11066 [(const_int 0)]
11067 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11068
11069 (define_split
11070 [(set (match_operand:TI 0 "register_operand" "")
11071 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11072 (match_operand:QI 2 "immediate_operand" "")))
11073 (clobber (reg:CC FLAGS_REG))]
11074 "TARGET_64BIT && reload_completed"
11075 [(const_int 0)]
11076 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11077
11078 (define_insn "x86_64_shrd"
11079 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11080 (ior:DI (ashiftrt:DI (match_dup 0)
11081 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11082 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11083 (minus:QI (const_int 64) (match_dup 2)))))
11084 (clobber (reg:CC FLAGS_REG))]
11085 "TARGET_64BIT"
11086 "@
11087 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11088 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11089 [(set_attr "type" "ishift")
11090 (set_attr "prefix_0f" "1")
11091 (set_attr "mode" "DI")
11092 (set_attr "athlon_decode" "vector")])
11093
11094 (define_expand "ashrdi3"
11095 [(set (match_operand:DI 0 "shiftdi_operand" "")
11096 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11097 (match_operand:QI 2 "nonmemory_operand" "")))]
11098 ""
11099 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11100
11101 (define_insn "*ashrdi3_63_rex64"
11102 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11103 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11104 (match_operand:DI 2 "const_int_operand" "i,i")))
11105 (clobber (reg:CC FLAGS_REG))]
11106 "TARGET_64BIT && INTVAL (operands[2]) == 63
11107 && (TARGET_USE_CLTD || optimize_size)
11108 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11109 "@
11110 {cqto|cqo}
11111 sar{q}\t{%2, %0|%0, %2}"
11112 [(set_attr "type" "imovx,ishift")
11113 (set_attr "prefix_0f" "0,*")
11114 (set_attr "length_immediate" "0,*")
11115 (set_attr "modrm" "0,1")
11116 (set_attr "mode" "DI")])
11117
11118 (define_insn "*ashrdi3_1_one_bit_rex64"
11119 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11120 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11121 (match_operand:QI 2 "const1_operand" "")))
11122 (clobber (reg:CC FLAGS_REG))]
11123 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11124 && (TARGET_SHIFT1 || optimize_size)"
11125 "sar{q}\t%0"
11126 [(set_attr "type" "ishift")
11127 (set (attr "length")
11128 (if_then_else (match_operand:DI 0 "register_operand" "")
11129 (const_string "2")
11130 (const_string "*")))])
11131
11132 (define_insn "*ashrdi3_1_rex64"
11133 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11134 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11135 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11136 (clobber (reg:CC FLAGS_REG))]
11137 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11138 "@
11139 sar{q}\t{%2, %0|%0, %2}
11140 sar{q}\t{%b2, %0|%0, %b2}"
11141 [(set_attr "type" "ishift")
11142 (set_attr "mode" "DI")])
11143
11144 ;; This pattern can't accept a variable shift count, since shifts by
11145 ;; zero don't affect the flags. We assume that shifts by constant
11146 ;; zero are optimized away.
11147 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11148 [(set (reg FLAGS_REG)
11149 (compare
11150 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11151 (match_operand:QI 2 "const1_operand" ""))
11152 (const_int 0)))
11153 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11154 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11155 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11156 && (TARGET_SHIFT1 || optimize_size)
11157 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11158 "sar{q}\t%0"
11159 [(set_attr "type" "ishift")
11160 (set (attr "length")
11161 (if_then_else (match_operand:DI 0 "register_operand" "")
11162 (const_string "2")
11163 (const_string "*")))])
11164
11165 ;; This pattern can't accept a variable shift count, since shifts by
11166 ;; zero don't affect the flags. We assume that shifts by constant
11167 ;; zero are optimized away.
11168 (define_insn "*ashrdi3_cmp_rex64"
11169 [(set (reg FLAGS_REG)
11170 (compare
11171 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11172 (match_operand:QI 2 "const_int_operand" "n"))
11173 (const_int 0)))
11174 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11175 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11176 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11177 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11178 "sar{q}\t{%2, %0|%0, %2}"
11179 [(set_attr "type" "ishift")
11180 (set_attr "mode" "DI")])
11181
11182 (define_insn "*ashrdi3_1"
11183 [(set (match_operand:DI 0 "register_operand" "=r")
11184 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11185 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11186 (clobber (reg:CC FLAGS_REG))]
11187 "!TARGET_64BIT"
11188 "#"
11189 [(set_attr "type" "multi")])
11190
11191 ;; By default we don't ask for a scratch register, because when DImode
11192 ;; values are manipulated, registers are already at a premium. But if
11193 ;; we have one handy, we won't turn it away.
11194 (define_peephole2
11195 [(match_scratch:SI 3 "r")
11196 (parallel [(set (match_operand:DI 0 "register_operand" "")
11197 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11198 (match_operand:QI 2 "nonmemory_operand" "")))
11199 (clobber (reg:CC FLAGS_REG))])
11200 (match_dup 3)]
11201 "!TARGET_64BIT && TARGET_CMOVE"
11202 [(const_int 0)]
11203 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11204
11205 (define_split
11206 [(set (match_operand:DI 0 "register_operand" "")
11207 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11208 (match_operand:QI 2 "nonmemory_operand" "")))
11209 (clobber (reg:CC FLAGS_REG))]
11210 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11211 ? flow2_completed : reload_completed)"
11212 [(const_int 0)]
11213 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11214
11215 (define_insn "x86_shrd_1"
11216 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11217 (ior:SI (ashiftrt:SI (match_dup 0)
11218 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11219 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11220 (minus:QI (const_int 32) (match_dup 2)))))
11221 (clobber (reg:CC FLAGS_REG))]
11222 ""
11223 "@
11224 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11225 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11226 [(set_attr "type" "ishift")
11227 (set_attr "prefix_0f" "1")
11228 (set_attr "pent_pair" "np")
11229 (set_attr "mode" "SI")])
11230
11231 (define_expand "x86_shift_adj_3"
11232 [(use (match_operand:SI 0 "register_operand" ""))
11233 (use (match_operand:SI 1 "register_operand" ""))
11234 (use (match_operand:QI 2 "register_operand" ""))]
11235 ""
11236 {
11237 rtx label = gen_label_rtx ();
11238 rtx tmp;
11239
11240 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11241
11242 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11243 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11244 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11245 gen_rtx_LABEL_REF (VOIDmode, label),
11246 pc_rtx);
11247 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11248 JUMP_LABEL (tmp) = label;
11249
11250 emit_move_insn (operands[0], operands[1]);
11251 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11252
11253 emit_label (label);
11254 LABEL_NUSES (label) = 1;
11255
11256 DONE;
11257 })
11258
11259 (define_insn "ashrsi3_31"
11260 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11261 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11262 (match_operand:SI 2 "const_int_operand" "i,i")))
11263 (clobber (reg:CC FLAGS_REG))]
11264 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11265 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11266 "@
11267 {cltd|cdq}
11268 sar{l}\t{%2, %0|%0, %2}"
11269 [(set_attr "type" "imovx,ishift")
11270 (set_attr "prefix_0f" "0,*")
11271 (set_attr "length_immediate" "0,*")
11272 (set_attr "modrm" "0,1")
11273 (set_attr "mode" "SI")])
11274
11275 (define_insn "*ashrsi3_31_zext"
11276 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11277 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11278 (match_operand:SI 2 "const_int_operand" "i,i"))))
11279 (clobber (reg:CC FLAGS_REG))]
11280 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11281 && INTVAL (operands[2]) == 31
11282 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11283 "@
11284 {cltd|cdq}
11285 sar{l}\t{%2, %k0|%k0, %2}"
11286 [(set_attr "type" "imovx,ishift")
11287 (set_attr "prefix_0f" "0,*")
11288 (set_attr "length_immediate" "0,*")
11289 (set_attr "modrm" "0,1")
11290 (set_attr "mode" "SI")])
11291
11292 (define_expand "ashrsi3"
11293 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11294 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11295 (match_operand:QI 2 "nonmemory_operand" "")))
11296 (clobber (reg:CC FLAGS_REG))]
11297 ""
11298 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11299
11300 (define_insn "*ashrsi3_1_one_bit"
11301 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11302 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11303 (match_operand:QI 2 "const1_operand" "")))
11304 (clobber (reg:CC FLAGS_REG))]
11305 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11306 && (TARGET_SHIFT1 || optimize_size)"
11307 "sar{l}\t%0"
11308 [(set_attr "type" "ishift")
11309 (set (attr "length")
11310 (if_then_else (match_operand:SI 0 "register_operand" "")
11311 (const_string "2")
11312 (const_string "*")))])
11313
11314 (define_insn "*ashrsi3_1_one_bit_zext"
11315 [(set (match_operand:DI 0 "register_operand" "=r")
11316 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11317 (match_operand:QI 2 "const1_operand" ""))))
11318 (clobber (reg:CC FLAGS_REG))]
11319 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11320 && (TARGET_SHIFT1 || optimize_size)"
11321 "sar{l}\t%k0"
11322 [(set_attr "type" "ishift")
11323 (set_attr "length" "2")])
11324
11325 (define_insn "*ashrsi3_1"
11326 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11327 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11328 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11329 (clobber (reg:CC FLAGS_REG))]
11330 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11331 "@
11332 sar{l}\t{%2, %0|%0, %2}
11333 sar{l}\t{%b2, %0|%0, %b2}"
11334 [(set_attr "type" "ishift")
11335 (set_attr "mode" "SI")])
11336
11337 (define_insn "*ashrsi3_1_zext"
11338 [(set (match_operand:DI 0 "register_operand" "=r,r")
11339 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11340 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11341 (clobber (reg:CC FLAGS_REG))]
11342 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11343 "@
11344 sar{l}\t{%2, %k0|%k0, %2}
11345 sar{l}\t{%b2, %k0|%k0, %b2}"
11346 [(set_attr "type" "ishift")
11347 (set_attr "mode" "SI")])
11348
11349 ;; This pattern can't accept a variable shift count, since shifts by
11350 ;; zero don't affect the flags. We assume that shifts by constant
11351 ;; zero are optimized away.
11352 (define_insn "*ashrsi3_one_bit_cmp"
11353 [(set (reg FLAGS_REG)
11354 (compare
11355 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11356 (match_operand:QI 2 "const1_operand" ""))
11357 (const_int 0)))
11358 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11359 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11360 "ix86_match_ccmode (insn, CCGOCmode)
11361 && (TARGET_SHIFT1 || optimize_size)
11362 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11363 "sar{l}\t%0"
11364 [(set_attr "type" "ishift")
11365 (set (attr "length")
11366 (if_then_else (match_operand:SI 0 "register_operand" "")
11367 (const_string "2")
11368 (const_string "*")))])
11369
11370 (define_insn "*ashrsi3_one_bit_cmp_zext"
11371 [(set (reg FLAGS_REG)
11372 (compare
11373 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11374 (match_operand:QI 2 "const1_operand" ""))
11375 (const_int 0)))
11376 (set (match_operand:DI 0 "register_operand" "=r")
11377 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11378 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11379 && (TARGET_SHIFT1 || optimize_size)
11380 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11381 "sar{l}\t%k0"
11382 [(set_attr "type" "ishift")
11383 (set_attr "length" "2")])
11384
11385 ;; This pattern can't accept a variable shift count, since shifts by
11386 ;; zero don't affect the flags. We assume that shifts by constant
11387 ;; zero are optimized away.
11388 (define_insn "*ashrsi3_cmp"
11389 [(set (reg FLAGS_REG)
11390 (compare
11391 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11392 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11393 (const_int 0)))
11394 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11395 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11396 "ix86_match_ccmode (insn, CCGOCmode)
11397 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11398 "sar{l}\t{%2, %0|%0, %2}"
11399 [(set_attr "type" "ishift")
11400 (set_attr "mode" "SI")])
11401
11402 (define_insn "*ashrsi3_cmp_zext"
11403 [(set (reg FLAGS_REG)
11404 (compare
11405 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11406 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11407 (const_int 0)))
11408 (set (match_operand:DI 0 "register_operand" "=r")
11409 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11410 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11411 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11412 "sar{l}\t{%2, %k0|%k0, %2}"
11413 [(set_attr "type" "ishift")
11414 (set_attr "mode" "SI")])
11415
11416 (define_expand "ashrhi3"
11417 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11418 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11419 (match_operand:QI 2 "nonmemory_operand" "")))
11420 (clobber (reg:CC FLAGS_REG))]
11421 "TARGET_HIMODE_MATH"
11422 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11423
11424 (define_insn "*ashrhi3_1_one_bit"
11425 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11426 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11427 (match_operand:QI 2 "const1_operand" "")))
11428 (clobber (reg:CC FLAGS_REG))]
11429 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11430 && (TARGET_SHIFT1 || optimize_size)"
11431 "sar{w}\t%0"
11432 [(set_attr "type" "ishift")
11433 (set (attr "length")
11434 (if_then_else (match_operand 0 "register_operand" "")
11435 (const_string "2")
11436 (const_string "*")))])
11437
11438 (define_insn "*ashrhi3_1"
11439 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11440 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11441 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11442 (clobber (reg:CC FLAGS_REG))]
11443 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11444 "@
11445 sar{w}\t{%2, %0|%0, %2}
11446 sar{w}\t{%b2, %0|%0, %b2}"
11447 [(set_attr "type" "ishift")
11448 (set_attr "mode" "HI")])
11449
11450 ;; This pattern can't accept a variable shift count, since shifts by
11451 ;; zero don't affect the flags. We assume that shifts by constant
11452 ;; zero are optimized away.
11453 (define_insn "*ashrhi3_one_bit_cmp"
11454 [(set (reg FLAGS_REG)
11455 (compare
11456 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11457 (match_operand:QI 2 "const1_operand" ""))
11458 (const_int 0)))
11459 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11460 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11461 "ix86_match_ccmode (insn, CCGOCmode)
11462 && (TARGET_SHIFT1 || optimize_size)
11463 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11464 "sar{w}\t%0"
11465 [(set_attr "type" "ishift")
11466 (set (attr "length")
11467 (if_then_else (match_operand 0 "register_operand" "")
11468 (const_string "2")
11469 (const_string "*")))])
11470
11471 ;; This pattern can't accept a variable shift count, since shifts by
11472 ;; zero don't affect the flags. We assume that shifts by constant
11473 ;; zero are optimized away.
11474 (define_insn "*ashrhi3_cmp"
11475 [(set (reg FLAGS_REG)
11476 (compare
11477 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11478 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11479 (const_int 0)))
11480 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11481 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11482 "ix86_match_ccmode (insn, CCGOCmode)
11483 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11484 "sar{w}\t{%2, %0|%0, %2}"
11485 [(set_attr "type" "ishift")
11486 (set_attr "mode" "HI")])
11487
11488 (define_expand "ashrqi3"
11489 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11490 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11491 (match_operand:QI 2 "nonmemory_operand" "")))
11492 (clobber (reg:CC FLAGS_REG))]
11493 "TARGET_QIMODE_MATH"
11494 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11495
11496 (define_insn "*ashrqi3_1_one_bit"
11497 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11498 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11499 (match_operand:QI 2 "const1_operand" "")))
11500 (clobber (reg:CC FLAGS_REG))]
11501 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11502 && (TARGET_SHIFT1 || optimize_size)"
11503 "sar{b}\t%0"
11504 [(set_attr "type" "ishift")
11505 (set (attr "length")
11506 (if_then_else (match_operand 0 "register_operand" "")
11507 (const_string "2")
11508 (const_string "*")))])
11509
11510 (define_insn "*ashrqi3_1_one_bit_slp"
11511 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11512 (ashiftrt:QI (match_dup 0)
11513 (match_operand:QI 1 "const1_operand" "")))
11514 (clobber (reg:CC FLAGS_REG))]
11515 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11516 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11517 && (TARGET_SHIFT1 || optimize_size)"
11518 "sar{b}\t%0"
11519 [(set_attr "type" "ishift1")
11520 (set (attr "length")
11521 (if_then_else (match_operand 0 "register_operand" "")
11522 (const_string "2")
11523 (const_string "*")))])
11524
11525 (define_insn "*ashrqi3_1"
11526 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11527 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11528 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11529 (clobber (reg:CC FLAGS_REG))]
11530 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11531 "@
11532 sar{b}\t{%2, %0|%0, %2}
11533 sar{b}\t{%b2, %0|%0, %b2}"
11534 [(set_attr "type" "ishift")
11535 (set_attr "mode" "QI")])
11536
11537 (define_insn "*ashrqi3_1_slp"
11538 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11539 (ashiftrt:QI (match_dup 0)
11540 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11541 (clobber (reg:CC FLAGS_REG))]
11542 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11543 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11544 "@
11545 sar{b}\t{%1, %0|%0, %1}
11546 sar{b}\t{%b1, %0|%0, %b1}"
11547 [(set_attr "type" "ishift1")
11548 (set_attr "mode" "QI")])
11549
11550 ;; This pattern can't accept a variable shift count, since shifts by
11551 ;; zero don't affect the flags. We assume that shifts by constant
11552 ;; zero are optimized away.
11553 (define_insn "*ashrqi3_one_bit_cmp"
11554 [(set (reg FLAGS_REG)
11555 (compare
11556 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11557 (match_operand:QI 2 "const1_operand" "I"))
11558 (const_int 0)))
11559 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11560 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11561 "ix86_match_ccmode (insn, CCGOCmode)
11562 && (TARGET_SHIFT1 || optimize_size)
11563 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11564 "sar{b}\t%0"
11565 [(set_attr "type" "ishift")
11566 (set (attr "length")
11567 (if_then_else (match_operand 0 "register_operand" "")
11568 (const_string "2")
11569 (const_string "*")))])
11570
11571 ;; This pattern can't accept a variable shift count, since shifts by
11572 ;; zero don't affect the flags. We assume that shifts by constant
11573 ;; zero are optimized away.
11574 (define_insn "*ashrqi3_cmp"
11575 [(set (reg FLAGS_REG)
11576 (compare
11577 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11578 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11579 (const_int 0)))
11580 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11581 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11582 "ix86_match_ccmode (insn, CCGOCmode)
11583 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11584 "sar{b}\t{%2, %0|%0, %2}"
11585 [(set_attr "type" "ishift")
11586 (set_attr "mode" "QI")])
11587 \f
11588 ;; Logical shift instructions
11589
11590 ;; See comment above `ashldi3' about how this works.
11591
11592 (define_expand "lshrti3"
11593 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11594 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11595 (match_operand:QI 2 "nonmemory_operand" "")))
11596 (clobber (reg:CC FLAGS_REG))])]
11597 "TARGET_64BIT"
11598 {
11599 if (! immediate_operand (operands[2], QImode))
11600 {
11601 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11602 DONE;
11603 }
11604 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11605 DONE;
11606 })
11607
11608 (define_insn "lshrti3_1"
11609 [(set (match_operand:TI 0 "register_operand" "=r")
11610 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11611 (match_operand:QI 2 "register_operand" "c")))
11612 (clobber (match_scratch:DI 3 "=&r"))
11613 (clobber (reg:CC FLAGS_REG))]
11614 "TARGET_64BIT"
11615 "#"
11616 [(set_attr "type" "multi")])
11617
11618 (define_insn "*lshrti3_2"
11619 [(set (match_operand:TI 0 "register_operand" "=r")
11620 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11621 (match_operand:QI 2 "immediate_operand" "O")))
11622 (clobber (reg:CC FLAGS_REG))]
11623 "TARGET_64BIT"
11624 "#"
11625 [(set_attr "type" "multi")])
11626
11627 (define_split
11628 [(set (match_operand:TI 0 "register_operand" "")
11629 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11630 (match_operand:QI 2 "register_operand" "")))
11631 (clobber (match_scratch:DI 3 ""))
11632 (clobber (reg:CC FLAGS_REG))]
11633 "TARGET_64BIT && reload_completed"
11634 [(const_int 0)]
11635 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11636
11637 (define_split
11638 [(set (match_operand:TI 0 "register_operand" "")
11639 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11640 (match_operand:QI 2 "immediate_operand" "")))
11641 (clobber (reg:CC FLAGS_REG))]
11642 "TARGET_64BIT && reload_completed"
11643 [(const_int 0)]
11644 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11645
11646 (define_expand "lshrdi3"
11647 [(set (match_operand:DI 0 "shiftdi_operand" "")
11648 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11649 (match_operand:QI 2 "nonmemory_operand" "")))]
11650 ""
11651 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11652
11653 (define_insn "*lshrdi3_1_one_bit_rex64"
11654 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11655 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11656 (match_operand:QI 2 "const1_operand" "")))
11657 (clobber (reg:CC FLAGS_REG))]
11658 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11659 && (TARGET_SHIFT1 || optimize_size)"
11660 "shr{q}\t%0"
11661 [(set_attr "type" "ishift")
11662 (set (attr "length")
11663 (if_then_else (match_operand:DI 0 "register_operand" "")
11664 (const_string "2")
11665 (const_string "*")))])
11666
11667 (define_insn "*lshrdi3_1_rex64"
11668 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11669 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11670 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11671 (clobber (reg:CC FLAGS_REG))]
11672 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11673 "@
11674 shr{q}\t{%2, %0|%0, %2}
11675 shr{q}\t{%b2, %0|%0, %b2}"
11676 [(set_attr "type" "ishift")
11677 (set_attr "mode" "DI")])
11678
11679 ;; This pattern can't accept a variable shift count, since shifts by
11680 ;; zero don't affect the flags. We assume that shifts by constant
11681 ;; zero are optimized away.
11682 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11683 [(set (reg FLAGS_REG)
11684 (compare
11685 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11686 (match_operand:QI 2 "const1_operand" ""))
11687 (const_int 0)))
11688 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11689 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11690 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11691 && (TARGET_SHIFT1 || optimize_size)
11692 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11693 "shr{q}\t%0"
11694 [(set_attr "type" "ishift")
11695 (set (attr "length")
11696 (if_then_else (match_operand:DI 0 "register_operand" "")
11697 (const_string "2")
11698 (const_string "*")))])
11699
11700 ;; This pattern can't accept a variable shift count, since shifts by
11701 ;; zero don't affect the flags. We assume that shifts by constant
11702 ;; zero are optimized away.
11703 (define_insn "*lshrdi3_cmp_rex64"
11704 [(set (reg FLAGS_REG)
11705 (compare
11706 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11707 (match_operand:QI 2 "const_int_operand" "e"))
11708 (const_int 0)))
11709 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11710 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11711 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11712 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11713 "shr{q}\t{%2, %0|%0, %2}"
11714 [(set_attr "type" "ishift")
11715 (set_attr "mode" "DI")])
11716
11717 (define_insn "*lshrdi3_1"
11718 [(set (match_operand:DI 0 "register_operand" "=r")
11719 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11720 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11721 (clobber (reg:CC FLAGS_REG))]
11722 "!TARGET_64BIT"
11723 "#"
11724 [(set_attr "type" "multi")])
11725
11726 ;; By default we don't ask for a scratch register, because when DImode
11727 ;; values are manipulated, registers are already at a premium. But if
11728 ;; we have one handy, we won't turn it away.
11729 (define_peephole2
11730 [(match_scratch:SI 3 "r")
11731 (parallel [(set (match_operand:DI 0 "register_operand" "")
11732 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11733 (match_operand:QI 2 "nonmemory_operand" "")))
11734 (clobber (reg:CC FLAGS_REG))])
11735 (match_dup 3)]
11736 "!TARGET_64BIT && TARGET_CMOVE"
11737 [(const_int 0)]
11738 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11739
11740 (define_split
11741 [(set (match_operand:DI 0 "register_operand" "")
11742 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11743 (match_operand:QI 2 "nonmemory_operand" "")))
11744 (clobber (reg:CC FLAGS_REG))]
11745 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11746 ? flow2_completed : reload_completed)"
11747 [(const_int 0)]
11748 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11749
11750 (define_expand "lshrsi3"
11751 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11752 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11753 (match_operand:QI 2 "nonmemory_operand" "")))
11754 (clobber (reg:CC FLAGS_REG))]
11755 ""
11756 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11757
11758 (define_insn "*lshrsi3_1_one_bit"
11759 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11760 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11761 (match_operand:QI 2 "const1_operand" "")))
11762 (clobber (reg:CC FLAGS_REG))]
11763 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11764 && (TARGET_SHIFT1 || optimize_size)"
11765 "shr{l}\t%0"
11766 [(set_attr "type" "ishift")
11767 (set (attr "length")
11768 (if_then_else (match_operand:SI 0 "register_operand" "")
11769 (const_string "2")
11770 (const_string "*")))])
11771
11772 (define_insn "*lshrsi3_1_one_bit_zext"
11773 [(set (match_operand:DI 0 "register_operand" "=r")
11774 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11775 (match_operand:QI 2 "const1_operand" "")))
11776 (clobber (reg:CC FLAGS_REG))]
11777 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11778 && (TARGET_SHIFT1 || optimize_size)"
11779 "shr{l}\t%k0"
11780 [(set_attr "type" "ishift")
11781 (set_attr "length" "2")])
11782
11783 (define_insn "*lshrsi3_1"
11784 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11785 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11786 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11787 (clobber (reg:CC FLAGS_REG))]
11788 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11789 "@
11790 shr{l}\t{%2, %0|%0, %2}
11791 shr{l}\t{%b2, %0|%0, %b2}"
11792 [(set_attr "type" "ishift")
11793 (set_attr "mode" "SI")])
11794
11795 (define_insn "*lshrsi3_1_zext"
11796 [(set (match_operand:DI 0 "register_operand" "=r,r")
11797 (zero_extend:DI
11798 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11799 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11800 (clobber (reg:CC FLAGS_REG))]
11801 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11802 "@
11803 shr{l}\t{%2, %k0|%k0, %2}
11804 shr{l}\t{%b2, %k0|%k0, %b2}"
11805 [(set_attr "type" "ishift")
11806 (set_attr "mode" "SI")])
11807
11808 ;; This pattern can't accept a variable shift count, since shifts by
11809 ;; zero don't affect the flags. We assume that shifts by constant
11810 ;; zero are optimized away.
11811 (define_insn "*lshrsi3_one_bit_cmp"
11812 [(set (reg FLAGS_REG)
11813 (compare
11814 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11815 (match_operand:QI 2 "const1_operand" ""))
11816 (const_int 0)))
11817 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11818 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11819 "ix86_match_ccmode (insn, CCGOCmode)
11820 && (TARGET_SHIFT1 || optimize_size)
11821 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11822 "shr{l}\t%0"
11823 [(set_attr "type" "ishift")
11824 (set (attr "length")
11825 (if_then_else (match_operand:SI 0 "register_operand" "")
11826 (const_string "2")
11827 (const_string "*")))])
11828
11829 (define_insn "*lshrsi3_cmp_one_bit_zext"
11830 [(set (reg FLAGS_REG)
11831 (compare
11832 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11833 (match_operand:QI 2 "const1_operand" ""))
11834 (const_int 0)))
11835 (set (match_operand:DI 0 "register_operand" "=r")
11836 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11837 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11838 && (TARGET_SHIFT1 || optimize_size)
11839 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11840 "shr{l}\t%k0"
11841 [(set_attr "type" "ishift")
11842 (set_attr "length" "2")])
11843
11844 ;; This pattern can't accept a variable shift count, since shifts by
11845 ;; zero don't affect the flags. We assume that shifts by constant
11846 ;; zero are optimized away.
11847 (define_insn "*lshrsi3_cmp"
11848 [(set (reg FLAGS_REG)
11849 (compare
11850 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11851 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11852 (const_int 0)))
11853 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11854 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11855 "ix86_match_ccmode (insn, CCGOCmode)
11856 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11857 "shr{l}\t{%2, %0|%0, %2}"
11858 [(set_attr "type" "ishift")
11859 (set_attr "mode" "SI")])
11860
11861 (define_insn "*lshrsi3_cmp_zext"
11862 [(set (reg FLAGS_REG)
11863 (compare
11864 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11865 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11866 (const_int 0)))
11867 (set (match_operand:DI 0 "register_operand" "=r")
11868 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11869 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11870 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11871 "shr{l}\t{%2, %k0|%k0, %2}"
11872 [(set_attr "type" "ishift")
11873 (set_attr "mode" "SI")])
11874
11875 (define_expand "lshrhi3"
11876 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11877 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11878 (match_operand:QI 2 "nonmemory_operand" "")))
11879 (clobber (reg:CC FLAGS_REG))]
11880 "TARGET_HIMODE_MATH"
11881 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11882
11883 (define_insn "*lshrhi3_1_one_bit"
11884 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11885 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11886 (match_operand:QI 2 "const1_operand" "")))
11887 (clobber (reg:CC FLAGS_REG))]
11888 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11889 && (TARGET_SHIFT1 || optimize_size)"
11890 "shr{w}\t%0"
11891 [(set_attr "type" "ishift")
11892 (set (attr "length")
11893 (if_then_else (match_operand 0 "register_operand" "")
11894 (const_string "2")
11895 (const_string "*")))])
11896
11897 (define_insn "*lshrhi3_1"
11898 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11899 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11900 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11901 (clobber (reg:CC FLAGS_REG))]
11902 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11903 "@
11904 shr{w}\t{%2, %0|%0, %2}
11905 shr{w}\t{%b2, %0|%0, %b2}"
11906 [(set_attr "type" "ishift")
11907 (set_attr "mode" "HI")])
11908
11909 ;; This pattern can't accept a variable shift count, since shifts by
11910 ;; zero don't affect the flags. We assume that shifts by constant
11911 ;; zero are optimized away.
11912 (define_insn "*lshrhi3_one_bit_cmp"
11913 [(set (reg FLAGS_REG)
11914 (compare
11915 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11916 (match_operand:QI 2 "const1_operand" ""))
11917 (const_int 0)))
11918 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11919 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11920 "ix86_match_ccmode (insn, CCGOCmode)
11921 && (TARGET_SHIFT1 || optimize_size)
11922 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11923 "shr{w}\t%0"
11924 [(set_attr "type" "ishift")
11925 (set (attr "length")
11926 (if_then_else (match_operand:SI 0 "register_operand" "")
11927 (const_string "2")
11928 (const_string "*")))])
11929
11930 ;; This pattern can't accept a variable shift count, since shifts by
11931 ;; zero don't affect the flags. We assume that shifts by constant
11932 ;; zero are optimized away.
11933 (define_insn "*lshrhi3_cmp"
11934 [(set (reg FLAGS_REG)
11935 (compare
11936 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11937 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11938 (const_int 0)))
11939 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11940 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11941 "ix86_match_ccmode (insn, CCGOCmode)
11942 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11943 "shr{w}\t{%2, %0|%0, %2}"
11944 [(set_attr "type" "ishift")
11945 (set_attr "mode" "HI")])
11946
11947 (define_expand "lshrqi3"
11948 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11949 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11950 (match_operand:QI 2 "nonmemory_operand" "")))
11951 (clobber (reg:CC FLAGS_REG))]
11952 "TARGET_QIMODE_MATH"
11953 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11954
11955 (define_insn "*lshrqi3_1_one_bit"
11956 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11957 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11958 (match_operand:QI 2 "const1_operand" "")))
11959 (clobber (reg:CC FLAGS_REG))]
11960 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11961 && (TARGET_SHIFT1 || optimize_size)"
11962 "shr{b}\t%0"
11963 [(set_attr "type" "ishift")
11964 (set (attr "length")
11965 (if_then_else (match_operand 0 "register_operand" "")
11966 (const_string "2")
11967 (const_string "*")))])
11968
11969 (define_insn "*lshrqi3_1_one_bit_slp"
11970 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11971 (lshiftrt:QI (match_dup 0)
11972 (match_operand:QI 1 "const1_operand" "")))
11973 (clobber (reg:CC FLAGS_REG))]
11974 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11975 && (TARGET_SHIFT1 || optimize_size)"
11976 "shr{b}\t%0"
11977 [(set_attr "type" "ishift1")
11978 (set (attr "length")
11979 (if_then_else (match_operand 0 "register_operand" "")
11980 (const_string "2")
11981 (const_string "*")))])
11982
11983 (define_insn "*lshrqi3_1"
11984 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11985 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11986 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11987 (clobber (reg:CC FLAGS_REG))]
11988 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11989 "@
11990 shr{b}\t{%2, %0|%0, %2}
11991 shr{b}\t{%b2, %0|%0, %b2}"
11992 [(set_attr "type" "ishift")
11993 (set_attr "mode" "QI")])
11994
11995 (define_insn "*lshrqi3_1_slp"
11996 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11997 (lshiftrt:QI (match_dup 0)
11998 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11999 (clobber (reg:CC FLAGS_REG))]
12000 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12001 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12002 "@
12003 shr{b}\t{%1, %0|%0, %1}
12004 shr{b}\t{%b1, %0|%0, %b1}"
12005 [(set_attr "type" "ishift1")
12006 (set_attr "mode" "QI")])
12007
12008 ;; This pattern can't accept a variable shift count, since shifts by
12009 ;; zero don't affect the flags. We assume that shifts by constant
12010 ;; zero are optimized away.
12011 (define_insn "*lshrqi2_one_bit_cmp"
12012 [(set (reg FLAGS_REG)
12013 (compare
12014 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12015 (match_operand:QI 2 "const1_operand" ""))
12016 (const_int 0)))
12017 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12018 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12019 "ix86_match_ccmode (insn, CCGOCmode)
12020 && (TARGET_SHIFT1 || optimize_size)
12021 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12022 "shr{b}\t%0"
12023 [(set_attr "type" "ishift")
12024 (set (attr "length")
12025 (if_then_else (match_operand:SI 0 "register_operand" "")
12026 (const_string "2")
12027 (const_string "*")))])
12028
12029 ;; This pattern can't accept a variable shift count, since shifts by
12030 ;; zero don't affect the flags. We assume that shifts by constant
12031 ;; zero are optimized away.
12032 (define_insn "*lshrqi2_cmp"
12033 [(set (reg FLAGS_REG)
12034 (compare
12035 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12036 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12037 (const_int 0)))
12038 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12039 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12040 "ix86_match_ccmode (insn, CCGOCmode)
12041 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12042 "shr{b}\t{%2, %0|%0, %2}"
12043 [(set_attr "type" "ishift")
12044 (set_attr "mode" "QI")])
12045 \f
12046 ;; Rotate instructions
12047
12048 (define_expand "rotldi3"
12049 [(set (match_operand:DI 0 "shiftdi_operand" "")
12050 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12051 (match_operand:QI 2 "nonmemory_operand" "")))
12052 (clobber (reg:CC FLAGS_REG))]
12053 ""
12054 {
12055 if (TARGET_64BIT)
12056 {
12057 ix86_expand_binary_operator (ROTATE, DImode, operands);
12058 DONE;
12059 }
12060 if (!const_1_to_31_operand (operands[2], VOIDmode))
12061 FAIL;
12062 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12063 DONE;
12064 })
12065
12066 ;; Implement rotation using two double-precision shift instructions
12067 ;; and a scratch register.
12068 (define_insn_and_split "ix86_rotldi3"
12069 [(set (match_operand:DI 0 "register_operand" "=r")
12070 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12071 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12072 (clobber (reg:CC FLAGS_REG))
12073 (clobber (match_scratch:SI 3 "=&r"))]
12074 "!TARGET_64BIT"
12075 ""
12076 "&& reload_completed"
12077 [(set (match_dup 3) (match_dup 4))
12078 (parallel
12079 [(set (match_dup 4)
12080 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12081 (lshiftrt:SI (match_dup 5)
12082 (minus:QI (const_int 32) (match_dup 2)))))
12083 (clobber (reg:CC FLAGS_REG))])
12084 (parallel
12085 [(set (match_dup 5)
12086 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12087 (lshiftrt:SI (match_dup 3)
12088 (minus:QI (const_int 32) (match_dup 2)))))
12089 (clobber (reg:CC FLAGS_REG))])]
12090 "split_di (operands, 1, operands + 4, operands + 5);")
12091
12092 (define_insn "*rotlsi3_1_one_bit_rex64"
12093 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12094 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12095 (match_operand:QI 2 "const1_operand" "")))
12096 (clobber (reg:CC FLAGS_REG))]
12097 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12098 && (TARGET_SHIFT1 || optimize_size)"
12099 "rol{q}\t%0"
12100 [(set_attr "type" "rotate")
12101 (set (attr "length")
12102 (if_then_else (match_operand:DI 0 "register_operand" "")
12103 (const_string "2")
12104 (const_string "*")))])
12105
12106 (define_insn "*rotldi3_1_rex64"
12107 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12108 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12109 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12110 (clobber (reg:CC FLAGS_REG))]
12111 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12112 "@
12113 rol{q}\t{%2, %0|%0, %2}
12114 rol{q}\t{%b2, %0|%0, %b2}"
12115 [(set_attr "type" "rotate")
12116 (set_attr "mode" "DI")])
12117
12118 (define_expand "rotlsi3"
12119 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12120 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12121 (match_operand:QI 2 "nonmemory_operand" "")))
12122 (clobber (reg:CC FLAGS_REG))]
12123 ""
12124 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12125
12126 (define_insn "*rotlsi3_1_one_bit"
12127 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12128 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12129 (match_operand:QI 2 "const1_operand" "")))
12130 (clobber (reg:CC FLAGS_REG))]
12131 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12132 && (TARGET_SHIFT1 || optimize_size)"
12133 "rol{l}\t%0"
12134 [(set_attr "type" "rotate")
12135 (set (attr "length")
12136 (if_then_else (match_operand:SI 0 "register_operand" "")
12137 (const_string "2")
12138 (const_string "*")))])
12139
12140 (define_insn "*rotlsi3_1_one_bit_zext"
12141 [(set (match_operand:DI 0 "register_operand" "=r")
12142 (zero_extend:DI
12143 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12144 (match_operand:QI 2 "const1_operand" ""))))
12145 (clobber (reg:CC FLAGS_REG))]
12146 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12147 && (TARGET_SHIFT1 || optimize_size)"
12148 "rol{l}\t%k0"
12149 [(set_attr "type" "rotate")
12150 (set_attr "length" "2")])
12151
12152 (define_insn "*rotlsi3_1"
12153 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12154 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12155 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12156 (clobber (reg:CC FLAGS_REG))]
12157 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12158 "@
12159 rol{l}\t{%2, %0|%0, %2}
12160 rol{l}\t{%b2, %0|%0, %b2}"
12161 [(set_attr "type" "rotate")
12162 (set_attr "mode" "SI")])
12163
12164 (define_insn "*rotlsi3_1_zext"
12165 [(set (match_operand:DI 0 "register_operand" "=r,r")
12166 (zero_extend:DI
12167 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12168 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12169 (clobber (reg:CC FLAGS_REG))]
12170 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12171 "@
12172 rol{l}\t{%2, %k0|%k0, %2}
12173 rol{l}\t{%b2, %k0|%k0, %b2}"
12174 [(set_attr "type" "rotate")
12175 (set_attr "mode" "SI")])
12176
12177 (define_expand "rotlhi3"
12178 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12179 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12180 (match_operand:QI 2 "nonmemory_operand" "")))
12181 (clobber (reg:CC FLAGS_REG))]
12182 "TARGET_HIMODE_MATH"
12183 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12184
12185 (define_insn "*rotlhi3_1_one_bit"
12186 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12187 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12188 (match_operand:QI 2 "const1_operand" "")))
12189 (clobber (reg:CC FLAGS_REG))]
12190 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12191 && (TARGET_SHIFT1 || optimize_size)"
12192 "rol{w}\t%0"
12193 [(set_attr "type" "rotate")
12194 (set (attr "length")
12195 (if_then_else (match_operand 0 "register_operand" "")
12196 (const_string "2")
12197 (const_string "*")))])
12198
12199 (define_insn "*rotlhi3_1"
12200 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12201 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12202 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12203 (clobber (reg:CC FLAGS_REG))]
12204 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12205 "@
12206 rol{w}\t{%2, %0|%0, %2}
12207 rol{w}\t{%b2, %0|%0, %b2}"
12208 [(set_attr "type" "rotate")
12209 (set_attr "mode" "HI")])
12210
12211 (define_expand "rotlqi3"
12212 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12213 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12214 (match_operand:QI 2 "nonmemory_operand" "")))
12215 (clobber (reg:CC FLAGS_REG))]
12216 "TARGET_QIMODE_MATH"
12217 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12218
12219 (define_insn "*rotlqi3_1_one_bit_slp"
12220 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12221 (rotate:QI (match_dup 0)
12222 (match_operand:QI 1 "const1_operand" "")))
12223 (clobber (reg:CC FLAGS_REG))]
12224 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12225 && (TARGET_SHIFT1 || optimize_size)"
12226 "rol{b}\t%0"
12227 [(set_attr "type" "rotate1")
12228 (set (attr "length")
12229 (if_then_else (match_operand 0 "register_operand" "")
12230 (const_string "2")
12231 (const_string "*")))])
12232
12233 (define_insn "*rotlqi3_1_one_bit"
12234 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12235 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12236 (match_operand:QI 2 "const1_operand" "")))
12237 (clobber (reg:CC FLAGS_REG))]
12238 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12239 && (TARGET_SHIFT1 || optimize_size)"
12240 "rol{b}\t%0"
12241 [(set_attr "type" "rotate")
12242 (set (attr "length")
12243 (if_then_else (match_operand 0 "register_operand" "")
12244 (const_string "2")
12245 (const_string "*")))])
12246
12247 (define_insn "*rotlqi3_1_slp"
12248 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12249 (rotate:QI (match_dup 0)
12250 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12251 (clobber (reg:CC FLAGS_REG))]
12252 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12253 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12254 "@
12255 rol{b}\t{%1, %0|%0, %1}
12256 rol{b}\t{%b1, %0|%0, %b1}"
12257 [(set_attr "type" "rotate1")
12258 (set_attr "mode" "QI")])
12259
12260 (define_insn "*rotlqi3_1"
12261 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12262 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12263 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12264 (clobber (reg:CC FLAGS_REG))]
12265 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12266 "@
12267 rol{b}\t{%2, %0|%0, %2}
12268 rol{b}\t{%b2, %0|%0, %b2}"
12269 [(set_attr "type" "rotate")
12270 (set_attr "mode" "QI")])
12271
12272 (define_expand "rotrdi3"
12273 [(set (match_operand:DI 0 "shiftdi_operand" "")
12274 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12275 (match_operand:QI 2 "nonmemory_operand" "")))
12276 (clobber (reg:CC FLAGS_REG))]
12277 ""
12278 {
12279 if (TARGET_64BIT)
12280 {
12281 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12282 DONE;
12283 }
12284 if (!const_1_to_31_operand (operands[2], VOIDmode))
12285 FAIL;
12286 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12287 DONE;
12288 })
12289
12290 ;; Implement rotation using two double-precision shift instructions
12291 ;; and a scratch register.
12292 (define_insn_and_split "ix86_rotrdi3"
12293 [(set (match_operand:DI 0 "register_operand" "=r")
12294 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12295 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12296 (clobber (reg:CC FLAGS_REG))
12297 (clobber (match_scratch:SI 3 "=&r"))]
12298 "!TARGET_64BIT"
12299 ""
12300 "&& reload_completed"
12301 [(set (match_dup 3) (match_dup 4))
12302 (parallel
12303 [(set (match_dup 4)
12304 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12305 (ashift:SI (match_dup 5)
12306 (minus:QI (const_int 32) (match_dup 2)))))
12307 (clobber (reg:CC FLAGS_REG))])
12308 (parallel
12309 [(set (match_dup 5)
12310 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12311 (ashift:SI (match_dup 3)
12312 (minus:QI (const_int 32) (match_dup 2)))))
12313 (clobber (reg:CC FLAGS_REG))])]
12314 "split_di (operands, 1, operands + 4, operands + 5);")
12315
12316 (define_insn "*rotrdi3_1_one_bit_rex64"
12317 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12318 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12319 (match_operand:QI 2 "const1_operand" "")))
12320 (clobber (reg:CC FLAGS_REG))]
12321 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12322 && (TARGET_SHIFT1 || optimize_size)"
12323 "ror{q}\t%0"
12324 [(set_attr "type" "rotate")
12325 (set (attr "length")
12326 (if_then_else (match_operand:DI 0 "register_operand" "")
12327 (const_string "2")
12328 (const_string "*")))])
12329
12330 (define_insn "*rotrdi3_1_rex64"
12331 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12332 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12333 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12334 (clobber (reg:CC FLAGS_REG))]
12335 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12336 "@
12337 ror{q}\t{%2, %0|%0, %2}
12338 ror{q}\t{%b2, %0|%0, %b2}"
12339 [(set_attr "type" "rotate")
12340 (set_attr "mode" "DI")])
12341
12342 (define_expand "rotrsi3"
12343 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12344 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12345 (match_operand:QI 2 "nonmemory_operand" "")))
12346 (clobber (reg:CC FLAGS_REG))]
12347 ""
12348 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12349
12350 (define_insn "*rotrsi3_1_one_bit"
12351 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12352 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12353 (match_operand:QI 2 "const1_operand" "")))
12354 (clobber (reg:CC FLAGS_REG))]
12355 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12356 && (TARGET_SHIFT1 || optimize_size)"
12357 "ror{l}\t%0"
12358 [(set_attr "type" "rotate")
12359 (set (attr "length")
12360 (if_then_else (match_operand:SI 0 "register_operand" "")
12361 (const_string "2")
12362 (const_string "*")))])
12363
12364 (define_insn "*rotrsi3_1_one_bit_zext"
12365 [(set (match_operand:DI 0 "register_operand" "=r")
12366 (zero_extend:DI
12367 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12368 (match_operand:QI 2 "const1_operand" ""))))
12369 (clobber (reg:CC FLAGS_REG))]
12370 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12371 && (TARGET_SHIFT1 || optimize_size)"
12372 "ror{l}\t%k0"
12373 [(set_attr "type" "rotate")
12374 (set (attr "length")
12375 (if_then_else (match_operand:SI 0 "register_operand" "")
12376 (const_string "2")
12377 (const_string "*")))])
12378
12379 (define_insn "*rotrsi3_1"
12380 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12381 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12382 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12383 (clobber (reg:CC FLAGS_REG))]
12384 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12385 "@
12386 ror{l}\t{%2, %0|%0, %2}
12387 ror{l}\t{%b2, %0|%0, %b2}"
12388 [(set_attr "type" "rotate")
12389 (set_attr "mode" "SI")])
12390
12391 (define_insn "*rotrsi3_1_zext"
12392 [(set (match_operand:DI 0 "register_operand" "=r,r")
12393 (zero_extend:DI
12394 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12395 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12396 (clobber (reg:CC FLAGS_REG))]
12397 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12398 "@
12399 ror{l}\t{%2, %k0|%k0, %2}
12400 ror{l}\t{%b2, %k0|%k0, %b2}"
12401 [(set_attr "type" "rotate")
12402 (set_attr "mode" "SI")])
12403
12404 (define_expand "rotrhi3"
12405 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12406 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12407 (match_operand:QI 2 "nonmemory_operand" "")))
12408 (clobber (reg:CC FLAGS_REG))]
12409 "TARGET_HIMODE_MATH"
12410 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12411
12412 (define_insn "*rotrhi3_one_bit"
12413 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12414 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12415 (match_operand:QI 2 "const1_operand" "")))
12416 (clobber (reg:CC FLAGS_REG))]
12417 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12418 && (TARGET_SHIFT1 || optimize_size)"
12419 "ror{w}\t%0"
12420 [(set_attr "type" "rotate")
12421 (set (attr "length")
12422 (if_then_else (match_operand 0 "register_operand" "")
12423 (const_string "2")
12424 (const_string "*")))])
12425
12426 (define_insn "*rotrhi3"
12427 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12428 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12429 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12430 (clobber (reg:CC FLAGS_REG))]
12431 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12432 "@
12433 ror{w}\t{%2, %0|%0, %2}
12434 ror{w}\t{%b2, %0|%0, %b2}"
12435 [(set_attr "type" "rotate")
12436 (set_attr "mode" "HI")])
12437
12438 (define_expand "rotrqi3"
12439 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12440 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12441 (match_operand:QI 2 "nonmemory_operand" "")))
12442 (clobber (reg:CC FLAGS_REG))]
12443 "TARGET_QIMODE_MATH"
12444 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12445
12446 (define_insn "*rotrqi3_1_one_bit"
12447 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12448 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12449 (match_operand:QI 2 "const1_operand" "")))
12450 (clobber (reg:CC FLAGS_REG))]
12451 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12452 && (TARGET_SHIFT1 || optimize_size)"
12453 "ror{b}\t%0"
12454 [(set_attr "type" "rotate")
12455 (set (attr "length")
12456 (if_then_else (match_operand 0 "register_operand" "")
12457 (const_string "2")
12458 (const_string "*")))])
12459
12460 (define_insn "*rotrqi3_1_one_bit_slp"
12461 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12462 (rotatert:QI (match_dup 0)
12463 (match_operand:QI 1 "const1_operand" "")))
12464 (clobber (reg:CC FLAGS_REG))]
12465 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12466 && (TARGET_SHIFT1 || optimize_size)"
12467 "ror{b}\t%0"
12468 [(set_attr "type" "rotate1")
12469 (set (attr "length")
12470 (if_then_else (match_operand 0 "register_operand" "")
12471 (const_string "2")
12472 (const_string "*")))])
12473
12474 (define_insn "*rotrqi3_1"
12475 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12476 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12477 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12478 (clobber (reg:CC FLAGS_REG))]
12479 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12480 "@
12481 ror{b}\t{%2, %0|%0, %2}
12482 ror{b}\t{%b2, %0|%0, %b2}"
12483 [(set_attr "type" "rotate")
12484 (set_attr "mode" "QI")])
12485
12486 (define_insn "*rotrqi3_1_slp"
12487 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12488 (rotatert:QI (match_dup 0)
12489 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12490 (clobber (reg:CC FLAGS_REG))]
12491 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12492 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12493 "@
12494 ror{b}\t{%1, %0|%0, %1}
12495 ror{b}\t{%b1, %0|%0, %b1}"
12496 [(set_attr "type" "rotate1")
12497 (set_attr "mode" "QI")])
12498 \f
12499 ;; Bit set / bit test instructions
12500
12501 (define_expand "extv"
12502 [(set (match_operand:SI 0 "register_operand" "")
12503 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12504 (match_operand:SI 2 "const8_operand" "")
12505 (match_operand:SI 3 "const8_operand" "")))]
12506 ""
12507 {
12508 /* Handle extractions from %ah et al. */
12509 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12510 FAIL;
12511
12512 /* From mips.md: extract_bit_field doesn't verify that our source
12513 matches the predicate, so check it again here. */
12514 if (! ext_register_operand (operands[1], VOIDmode))
12515 FAIL;
12516 })
12517
12518 (define_expand "extzv"
12519 [(set (match_operand:SI 0 "register_operand" "")
12520 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12521 (match_operand:SI 2 "const8_operand" "")
12522 (match_operand:SI 3 "const8_operand" "")))]
12523 ""
12524 {
12525 /* Handle extractions from %ah et al. */
12526 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12527 FAIL;
12528
12529 /* From mips.md: extract_bit_field doesn't verify that our source
12530 matches the predicate, so check it again here. */
12531 if (! ext_register_operand (operands[1], VOIDmode))
12532 FAIL;
12533 })
12534
12535 (define_expand "insv"
12536 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12537 (match_operand 1 "const8_operand" "")
12538 (match_operand 2 "const8_operand" ""))
12539 (match_operand 3 "register_operand" ""))]
12540 ""
12541 {
12542 /* Handle insertions to %ah et al. */
12543 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12544 FAIL;
12545
12546 /* From mips.md: insert_bit_field doesn't verify that our source
12547 matches the predicate, so check it again here. */
12548 if (! ext_register_operand (operands[0], VOIDmode))
12549 FAIL;
12550
12551 if (TARGET_64BIT)
12552 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12553 else
12554 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12555
12556 DONE;
12557 })
12558
12559 ;; %%% bts, btr, btc, bt.
12560 ;; In general these instructions are *slow* when applied to memory,
12561 ;; since they enforce atomic operation. When applied to registers,
12562 ;; it depends on the cpu implementation. They're never faster than
12563 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12564 ;; no point. But in 64-bit, we can't hold the relevant immediates
12565 ;; within the instruction itself, so operating on bits in the high
12566 ;; 32-bits of a register becomes easier.
12567 ;;
12568 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12569 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12570 ;; negdf respectively, so they can never be disabled entirely.
12571
12572 (define_insn "*btsq"
12573 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12574 (const_int 1)
12575 (match_operand:DI 1 "const_0_to_63_operand" ""))
12576 (const_int 1))
12577 (clobber (reg:CC FLAGS_REG))]
12578 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12579 "bts{q} %1,%0"
12580 [(set_attr "type" "alu1")])
12581
12582 (define_insn "*btrq"
12583 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12584 (const_int 1)
12585 (match_operand:DI 1 "const_0_to_63_operand" ""))
12586 (const_int 0))
12587 (clobber (reg:CC FLAGS_REG))]
12588 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12589 "btr{q} %1,%0"
12590 [(set_attr "type" "alu1")])
12591
12592 (define_insn "*btcq"
12593 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12594 (const_int 1)
12595 (match_operand:DI 1 "const_0_to_63_operand" ""))
12596 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12597 (clobber (reg:CC FLAGS_REG))]
12598 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12599 "btc{q} %1,%0"
12600 [(set_attr "type" "alu1")])
12601
12602 ;; Allow Nocona to avoid these instructions if a register is available.
12603
12604 (define_peephole2
12605 [(match_scratch:DI 2 "r")
12606 (parallel [(set (zero_extract:DI
12607 (match_operand:DI 0 "register_operand" "")
12608 (const_int 1)
12609 (match_operand:DI 1 "const_0_to_63_operand" ""))
12610 (const_int 1))
12611 (clobber (reg:CC FLAGS_REG))])]
12612 "TARGET_64BIT && !TARGET_USE_BT"
12613 [(const_int 0)]
12614 {
12615 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12616 rtx op1;
12617
12618 if (HOST_BITS_PER_WIDE_INT >= 64)
12619 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620 else if (i < HOST_BITS_PER_WIDE_INT)
12621 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12622 else
12623 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12624
12625 op1 = immed_double_const (lo, hi, DImode);
12626 if (i >= 31)
12627 {
12628 emit_move_insn (operands[2], op1);
12629 op1 = operands[2];
12630 }
12631
12632 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12633 DONE;
12634 })
12635
12636 (define_peephole2
12637 [(match_scratch:DI 2 "r")
12638 (parallel [(set (zero_extract:DI
12639 (match_operand:DI 0 "register_operand" "")
12640 (const_int 1)
12641 (match_operand:DI 1 "const_0_to_63_operand" ""))
12642 (const_int 0))
12643 (clobber (reg:CC FLAGS_REG))])]
12644 "TARGET_64BIT && !TARGET_USE_BT"
12645 [(const_int 0)]
12646 {
12647 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12648 rtx op1;
12649
12650 if (HOST_BITS_PER_WIDE_INT >= 64)
12651 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652 else if (i < HOST_BITS_PER_WIDE_INT)
12653 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12654 else
12655 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12656
12657 op1 = immed_double_const (~lo, ~hi, DImode);
12658 if (i >= 32)
12659 {
12660 emit_move_insn (operands[2], op1);
12661 op1 = operands[2];
12662 }
12663
12664 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12665 DONE;
12666 })
12667
12668 (define_peephole2
12669 [(match_scratch:DI 2 "r")
12670 (parallel [(set (zero_extract:DI
12671 (match_operand:DI 0 "register_operand" "")
12672 (const_int 1)
12673 (match_operand:DI 1 "const_0_to_63_operand" ""))
12674 (not:DI (zero_extract:DI
12675 (match_dup 0) (const_int 1) (match_dup 1))))
12676 (clobber (reg:CC FLAGS_REG))])]
12677 "TARGET_64BIT && !TARGET_USE_BT"
12678 [(const_int 0)]
12679 {
12680 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12681 rtx op1;
12682
12683 if (HOST_BITS_PER_WIDE_INT >= 64)
12684 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12685 else if (i < HOST_BITS_PER_WIDE_INT)
12686 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12687 else
12688 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12689
12690 op1 = immed_double_const (lo, hi, DImode);
12691 if (i >= 31)
12692 {
12693 emit_move_insn (operands[2], op1);
12694 op1 = operands[2];
12695 }
12696
12697 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12698 DONE;
12699 })
12700 \f
12701 ;; Store-flag instructions.
12702
12703 ;; For all sCOND expanders, also expand the compare or test insn that
12704 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12705
12706 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12707 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12708 ;; way, which can later delete the movzx if only QImode is needed.
12709
12710 (define_expand "seq"
12711 [(set (match_operand:QI 0 "register_operand" "")
12712 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12713 ""
12714 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12715
12716 (define_expand "sne"
12717 [(set (match_operand:QI 0 "register_operand" "")
12718 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12719 ""
12720 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12721
12722 (define_expand "sgt"
12723 [(set (match_operand:QI 0 "register_operand" "")
12724 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12725 ""
12726 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12727
12728 (define_expand "sgtu"
12729 [(set (match_operand:QI 0 "register_operand" "")
12730 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12731 ""
12732 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12733
12734 (define_expand "slt"
12735 [(set (match_operand:QI 0 "register_operand" "")
12736 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12737 ""
12738 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12739
12740 (define_expand "sltu"
12741 [(set (match_operand:QI 0 "register_operand" "")
12742 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12743 ""
12744 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12745
12746 (define_expand "sge"
12747 [(set (match_operand:QI 0 "register_operand" "")
12748 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12749 ""
12750 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12751
12752 (define_expand "sgeu"
12753 [(set (match_operand:QI 0 "register_operand" "")
12754 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12755 ""
12756 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12757
12758 (define_expand "sle"
12759 [(set (match_operand:QI 0 "register_operand" "")
12760 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12761 ""
12762 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12763
12764 (define_expand "sleu"
12765 [(set (match_operand:QI 0 "register_operand" "")
12766 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12767 ""
12768 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12769
12770 (define_expand "sunordered"
12771 [(set (match_operand:QI 0 "register_operand" "")
12772 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12773 "TARGET_80387 || TARGET_SSE"
12774 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12775
12776 (define_expand "sordered"
12777 [(set (match_operand:QI 0 "register_operand" "")
12778 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12779 "TARGET_80387"
12780 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12781
12782 (define_expand "suneq"
12783 [(set (match_operand:QI 0 "register_operand" "")
12784 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12785 "TARGET_80387 || TARGET_SSE"
12786 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12787
12788 (define_expand "sunge"
12789 [(set (match_operand:QI 0 "register_operand" "")
12790 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12791 "TARGET_80387 || TARGET_SSE"
12792 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12793
12794 (define_expand "sungt"
12795 [(set (match_operand:QI 0 "register_operand" "")
12796 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12797 "TARGET_80387 || TARGET_SSE"
12798 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12799
12800 (define_expand "sunle"
12801 [(set (match_operand:QI 0 "register_operand" "")
12802 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12803 "TARGET_80387 || TARGET_SSE"
12804 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12805
12806 (define_expand "sunlt"
12807 [(set (match_operand:QI 0 "register_operand" "")
12808 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12809 "TARGET_80387 || TARGET_SSE"
12810 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12811
12812 (define_expand "sltgt"
12813 [(set (match_operand:QI 0 "register_operand" "")
12814 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12815 "TARGET_80387 || TARGET_SSE"
12816 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12817
12818 (define_insn "*setcc_1"
12819 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12820 (match_operator:QI 1 "ix86_comparison_operator"
12821 [(reg FLAGS_REG) (const_int 0)]))]
12822 ""
12823 "set%C1\t%0"
12824 [(set_attr "type" "setcc")
12825 (set_attr "mode" "QI")])
12826
12827 (define_insn "*setcc_2"
12828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12829 (match_operator:QI 1 "ix86_comparison_operator"
12830 [(reg FLAGS_REG) (const_int 0)]))]
12831 ""
12832 "set%C1\t%0"
12833 [(set_attr "type" "setcc")
12834 (set_attr "mode" "QI")])
12835
12836 ;; In general it is not safe to assume too much about CCmode registers,
12837 ;; so simplify-rtx stops when it sees a second one. Under certain
12838 ;; conditions this is safe on x86, so help combine not create
12839 ;;
12840 ;; seta %al
12841 ;; testb %al, %al
12842 ;; sete %al
12843
12844 (define_split
12845 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12846 (ne:QI (match_operator 1 "ix86_comparison_operator"
12847 [(reg FLAGS_REG) (const_int 0)])
12848 (const_int 0)))]
12849 ""
12850 [(set (match_dup 0) (match_dup 1))]
12851 {
12852 PUT_MODE (operands[1], QImode);
12853 })
12854
12855 (define_split
12856 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12857 (ne:QI (match_operator 1 "ix86_comparison_operator"
12858 [(reg FLAGS_REG) (const_int 0)])
12859 (const_int 0)))]
12860 ""
12861 [(set (match_dup 0) (match_dup 1))]
12862 {
12863 PUT_MODE (operands[1], QImode);
12864 })
12865
12866 (define_split
12867 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12868 (eq:QI (match_operator 1 "ix86_comparison_operator"
12869 [(reg FLAGS_REG) (const_int 0)])
12870 (const_int 0)))]
12871 ""
12872 [(set (match_dup 0) (match_dup 1))]
12873 {
12874 rtx new_op1 = copy_rtx (operands[1]);
12875 operands[1] = new_op1;
12876 PUT_MODE (new_op1, QImode);
12877 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12878 GET_MODE (XEXP (new_op1, 0))));
12879
12880 /* Make sure that (a) the CCmode we have for the flags is strong
12881 enough for the reversed compare or (b) we have a valid FP compare. */
12882 if (! ix86_comparison_operator (new_op1, VOIDmode))
12883 FAIL;
12884 })
12885
12886 (define_split
12887 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12888 (eq:QI (match_operator 1 "ix86_comparison_operator"
12889 [(reg FLAGS_REG) (const_int 0)])
12890 (const_int 0)))]
12891 ""
12892 [(set (match_dup 0) (match_dup 1))]
12893 {
12894 rtx new_op1 = copy_rtx (operands[1]);
12895 operands[1] = new_op1;
12896 PUT_MODE (new_op1, QImode);
12897 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12898 GET_MODE (XEXP (new_op1, 0))));
12899
12900 /* Make sure that (a) the CCmode we have for the flags is strong
12901 enough for the reversed compare or (b) we have a valid FP compare. */
12902 if (! ix86_comparison_operator (new_op1, VOIDmode))
12903 FAIL;
12904 })
12905
12906 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12907 ;; subsequent logical operations are used to imitate conditional moves.
12908 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12909 ;; it directly.
12910
12911 (define_insn "*sse_setccsf"
12912 [(set (match_operand:SF 0 "register_operand" "=x")
12913 (match_operator:SF 1 "sse_comparison_operator"
12914 [(match_operand:SF 2 "register_operand" "0")
12915 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12916 "TARGET_SSE"
12917 "cmp%D1ss\t{%3, %0|%0, %3}"
12918 [(set_attr "type" "ssecmp")
12919 (set_attr "mode" "SF")])
12920
12921 (define_insn "*sse_setccdf"
12922 [(set (match_operand:DF 0 "register_operand" "=Y")
12923 (match_operator:DF 1 "sse_comparison_operator"
12924 [(match_operand:DF 2 "register_operand" "0")
12925 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12926 "TARGET_SSE2"
12927 "cmp%D1sd\t{%3, %0|%0, %3}"
12928 [(set_attr "type" "ssecmp")
12929 (set_attr "mode" "DF")])
12930 \f
12931 ;; Basic conditional jump instructions.
12932 ;; We ignore the overflow flag for signed branch instructions.
12933
12934 ;; For all bCOND expanders, also expand the compare or test insn that
12935 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12936
12937 (define_expand "beq"
12938 [(set (pc)
12939 (if_then_else (match_dup 1)
12940 (label_ref (match_operand 0 "" ""))
12941 (pc)))]
12942 ""
12943 "ix86_expand_branch (EQ, operands[0]); DONE;")
12944
12945 (define_expand "bne"
12946 [(set (pc)
12947 (if_then_else (match_dup 1)
12948 (label_ref (match_operand 0 "" ""))
12949 (pc)))]
12950 ""
12951 "ix86_expand_branch (NE, operands[0]); DONE;")
12952
12953 (define_expand "bgt"
12954 [(set (pc)
12955 (if_then_else (match_dup 1)
12956 (label_ref (match_operand 0 "" ""))
12957 (pc)))]
12958 ""
12959 "ix86_expand_branch (GT, operands[0]); DONE;")
12960
12961 (define_expand "bgtu"
12962 [(set (pc)
12963 (if_then_else (match_dup 1)
12964 (label_ref (match_operand 0 "" ""))
12965 (pc)))]
12966 ""
12967 "ix86_expand_branch (GTU, operands[0]); DONE;")
12968
12969 (define_expand "blt"
12970 [(set (pc)
12971 (if_then_else (match_dup 1)
12972 (label_ref (match_operand 0 "" ""))
12973 (pc)))]
12974 ""
12975 "ix86_expand_branch (LT, operands[0]); DONE;")
12976
12977 (define_expand "bltu"
12978 [(set (pc)
12979 (if_then_else (match_dup 1)
12980 (label_ref (match_operand 0 "" ""))
12981 (pc)))]
12982 ""
12983 "ix86_expand_branch (LTU, operands[0]); DONE;")
12984
12985 (define_expand "bge"
12986 [(set (pc)
12987 (if_then_else (match_dup 1)
12988 (label_ref (match_operand 0 "" ""))
12989 (pc)))]
12990 ""
12991 "ix86_expand_branch (GE, operands[0]); DONE;")
12992
12993 (define_expand "bgeu"
12994 [(set (pc)
12995 (if_then_else (match_dup 1)
12996 (label_ref (match_operand 0 "" ""))
12997 (pc)))]
12998 ""
12999 "ix86_expand_branch (GEU, operands[0]); DONE;")
13000
13001 (define_expand "ble"
13002 [(set (pc)
13003 (if_then_else (match_dup 1)
13004 (label_ref (match_operand 0 "" ""))
13005 (pc)))]
13006 ""
13007 "ix86_expand_branch (LE, operands[0]); DONE;")
13008
13009 (define_expand "bleu"
13010 [(set (pc)
13011 (if_then_else (match_dup 1)
13012 (label_ref (match_operand 0 "" ""))
13013 (pc)))]
13014 ""
13015 "ix86_expand_branch (LEU, operands[0]); DONE;")
13016
13017 (define_expand "bunordered"
13018 [(set (pc)
13019 (if_then_else (match_dup 1)
13020 (label_ref (match_operand 0 "" ""))
13021 (pc)))]
13022 "TARGET_80387 || TARGET_SSE_MATH"
13023 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13024
13025 (define_expand "bordered"
13026 [(set (pc)
13027 (if_then_else (match_dup 1)
13028 (label_ref (match_operand 0 "" ""))
13029 (pc)))]
13030 "TARGET_80387 || TARGET_SSE_MATH"
13031 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13032
13033 (define_expand "buneq"
13034 [(set (pc)
13035 (if_then_else (match_dup 1)
13036 (label_ref (match_operand 0 "" ""))
13037 (pc)))]
13038 "TARGET_80387 || TARGET_SSE_MATH"
13039 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13040
13041 (define_expand "bunge"
13042 [(set (pc)
13043 (if_then_else (match_dup 1)
13044 (label_ref (match_operand 0 "" ""))
13045 (pc)))]
13046 "TARGET_80387 || TARGET_SSE_MATH"
13047 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13048
13049 (define_expand "bungt"
13050 [(set (pc)
13051 (if_then_else (match_dup 1)
13052 (label_ref (match_operand 0 "" ""))
13053 (pc)))]
13054 "TARGET_80387 || TARGET_SSE_MATH"
13055 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13056
13057 (define_expand "bunle"
13058 [(set (pc)
13059 (if_then_else (match_dup 1)
13060 (label_ref (match_operand 0 "" ""))
13061 (pc)))]
13062 "TARGET_80387 || TARGET_SSE_MATH"
13063 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13064
13065 (define_expand "bunlt"
13066 [(set (pc)
13067 (if_then_else (match_dup 1)
13068 (label_ref (match_operand 0 "" ""))
13069 (pc)))]
13070 "TARGET_80387 || TARGET_SSE_MATH"
13071 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13072
13073 (define_expand "bltgt"
13074 [(set (pc)
13075 (if_then_else (match_dup 1)
13076 (label_ref (match_operand 0 "" ""))
13077 (pc)))]
13078 "TARGET_80387 || TARGET_SSE_MATH"
13079 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13080
13081 (define_insn "*jcc_1"
13082 [(set (pc)
13083 (if_then_else (match_operator 1 "ix86_comparison_operator"
13084 [(reg FLAGS_REG) (const_int 0)])
13085 (label_ref (match_operand 0 "" ""))
13086 (pc)))]
13087 ""
13088 "%+j%C1\t%l0"
13089 [(set_attr "type" "ibr")
13090 (set_attr "modrm" "0")
13091 (set (attr "length")
13092 (if_then_else (and (ge (minus (match_dup 0) (pc))
13093 (const_int -126))
13094 (lt (minus (match_dup 0) (pc))
13095 (const_int 128)))
13096 (const_int 2)
13097 (const_int 6)))])
13098
13099 (define_insn "*jcc_2"
13100 [(set (pc)
13101 (if_then_else (match_operator 1 "ix86_comparison_operator"
13102 [(reg FLAGS_REG) (const_int 0)])
13103 (pc)
13104 (label_ref (match_operand 0 "" ""))))]
13105 ""
13106 "%+j%c1\t%l0"
13107 [(set_attr "type" "ibr")
13108 (set_attr "modrm" "0")
13109 (set (attr "length")
13110 (if_then_else (and (ge (minus (match_dup 0) (pc))
13111 (const_int -126))
13112 (lt (minus (match_dup 0) (pc))
13113 (const_int 128)))
13114 (const_int 2)
13115 (const_int 6)))])
13116
13117 ;; In general it is not safe to assume too much about CCmode registers,
13118 ;; so simplify-rtx stops when it sees a second one. Under certain
13119 ;; conditions this is safe on x86, so help combine not create
13120 ;;
13121 ;; seta %al
13122 ;; testb %al, %al
13123 ;; je Lfoo
13124
13125 (define_split
13126 [(set (pc)
13127 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13128 [(reg FLAGS_REG) (const_int 0)])
13129 (const_int 0))
13130 (label_ref (match_operand 1 "" ""))
13131 (pc)))]
13132 ""
13133 [(set (pc)
13134 (if_then_else (match_dup 0)
13135 (label_ref (match_dup 1))
13136 (pc)))]
13137 {
13138 PUT_MODE (operands[0], VOIDmode);
13139 })
13140
13141 (define_split
13142 [(set (pc)
13143 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13144 [(reg FLAGS_REG) (const_int 0)])
13145 (const_int 0))
13146 (label_ref (match_operand 1 "" ""))
13147 (pc)))]
13148 ""
13149 [(set (pc)
13150 (if_then_else (match_dup 0)
13151 (label_ref (match_dup 1))
13152 (pc)))]
13153 {
13154 rtx new_op0 = copy_rtx (operands[0]);
13155 operands[0] = new_op0;
13156 PUT_MODE (new_op0, VOIDmode);
13157 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13158 GET_MODE (XEXP (new_op0, 0))));
13159
13160 /* Make sure that (a) the CCmode we have for the flags is strong
13161 enough for the reversed compare or (b) we have a valid FP compare. */
13162 if (! ix86_comparison_operator (new_op0, VOIDmode))
13163 FAIL;
13164 })
13165
13166 ;; Define combination compare-and-branch fp compare instructions to use
13167 ;; during early optimization. Splitting the operation apart early makes
13168 ;; for bad code when we want to reverse the operation.
13169
13170 (define_insn "*fp_jcc_1_mixed"
13171 [(set (pc)
13172 (if_then_else (match_operator 0 "comparison_operator"
13173 [(match_operand 1 "register_operand" "f,x")
13174 (match_operand 2 "nonimmediate_operand" "f,xm")])
13175 (label_ref (match_operand 3 "" ""))
13176 (pc)))
13177 (clobber (reg:CCFP FPSR_REG))
13178 (clobber (reg:CCFP FLAGS_REG))]
13179 "TARGET_MIX_SSE_I387
13180 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13181 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13182 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13183 "#")
13184
13185 (define_insn "*fp_jcc_1_sse"
13186 [(set (pc)
13187 (if_then_else (match_operator 0 "comparison_operator"
13188 [(match_operand 1 "register_operand" "x")
13189 (match_operand 2 "nonimmediate_operand" "xm")])
13190 (label_ref (match_operand 3 "" ""))
13191 (pc)))
13192 (clobber (reg:CCFP FPSR_REG))
13193 (clobber (reg:CCFP FLAGS_REG))]
13194 "TARGET_SSE_MATH
13195 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13196 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13197 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13198 "#")
13199
13200 (define_insn "*fp_jcc_1_387"
13201 [(set (pc)
13202 (if_then_else (match_operator 0 "comparison_operator"
13203 [(match_operand 1 "register_operand" "f")
13204 (match_operand 2 "register_operand" "f")])
13205 (label_ref (match_operand 3 "" ""))
13206 (pc)))
13207 (clobber (reg:CCFP FPSR_REG))
13208 (clobber (reg:CCFP FLAGS_REG))]
13209 "TARGET_CMOVE && TARGET_80387
13210 && FLOAT_MODE_P (GET_MODE (operands[1]))
13211 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13212 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13213 "#")
13214
13215 (define_insn "*fp_jcc_2_mixed"
13216 [(set (pc)
13217 (if_then_else (match_operator 0 "comparison_operator"
13218 [(match_operand 1 "register_operand" "f,x")
13219 (match_operand 2 "nonimmediate_operand" "f,xm")])
13220 (pc)
13221 (label_ref (match_operand 3 "" ""))))
13222 (clobber (reg:CCFP FPSR_REG))
13223 (clobber (reg:CCFP FLAGS_REG))]
13224 "TARGET_MIX_SSE_I387
13225 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13226 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13227 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13228 "#")
13229
13230 (define_insn "*fp_jcc_2_sse"
13231 [(set (pc)
13232 (if_then_else (match_operator 0 "comparison_operator"
13233 [(match_operand 1 "register_operand" "x")
13234 (match_operand 2 "nonimmediate_operand" "xm")])
13235 (pc)
13236 (label_ref (match_operand 3 "" ""))))
13237 (clobber (reg:CCFP FPSR_REG))
13238 (clobber (reg:CCFP FLAGS_REG))]
13239 "TARGET_SSE_MATH
13240 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13241 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13242 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13243 "#")
13244
13245 (define_insn "*fp_jcc_2_387"
13246 [(set (pc)
13247 (if_then_else (match_operator 0 "comparison_operator"
13248 [(match_operand 1 "register_operand" "f")
13249 (match_operand 2 "register_operand" "f")])
13250 (pc)
13251 (label_ref (match_operand 3 "" ""))))
13252 (clobber (reg:CCFP FPSR_REG))
13253 (clobber (reg:CCFP FLAGS_REG))]
13254 "TARGET_CMOVE && TARGET_80387
13255 && FLOAT_MODE_P (GET_MODE (operands[1]))
13256 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13257 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13258 "#")
13259
13260 (define_insn "*fp_jcc_3_387"
13261 [(set (pc)
13262 (if_then_else (match_operator 0 "comparison_operator"
13263 [(match_operand 1 "register_operand" "f")
13264 (match_operand 2 "nonimmediate_operand" "fm")])
13265 (label_ref (match_operand 3 "" ""))
13266 (pc)))
13267 (clobber (reg:CCFP FPSR_REG))
13268 (clobber (reg:CCFP FLAGS_REG))
13269 (clobber (match_scratch:HI 4 "=a"))]
13270 "TARGET_80387
13271 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13272 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13273 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13274 && SELECT_CC_MODE (GET_CODE (operands[0]),
13275 operands[1], operands[2]) == CCFPmode
13276 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13277 "#")
13278
13279 (define_insn "*fp_jcc_4_387"
13280 [(set (pc)
13281 (if_then_else (match_operator 0 "comparison_operator"
13282 [(match_operand 1 "register_operand" "f")
13283 (match_operand 2 "nonimmediate_operand" "fm")])
13284 (pc)
13285 (label_ref (match_operand 3 "" ""))))
13286 (clobber (reg:CCFP FPSR_REG))
13287 (clobber (reg:CCFP FLAGS_REG))
13288 (clobber (match_scratch:HI 4 "=a"))]
13289 "TARGET_80387
13290 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13291 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13292 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13293 && SELECT_CC_MODE (GET_CODE (operands[0]),
13294 operands[1], operands[2]) == CCFPmode
13295 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13296 "#")
13297
13298 (define_insn "*fp_jcc_5_387"
13299 [(set (pc)
13300 (if_then_else (match_operator 0 "comparison_operator"
13301 [(match_operand 1 "register_operand" "f")
13302 (match_operand 2 "register_operand" "f")])
13303 (label_ref (match_operand 3 "" ""))
13304 (pc)))
13305 (clobber (reg:CCFP FPSR_REG))
13306 (clobber (reg:CCFP FLAGS_REG))
13307 (clobber (match_scratch:HI 4 "=a"))]
13308 "TARGET_80387
13309 && FLOAT_MODE_P (GET_MODE (operands[1]))
13310 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13311 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13312 "#")
13313
13314 (define_insn "*fp_jcc_6_387"
13315 [(set (pc)
13316 (if_then_else (match_operator 0 "comparison_operator"
13317 [(match_operand 1 "register_operand" "f")
13318 (match_operand 2 "register_operand" "f")])
13319 (pc)
13320 (label_ref (match_operand 3 "" ""))))
13321 (clobber (reg:CCFP FPSR_REG))
13322 (clobber (reg:CCFP FLAGS_REG))
13323 (clobber (match_scratch:HI 4 "=a"))]
13324 "TARGET_80387
13325 && FLOAT_MODE_P (GET_MODE (operands[1]))
13326 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13327 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13328 "#")
13329
13330 (define_insn "*fp_jcc_7_387"
13331 [(set (pc)
13332 (if_then_else (match_operator 0 "comparison_operator"
13333 [(match_operand 1 "register_operand" "f")
13334 (match_operand 2 "const0_operand" "X")])
13335 (label_ref (match_operand 3 "" ""))
13336 (pc)))
13337 (clobber (reg:CCFP FPSR_REG))
13338 (clobber (reg:CCFP FLAGS_REG))
13339 (clobber (match_scratch:HI 4 "=a"))]
13340 "TARGET_80387
13341 && FLOAT_MODE_P (GET_MODE (operands[1]))
13342 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13343 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13344 && SELECT_CC_MODE (GET_CODE (operands[0]),
13345 operands[1], operands[2]) == CCFPmode
13346 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13347 "#")
13348
13349 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13350 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13351 ;; with a precedence over other operators and is always put in the first
13352 ;; place. Swap condition and operands to match ficom instruction.
13353
13354 (define_insn "*fp_jcc_8<mode>_387"
13355 [(set (pc)
13356 (if_then_else (match_operator 0 "comparison_operator"
13357 [(match_operator 1 "float_operator"
13358 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13359 (match_operand 3 "register_operand" "f,f")])
13360 (label_ref (match_operand 4 "" ""))
13361 (pc)))
13362 (clobber (reg:CCFP FPSR_REG))
13363 (clobber (reg:CCFP FLAGS_REG))
13364 (clobber (match_scratch:HI 5 "=a,a"))]
13365 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13366 && FLOAT_MODE_P (GET_MODE (operands[3]))
13367 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13368 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13369 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13370 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13371 "#")
13372
13373 (define_split
13374 [(set (pc)
13375 (if_then_else (match_operator 0 "comparison_operator"
13376 [(match_operand 1 "register_operand" "")
13377 (match_operand 2 "nonimmediate_operand" "")])
13378 (match_operand 3 "" "")
13379 (match_operand 4 "" "")))
13380 (clobber (reg:CCFP FPSR_REG))
13381 (clobber (reg:CCFP FLAGS_REG))]
13382 "reload_completed"
13383 [(const_int 0)]
13384 {
13385 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13386 operands[3], operands[4], NULL_RTX, NULL_RTX);
13387 DONE;
13388 })
13389
13390 (define_split
13391 [(set (pc)
13392 (if_then_else (match_operator 0 "comparison_operator"
13393 [(match_operand 1 "register_operand" "")
13394 (match_operand 2 "general_operand" "")])
13395 (match_operand 3 "" "")
13396 (match_operand 4 "" "")))
13397 (clobber (reg:CCFP FPSR_REG))
13398 (clobber (reg:CCFP FLAGS_REG))
13399 (clobber (match_scratch:HI 5 "=a"))]
13400 "reload_completed"
13401 [(const_int 0)]
13402 {
13403 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13404 operands[3], operands[4], operands[5], NULL_RTX);
13405 DONE;
13406 })
13407
13408 (define_split
13409 [(set (pc)
13410 (if_then_else (match_operator 0 "comparison_operator"
13411 [(match_operator 1 "float_operator"
13412 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13413 (match_operand 3 "register_operand" "")])
13414 (match_operand 4 "" "")
13415 (match_operand 5 "" "")))
13416 (clobber (reg:CCFP FPSR_REG))
13417 (clobber (reg:CCFP FLAGS_REG))
13418 (clobber (match_scratch:HI 6 "=a"))]
13419 "reload_completed"
13420 [(const_int 0)]
13421 {
13422 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13423 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13424 operands[3], operands[7],
13425 operands[4], operands[5], operands[6], NULL_RTX);
13426 DONE;
13427 })
13428
13429 ;; %%% Kill this when reload knows how to do it.
13430 (define_split
13431 [(set (pc)
13432 (if_then_else (match_operator 0 "comparison_operator"
13433 [(match_operator 1 "float_operator"
13434 [(match_operand:X87MODEI12 2 "register_operand" "")])
13435 (match_operand 3 "register_operand" "")])
13436 (match_operand 4 "" "")
13437 (match_operand 5 "" "")))
13438 (clobber (reg:CCFP FPSR_REG))
13439 (clobber (reg:CCFP FLAGS_REG))
13440 (clobber (match_scratch:HI 6 "=a"))]
13441 "reload_completed"
13442 [(const_int 0)]
13443 {
13444 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13445 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13446 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13447 operands[3], operands[7],
13448 operands[4], operands[5], operands[6], operands[2]);
13449 DONE;
13450 })
13451 \f
13452 ;; Unconditional and other jump instructions
13453
13454 (define_insn "jump"
13455 [(set (pc)
13456 (label_ref (match_operand 0 "" "")))]
13457 ""
13458 "jmp\t%l0"
13459 [(set_attr "type" "ibr")
13460 (set (attr "length")
13461 (if_then_else (and (ge (minus (match_dup 0) (pc))
13462 (const_int -126))
13463 (lt (minus (match_dup 0) (pc))
13464 (const_int 128)))
13465 (const_int 2)
13466 (const_int 5)))
13467 (set_attr "modrm" "0")])
13468
13469 (define_expand "indirect_jump"
13470 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13471 ""
13472 "")
13473
13474 (define_insn "*indirect_jump"
13475 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13476 "!TARGET_64BIT"
13477 "jmp\t%A0"
13478 [(set_attr "type" "ibr")
13479 (set_attr "length_immediate" "0")])
13480
13481 (define_insn "*indirect_jump_rtx64"
13482 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13483 "TARGET_64BIT"
13484 "jmp\t%A0"
13485 [(set_attr "type" "ibr")
13486 (set_attr "length_immediate" "0")])
13487
13488 (define_expand "tablejump"
13489 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13490 (use (label_ref (match_operand 1 "" "")))])]
13491 ""
13492 {
13493 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13494 relative. Convert the relative address to an absolute address. */
13495 if (flag_pic)
13496 {
13497 rtx op0, op1;
13498 enum rtx_code code;
13499
13500 if (TARGET_64BIT)
13501 {
13502 code = PLUS;
13503 op0 = operands[0];
13504 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13505 }
13506 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13507 {
13508 code = PLUS;
13509 op0 = operands[0];
13510 op1 = pic_offset_table_rtx;
13511 }
13512 else
13513 {
13514 code = MINUS;
13515 op0 = pic_offset_table_rtx;
13516 op1 = operands[0];
13517 }
13518
13519 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13520 OPTAB_DIRECT);
13521 }
13522 })
13523
13524 (define_insn "*tablejump_1"
13525 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13526 (use (label_ref (match_operand 1 "" "")))]
13527 "!TARGET_64BIT"
13528 "jmp\t%A0"
13529 [(set_attr "type" "ibr")
13530 (set_attr "length_immediate" "0")])
13531
13532 (define_insn "*tablejump_1_rtx64"
13533 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13534 (use (label_ref (match_operand 1 "" "")))]
13535 "TARGET_64BIT"
13536 "jmp\t%A0"
13537 [(set_attr "type" "ibr")
13538 (set_attr "length_immediate" "0")])
13539 \f
13540 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13541
13542 (define_peephole2
13543 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13544 (set (match_operand:QI 1 "register_operand" "")
13545 (match_operator:QI 2 "ix86_comparison_operator"
13546 [(reg FLAGS_REG) (const_int 0)]))
13547 (set (match_operand 3 "q_regs_operand" "")
13548 (zero_extend (match_dup 1)))]
13549 "(peep2_reg_dead_p (3, operands[1])
13550 || operands_match_p (operands[1], operands[3]))
13551 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13552 [(set (match_dup 4) (match_dup 0))
13553 (set (strict_low_part (match_dup 5))
13554 (match_dup 2))]
13555 {
13556 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13557 operands[5] = gen_lowpart (QImode, operands[3]);
13558 ix86_expand_clear (operands[3]);
13559 })
13560
13561 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13562
13563 (define_peephole2
13564 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13565 (set (match_operand:QI 1 "register_operand" "")
13566 (match_operator:QI 2 "ix86_comparison_operator"
13567 [(reg FLAGS_REG) (const_int 0)]))
13568 (parallel [(set (match_operand 3 "q_regs_operand" "")
13569 (zero_extend (match_dup 1)))
13570 (clobber (reg:CC FLAGS_REG))])]
13571 "(peep2_reg_dead_p (3, operands[1])
13572 || operands_match_p (operands[1], operands[3]))
13573 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13574 [(set (match_dup 4) (match_dup 0))
13575 (set (strict_low_part (match_dup 5))
13576 (match_dup 2))]
13577 {
13578 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13579 operands[5] = gen_lowpart (QImode, operands[3]);
13580 ix86_expand_clear (operands[3]);
13581 })
13582 \f
13583 ;; Call instructions.
13584
13585 ;; The predicates normally associated with named expanders are not properly
13586 ;; checked for calls. This is a bug in the generic code, but it isn't that
13587 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13588
13589 ;; Call subroutine returning no value.
13590
13591 (define_expand "call_pop"
13592 [(parallel [(call (match_operand:QI 0 "" "")
13593 (match_operand:SI 1 "" ""))
13594 (set (reg:SI SP_REG)
13595 (plus:SI (reg:SI SP_REG)
13596 (match_operand:SI 3 "" "")))])]
13597 "!TARGET_64BIT"
13598 {
13599 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13600 DONE;
13601 })
13602
13603 (define_insn "*call_pop_0"
13604 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13605 (match_operand:SI 1 "" ""))
13606 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13607 (match_operand:SI 2 "immediate_operand" "")))]
13608 "!TARGET_64BIT"
13609 {
13610 if (SIBLING_CALL_P (insn))
13611 return "jmp\t%P0";
13612 else
13613 return "call\t%P0";
13614 }
13615 [(set_attr "type" "call")])
13616
13617 (define_insn "*call_pop_1"
13618 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13619 (match_operand:SI 1 "" ""))
13620 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13621 (match_operand:SI 2 "immediate_operand" "i")))]
13622 "!TARGET_64BIT"
13623 {
13624 if (constant_call_address_operand (operands[0], Pmode))
13625 {
13626 if (SIBLING_CALL_P (insn))
13627 return "jmp\t%P0";
13628 else
13629 return "call\t%P0";
13630 }
13631 if (SIBLING_CALL_P (insn))
13632 return "jmp\t%A0";
13633 else
13634 return "call\t%A0";
13635 }
13636 [(set_attr "type" "call")])
13637
13638 (define_expand "call"
13639 [(call (match_operand:QI 0 "" "")
13640 (match_operand 1 "" ""))
13641 (use (match_operand 2 "" ""))]
13642 ""
13643 {
13644 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13645 DONE;
13646 })
13647
13648 (define_expand "sibcall"
13649 [(call (match_operand:QI 0 "" "")
13650 (match_operand 1 "" ""))
13651 (use (match_operand 2 "" ""))]
13652 ""
13653 {
13654 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13655 DONE;
13656 })
13657
13658 (define_insn "*call_0"
13659 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13660 (match_operand 1 "" ""))]
13661 ""
13662 {
13663 if (SIBLING_CALL_P (insn))
13664 return "jmp\t%P0";
13665 else
13666 return "call\t%P0";
13667 }
13668 [(set_attr "type" "call")])
13669
13670 (define_insn "*call_1"
13671 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13672 (match_operand 1 "" ""))]
13673 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13674 {
13675 if (constant_call_address_operand (operands[0], Pmode))
13676 return "call\t%P0";
13677 return "call\t%A0";
13678 }
13679 [(set_attr "type" "call")])
13680
13681 (define_insn "*sibcall_1"
13682 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13683 (match_operand 1 "" ""))]
13684 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13685 {
13686 if (constant_call_address_operand (operands[0], Pmode))
13687 return "jmp\t%P0";
13688 return "jmp\t%A0";
13689 }
13690 [(set_attr "type" "call")])
13691
13692 (define_insn "*call_1_rex64"
13693 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13694 (match_operand 1 "" ""))]
13695 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13696 {
13697 if (constant_call_address_operand (operands[0], Pmode))
13698 return "call\t%P0";
13699 return "call\t%A0";
13700 }
13701 [(set_attr "type" "call")])
13702
13703 (define_insn "*sibcall_1_rex64"
13704 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13705 (match_operand 1 "" ""))]
13706 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13707 "jmp\t%P0"
13708 [(set_attr "type" "call")])
13709
13710 (define_insn "*sibcall_1_rex64_v"
13711 [(call (mem:QI (reg:DI 40))
13712 (match_operand 0 "" ""))]
13713 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13714 "jmp\t*%%r11"
13715 [(set_attr "type" "call")])
13716
13717
13718 ;; Call subroutine, returning value in operand 0
13719
13720 (define_expand "call_value_pop"
13721 [(parallel [(set (match_operand 0 "" "")
13722 (call (match_operand:QI 1 "" "")
13723 (match_operand:SI 2 "" "")))
13724 (set (reg:SI SP_REG)
13725 (plus:SI (reg:SI SP_REG)
13726 (match_operand:SI 4 "" "")))])]
13727 "!TARGET_64BIT"
13728 {
13729 ix86_expand_call (operands[0], operands[1], operands[2],
13730 operands[3], operands[4], 0);
13731 DONE;
13732 })
13733
13734 (define_expand "call_value"
13735 [(set (match_operand 0 "" "")
13736 (call (match_operand:QI 1 "" "")
13737 (match_operand:SI 2 "" "")))
13738 (use (match_operand:SI 3 "" ""))]
13739 ;; Operand 2 not used on the i386.
13740 ""
13741 {
13742 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13743 DONE;
13744 })
13745
13746 (define_expand "sibcall_value"
13747 [(set (match_operand 0 "" "")
13748 (call (match_operand:QI 1 "" "")
13749 (match_operand:SI 2 "" "")))
13750 (use (match_operand:SI 3 "" ""))]
13751 ;; Operand 2 not used on the i386.
13752 ""
13753 {
13754 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13755 DONE;
13756 })
13757
13758 ;; Call subroutine returning any type.
13759
13760 (define_expand "untyped_call"
13761 [(parallel [(call (match_operand 0 "" "")
13762 (const_int 0))
13763 (match_operand 1 "" "")
13764 (match_operand 2 "" "")])]
13765 ""
13766 {
13767 int i;
13768
13769 /* In order to give reg-stack an easier job in validating two
13770 coprocessor registers as containing a possible return value,
13771 simply pretend the untyped call returns a complex long double
13772 value. */
13773
13774 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13775 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13776 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13777 NULL, 0);
13778
13779 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13780 {
13781 rtx set = XVECEXP (operands[2], 0, i);
13782 emit_move_insn (SET_DEST (set), SET_SRC (set));
13783 }
13784
13785 /* The optimizer does not know that the call sets the function value
13786 registers we stored in the result block. We avoid problems by
13787 claiming that all hard registers are used and clobbered at this
13788 point. */
13789 emit_insn (gen_blockage (const0_rtx));
13790
13791 DONE;
13792 })
13793 \f
13794 ;; Prologue and epilogue instructions
13795
13796 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13797 ;; all of memory. This blocks insns from being moved across this point.
13798
13799 (define_insn "blockage"
13800 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13801 ""
13802 ""
13803 [(set_attr "length" "0")])
13804
13805 ;; Insn emitted into the body of a function to return from a function.
13806 ;; This is only done if the function's epilogue is known to be simple.
13807 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13808
13809 (define_expand "return"
13810 [(return)]
13811 "ix86_can_use_return_insn_p ()"
13812 {
13813 if (current_function_pops_args)
13814 {
13815 rtx popc = GEN_INT (current_function_pops_args);
13816 emit_jump_insn (gen_return_pop_internal (popc));
13817 DONE;
13818 }
13819 })
13820
13821 (define_insn "return_internal"
13822 [(return)]
13823 "reload_completed"
13824 "ret"
13825 [(set_attr "length" "1")
13826 (set_attr "length_immediate" "0")
13827 (set_attr "modrm" "0")])
13828
13829 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13830 ;; instruction Athlon and K8 have.
13831
13832 (define_insn "return_internal_long"
13833 [(return)
13834 (unspec [(const_int 0)] UNSPEC_REP)]
13835 "reload_completed"
13836 "rep {;} ret"
13837 [(set_attr "length" "1")
13838 (set_attr "length_immediate" "0")
13839 (set_attr "prefix_rep" "1")
13840 (set_attr "modrm" "0")])
13841
13842 (define_insn "return_pop_internal"
13843 [(return)
13844 (use (match_operand:SI 0 "const_int_operand" ""))]
13845 "reload_completed"
13846 "ret\t%0"
13847 [(set_attr "length" "3")
13848 (set_attr "length_immediate" "2")
13849 (set_attr "modrm" "0")])
13850
13851 (define_insn "return_indirect_internal"
13852 [(return)
13853 (use (match_operand:SI 0 "register_operand" "r"))]
13854 "reload_completed"
13855 "jmp\t%A0"
13856 [(set_attr "type" "ibr")
13857 (set_attr "length_immediate" "0")])
13858
13859 (define_insn "nop"
13860 [(const_int 0)]
13861 ""
13862 "nop"
13863 [(set_attr "length" "1")
13864 (set_attr "length_immediate" "0")
13865 (set_attr "modrm" "0")])
13866
13867 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13868 ;; branch prediction penalty for the third jump in a 16-byte
13869 ;; block on K8.
13870
13871 (define_insn "align"
13872 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13873 ""
13874 {
13875 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13876 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13877 #else
13878 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13879 The align insn is used to avoid 3 jump instructions in the row to improve
13880 branch prediction and the benefits hardly outweigh the cost of extra 8
13881 nops on the average inserted by full alignment pseudo operation. */
13882 #endif
13883 return "";
13884 }
13885 [(set_attr "length" "16")])
13886
13887 (define_expand "prologue"
13888 [(const_int 1)]
13889 ""
13890 "ix86_expand_prologue (); DONE;")
13891
13892 (define_insn "set_got"
13893 [(set (match_operand:SI 0 "register_operand" "=r")
13894 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13895 (clobber (reg:CC FLAGS_REG))]
13896 "!TARGET_64BIT"
13897 { return output_set_got (operands[0], NULL_RTX); }
13898 [(set_attr "type" "multi")
13899 (set_attr "length" "12")])
13900
13901 (define_insn "set_got_labelled"
13902 [(set (match_operand:SI 0 "register_operand" "=r")
13903 (unspec:SI [(label_ref (match_operand 1 "" ""))]
13904 UNSPEC_SET_GOT))
13905 (clobber (reg:CC FLAGS_REG))]
13906 "!TARGET_64BIT"
13907 { return output_set_got (operands[0], operands[1]); }
13908 [(set_attr "type" "multi")
13909 (set_attr "length" "12")])
13910
13911 (define_insn "set_got_rex64"
13912 [(set (match_operand:DI 0 "register_operand" "=r")
13913 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13914 "TARGET_64BIT"
13915 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13916 [(set_attr "type" "lea")
13917 (set_attr "length" "6")])
13918
13919 (define_expand "epilogue"
13920 [(const_int 1)]
13921 ""
13922 "ix86_expand_epilogue (1); DONE;")
13923
13924 (define_expand "sibcall_epilogue"
13925 [(const_int 1)]
13926 ""
13927 "ix86_expand_epilogue (0); DONE;")
13928
13929 (define_expand "eh_return"
13930 [(use (match_operand 0 "register_operand" ""))]
13931 ""
13932 {
13933 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13934
13935 /* Tricky bit: we write the address of the handler to which we will
13936 be returning into someone else's stack frame, one word below the
13937 stack address we wish to restore. */
13938 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13939 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13940 tmp = gen_rtx_MEM (Pmode, tmp);
13941 emit_move_insn (tmp, ra);
13942
13943 if (Pmode == SImode)
13944 emit_jump_insn (gen_eh_return_si (sa));
13945 else
13946 emit_jump_insn (gen_eh_return_di (sa));
13947 emit_barrier ();
13948 DONE;
13949 })
13950
13951 (define_insn_and_split "eh_return_si"
13952 [(set (pc)
13953 (unspec [(match_operand:SI 0 "register_operand" "c")]
13954 UNSPEC_EH_RETURN))]
13955 "!TARGET_64BIT"
13956 "#"
13957 "reload_completed"
13958 [(const_int 1)]
13959 "ix86_expand_epilogue (2); DONE;")
13960
13961 (define_insn_and_split "eh_return_di"
13962 [(set (pc)
13963 (unspec [(match_operand:DI 0 "register_operand" "c")]
13964 UNSPEC_EH_RETURN))]
13965 "TARGET_64BIT"
13966 "#"
13967 "reload_completed"
13968 [(const_int 1)]
13969 "ix86_expand_epilogue (2); DONE;")
13970
13971 (define_insn "leave"
13972 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13973 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13974 (clobber (mem:BLK (scratch)))]
13975 "!TARGET_64BIT"
13976 "leave"
13977 [(set_attr "type" "leave")])
13978
13979 (define_insn "leave_rex64"
13980 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13981 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13982 (clobber (mem:BLK (scratch)))]
13983 "TARGET_64BIT"
13984 "leave"
13985 [(set_attr "type" "leave")])
13986 \f
13987 (define_expand "ffssi2"
13988 [(parallel
13989 [(set (match_operand:SI 0 "register_operand" "")
13990 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13991 (clobber (match_scratch:SI 2 ""))
13992 (clobber (reg:CC FLAGS_REG))])]
13993 ""
13994 "")
13995
13996 (define_insn_and_split "*ffs_cmove"
13997 [(set (match_operand:SI 0 "register_operand" "=r")
13998 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13999 (clobber (match_scratch:SI 2 "=&r"))
14000 (clobber (reg:CC FLAGS_REG))]
14001 "TARGET_CMOVE"
14002 "#"
14003 "&& reload_completed"
14004 [(set (match_dup 2) (const_int -1))
14005 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14006 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14007 (set (match_dup 0) (if_then_else:SI
14008 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14009 (match_dup 2)
14010 (match_dup 0)))
14011 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14012 (clobber (reg:CC FLAGS_REG))])]
14013 "")
14014
14015 (define_insn_and_split "*ffs_no_cmove"
14016 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14017 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14018 (clobber (match_scratch:SI 2 "=&q"))
14019 (clobber (reg:CC FLAGS_REG))]
14020 ""
14021 "#"
14022 "reload_completed"
14023 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14024 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14025 (set (strict_low_part (match_dup 3))
14026 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14027 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14028 (clobber (reg:CC FLAGS_REG))])
14029 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14030 (clobber (reg:CC FLAGS_REG))])
14031 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14032 (clobber (reg:CC FLAGS_REG))])]
14033 {
14034 operands[3] = gen_lowpart (QImode, operands[2]);
14035 ix86_expand_clear (operands[2]);
14036 })
14037
14038 (define_insn "*ffssi_1"
14039 [(set (reg:CCZ FLAGS_REG)
14040 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14041 (const_int 0)))
14042 (set (match_operand:SI 0 "register_operand" "=r")
14043 (ctz:SI (match_dup 1)))]
14044 ""
14045 "bsf{l}\t{%1, %0|%0, %1}"
14046 [(set_attr "prefix_0f" "1")])
14047
14048 (define_expand "ffsdi2"
14049 [(parallel
14050 [(set (match_operand:DI 0 "register_operand" "")
14051 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14052 (clobber (match_scratch:DI 2 ""))
14053 (clobber (reg:CC FLAGS_REG))])]
14054 "TARGET_64BIT && TARGET_CMOVE"
14055 "")
14056
14057 (define_insn_and_split "*ffs_rex64"
14058 [(set (match_operand:DI 0 "register_operand" "=r")
14059 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14060 (clobber (match_scratch:DI 2 "=&r"))
14061 (clobber (reg:CC FLAGS_REG))]
14062 "TARGET_64BIT && TARGET_CMOVE"
14063 "#"
14064 "&& reload_completed"
14065 [(set (match_dup 2) (const_int -1))
14066 (parallel [(set (reg:CCZ FLAGS_REG)
14067 (compare:CCZ (match_dup 1) (const_int 0)))
14068 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14069 (set (match_dup 0) (if_then_else:DI
14070 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14071 (match_dup 2)
14072 (match_dup 0)))
14073 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14074 (clobber (reg:CC FLAGS_REG))])]
14075 "")
14076
14077 (define_insn "*ffsdi_1"
14078 [(set (reg:CCZ FLAGS_REG)
14079 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14080 (const_int 0)))
14081 (set (match_operand:DI 0 "register_operand" "=r")
14082 (ctz:DI (match_dup 1)))]
14083 "TARGET_64BIT"
14084 "bsf{q}\t{%1, %0|%0, %1}"
14085 [(set_attr "prefix_0f" "1")])
14086
14087 (define_insn "ctzsi2"
14088 [(set (match_operand:SI 0 "register_operand" "=r")
14089 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14090 (clobber (reg:CC FLAGS_REG))]
14091 ""
14092 "bsf{l}\t{%1, %0|%0, %1}"
14093 [(set_attr "prefix_0f" "1")])
14094
14095 (define_insn "ctzdi2"
14096 [(set (match_operand:DI 0 "register_operand" "=r")
14097 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14098 (clobber (reg:CC FLAGS_REG))]
14099 "TARGET_64BIT"
14100 "bsf{q}\t{%1, %0|%0, %1}"
14101 [(set_attr "prefix_0f" "1")])
14102
14103 (define_expand "clzsi2"
14104 [(parallel
14105 [(set (match_operand:SI 0 "register_operand" "")
14106 (minus:SI (const_int 31)
14107 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14108 (clobber (reg:CC FLAGS_REG))])
14109 (parallel
14110 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14111 (clobber (reg:CC FLAGS_REG))])]
14112 ""
14113 "")
14114
14115 (define_insn "*bsr"
14116 [(set (match_operand:SI 0 "register_operand" "=r")
14117 (minus:SI (const_int 31)
14118 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14119 (clobber (reg:CC FLAGS_REG))]
14120 ""
14121 "bsr{l}\t{%1, %0|%0, %1}"
14122 [(set_attr "prefix_0f" "1")])
14123
14124 (define_expand "clzdi2"
14125 [(parallel
14126 [(set (match_operand:DI 0 "register_operand" "")
14127 (minus:DI (const_int 63)
14128 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14129 (clobber (reg:CC FLAGS_REG))])
14130 (parallel
14131 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14132 (clobber (reg:CC FLAGS_REG))])]
14133 "TARGET_64BIT"
14134 "")
14135
14136 (define_insn "*bsr_rex64"
14137 [(set (match_operand:DI 0 "register_operand" "=r")
14138 (minus:DI (const_int 63)
14139 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14140 (clobber (reg:CC FLAGS_REG))]
14141 "TARGET_64BIT"
14142 "bsr{q}\t{%1, %0|%0, %1}"
14143 [(set_attr "prefix_0f" "1")])
14144 \f
14145 ;; Thread-local storage patterns for ELF.
14146 ;;
14147 ;; Note that these code sequences must appear exactly as shown
14148 ;; in order to allow linker relaxation.
14149
14150 (define_insn "*tls_global_dynamic_32_gnu"
14151 [(set (match_operand:SI 0 "register_operand" "=a")
14152 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14153 (match_operand:SI 2 "tls_symbolic_operand" "")
14154 (match_operand:SI 3 "call_insn_operand" "")]
14155 UNSPEC_TLS_GD))
14156 (clobber (match_scratch:SI 4 "=d"))
14157 (clobber (match_scratch:SI 5 "=c"))
14158 (clobber (reg:CC FLAGS_REG))]
14159 "!TARGET_64BIT && TARGET_GNU_TLS"
14160 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14161 [(set_attr "type" "multi")
14162 (set_attr "length" "12")])
14163
14164 (define_insn "*tls_global_dynamic_32_sun"
14165 [(set (match_operand:SI 0 "register_operand" "=a")
14166 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14167 (match_operand:SI 2 "tls_symbolic_operand" "")
14168 (match_operand:SI 3 "call_insn_operand" "")]
14169 UNSPEC_TLS_GD))
14170 (clobber (match_scratch:SI 4 "=d"))
14171 (clobber (match_scratch:SI 5 "=c"))
14172 (clobber (reg:CC FLAGS_REG))]
14173 "!TARGET_64BIT && TARGET_SUN_TLS"
14174 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14175 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14176 [(set_attr "type" "multi")
14177 (set_attr "length" "14")])
14178
14179 (define_expand "tls_global_dynamic_32"
14180 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14181 (unspec:SI
14182 [(match_dup 2)
14183 (match_operand:SI 1 "tls_symbolic_operand" "")
14184 (match_dup 3)]
14185 UNSPEC_TLS_GD))
14186 (clobber (match_scratch:SI 4 ""))
14187 (clobber (match_scratch:SI 5 ""))
14188 (clobber (reg:CC FLAGS_REG))])]
14189 ""
14190 {
14191 if (flag_pic)
14192 operands[2] = pic_offset_table_rtx;
14193 else
14194 {
14195 operands[2] = gen_reg_rtx (Pmode);
14196 emit_insn (gen_set_got (operands[2]));
14197 }
14198 if (TARGET_GNU2_TLS)
14199 {
14200 emit_insn (gen_tls_dynamic_gnu2_32
14201 (operands[0], operands[1], operands[2]));
14202 DONE;
14203 }
14204 operands[3] = ix86_tls_get_addr ();
14205 })
14206
14207 (define_insn "*tls_global_dynamic_64"
14208 [(set (match_operand:DI 0 "register_operand" "=a")
14209 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14210 (match_operand:DI 3 "" "")))
14211 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14212 UNSPEC_TLS_GD)]
14213 "TARGET_64BIT"
14214 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14215 [(set_attr "type" "multi")
14216 (set_attr "length" "16")])
14217
14218 (define_expand "tls_global_dynamic_64"
14219 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14220 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14221 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14222 UNSPEC_TLS_GD)])]
14223 ""
14224 {
14225 if (TARGET_GNU2_TLS)
14226 {
14227 emit_insn (gen_tls_dynamic_gnu2_64
14228 (operands[0], operands[1]));
14229 DONE;
14230 }
14231 operands[2] = ix86_tls_get_addr ();
14232 })
14233
14234 (define_insn "*tls_local_dynamic_base_32_gnu"
14235 [(set (match_operand:SI 0 "register_operand" "=a")
14236 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14237 (match_operand:SI 2 "call_insn_operand" "")]
14238 UNSPEC_TLS_LD_BASE))
14239 (clobber (match_scratch:SI 3 "=d"))
14240 (clobber (match_scratch:SI 4 "=c"))
14241 (clobber (reg:CC FLAGS_REG))]
14242 "!TARGET_64BIT && TARGET_GNU_TLS"
14243 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14244 [(set_attr "type" "multi")
14245 (set_attr "length" "11")])
14246
14247 (define_insn "*tls_local_dynamic_base_32_sun"
14248 [(set (match_operand:SI 0 "register_operand" "=a")
14249 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14250 (match_operand:SI 2 "call_insn_operand" "")]
14251 UNSPEC_TLS_LD_BASE))
14252 (clobber (match_scratch:SI 3 "=d"))
14253 (clobber (match_scratch:SI 4 "=c"))
14254 (clobber (reg:CC FLAGS_REG))]
14255 "!TARGET_64BIT && TARGET_SUN_TLS"
14256 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14257 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14258 [(set_attr "type" "multi")
14259 (set_attr "length" "13")])
14260
14261 (define_expand "tls_local_dynamic_base_32"
14262 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14263 (unspec:SI [(match_dup 1) (match_dup 2)]
14264 UNSPEC_TLS_LD_BASE))
14265 (clobber (match_scratch:SI 3 ""))
14266 (clobber (match_scratch:SI 4 ""))
14267 (clobber (reg:CC FLAGS_REG))])]
14268 ""
14269 {
14270 if (flag_pic)
14271 operands[1] = pic_offset_table_rtx;
14272 else
14273 {
14274 operands[1] = gen_reg_rtx (Pmode);
14275 emit_insn (gen_set_got (operands[1]));
14276 }
14277 if (TARGET_GNU2_TLS)
14278 {
14279 emit_insn (gen_tls_dynamic_gnu2_32
14280 (operands[0], ix86_tls_module_base (), operands[1]));
14281 DONE;
14282 }
14283 operands[2] = ix86_tls_get_addr ();
14284 })
14285
14286 (define_insn "*tls_local_dynamic_base_64"
14287 [(set (match_operand:DI 0 "register_operand" "=a")
14288 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14289 (match_operand:DI 2 "" "")))
14290 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14291 "TARGET_64BIT"
14292 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14293 [(set_attr "type" "multi")
14294 (set_attr "length" "12")])
14295
14296 (define_expand "tls_local_dynamic_base_64"
14297 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14298 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14299 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14300 ""
14301 {
14302 if (TARGET_GNU2_TLS)
14303 {
14304 emit_insn (gen_tls_dynamic_gnu2_64
14305 (operands[0], ix86_tls_module_base ()));
14306 DONE;
14307 }
14308 operands[1] = ix86_tls_get_addr ();
14309 })
14310
14311 ;; Local dynamic of a single variable is a lose. Show combine how
14312 ;; to convert that back to global dynamic.
14313
14314 (define_insn_and_split "*tls_local_dynamic_32_once"
14315 [(set (match_operand:SI 0 "register_operand" "=a")
14316 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14317 (match_operand:SI 2 "call_insn_operand" "")]
14318 UNSPEC_TLS_LD_BASE)
14319 (const:SI (unspec:SI
14320 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14321 UNSPEC_DTPOFF))))
14322 (clobber (match_scratch:SI 4 "=d"))
14323 (clobber (match_scratch:SI 5 "=c"))
14324 (clobber (reg:CC FLAGS_REG))]
14325 ""
14326 "#"
14327 ""
14328 [(parallel [(set (match_dup 0)
14329 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14330 UNSPEC_TLS_GD))
14331 (clobber (match_dup 4))
14332 (clobber (match_dup 5))
14333 (clobber (reg:CC FLAGS_REG))])]
14334 "")
14335
14336 ;; Load and add the thread base pointer from %gs:0.
14337
14338 (define_insn "*load_tp_si"
14339 [(set (match_operand:SI 0 "register_operand" "=r")
14340 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14341 "!TARGET_64BIT"
14342 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14343 [(set_attr "type" "imov")
14344 (set_attr "modrm" "0")
14345 (set_attr "length" "7")
14346 (set_attr "memory" "load")
14347 (set_attr "imm_disp" "false")])
14348
14349 (define_insn "*add_tp_si"
14350 [(set (match_operand:SI 0 "register_operand" "=r")
14351 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14352 (match_operand:SI 1 "register_operand" "0")))
14353 (clobber (reg:CC FLAGS_REG))]
14354 "!TARGET_64BIT"
14355 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14356 [(set_attr "type" "alu")
14357 (set_attr "modrm" "0")
14358 (set_attr "length" "7")
14359 (set_attr "memory" "load")
14360 (set_attr "imm_disp" "false")])
14361
14362 (define_insn "*load_tp_di"
14363 [(set (match_operand:DI 0 "register_operand" "=r")
14364 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14365 "TARGET_64BIT"
14366 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14367 [(set_attr "type" "imov")
14368 (set_attr "modrm" "0")
14369 (set_attr "length" "7")
14370 (set_attr "memory" "load")
14371 (set_attr "imm_disp" "false")])
14372
14373 (define_insn "*add_tp_di"
14374 [(set (match_operand:DI 0 "register_operand" "=r")
14375 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14376 (match_operand:DI 1 "register_operand" "0")))
14377 (clobber (reg:CC FLAGS_REG))]
14378 "TARGET_64BIT"
14379 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14380 [(set_attr "type" "alu")
14381 (set_attr "modrm" "0")
14382 (set_attr "length" "7")
14383 (set_attr "memory" "load")
14384 (set_attr "imm_disp" "false")])
14385
14386 ;; GNU2 TLS patterns can be split.
14387
14388 (define_expand "tls_dynamic_gnu2_32"
14389 [(set (match_dup 3)
14390 (plus:SI (match_operand:SI 2 "register_operand" "")
14391 (const:SI
14392 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14393 UNSPEC_TLSDESC))))
14394 (parallel
14395 [(set (match_operand:SI 0 "register_operand" "")
14396 (unspec:SI [(match_dup 1) (match_dup 3)
14397 (match_dup 2) (reg:SI SP_REG)]
14398 UNSPEC_TLSDESC))
14399 (clobber (reg:CC FLAGS_REG))])]
14400 "!TARGET_64BIT && TARGET_GNU2_TLS"
14401 {
14402 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14403 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14404 })
14405
14406 (define_insn "*tls_dynamic_lea_32"
14407 [(set (match_operand:SI 0 "register_operand" "=r")
14408 (plus:SI (match_operand:SI 1 "register_operand" "b")
14409 (const:SI
14410 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14411 UNSPEC_TLSDESC))))]
14412 "!TARGET_64BIT && TARGET_GNU2_TLS"
14413 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14414 [(set_attr "type" "lea")
14415 (set_attr "mode" "SI")
14416 (set_attr "length" "6")
14417 (set_attr "length_address" "4")])
14418
14419 (define_insn "*tls_dynamic_call_32"
14420 [(set (match_operand:SI 0 "register_operand" "=a")
14421 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14422 (match_operand:SI 2 "register_operand" "0")
14423 ;; we have to make sure %ebx still points to the GOT
14424 (match_operand:SI 3 "register_operand" "b")
14425 (reg:SI SP_REG)]
14426 UNSPEC_TLSDESC))
14427 (clobber (reg:CC FLAGS_REG))]
14428 "!TARGET_64BIT && TARGET_GNU2_TLS"
14429 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14430 [(set_attr "type" "call")
14431 (set_attr "length" "2")
14432 (set_attr "length_address" "0")])
14433
14434 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14435 [(set (match_operand:SI 0 "register_operand" "=&a")
14436 (plus:SI
14437 (plus:SI (match_operand:SI 3 "tp_or_register_operand" "ir")
14438 (unspec:SI [(match_operand:SI 4 "tls_modbase_operand" "")
14439 (match_operand:SI 5 "" "")
14440 (match_operand:SI 2 "register_operand" "b")
14441 (reg:SI SP_REG)]
14442 UNSPEC_TLSDESC))
14443 (const:SI (unspec:SI
14444 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14445 UNSPEC_DTPOFF))))
14446 (clobber (reg:CC FLAGS_REG))]
14447 "!TARGET_64BIT && TARGET_GNU2_TLS"
14448 "#"
14449 ""
14450 [(parallel
14451 [(set (match_dup 0)
14452 (plus:SI (match_dup 3)
14453 (match_dup 5)))
14454 (clobber (reg:CC FLAGS_REG))])]
14455 {
14456 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14457 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14458 })
14459
14460 (define_expand "tls_dynamic_gnu2_64"
14461 [(set (match_dup 2)
14462 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14463 UNSPEC_TLSDESC))
14464 (parallel
14465 [(set (match_operand:DI 0 "register_operand" "")
14466 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14467 UNSPEC_TLSDESC))
14468 (clobber (reg:CC FLAGS_REG))])]
14469 "TARGET_64BIT && TARGET_GNU2_TLS"
14470 {
14471 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14472 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14473 })
14474
14475 (define_insn "*tls_dynamic_lea_64"
14476 [(set (match_operand:DI 0 "register_operand" "=r")
14477 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14478 UNSPEC_TLSDESC))]
14479 "TARGET_64BIT && TARGET_GNU2_TLS"
14480 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14481 [(set_attr "type" "lea")
14482 (set_attr "mode" "DI")
14483 (set_attr "length" "7")
14484 (set_attr "length_address" "4")])
14485
14486 (define_insn "*tls_dynamic_call_64"
14487 [(set (match_operand:DI 0 "register_operand" "=a")
14488 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14489 (match_operand:DI 2 "register_operand" "0")
14490 (reg:DI SP_REG)]
14491 UNSPEC_TLSDESC))
14492 (clobber (reg:CC FLAGS_REG))]
14493 "TARGET_64BIT && TARGET_GNU2_TLS"
14494 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14495 [(set_attr "type" "call")
14496 (set_attr "length" "2")
14497 (set_attr "length_address" "0")])
14498
14499 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14500 [(set (match_operand:DI 0 "register_operand" "=&a")
14501 (plus:DI
14502 (plus:DI (match_operand:DI 2 "tp_or_register_operand" "ir")
14503 (unspec:DI [(match_operand:DI 3 "tls_modbase_operand" "")
14504 (match_operand:DI 4 "" "")
14505 (reg:DI SP_REG)]
14506 UNSPEC_TLSDESC))
14507 (const:DI (unspec:DI
14508 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14509 UNSPEC_DTPOFF))))
14510 (clobber (reg:CC FLAGS_REG))]
14511 "TARGET_64BIT && TARGET_GNU2_TLS"
14512 "#"
14513 ""
14514 [(parallel
14515 [(set (match_dup 0)
14516 (plus:DI (match_dup 2)
14517 (match_dup 4)))
14518 (clobber (reg:CC FLAGS_REG))])]
14519 {
14520 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14521 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14522 })
14523
14524 ;;
14525 \f
14526 ;; These patterns match the binary 387 instructions for addM3, subM3,
14527 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14528 ;; SFmode. The first is the normal insn, the second the same insn but
14529 ;; with one operand a conversion, and the third the same insn but with
14530 ;; the other operand a conversion. The conversion may be SFmode or
14531 ;; SImode if the target mode DFmode, but only SImode if the target mode
14532 ;; is SFmode.
14533
14534 ;; Gcc is slightly more smart about handling normal two address instructions
14535 ;; so use special patterns for add and mull.
14536
14537 (define_insn "*fop_sf_comm_mixed"
14538 [(set (match_operand:SF 0 "register_operand" "=f,x")
14539 (match_operator:SF 3 "binary_fp_operator"
14540 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14541 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14542 "TARGET_MIX_SSE_I387
14543 && COMMUTATIVE_ARITH_P (operands[3])
14544 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14545 "* return output_387_binary_op (insn, operands);"
14546 [(set (attr "type")
14547 (if_then_else (eq_attr "alternative" "1")
14548 (if_then_else (match_operand:SF 3 "mult_operator" "")
14549 (const_string "ssemul")
14550 (const_string "sseadd"))
14551 (if_then_else (match_operand:SF 3 "mult_operator" "")
14552 (const_string "fmul")
14553 (const_string "fop"))))
14554 (set_attr "mode" "SF")])
14555
14556 (define_insn "*fop_sf_comm_sse"
14557 [(set (match_operand:SF 0 "register_operand" "=x")
14558 (match_operator:SF 3 "binary_fp_operator"
14559 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14560 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14561 "TARGET_SSE_MATH
14562 && COMMUTATIVE_ARITH_P (operands[3])
14563 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14564 "* return output_387_binary_op (insn, operands);"
14565 [(set (attr "type")
14566 (if_then_else (match_operand:SF 3 "mult_operator" "")
14567 (const_string "ssemul")
14568 (const_string "sseadd")))
14569 (set_attr "mode" "SF")])
14570
14571 (define_insn "*fop_sf_comm_i387"
14572 [(set (match_operand:SF 0 "register_operand" "=f")
14573 (match_operator:SF 3 "binary_fp_operator"
14574 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14575 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14576 "TARGET_80387
14577 && COMMUTATIVE_ARITH_P (operands[3])
14578 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14579 "* return output_387_binary_op (insn, operands);"
14580 [(set (attr "type")
14581 (if_then_else (match_operand:SF 3 "mult_operator" "")
14582 (const_string "fmul")
14583 (const_string "fop")))
14584 (set_attr "mode" "SF")])
14585
14586 (define_insn "*fop_sf_1_mixed"
14587 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14588 (match_operator:SF 3 "binary_fp_operator"
14589 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14590 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
14591 "TARGET_MIX_SSE_I387
14592 && !COMMUTATIVE_ARITH_P (operands[3])
14593 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14594 "* return output_387_binary_op (insn, operands);"
14595 [(set (attr "type")
14596 (cond [(and (eq_attr "alternative" "2")
14597 (match_operand:SF 3 "mult_operator" ""))
14598 (const_string "ssemul")
14599 (and (eq_attr "alternative" "2")
14600 (match_operand:SF 3 "div_operator" ""))
14601 (const_string "ssediv")
14602 (eq_attr "alternative" "2")
14603 (const_string "sseadd")
14604 (match_operand:SF 3 "mult_operator" "")
14605 (const_string "fmul")
14606 (match_operand:SF 3 "div_operator" "")
14607 (const_string "fdiv")
14608 ]
14609 (const_string "fop")))
14610 (set_attr "mode" "SF")])
14611
14612 (define_insn "*fop_sf_1_sse"
14613 [(set (match_operand:SF 0 "register_operand" "=x")
14614 (match_operator:SF 3 "binary_fp_operator"
14615 [(match_operand:SF 1 "register_operand" "0")
14616 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14617 "TARGET_SSE_MATH
14618 && !COMMUTATIVE_ARITH_P (operands[3])"
14619 "* return output_387_binary_op (insn, operands);"
14620 [(set (attr "type")
14621 (cond [(match_operand:SF 3 "mult_operator" "")
14622 (const_string "ssemul")
14623 (match_operand:SF 3 "div_operator" "")
14624 (const_string "ssediv")
14625 ]
14626 (const_string "sseadd")))
14627 (set_attr "mode" "SF")])
14628
14629 ;; This pattern is not fully shadowed by the pattern above.
14630 (define_insn "*fop_sf_1_i387"
14631 [(set (match_operand:SF 0 "register_operand" "=f,f")
14632 (match_operator:SF 3 "binary_fp_operator"
14633 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14634 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14635 "TARGET_80387 && !TARGET_SSE_MATH
14636 && !COMMUTATIVE_ARITH_P (operands[3])
14637 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14638 "* return output_387_binary_op (insn, operands);"
14639 [(set (attr "type")
14640 (cond [(match_operand:SF 3 "mult_operator" "")
14641 (const_string "fmul")
14642 (match_operand:SF 3 "div_operator" "")
14643 (const_string "fdiv")
14644 ]
14645 (const_string "fop")))
14646 (set_attr "mode" "SF")])
14647
14648 ;; ??? Add SSE splitters for these!
14649 (define_insn "*fop_sf_2<mode>_i387"
14650 [(set (match_operand:SF 0 "register_operand" "=f,f")
14651 (match_operator:SF 3 "binary_fp_operator"
14652 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14653 (match_operand:SF 2 "register_operand" "0,0")]))]
14654 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14655 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14656 [(set (attr "type")
14657 (cond [(match_operand:SF 3 "mult_operator" "")
14658 (const_string "fmul")
14659 (match_operand:SF 3 "div_operator" "")
14660 (const_string "fdiv")
14661 ]
14662 (const_string "fop")))
14663 (set_attr "fp_int_src" "true")
14664 (set_attr "mode" "<MODE>")])
14665
14666 (define_insn "*fop_sf_3<mode>_i387"
14667 [(set (match_operand:SF 0 "register_operand" "=f,f")
14668 (match_operator:SF 3 "binary_fp_operator"
14669 [(match_operand:SF 1 "register_operand" "0,0")
14670 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14671 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14672 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14673 [(set (attr "type")
14674 (cond [(match_operand:SF 3 "mult_operator" "")
14675 (const_string "fmul")
14676 (match_operand:SF 3 "div_operator" "")
14677 (const_string "fdiv")
14678 ]
14679 (const_string "fop")))
14680 (set_attr "fp_int_src" "true")
14681 (set_attr "mode" "<MODE>")])
14682
14683 (define_insn "*fop_df_comm_mixed"
14684 [(set (match_operand:DF 0 "register_operand" "=f,Y")
14685 (match_operator:DF 3 "binary_fp_operator"
14686 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14687 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
14688 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14689 && COMMUTATIVE_ARITH_P (operands[3])
14690 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14691 "* return output_387_binary_op (insn, operands);"
14692 [(set (attr "type")
14693 (if_then_else (eq_attr "alternative" "1")
14694 (if_then_else (match_operand:SF 3 "mult_operator" "")
14695 (const_string "ssemul")
14696 (const_string "sseadd"))
14697 (if_then_else (match_operand:SF 3 "mult_operator" "")
14698 (const_string "fmul")
14699 (const_string "fop"))))
14700 (set_attr "mode" "DF")])
14701
14702 (define_insn "*fop_df_comm_sse"
14703 [(set (match_operand:DF 0 "register_operand" "=Y")
14704 (match_operator:DF 3 "binary_fp_operator"
14705 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14706 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14707 "TARGET_SSE2 && TARGET_SSE_MATH
14708 && COMMUTATIVE_ARITH_P (operands[3])
14709 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14710 "* return output_387_binary_op (insn, operands);"
14711 [(set (attr "type")
14712 (if_then_else (match_operand:SF 3 "mult_operator" "")
14713 (const_string "ssemul")
14714 (const_string "sseadd")))
14715 (set_attr "mode" "DF")])
14716
14717 (define_insn "*fop_df_comm_i387"
14718 [(set (match_operand:DF 0 "register_operand" "=f")
14719 (match_operator:DF 3 "binary_fp_operator"
14720 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14721 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14722 "TARGET_80387
14723 && COMMUTATIVE_ARITH_P (operands[3])
14724 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14725 "* return output_387_binary_op (insn, operands);"
14726 [(set (attr "type")
14727 (if_then_else (match_operand:SF 3 "mult_operator" "")
14728 (const_string "fmul")
14729 (const_string "fop")))
14730 (set_attr "mode" "DF")])
14731
14732 (define_insn "*fop_df_1_mixed"
14733 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
14734 (match_operator:DF 3 "binary_fp_operator"
14735 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14736 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
14737 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14738 && !COMMUTATIVE_ARITH_P (operands[3])
14739 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14740 "* return output_387_binary_op (insn, operands);"
14741 [(set (attr "type")
14742 (cond [(and (eq_attr "alternative" "2")
14743 (match_operand:SF 3 "mult_operator" ""))
14744 (const_string "ssemul")
14745 (and (eq_attr "alternative" "2")
14746 (match_operand:SF 3 "div_operator" ""))
14747 (const_string "ssediv")
14748 (eq_attr "alternative" "2")
14749 (const_string "sseadd")
14750 (match_operand:DF 3 "mult_operator" "")
14751 (const_string "fmul")
14752 (match_operand:DF 3 "div_operator" "")
14753 (const_string "fdiv")
14754 ]
14755 (const_string "fop")))
14756 (set_attr "mode" "DF")])
14757
14758 (define_insn "*fop_df_1_sse"
14759 [(set (match_operand:DF 0 "register_operand" "=Y")
14760 (match_operator:DF 3 "binary_fp_operator"
14761 [(match_operand:DF 1 "register_operand" "0")
14762 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14763 "TARGET_SSE2 && TARGET_SSE_MATH
14764 && !COMMUTATIVE_ARITH_P (operands[3])"
14765 "* return output_387_binary_op (insn, operands);"
14766 [(set_attr "mode" "DF")
14767 (set (attr "type")
14768 (cond [(match_operand:SF 3 "mult_operator" "")
14769 (const_string "ssemul")
14770 (match_operand:SF 3 "div_operator" "")
14771 (const_string "ssediv")
14772 ]
14773 (const_string "sseadd")))])
14774
14775 ;; This pattern is not fully shadowed by the pattern above.
14776 (define_insn "*fop_df_1_i387"
14777 [(set (match_operand:DF 0 "register_operand" "=f,f")
14778 (match_operator:DF 3 "binary_fp_operator"
14779 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14780 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14781 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14782 && !COMMUTATIVE_ARITH_P (operands[3])
14783 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14784 "* return output_387_binary_op (insn, operands);"
14785 [(set (attr "type")
14786 (cond [(match_operand:DF 3 "mult_operator" "")
14787 (const_string "fmul")
14788 (match_operand:DF 3 "div_operator" "")
14789 (const_string "fdiv")
14790 ]
14791 (const_string "fop")))
14792 (set_attr "mode" "DF")])
14793
14794 ;; ??? Add SSE splitters for these!
14795 (define_insn "*fop_df_2<mode>_i387"
14796 [(set (match_operand:DF 0 "register_operand" "=f,f")
14797 (match_operator:DF 3 "binary_fp_operator"
14798 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14799 (match_operand:DF 2 "register_operand" "0,0")]))]
14800 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14801 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14802 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14803 [(set (attr "type")
14804 (cond [(match_operand:DF 3 "mult_operator" "")
14805 (const_string "fmul")
14806 (match_operand:DF 3 "div_operator" "")
14807 (const_string "fdiv")
14808 ]
14809 (const_string "fop")))
14810 (set_attr "fp_int_src" "true")
14811 (set_attr "mode" "<MODE>")])
14812
14813 (define_insn "*fop_df_3<mode>_i387"
14814 [(set (match_operand:DF 0 "register_operand" "=f,f")
14815 (match_operator:DF 3 "binary_fp_operator"
14816 [(match_operand:DF 1 "register_operand" "0,0")
14817 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14818 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14819 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14820 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14821 [(set (attr "type")
14822 (cond [(match_operand:DF 3 "mult_operator" "")
14823 (const_string "fmul")
14824 (match_operand:DF 3 "div_operator" "")
14825 (const_string "fdiv")
14826 ]
14827 (const_string "fop")))
14828 (set_attr "fp_int_src" "true")
14829 (set_attr "mode" "<MODE>")])
14830
14831 (define_insn "*fop_df_4_i387"
14832 [(set (match_operand:DF 0 "register_operand" "=f,f")
14833 (match_operator:DF 3 "binary_fp_operator"
14834 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14835 (match_operand:DF 2 "register_operand" "0,f")]))]
14836 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14837 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14838 "* return output_387_binary_op (insn, operands);"
14839 [(set (attr "type")
14840 (cond [(match_operand:DF 3 "mult_operator" "")
14841 (const_string "fmul")
14842 (match_operand:DF 3 "div_operator" "")
14843 (const_string "fdiv")
14844 ]
14845 (const_string "fop")))
14846 (set_attr "mode" "SF")])
14847
14848 (define_insn "*fop_df_5_i387"
14849 [(set (match_operand:DF 0 "register_operand" "=f,f")
14850 (match_operator:DF 3 "binary_fp_operator"
14851 [(match_operand:DF 1 "register_operand" "0,f")
14852 (float_extend:DF
14853 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14854 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14855 "* return output_387_binary_op (insn, operands);"
14856 [(set (attr "type")
14857 (cond [(match_operand:DF 3 "mult_operator" "")
14858 (const_string "fmul")
14859 (match_operand:DF 3 "div_operator" "")
14860 (const_string "fdiv")
14861 ]
14862 (const_string "fop")))
14863 (set_attr "mode" "SF")])
14864
14865 (define_insn "*fop_df_6_i387"
14866 [(set (match_operand:DF 0 "register_operand" "=f,f")
14867 (match_operator:DF 3 "binary_fp_operator"
14868 [(float_extend:DF
14869 (match_operand:SF 1 "register_operand" "0,f"))
14870 (float_extend:DF
14871 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14872 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14873 "* return output_387_binary_op (insn, operands);"
14874 [(set (attr "type")
14875 (cond [(match_operand:DF 3 "mult_operator" "")
14876 (const_string "fmul")
14877 (match_operand:DF 3 "div_operator" "")
14878 (const_string "fdiv")
14879 ]
14880 (const_string "fop")))
14881 (set_attr "mode" "SF")])
14882
14883 (define_insn "*fop_xf_comm_i387"
14884 [(set (match_operand:XF 0 "register_operand" "=f")
14885 (match_operator:XF 3 "binary_fp_operator"
14886 [(match_operand:XF 1 "register_operand" "%0")
14887 (match_operand:XF 2 "register_operand" "f")]))]
14888 "TARGET_80387
14889 && COMMUTATIVE_ARITH_P (operands[3])"
14890 "* return output_387_binary_op (insn, operands);"
14891 [(set (attr "type")
14892 (if_then_else (match_operand:XF 3 "mult_operator" "")
14893 (const_string "fmul")
14894 (const_string "fop")))
14895 (set_attr "mode" "XF")])
14896
14897 (define_insn "*fop_xf_1_i387"
14898 [(set (match_operand:XF 0 "register_operand" "=f,f")
14899 (match_operator:XF 3 "binary_fp_operator"
14900 [(match_operand:XF 1 "register_operand" "0,f")
14901 (match_operand:XF 2 "register_operand" "f,0")]))]
14902 "TARGET_80387
14903 && !COMMUTATIVE_ARITH_P (operands[3])"
14904 "* return output_387_binary_op (insn, operands);"
14905 [(set (attr "type")
14906 (cond [(match_operand:XF 3 "mult_operator" "")
14907 (const_string "fmul")
14908 (match_operand:XF 3 "div_operator" "")
14909 (const_string "fdiv")
14910 ]
14911 (const_string "fop")))
14912 (set_attr "mode" "XF")])
14913
14914 (define_insn "*fop_xf_2<mode>_i387"
14915 [(set (match_operand:XF 0 "register_operand" "=f,f")
14916 (match_operator:XF 3 "binary_fp_operator"
14917 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14918 (match_operand:XF 2 "register_operand" "0,0")]))]
14919 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14920 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14921 [(set (attr "type")
14922 (cond [(match_operand:XF 3 "mult_operator" "")
14923 (const_string "fmul")
14924 (match_operand:XF 3 "div_operator" "")
14925 (const_string "fdiv")
14926 ]
14927 (const_string "fop")))
14928 (set_attr "fp_int_src" "true")
14929 (set_attr "mode" "<MODE>")])
14930
14931 (define_insn "*fop_xf_3<mode>_i387"
14932 [(set (match_operand:XF 0 "register_operand" "=f,f")
14933 (match_operator:XF 3 "binary_fp_operator"
14934 [(match_operand:XF 1 "register_operand" "0,0")
14935 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14936 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14937 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14938 [(set (attr "type")
14939 (cond [(match_operand:XF 3 "mult_operator" "")
14940 (const_string "fmul")
14941 (match_operand:XF 3 "div_operator" "")
14942 (const_string "fdiv")
14943 ]
14944 (const_string "fop")))
14945 (set_attr "fp_int_src" "true")
14946 (set_attr "mode" "<MODE>")])
14947
14948 (define_insn "*fop_xf_4_i387"
14949 [(set (match_operand:XF 0 "register_operand" "=f,f")
14950 (match_operator:XF 3 "binary_fp_operator"
14951 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14952 (match_operand:XF 2 "register_operand" "0,f")]))]
14953 "TARGET_80387"
14954 "* return output_387_binary_op (insn, operands);"
14955 [(set (attr "type")
14956 (cond [(match_operand:XF 3 "mult_operator" "")
14957 (const_string "fmul")
14958 (match_operand:XF 3 "div_operator" "")
14959 (const_string "fdiv")
14960 ]
14961 (const_string "fop")))
14962 (set_attr "mode" "SF")])
14963
14964 (define_insn "*fop_xf_5_i387"
14965 [(set (match_operand:XF 0 "register_operand" "=f,f")
14966 (match_operator:XF 3 "binary_fp_operator"
14967 [(match_operand:XF 1 "register_operand" "0,f")
14968 (float_extend:XF
14969 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14970 "TARGET_80387"
14971 "* return output_387_binary_op (insn, operands);"
14972 [(set (attr "type")
14973 (cond [(match_operand:XF 3 "mult_operator" "")
14974 (const_string "fmul")
14975 (match_operand:XF 3 "div_operator" "")
14976 (const_string "fdiv")
14977 ]
14978 (const_string "fop")))
14979 (set_attr "mode" "SF")])
14980
14981 (define_insn "*fop_xf_6_i387"
14982 [(set (match_operand:XF 0 "register_operand" "=f,f")
14983 (match_operator:XF 3 "binary_fp_operator"
14984 [(float_extend:XF
14985 (match_operand 1 "register_operand" "0,f"))
14986 (float_extend:XF
14987 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14988 "TARGET_80387"
14989 "* return output_387_binary_op (insn, operands);"
14990 [(set (attr "type")
14991 (cond [(match_operand:XF 3 "mult_operator" "")
14992 (const_string "fmul")
14993 (match_operand:XF 3 "div_operator" "")
14994 (const_string "fdiv")
14995 ]
14996 (const_string "fop")))
14997 (set_attr "mode" "SF")])
14998
14999 (define_split
15000 [(set (match_operand 0 "register_operand" "")
15001 (match_operator 3 "binary_fp_operator"
15002 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15003 (match_operand 2 "register_operand" "")]))]
15004 "TARGET_80387 && reload_completed
15005 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15006 [(const_int 0)]
15007 {
15008 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15009 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15010 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15011 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15012 GET_MODE (operands[3]),
15013 operands[4],
15014 operands[2])));
15015 ix86_free_from_memory (GET_MODE (operands[1]));
15016 DONE;
15017 })
15018
15019 (define_split
15020 [(set (match_operand 0 "register_operand" "")
15021 (match_operator 3 "binary_fp_operator"
15022 [(match_operand 1 "register_operand" "")
15023 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15024 "TARGET_80387 && reload_completed
15025 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15026 [(const_int 0)]
15027 {
15028 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15029 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15030 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15031 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15032 GET_MODE (operands[3]),
15033 operands[1],
15034 operands[4])));
15035 ix86_free_from_memory (GET_MODE (operands[2]));
15036 DONE;
15037 })
15038 \f
15039 ;; FPU special functions.
15040
15041 (define_expand "sqrtsf2"
15042 [(set (match_operand:SF 0 "register_operand" "")
15043 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15044 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15045 {
15046 if (!TARGET_SSE_MATH)
15047 operands[1] = force_reg (SFmode, operands[1]);
15048 })
15049
15050 (define_insn "*sqrtsf2_mixed"
15051 [(set (match_operand:SF 0 "register_operand" "=f,x")
15052 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15053 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15054 "@
15055 fsqrt
15056 sqrtss\t{%1, %0|%0, %1}"
15057 [(set_attr "type" "fpspc,sse")
15058 (set_attr "mode" "SF,SF")
15059 (set_attr "athlon_decode" "direct,*")])
15060
15061 (define_insn "*sqrtsf2_sse"
15062 [(set (match_operand:SF 0 "register_operand" "=x")
15063 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15064 "TARGET_SSE_MATH"
15065 "sqrtss\t{%1, %0|%0, %1}"
15066 [(set_attr "type" "sse")
15067 (set_attr "mode" "SF")
15068 (set_attr "athlon_decode" "*")])
15069
15070 (define_insn "*sqrtsf2_i387"
15071 [(set (match_operand:SF 0 "register_operand" "=f")
15072 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15073 "TARGET_USE_FANCY_MATH_387"
15074 "fsqrt"
15075 [(set_attr "type" "fpspc")
15076 (set_attr "mode" "SF")
15077 (set_attr "athlon_decode" "direct")])
15078
15079 (define_expand "sqrtdf2"
15080 [(set (match_operand:DF 0 "register_operand" "")
15081 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15082 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15083 {
15084 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15085 operands[1] = force_reg (DFmode, operands[1]);
15086 })
15087
15088 (define_insn "*sqrtdf2_mixed"
15089 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15090 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15091 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15092 "@
15093 fsqrt
15094 sqrtsd\t{%1, %0|%0, %1}"
15095 [(set_attr "type" "fpspc,sse")
15096 (set_attr "mode" "DF,DF")
15097 (set_attr "athlon_decode" "direct,*")])
15098
15099 (define_insn "*sqrtdf2_sse"
15100 [(set (match_operand:DF 0 "register_operand" "=Y")
15101 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15102 "TARGET_SSE2 && TARGET_SSE_MATH"
15103 "sqrtsd\t{%1, %0|%0, %1}"
15104 [(set_attr "type" "sse")
15105 (set_attr "mode" "DF")
15106 (set_attr "athlon_decode" "*")])
15107
15108 (define_insn "*sqrtdf2_i387"
15109 [(set (match_operand:DF 0 "register_operand" "=f")
15110 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15111 "TARGET_USE_FANCY_MATH_387"
15112 "fsqrt"
15113 [(set_attr "type" "fpspc")
15114 (set_attr "mode" "DF")
15115 (set_attr "athlon_decode" "direct")])
15116
15117 (define_insn "*sqrtextendsfdf2_i387"
15118 [(set (match_operand:DF 0 "register_operand" "=f")
15119 (sqrt:DF (float_extend:DF
15120 (match_operand:SF 1 "register_operand" "0"))))]
15121 "TARGET_USE_FANCY_MATH_387
15122 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15123 "fsqrt"
15124 [(set_attr "type" "fpspc")
15125 (set_attr "mode" "DF")
15126 (set_attr "athlon_decode" "direct")])
15127
15128 (define_insn "sqrtxf2"
15129 [(set (match_operand:XF 0 "register_operand" "=f")
15130 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15131 "TARGET_USE_FANCY_MATH_387
15132 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15133 "fsqrt"
15134 [(set_attr "type" "fpspc")
15135 (set_attr "mode" "XF")
15136 (set_attr "athlon_decode" "direct")])
15137
15138 (define_insn "*sqrtextendsfxf2_i387"
15139 [(set (match_operand:XF 0 "register_operand" "=f")
15140 (sqrt:XF (float_extend:XF
15141 (match_operand:SF 1 "register_operand" "0"))))]
15142 "TARGET_USE_FANCY_MATH_387"
15143 "fsqrt"
15144 [(set_attr "type" "fpspc")
15145 (set_attr "mode" "XF")
15146 (set_attr "athlon_decode" "direct")])
15147
15148 (define_insn "*sqrtextenddfxf2_i387"
15149 [(set (match_operand:XF 0 "register_operand" "=f")
15150 (sqrt:XF (float_extend:XF
15151 (match_operand:DF 1 "register_operand" "0"))))]
15152 "TARGET_USE_FANCY_MATH_387"
15153 "fsqrt"
15154 [(set_attr "type" "fpspc")
15155 (set_attr "mode" "XF")
15156 (set_attr "athlon_decode" "direct")])
15157
15158 (define_insn "fpremxf4"
15159 [(set (match_operand:XF 0 "register_operand" "=f")
15160 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15161 (match_operand:XF 3 "register_operand" "1")]
15162 UNSPEC_FPREM_F))
15163 (set (match_operand:XF 1 "register_operand" "=u")
15164 (unspec:XF [(match_dup 2) (match_dup 3)]
15165 UNSPEC_FPREM_U))
15166 (set (reg:CCFP FPSR_REG)
15167 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15168 "TARGET_USE_FANCY_MATH_387
15169 && flag_unsafe_math_optimizations"
15170 "fprem"
15171 [(set_attr "type" "fpspc")
15172 (set_attr "mode" "XF")])
15173
15174 (define_expand "fmodsf3"
15175 [(use (match_operand:SF 0 "register_operand" ""))
15176 (use (match_operand:SF 1 "register_operand" ""))
15177 (use (match_operand:SF 2 "register_operand" ""))]
15178 "TARGET_USE_FANCY_MATH_387
15179 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15180 && flag_unsafe_math_optimizations"
15181 {
15182 rtx label = gen_label_rtx ();
15183
15184 rtx op1 = gen_reg_rtx (XFmode);
15185 rtx op2 = gen_reg_rtx (XFmode);
15186
15187 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15188 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15189
15190 emit_label (label);
15191
15192 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15193 ix86_emit_fp_unordered_jump (label);
15194
15195 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15196 DONE;
15197 })
15198
15199 (define_expand "fmoddf3"
15200 [(use (match_operand:DF 0 "register_operand" ""))
15201 (use (match_operand:DF 1 "register_operand" ""))
15202 (use (match_operand:DF 2 "register_operand" ""))]
15203 "TARGET_USE_FANCY_MATH_387
15204 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15205 && flag_unsafe_math_optimizations"
15206 {
15207 rtx label = gen_label_rtx ();
15208
15209 rtx op1 = gen_reg_rtx (XFmode);
15210 rtx op2 = gen_reg_rtx (XFmode);
15211
15212 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15213 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15214
15215 emit_label (label);
15216
15217 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15218 ix86_emit_fp_unordered_jump (label);
15219
15220 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15221 DONE;
15222 })
15223
15224 (define_expand "fmodxf3"
15225 [(use (match_operand:XF 0 "register_operand" ""))
15226 (use (match_operand:XF 1 "register_operand" ""))
15227 (use (match_operand:XF 2 "register_operand" ""))]
15228 "TARGET_USE_FANCY_MATH_387
15229 && flag_unsafe_math_optimizations"
15230 {
15231 rtx label = gen_label_rtx ();
15232
15233 emit_label (label);
15234
15235 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15236 operands[1], operands[2]));
15237 ix86_emit_fp_unordered_jump (label);
15238
15239 emit_move_insn (operands[0], operands[1]);
15240 DONE;
15241 })
15242
15243 (define_insn "fprem1xf4"
15244 [(set (match_operand:XF 0 "register_operand" "=f")
15245 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15246 (match_operand:XF 3 "register_operand" "1")]
15247 UNSPEC_FPREM1_F))
15248 (set (match_operand:XF 1 "register_operand" "=u")
15249 (unspec:XF [(match_dup 2) (match_dup 3)]
15250 UNSPEC_FPREM1_U))
15251 (set (reg:CCFP FPSR_REG)
15252 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15253 "TARGET_USE_FANCY_MATH_387
15254 && flag_unsafe_math_optimizations"
15255 "fprem1"
15256 [(set_attr "type" "fpspc")
15257 (set_attr "mode" "XF")])
15258
15259 (define_expand "dremsf3"
15260 [(use (match_operand:SF 0 "register_operand" ""))
15261 (use (match_operand:SF 1 "register_operand" ""))
15262 (use (match_operand:SF 2 "register_operand" ""))]
15263 "TARGET_USE_FANCY_MATH_387
15264 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15265 && flag_unsafe_math_optimizations"
15266 {
15267 rtx label = gen_label_rtx ();
15268
15269 rtx op1 = gen_reg_rtx (XFmode);
15270 rtx op2 = gen_reg_rtx (XFmode);
15271
15272 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15273 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15274
15275 emit_label (label);
15276
15277 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15278 ix86_emit_fp_unordered_jump (label);
15279
15280 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15281 DONE;
15282 })
15283
15284 (define_expand "dremdf3"
15285 [(use (match_operand:DF 0 "register_operand" ""))
15286 (use (match_operand:DF 1 "register_operand" ""))
15287 (use (match_operand:DF 2 "register_operand" ""))]
15288 "TARGET_USE_FANCY_MATH_387
15289 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15290 && flag_unsafe_math_optimizations"
15291 {
15292 rtx label = gen_label_rtx ();
15293
15294 rtx op1 = gen_reg_rtx (XFmode);
15295 rtx op2 = gen_reg_rtx (XFmode);
15296
15297 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15298 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15299
15300 emit_label (label);
15301
15302 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15303 ix86_emit_fp_unordered_jump (label);
15304
15305 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15306 DONE;
15307 })
15308
15309 (define_expand "dremxf3"
15310 [(use (match_operand:XF 0 "register_operand" ""))
15311 (use (match_operand:XF 1 "register_operand" ""))
15312 (use (match_operand:XF 2 "register_operand" ""))]
15313 "TARGET_USE_FANCY_MATH_387
15314 && flag_unsafe_math_optimizations"
15315 {
15316 rtx label = gen_label_rtx ();
15317
15318 emit_label (label);
15319
15320 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15321 operands[1], operands[2]));
15322 ix86_emit_fp_unordered_jump (label);
15323
15324 emit_move_insn (operands[0], operands[1]);
15325 DONE;
15326 })
15327
15328 (define_insn "*sindf2"
15329 [(set (match_operand:DF 0 "register_operand" "=f")
15330 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15331 "TARGET_USE_FANCY_MATH_387
15332 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15333 && flag_unsafe_math_optimizations"
15334 "fsin"
15335 [(set_attr "type" "fpspc")
15336 (set_attr "mode" "DF")])
15337
15338 (define_insn "*sinsf2"
15339 [(set (match_operand:SF 0 "register_operand" "=f")
15340 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15341 "TARGET_USE_FANCY_MATH_387
15342 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15343 && flag_unsafe_math_optimizations"
15344 "fsin"
15345 [(set_attr "type" "fpspc")
15346 (set_attr "mode" "SF")])
15347
15348 (define_insn "*sinextendsfdf2"
15349 [(set (match_operand:DF 0 "register_operand" "=f")
15350 (unspec:DF [(float_extend:DF
15351 (match_operand:SF 1 "register_operand" "0"))]
15352 UNSPEC_SIN))]
15353 "TARGET_USE_FANCY_MATH_387
15354 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15355 && flag_unsafe_math_optimizations"
15356 "fsin"
15357 [(set_attr "type" "fpspc")
15358 (set_attr "mode" "DF")])
15359
15360 (define_insn "*sinxf2"
15361 [(set (match_operand:XF 0 "register_operand" "=f")
15362 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15363 "TARGET_USE_FANCY_MATH_387
15364 && flag_unsafe_math_optimizations"
15365 "fsin"
15366 [(set_attr "type" "fpspc")
15367 (set_attr "mode" "XF")])
15368
15369 (define_insn "*cosdf2"
15370 [(set (match_operand:DF 0 "register_operand" "=f")
15371 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15372 "TARGET_USE_FANCY_MATH_387
15373 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15374 && flag_unsafe_math_optimizations"
15375 "fcos"
15376 [(set_attr "type" "fpspc")
15377 (set_attr "mode" "DF")])
15378
15379 (define_insn "*cossf2"
15380 [(set (match_operand:SF 0 "register_operand" "=f")
15381 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15382 "TARGET_USE_FANCY_MATH_387
15383 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15384 && flag_unsafe_math_optimizations"
15385 "fcos"
15386 [(set_attr "type" "fpspc")
15387 (set_attr "mode" "SF")])
15388
15389 (define_insn "*cosextendsfdf2"
15390 [(set (match_operand:DF 0 "register_operand" "=f")
15391 (unspec:DF [(float_extend:DF
15392 (match_operand:SF 1 "register_operand" "0"))]
15393 UNSPEC_COS))]
15394 "TARGET_USE_FANCY_MATH_387
15395 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15396 && flag_unsafe_math_optimizations"
15397 "fcos"
15398 [(set_attr "type" "fpspc")
15399 (set_attr "mode" "DF")])
15400
15401 (define_insn "*cosxf2"
15402 [(set (match_operand:XF 0 "register_operand" "=f")
15403 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15404 "TARGET_USE_FANCY_MATH_387
15405 && flag_unsafe_math_optimizations"
15406 "fcos"
15407 [(set_attr "type" "fpspc")
15408 (set_attr "mode" "XF")])
15409
15410 ;; With sincos pattern defined, sin and cos builtin function will be
15411 ;; expanded to sincos pattern with one of its outputs left unused.
15412 ;; Cse pass will detected, if two sincos patterns can be combined,
15413 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15414 ;; depending on the unused output.
15415
15416 (define_insn "sincosdf3"
15417 [(set (match_operand:DF 0 "register_operand" "=f")
15418 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15419 UNSPEC_SINCOS_COS))
15420 (set (match_operand:DF 1 "register_operand" "=u")
15421 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15422 "TARGET_USE_FANCY_MATH_387
15423 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15424 && flag_unsafe_math_optimizations"
15425 "fsincos"
15426 [(set_attr "type" "fpspc")
15427 (set_attr "mode" "DF")])
15428
15429 (define_split
15430 [(set (match_operand:DF 0 "register_operand" "")
15431 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15432 UNSPEC_SINCOS_COS))
15433 (set (match_operand:DF 1 "register_operand" "")
15434 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15435 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15436 && !reload_completed && !reload_in_progress"
15437 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15438 "")
15439
15440 (define_split
15441 [(set (match_operand:DF 0 "register_operand" "")
15442 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15443 UNSPEC_SINCOS_COS))
15444 (set (match_operand:DF 1 "register_operand" "")
15445 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15446 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15447 && !reload_completed && !reload_in_progress"
15448 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15449 "")
15450
15451 (define_insn "sincossf3"
15452 [(set (match_operand:SF 0 "register_operand" "=f")
15453 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15454 UNSPEC_SINCOS_COS))
15455 (set (match_operand:SF 1 "register_operand" "=u")
15456 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15457 "TARGET_USE_FANCY_MATH_387
15458 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15459 && flag_unsafe_math_optimizations"
15460 "fsincos"
15461 [(set_attr "type" "fpspc")
15462 (set_attr "mode" "SF")])
15463
15464 (define_split
15465 [(set (match_operand:SF 0 "register_operand" "")
15466 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15467 UNSPEC_SINCOS_COS))
15468 (set (match_operand:SF 1 "register_operand" "")
15469 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15470 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15471 && !reload_completed && !reload_in_progress"
15472 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15473 "")
15474
15475 (define_split
15476 [(set (match_operand:SF 0 "register_operand" "")
15477 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15478 UNSPEC_SINCOS_COS))
15479 (set (match_operand:SF 1 "register_operand" "")
15480 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15481 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15482 && !reload_completed && !reload_in_progress"
15483 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15484 "")
15485
15486 (define_insn "*sincosextendsfdf3"
15487 [(set (match_operand:DF 0 "register_operand" "=f")
15488 (unspec:DF [(float_extend:DF
15489 (match_operand:SF 2 "register_operand" "0"))]
15490 UNSPEC_SINCOS_COS))
15491 (set (match_operand:DF 1 "register_operand" "=u")
15492 (unspec:DF [(float_extend:DF
15493 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15494 "TARGET_USE_FANCY_MATH_387
15495 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15496 && flag_unsafe_math_optimizations"
15497 "fsincos"
15498 [(set_attr "type" "fpspc")
15499 (set_attr "mode" "DF")])
15500
15501 (define_split
15502 [(set (match_operand:DF 0 "register_operand" "")
15503 (unspec:DF [(float_extend:DF
15504 (match_operand:SF 2 "register_operand" ""))]
15505 UNSPEC_SINCOS_COS))
15506 (set (match_operand:DF 1 "register_operand" "")
15507 (unspec:DF [(float_extend:DF
15508 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15509 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15510 && !reload_completed && !reload_in_progress"
15511 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15512 (match_dup 2))] UNSPEC_SIN))]
15513 "")
15514
15515 (define_split
15516 [(set (match_operand:DF 0 "register_operand" "")
15517 (unspec:DF [(float_extend:DF
15518 (match_operand:SF 2 "register_operand" ""))]
15519 UNSPEC_SINCOS_COS))
15520 (set (match_operand:DF 1 "register_operand" "")
15521 (unspec:DF [(float_extend:DF
15522 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15523 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15524 && !reload_completed && !reload_in_progress"
15525 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15526 (match_dup 2))] UNSPEC_COS))]
15527 "")
15528
15529 (define_insn "sincosxf3"
15530 [(set (match_operand:XF 0 "register_operand" "=f")
15531 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15532 UNSPEC_SINCOS_COS))
15533 (set (match_operand:XF 1 "register_operand" "=u")
15534 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15535 "TARGET_USE_FANCY_MATH_387
15536 && flag_unsafe_math_optimizations"
15537 "fsincos"
15538 [(set_attr "type" "fpspc")
15539 (set_attr "mode" "XF")])
15540
15541 (define_split
15542 [(set (match_operand:XF 0 "register_operand" "")
15543 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15544 UNSPEC_SINCOS_COS))
15545 (set (match_operand:XF 1 "register_operand" "")
15546 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15547 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15548 && !reload_completed && !reload_in_progress"
15549 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15550 "")
15551
15552 (define_split
15553 [(set (match_operand:XF 0 "register_operand" "")
15554 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15555 UNSPEC_SINCOS_COS))
15556 (set (match_operand:XF 1 "register_operand" "")
15557 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15558 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15559 && !reload_completed && !reload_in_progress"
15560 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15561 "")
15562
15563 (define_insn "*tandf3_1"
15564 [(set (match_operand:DF 0 "register_operand" "=f")
15565 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15566 UNSPEC_TAN_ONE))
15567 (set (match_operand:DF 1 "register_operand" "=u")
15568 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15569 "TARGET_USE_FANCY_MATH_387
15570 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15571 && flag_unsafe_math_optimizations"
15572 "fptan"
15573 [(set_attr "type" "fpspc")
15574 (set_attr "mode" "DF")])
15575
15576 ;; optimize sequence: fptan
15577 ;; fstp %st(0)
15578 ;; fld1
15579 ;; into fptan insn.
15580
15581 (define_peephole2
15582 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15583 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15584 UNSPEC_TAN_ONE))
15585 (set (match_operand:DF 1 "register_operand" "")
15586 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15587 (set (match_dup 0)
15588 (match_operand:DF 3 "immediate_operand" ""))]
15589 "standard_80387_constant_p (operands[3]) == 2"
15590 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15591 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15592 "")
15593
15594 (define_expand "tandf2"
15595 [(parallel [(set (match_dup 2)
15596 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15597 UNSPEC_TAN_ONE))
15598 (set (match_operand:DF 0 "register_operand" "")
15599 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15600 "TARGET_USE_FANCY_MATH_387
15601 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15602 && flag_unsafe_math_optimizations"
15603 {
15604 operands[2] = gen_reg_rtx (DFmode);
15605 })
15606
15607 (define_insn "*tansf3_1"
15608 [(set (match_operand:SF 0 "register_operand" "=f")
15609 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15610 UNSPEC_TAN_ONE))
15611 (set (match_operand:SF 1 "register_operand" "=u")
15612 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15613 "TARGET_USE_FANCY_MATH_387
15614 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15615 && flag_unsafe_math_optimizations"
15616 "fptan"
15617 [(set_attr "type" "fpspc")
15618 (set_attr "mode" "SF")])
15619
15620 ;; optimize sequence: fptan
15621 ;; fstp %st(0)
15622 ;; fld1
15623 ;; into fptan insn.
15624
15625 (define_peephole2
15626 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15627 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15628 UNSPEC_TAN_ONE))
15629 (set (match_operand:SF 1 "register_operand" "")
15630 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15631 (set (match_dup 0)
15632 (match_operand:SF 3 "immediate_operand" ""))]
15633 "standard_80387_constant_p (operands[3]) == 2"
15634 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15635 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15636 "")
15637
15638 (define_expand "tansf2"
15639 [(parallel [(set (match_dup 2)
15640 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15641 UNSPEC_TAN_ONE))
15642 (set (match_operand:SF 0 "register_operand" "")
15643 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15644 "TARGET_USE_FANCY_MATH_387
15645 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15646 && flag_unsafe_math_optimizations"
15647 {
15648 operands[2] = gen_reg_rtx (SFmode);
15649 })
15650
15651 (define_insn "*tanxf3_1"
15652 [(set (match_operand:XF 0 "register_operand" "=f")
15653 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15654 UNSPEC_TAN_ONE))
15655 (set (match_operand:XF 1 "register_operand" "=u")
15656 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15657 "TARGET_USE_FANCY_MATH_387
15658 && flag_unsafe_math_optimizations"
15659 "fptan"
15660 [(set_attr "type" "fpspc")
15661 (set_attr "mode" "XF")])
15662
15663 ;; optimize sequence: fptan
15664 ;; fstp %st(0)
15665 ;; fld1
15666 ;; into fptan insn.
15667
15668 (define_peephole2
15669 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15670 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15671 UNSPEC_TAN_ONE))
15672 (set (match_operand:XF 1 "register_operand" "")
15673 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15674 (set (match_dup 0)
15675 (match_operand:XF 3 "immediate_operand" ""))]
15676 "standard_80387_constant_p (operands[3]) == 2"
15677 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15678 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15679 "")
15680
15681 (define_expand "tanxf2"
15682 [(parallel [(set (match_dup 2)
15683 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15684 UNSPEC_TAN_ONE))
15685 (set (match_operand:XF 0 "register_operand" "")
15686 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15687 "TARGET_USE_FANCY_MATH_387
15688 && flag_unsafe_math_optimizations"
15689 {
15690 operands[2] = gen_reg_rtx (XFmode);
15691 })
15692
15693 (define_insn "atan2df3_1"
15694 [(set (match_operand:DF 0 "register_operand" "=f")
15695 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15696 (match_operand:DF 1 "register_operand" "u")]
15697 UNSPEC_FPATAN))
15698 (clobber (match_scratch:DF 3 "=1"))]
15699 "TARGET_USE_FANCY_MATH_387
15700 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15701 && flag_unsafe_math_optimizations"
15702 "fpatan"
15703 [(set_attr "type" "fpspc")
15704 (set_attr "mode" "DF")])
15705
15706 (define_expand "atan2df3"
15707 [(use (match_operand:DF 0 "register_operand" ""))
15708 (use (match_operand:DF 2 "register_operand" ""))
15709 (use (match_operand:DF 1 "register_operand" ""))]
15710 "TARGET_USE_FANCY_MATH_387
15711 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15712 && flag_unsafe_math_optimizations"
15713 {
15714 rtx copy = gen_reg_rtx (DFmode);
15715 emit_move_insn (copy, operands[1]);
15716 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15717 DONE;
15718 })
15719
15720 (define_expand "atandf2"
15721 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15722 (unspec:DF [(match_dup 2)
15723 (match_operand:DF 1 "register_operand" "")]
15724 UNSPEC_FPATAN))
15725 (clobber (match_scratch:DF 3 ""))])]
15726 "TARGET_USE_FANCY_MATH_387
15727 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15728 && flag_unsafe_math_optimizations"
15729 {
15730 operands[2] = gen_reg_rtx (DFmode);
15731 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15732 })
15733
15734 (define_insn "atan2sf3_1"
15735 [(set (match_operand:SF 0 "register_operand" "=f")
15736 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15737 (match_operand:SF 1 "register_operand" "u")]
15738 UNSPEC_FPATAN))
15739 (clobber (match_scratch:SF 3 "=1"))]
15740 "TARGET_USE_FANCY_MATH_387
15741 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15742 && flag_unsafe_math_optimizations"
15743 "fpatan"
15744 [(set_attr "type" "fpspc")
15745 (set_attr "mode" "SF")])
15746
15747 (define_expand "atan2sf3"
15748 [(use (match_operand:SF 0 "register_operand" ""))
15749 (use (match_operand:SF 2 "register_operand" ""))
15750 (use (match_operand:SF 1 "register_operand" ""))]
15751 "TARGET_USE_FANCY_MATH_387
15752 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15753 && flag_unsafe_math_optimizations"
15754 {
15755 rtx copy = gen_reg_rtx (SFmode);
15756 emit_move_insn (copy, operands[1]);
15757 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15758 DONE;
15759 })
15760
15761 (define_expand "atansf2"
15762 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15763 (unspec:SF [(match_dup 2)
15764 (match_operand:SF 1 "register_operand" "")]
15765 UNSPEC_FPATAN))
15766 (clobber (match_scratch:SF 3 ""))])]
15767 "TARGET_USE_FANCY_MATH_387
15768 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15769 && flag_unsafe_math_optimizations"
15770 {
15771 operands[2] = gen_reg_rtx (SFmode);
15772 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15773 })
15774
15775 (define_insn "atan2xf3_1"
15776 [(set (match_operand:XF 0 "register_operand" "=f")
15777 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15778 (match_operand:XF 1 "register_operand" "u")]
15779 UNSPEC_FPATAN))
15780 (clobber (match_scratch:XF 3 "=1"))]
15781 "TARGET_USE_FANCY_MATH_387
15782 && flag_unsafe_math_optimizations"
15783 "fpatan"
15784 [(set_attr "type" "fpspc")
15785 (set_attr "mode" "XF")])
15786
15787 (define_expand "atan2xf3"
15788 [(use (match_operand:XF 0 "register_operand" ""))
15789 (use (match_operand:XF 2 "register_operand" ""))
15790 (use (match_operand:XF 1 "register_operand" ""))]
15791 "TARGET_USE_FANCY_MATH_387
15792 && flag_unsafe_math_optimizations"
15793 {
15794 rtx copy = gen_reg_rtx (XFmode);
15795 emit_move_insn (copy, operands[1]);
15796 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15797 DONE;
15798 })
15799
15800 (define_expand "atanxf2"
15801 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15802 (unspec:XF [(match_dup 2)
15803 (match_operand:XF 1 "register_operand" "")]
15804 UNSPEC_FPATAN))
15805 (clobber (match_scratch:XF 3 ""))])]
15806 "TARGET_USE_FANCY_MATH_387
15807 && flag_unsafe_math_optimizations"
15808 {
15809 operands[2] = gen_reg_rtx (XFmode);
15810 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15811 })
15812
15813 (define_expand "asindf2"
15814 [(set (match_dup 2)
15815 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15816 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15817 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15818 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15819 (parallel [(set (match_dup 7)
15820 (unspec:XF [(match_dup 6) (match_dup 2)]
15821 UNSPEC_FPATAN))
15822 (clobber (match_scratch:XF 8 ""))])
15823 (set (match_operand:DF 0 "register_operand" "")
15824 (float_truncate:DF (match_dup 7)))]
15825 "TARGET_USE_FANCY_MATH_387
15826 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15827 && flag_unsafe_math_optimizations"
15828 {
15829 int i;
15830
15831 for (i=2; i<8; i++)
15832 operands[i] = gen_reg_rtx (XFmode);
15833
15834 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15835 })
15836
15837 (define_expand "asinsf2"
15838 [(set (match_dup 2)
15839 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15840 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15841 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15842 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15843 (parallel [(set (match_dup 7)
15844 (unspec:XF [(match_dup 6) (match_dup 2)]
15845 UNSPEC_FPATAN))
15846 (clobber (match_scratch:XF 8 ""))])
15847 (set (match_operand:SF 0 "register_operand" "")
15848 (float_truncate:SF (match_dup 7)))]
15849 "TARGET_USE_FANCY_MATH_387
15850 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15851 && flag_unsafe_math_optimizations"
15852 {
15853 int i;
15854
15855 for (i=2; i<8; i++)
15856 operands[i] = gen_reg_rtx (XFmode);
15857
15858 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15859 })
15860
15861 (define_expand "asinxf2"
15862 [(set (match_dup 2)
15863 (mult:XF (match_operand:XF 1 "register_operand" "")
15864 (match_dup 1)))
15865 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15866 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15867 (parallel [(set (match_operand:XF 0 "register_operand" "")
15868 (unspec:XF [(match_dup 5) (match_dup 1)]
15869 UNSPEC_FPATAN))
15870 (clobber (match_scratch:XF 6 ""))])]
15871 "TARGET_USE_FANCY_MATH_387
15872 && flag_unsafe_math_optimizations"
15873 {
15874 int i;
15875
15876 for (i=2; i<6; i++)
15877 operands[i] = gen_reg_rtx (XFmode);
15878
15879 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15880 })
15881
15882 (define_expand "acosdf2"
15883 [(set (match_dup 2)
15884 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15885 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15886 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15887 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15888 (parallel [(set (match_dup 7)
15889 (unspec:XF [(match_dup 2) (match_dup 6)]
15890 UNSPEC_FPATAN))
15891 (clobber (match_scratch:XF 8 ""))])
15892 (set (match_operand:DF 0 "register_operand" "")
15893 (float_truncate:DF (match_dup 7)))]
15894 "TARGET_USE_FANCY_MATH_387
15895 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15896 && flag_unsafe_math_optimizations"
15897 {
15898 int i;
15899
15900 for (i=2; i<8; i++)
15901 operands[i] = gen_reg_rtx (XFmode);
15902
15903 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15904 })
15905
15906 (define_expand "acossf2"
15907 [(set (match_dup 2)
15908 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15909 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15910 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15911 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15912 (parallel [(set (match_dup 7)
15913 (unspec:XF [(match_dup 2) (match_dup 6)]
15914 UNSPEC_FPATAN))
15915 (clobber (match_scratch:XF 8 ""))])
15916 (set (match_operand:SF 0 "register_operand" "")
15917 (float_truncate:SF (match_dup 7)))]
15918 "TARGET_USE_FANCY_MATH_387
15919 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15920 && flag_unsafe_math_optimizations"
15921 {
15922 int i;
15923
15924 for (i=2; i<8; i++)
15925 operands[i] = gen_reg_rtx (XFmode);
15926
15927 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15928 })
15929
15930 (define_expand "acosxf2"
15931 [(set (match_dup 2)
15932 (mult:XF (match_operand:XF 1 "register_operand" "")
15933 (match_dup 1)))
15934 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15935 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15936 (parallel [(set (match_operand:XF 0 "register_operand" "")
15937 (unspec:XF [(match_dup 1) (match_dup 5)]
15938 UNSPEC_FPATAN))
15939 (clobber (match_scratch:XF 6 ""))])]
15940 "TARGET_USE_FANCY_MATH_387
15941 && flag_unsafe_math_optimizations"
15942 {
15943 int i;
15944
15945 for (i=2; i<6; i++)
15946 operands[i] = gen_reg_rtx (XFmode);
15947
15948 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15949 })
15950
15951 (define_insn "fyl2x_xf3"
15952 [(set (match_operand:XF 0 "register_operand" "=f")
15953 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15954 (match_operand:XF 1 "register_operand" "u")]
15955 UNSPEC_FYL2X))
15956 (clobber (match_scratch:XF 3 "=1"))]
15957 "TARGET_USE_FANCY_MATH_387
15958 && flag_unsafe_math_optimizations"
15959 "fyl2x"
15960 [(set_attr "type" "fpspc")
15961 (set_attr "mode" "XF")])
15962
15963 (define_expand "logsf2"
15964 [(set (match_dup 2)
15965 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15966 (parallel [(set (match_dup 4)
15967 (unspec:XF [(match_dup 2)
15968 (match_dup 3)] UNSPEC_FYL2X))
15969 (clobber (match_scratch:XF 5 ""))])
15970 (set (match_operand:SF 0 "register_operand" "")
15971 (float_truncate:SF (match_dup 4)))]
15972 "TARGET_USE_FANCY_MATH_387
15973 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15974 && flag_unsafe_math_optimizations"
15975 {
15976 rtx temp;
15977
15978 operands[2] = gen_reg_rtx (XFmode);
15979 operands[3] = gen_reg_rtx (XFmode);
15980 operands[4] = gen_reg_rtx (XFmode);
15981
15982 temp = standard_80387_constant_rtx (4); /* fldln2 */
15983 emit_move_insn (operands[3], temp);
15984 })
15985
15986 (define_expand "logdf2"
15987 [(set (match_dup 2)
15988 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15989 (parallel [(set (match_dup 4)
15990 (unspec:XF [(match_dup 2)
15991 (match_dup 3)] UNSPEC_FYL2X))
15992 (clobber (match_scratch:XF 5 ""))])
15993 (set (match_operand:DF 0 "register_operand" "")
15994 (float_truncate:DF (match_dup 4)))]
15995 "TARGET_USE_FANCY_MATH_387
15996 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15997 && flag_unsafe_math_optimizations"
15998 {
15999 rtx temp;
16000
16001 operands[2] = gen_reg_rtx (XFmode);
16002 operands[3] = gen_reg_rtx (XFmode);
16003 operands[4] = gen_reg_rtx (XFmode);
16004
16005 temp = standard_80387_constant_rtx (4); /* fldln2 */
16006 emit_move_insn (operands[3], temp);
16007 })
16008
16009 (define_expand "logxf2"
16010 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16011 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16012 (match_dup 2)] UNSPEC_FYL2X))
16013 (clobber (match_scratch:XF 3 ""))])]
16014 "TARGET_USE_FANCY_MATH_387
16015 && flag_unsafe_math_optimizations"
16016 {
16017 rtx temp;
16018
16019 operands[2] = gen_reg_rtx (XFmode);
16020 temp = standard_80387_constant_rtx (4); /* fldln2 */
16021 emit_move_insn (operands[2], temp);
16022 })
16023
16024 (define_expand "log10sf2"
16025 [(set (match_dup 2)
16026 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16027 (parallel [(set (match_dup 4)
16028 (unspec:XF [(match_dup 2)
16029 (match_dup 3)] UNSPEC_FYL2X))
16030 (clobber (match_scratch:XF 5 ""))])
16031 (set (match_operand:SF 0 "register_operand" "")
16032 (float_truncate:SF (match_dup 4)))]
16033 "TARGET_USE_FANCY_MATH_387
16034 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16035 && flag_unsafe_math_optimizations"
16036 {
16037 rtx temp;
16038
16039 operands[2] = gen_reg_rtx (XFmode);
16040 operands[3] = gen_reg_rtx (XFmode);
16041 operands[4] = gen_reg_rtx (XFmode);
16042
16043 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16044 emit_move_insn (operands[3], temp);
16045 })
16046
16047 (define_expand "log10df2"
16048 [(set (match_dup 2)
16049 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16050 (parallel [(set (match_dup 4)
16051 (unspec:XF [(match_dup 2)
16052 (match_dup 3)] UNSPEC_FYL2X))
16053 (clobber (match_scratch:XF 5 ""))])
16054 (set (match_operand:DF 0 "register_operand" "")
16055 (float_truncate:DF (match_dup 4)))]
16056 "TARGET_USE_FANCY_MATH_387
16057 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16058 && flag_unsafe_math_optimizations"
16059 {
16060 rtx temp;
16061
16062 operands[2] = gen_reg_rtx (XFmode);
16063 operands[3] = gen_reg_rtx (XFmode);
16064 operands[4] = gen_reg_rtx (XFmode);
16065
16066 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16067 emit_move_insn (operands[3], temp);
16068 })
16069
16070 (define_expand "log10xf2"
16071 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16072 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16073 (match_dup 2)] UNSPEC_FYL2X))
16074 (clobber (match_scratch:XF 3 ""))])]
16075 "TARGET_USE_FANCY_MATH_387
16076 && flag_unsafe_math_optimizations"
16077 {
16078 rtx temp;
16079
16080 operands[2] = gen_reg_rtx (XFmode);
16081 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16082 emit_move_insn (operands[2], temp);
16083 })
16084
16085 (define_expand "log2sf2"
16086 [(set (match_dup 2)
16087 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16088 (parallel [(set (match_dup 4)
16089 (unspec:XF [(match_dup 2)
16090 (match_dup 3)] UNSPEC_FYL2X))
16091 (clobber (match_scratch:XF 5 ""))])
16092 (set (match_operand:SF 0 "register_operand" "")
16093 (float_truncate:SF (match_dup 4)))]
16094 "TARGET_USE_FANCY_MATH_387
16095 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16096 && flag_unsafe_math_optimizations"
16097 {
16098 operands[2] = gen_reg_rtx (XFmode);
16099 operands[3] = gen_reg_rtx (XFmode);
16100 operands[4] = gen_reg_rtx (XFmode);
16101
16102 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16103 })
16104
16105 (define_expand "log2df2"
16106 [(set (match_dup 2)
16107 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16108 (parallel [(set (match_dup 4)
16109 (unspec:XF [(match_dup 2)
16110 (match_dup 3)] UNSPEC_FYL2X))
16111 (clobber (match_scratch:XF 5 ""))])
16112 (set (match_operand:DF 0 "register_operand" "")
16113 (float_truncate:DF (match_dup 4)))]
16114 "TARGET_USE_FANCY_MATH_387
16115 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16116 && flag_unsafe_math_optimizations"
16117 {
16118 operands[2] = gen_reg_rtx (XFmode);
16119 operands[3] = gen_reg_rtx (XFmode);
16120 operands[4] = gen_reg_rtx (XFmode);
16121
16122 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16123 })
16124
16125 (define_expand "log2xf2"
16126 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16127 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16128 (match_dup 2)] UNSPEC_FYL2X))
16129 (clobber (match_scratch:XF 3 ""))])]
16130 "TARGET_USE_FANCY_MATH_387
16131 && flag_unsafe_math_optimizations"
16132 {
16133 operands[2] = gen_reg_rtx (XFmode);
16134 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16135 })
16136
16137 (define_insn "fyl2xp1_xf3"
16138 [(set (match_operand:XF 0 "register_operand" "=f")
16139 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16140 (match_operand:XF 1 "register_operand" "u")]
16141 UNSPEC_FYL2XP1))
16142 (clobber (match_scratch:XF 3 "=1"))]
16143 "TARGET_USE_FANCY_MATH_387
16144 && flag_unsafe_math_optimizations"
16145 "fyl2xp1"
16146 [(set_attr "type" "fpspc")
16147 (set_attr "mode" "XF")])
16148
16149 (define_expand "log1psf2"
16150 [(use (match_operand:SF 0 "register_operand" ""))
16151 (use (match_operand:SF 1 "register_operand" ""))]
16152 "TARGET_USE_FANCY_MATH_387
16153 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16154 && flag_unsafe_math_optimizations"
16155 {
16156 rtx op0 = gen_reg_rtx (XFmode);
16157 rtx op1 = gen_reg_rtx (XFmode);
16158
16159 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16160 ix86_emit_i387_log1p (op0, op1);
16161 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16162 DONE;
16163 })
16164
16165 (define_expand "log1pdf2"
16166 [(use (match_operand:DF 0 "register_operand" ""))
16167 (use (match_operand:DF 1 "register_operand" ""))]
16168 "TARGET_USE_FANCY_MATH_387
16169 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16170 && flag_unsafe_math_optimizations"
16171 {
16172 rtx op0 = gen_reg_rtx (XFmode);
16173 rtx op1 = gen_reg_rtx (XFmode);
16174
16175 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16176 ix86_emit_i387_log1p (op0, op1);
16177 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16178 DONE;
16179 })
16180
16181 (define_expand "log1pxf2"
16182 [(use (match_operand:XF 0 "register_operand" ""))
16183 (use (match_operand:XF 1 "register_operand" ""))]
16184 "TARGET_USE_FANCY_MATH_387
16185 && flag_unsafe_math_optimizations"
16186 {
16187 ix86_emit_i387_log1p (operands[0], operands[1]);
16188 DONE;
16189 })
16190
16191 (define_insn "*fxtractxf3"
16192 [(set (match_operand:XF 0 "register_operand" "=f")
16193 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16194 UNSPEC_XTRACT_FRACT))
16195 (set (match_operand:XF 1 "register_operand" "=u")
16196 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16197 "TARGET_USE_FANCY_MATH_387
16198 && flag_unsafe_math_optimizations"
16199 "fxtract"
16200 [(set_attr "type" "fpspc")
16201 (set_attr "mode" "XF")])
16202
16203 (define_expand "logbsf2"
16204 [(set (match_dup 2)
16205 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16206 (parallel [(set (match_dup 3)
16207 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16208 (set (match_dup 4)
16209 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16210 (set (match_operand:SF 0 "register_operand" "")
16211 (float_truncate:SF (match_dup 4)))]
16212 "TARGET_USE_FANCY_MATH_387
16213 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16214 && flag_unsafe_math_optimizations"
16215 {
16216 operands[2] = gen_reg_rtx (XFmode);
16217 operands[3] = gen_reg_rtx (XFmode);
16218 operands[4] = gen_reg_rtx (XFmode);
16219 })
16220
16221 (define_expand "logbdf2"
16222 [(set (match_dup 2)
16223 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16224 (parallel [(set (match_dup 3)
16225 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16226 (set (match_dup 4)
16227 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16228 (set (match_operand:DF 0 "register_operand" "")
16229 (float_truncate:DF (match_dup 4)))]
16230 "TARGET_USE_FANCY_MATH_387
16231 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16232 && flag_unsafe_math_optimizations"
16233 {
16234 operands[2] = gen_reg_rtx (XFmode);
16235 operands[3] = gen_reg_rtx (XFmode);
16236 operands[4] = gen_reg_rtx (XFmode);
16237 })
16238
16239 (define_expand "logbxf2"
16240 [(parallel [(set (match_dup 2)
16241 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16242 UNSPEC_XTRACT_FRACT))
16243 (set (match_operand:XF 0 "register_operand" "")
16244 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16245 "TARGET_USE_FANCY_MATH_387
16246 && flag_unsafe_math_optimizations"
16247 {
16248 operands[2] = gen_reg_rtx (XFmode);
16249 })
16250
16251 (define_expand "ilogbsi2"
16252 [(parallel [(set (match_dup 2)
16253 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16254 UNSPEC_XTRACT_FRACT))
16255 (set (match_operand:XF 3 "register_operand" "")
16256 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16257 (parallel [(set (match_operand:SI 0 "register_operand" "")
16258 (fix:SI (match_dup 3)))
16259 (clobber (reg:CC FLAGS_REG))])]
16260 "TARGET_USE_FANCY_MATH_387
16261 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16262 && flag_unsafe_math_optimizations"
16263 {
16264 operands[2] = gen_reg_rtx (XFmode);
16265 operands[3] = gen_reg_rtx (XFmode);
16266 })
16267
16268 (define_insn "*f2xm1xf2"
16269 [(set (match_operand:XF 0 "register_operand" "=f")
16270 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16271 UNSPEC_F2XM1))]
16272 "TARGET_USE_FANCY_MATH_387
16273 && flag_unsafe_math_optimizations"
16274 "f2xm1"
16275 [(set_attr "type" "fpspc")
16276 (set_attr "mode" "XF")])
16277
16278 (define_insn "*fscalexf4"
16279 [(set (match_operand:XF 0 "register_operand" "=f")
16280 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16281 (match_operand:XF 3 "register_operand" "1")]
16282 UNSPEC_FSCALE_FRACT))
16283 (set (match_operand:XF 1 "register_operand" "=u")
16284 (unspec:XF [(match_dup 2) (match_dup 3)]
16285 UNSPEC_FSCALE_EXP))]
16286 "TARGET_USE_FANCY_MATH_387
16287 && flag_unsafe_math_optimizations"
16288 "fscale"
16289 [(set_attr "type" "fpspc")
16290 (set_attr "mode" "XF")])
16291
16292 (define_expand "expsf2"
16293 [(set (match_dup 2)
16294 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16295 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16296 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16297 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16298 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16299 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16300 (parallel [(set (match_dup 10)
16301 (unspec:XF [(match_dup 9) (match_dup 5)]
16302 UNSPEC_FSCALE_FRACT))
16303 (set (match_dup 11)
16304 (unspec:XF [(match_dup 9) (match_dup 5)]
16305 UNSPEC_FSCALE_EXP))])
16306 (set (match_operand:SF 0 "register_operand" "")
16307 (float_truncate:SF (match_dup 10)))]
16308 "TARGET_USE_FANCY_MATH_387
16309 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16310 && flag_unsafe_math_optimizations"
16311 {
16312 rtx temp;
16313 int i;
16314
16315 for (i=2; i<12; i++)
16316 operands[i] = gen_reg_rtx (XFmode);
16317 temp = standard_80387_constant_rtx (5); /* fldl2e */
16318 emit_move_insn (operands[3], temp);
16319 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16320 })
16321
16322 (define_expand "expdf2"
16323 [(set (match_dup 2)
16324 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16325 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16326 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16327 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16328 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16329 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16330 (parallel [(set (match_dup 10)
16331 (unspec:XF [(match_dup 9) (match_dup 5)]
16332 UNSPEC_FSCALE_FRACT))
16333 (set (match_dup 11)
16334 (unspec:XF [(match_dup 9) (match_dup 5)]
16335 UNSPEC_FSCALE_EXP))])
16336 (set (match_operand:DF 0 "register_operand" "")
16337 (float_truncate:DF (match_dup 10)))]
16338 "TARGET_USE_FANCY_MATH_387
16339 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16340 && flag_unsafe_math_optimizations"
16341 {
16342 rtx temp;
16343 int i;
16344
16345 for (i=2; i<12; i++)
16346 operands[i] = gen_reg_rtx (XFmode);
16347 temp = standard_80387_constant_rtx (5); /* fldl2e */
16348 emit_move_insn (operands[3], temp);
16349 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16350 })
16351
16352 (define_expand "expxf2"
16353 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16354 (match_dup 2)))
16355 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16356 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16357 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16358 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16359 (parallel [(set (match_operand:XF 0 "register_operand" "")
16360 (unspec:XF [(match_dup 8) (match_dup 4)]
16361 UNSPEC_FSCALE_FRACT))
16362 (set (match_dup 9)
16363 (unspec:XF [(match_dup 8) (match_dup 4)]
16364 UNSPEC_FSCALE_EXP))])]
16365 "TARGET_USE_FANCY_MATH_387
16366 && flag_unsafe_math_optimizations"
16367 {
16368 rtx temp;
16369 int i;
16370
16371 for (i=2; i<10; i++)
16372 operands[i] = gen_reg_rtx (XFmode);
16373 temp = standard_80387_constant_rtx (5); /* fldl2e */
16374 emit_move_insn (operands[2], temp);
16375 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16376 })
16377
16378 (define_expand "exp10sf2"
16379 [(set (match_dup 2)
16380 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16381 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16382 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16383 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16384 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16385 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16386 (parallel [(set (match_dup 10)
16387 (unspec:XF [(match_dup 9) (match_dup 5)]
16388 UNSPEC_FSCALE_FRACT))
16389 (set (match_dup 11)
16390 (unspec:XF [(match_dup 9) (match_dup 5)]
16391 UNSPEC_FSCALE_EXP))])
16392 (set (match_operand:SF 0 "register_operand" "")
16393 (float_truncate:SF (match_dup 10)))]
16394 "TARGET_USE_FANCY_MATH_387
16395 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16396 && flag_unsafe_math_optimizations"
16397 {
16398 rtx temp;
16399 int i;
16400
16401 for (i=2; i<12; i++)
16402 operands[i] = gen_reg_rtx (XFmode);
16403 temp = standard_80387_constant_rtx (6); /* fldl2t */
16404 emit_move_insn (operands[3], temp);
16405 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16406 })
16407
16408 (define_expand "exp10df2"
16409 [(set (match_dup 2)
16410 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16411 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16412 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16413 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16414 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16415 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16416 (parallel [(set (match_dup 10)
16417 (unspec:XF [(match_dup 9) (match_dup 5)]
16418 UNSPEC_FSCALE_FRACT))
16419 (set (match_dup 11)
16420 (unspec:XF [(match_dup 9) (match_dup 5)]
16421 UNSPEC_FSCALE_EXP))])
16422 (set (match_operand:DF 0 "register_operand" "")
16423 (float_truncate:DF (match_dup 10)))]
16424 "TARGET_USE_FANCY_MATH_387
16425 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16426 && flag_unsafe_math_optimizations"
16427 {
16428 rtx temp;
16429 int i;
16430
16431 for (i=2; i<12; i++)
16432 operands[i] = gen_reg_rtx (XFmode);
16433 temp = standard_80387_constant_rtx (6); /* fldl2t */
16434 emit_move_insn (operands[3], temp);
16435 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16436 })
16437
16438 (define_expand "exp10xf2"
16439 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16440 (match_dup 2)))
16441 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16442 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16443 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16444 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16445 (parallel [(set (match_operand:XF 0 "register_operand" "")
16446 (unspec:XF [(match_dup 8) (match_dup 4)]
16447 UNSPEC_FSCALE_FRACT))
16448 (set (match_dup 9)
16449 (unspec:XF [(match_dup 8) (match_dup 4)]
16450 UNSPEC_FSCALE_EXP))])]
16451 "TARGET_USE_FANCY_MATH_387
16452 && flag_unsafe_math_optimizations"
16453 {
16454 rtx temp;
16455 int i;
16456
16457 for (i=2; i<10; i++)
16458 operands[i] = gen_reg_rtx (XFmode);
16459 temp = standard_80387_constant_rtx (6); /* fldl2t */
16460 emit_move_insn (operands[2], temp);
16461 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16462 })
16463
16464 (define_expand "exp2sf2"
16465 [(set (match_dup 2)
16466 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16467 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16468 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16469 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16470 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16471 (parallel [(set (match_dup 8)
16472 (unspec:XF [(match_dup 7) (match_dup 3)]
16473 UNSPEC_FSCALE_FRACT))
16474 (set (match_dup 9)
16475 (unspec:XF [(match_dup 7) (match_dup 3)]
16476 UNSPEC_FSCALE_EXP))])
16477 (set (match_operand:SF 0 "register_operand" "")
16478 (float_truncate:SF (match_dup 8)))]
16479 "TARGET_USE_FANCY_MATH_387
16480 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16481 && flag_unsafe_math_optimizations"
16482 {
16483 int i;
16484
16485 for (i=2; i<10; i++)
16486 operands[i] = gen_reg_rtx (XFmode);
16487 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16488 })
16489
16490 (define_expand "exp2df2"
16491 [(set (match_dup 2)
16492 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16493 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16494 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16495 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16496 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16497 (parallel [(set (match_dup 8)
16498 (unspec:XF [(match_dup 7) (match_dup 3)]
16499 UNSPEC_FSCALE_FRACT))
16500 (set (match_dup 9)
16501 (unspec:XF [(match_dup 7) (match_dup 3)]
16502 UNSPEC_FSCALE_EXP))])
16503 (set (match_operand:DF 0 "register_operand" "")
16504 (float_truncate:DF (match_dup 8)))]
16505 "TARGET_USE_FANCY_MATH_387
16506 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16507 && flag_unsafe_math_optimizations"
16508 {
16509 int i;
16510
16511 for (i=2; i<10; i++)
16512 operands[i] = gen_reg_rtx (XFmode);
16513 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16514 })
16515
16516 (define_expand "exp2xf2"
16517 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16518 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16519 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16520 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16521 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16522 (parallel [(set (match_operand:XF 0 "register_operand" "")
16523 (unspec:XF [(match_dup 7) (match_dup 3)]
16524 UNSPEC_FSCALE_FRACT))
16525 (set (match_dup 8)
16526 (unspec:XF [(match_dup 7) (match_dup 3)]
16527 UNSPEC_FSCALE_EXP))])]
16528 "TARGET_USE_FANCY_MATH_387
16529 && flag_unsafe_math_optimizations"
16530 {
16531 int i;
16532
16533 for (i=2; i<9; i++)
16534 operands[i] = gen_reg_rtx (XFmode);
16535 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16536 })
16537
16538 (define_expand "expm1df2"
16539 [(set (match_dup 2)
16540 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16541 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16542 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16543 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16544 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16545 (parallel [(set (match_dup 8)
16546 (unspec:XF [(match_dup 7) (match_dup 5)]
16547 UNSPEC_FSCALE_FRACT))
16548 (set (match_dup 9)
16549 (unspec:XF [(match_dup 7) (match_dup 5)]
16550 UNSPEC_FSCALE_EXP))])
16551 (parallel [(set (match_dup 11)
16552 (unspec:XF [(match_dup 10) (match_dup 9)]
16553 UNSPEC_FSCALE_FRACT))
16554 (set (match_dup 12)
16555 (unspec:XF [(match_dup 10) (match_dup 9)]
16556 UNSPEC_FSCALE_EXP))])
16557 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16558 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16559 (set (match_operand:DF 0 "register_operand" "")
16560 (float_truncate:DF (match_dup 14)))]
16561 "TARGET_USE_FANCY_MATH_387
16562 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16563 && flag_unsafe_math_optimizations"
16564 {
16565 rtx temp;
16566 int i;
16567
16568 for (i=2; i<15; i++)
16569 operands[i] = gen_reg_rtx (XFmode);
16570 temp = standard_80387_constant_rtx (5); /* fldl2e */
16571 emit_move_insn (operands[3], temp);
16572 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16573 })
16574
16575 (define_expand "expm1sf2"
16576 [(set (match_dup 2)
16577 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16578 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16579 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16580 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16581 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16582 (parallel [(set (match_dup 8)
16583 (unspec:XF [(match_dup 7) (match_dup 5)]
16584 UNSPEC_FSCALE_FRACT))
16585 (set (match_dup 9)
16586 (unspec:XF [(match_dup 7) (match_dup 5)]
16587 UNSPEC_FSCALE_EXP))])
16588 (parallel [(set (match_dup 11)
16589 (unspec:XF [(match_dup 10) (match_dup 9)]
16590 UNSPEC_FSCALE_FRACT))
16591 (set (match_dup 12)
16592 (unspec:XF [(match_dup 10) (match_dup 9)]
16593 UNSPEC_FSCALE_EXP))])
16594 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16595 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16596 (set (match_operand:SF 0 "register_operand" "")
16597 (float_truncate:SF (match_dup 14)))]
16598 "TARGET_USE_FANCY_MATH_387
16599 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16600 && flag_unsafe_math_optimizations"
16601 {
16602 rtx temp;
16603 int i;
16604
16605 for (i=2; i<15; i++)
16606 operands[i] = gen_reg_rtx (XFmode);
16607 temp = standard_80387_constant_rtx (5); /* fldl2e */
16608 emit_move_insn (operands[3], temp);
16609 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16610 })
16611
16612 (define_expand "expm1xf2"
16613 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16614 (match_dup 2)))
16615 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16616 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16617 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16618 (parallel [(set (match_dup 7)
16619 (unspec:XF [(match_dup 6) (match_dup 4)]
16620 UNSPEC_FSCALE_FRACT))
16621 (set (match_dup 8)
16622 (unspec:XF [(match_dup 6) (match_dup 4)]
16623 UNSPEC_FSCALE_EXP))])
16624 (parallel [(set (match_dup 10)
16625 (unspec:XF [(match_dup 9) (match_dup 8)]
16626 UNSPEC_FSCALE_FRACT))
16627 (set (match_dup 11)
16628 (unspec:XF [(match_dup 9) (match_dup 8)]
16629 UNSPEC_FSCALE_EXP))])
16630 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16631 (set (match_operand:XF 0 "register_operand" "")
16632 (plus:XF (match_dup 12) (match_dup 7)))]
16633 "TARGET_USE_FANCY_MATH_387
16634 && flag_unsafe_math_optimizations"
16635 {
16636 rtx temp;
16637 int i;
16638
16639 for (i=2; i<13; i++)
16640 operands[i] = gen_reg_rtx (XFmode);
16641 temp = standard_80387_constant_rtx (5); /* fldl2e */
16642 emit_move_insn (operands[2], temp);
16643 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16644 })
16645
16646 (define_expand "ldexpdf3"
16647 [(set (match_dup 3)
16648 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16649 (set (match_dup 4)
16650 (float:XF (match_operand:SI 2 "register_operand" "")))
16651 (parallel [(set (match_dup 5)
16652 (unspec:XF [(match_dup 3) (match_dup 4)]
16653 UNSPEC_FSCALE_FRACT))
16654 (set (match_dup 6)
16655 (unspec:XF [(match_dup 3) (match_dup 4)]
16656 UNSPEC_FSCALE_EXP))])
16657 (set (match_operand:DF 0 "register_operand" "")
16658 (float_truncate:DF (match_dup 5)))]
16659 "TARGET_USE_FANCY_MATH_387
16660 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16661 && flag_unsafe_math_optimizations"
16662 {
16663 int i;
16664
16665 for (i=3; i<7; i++)
16666 operands[i] = gen_reg_rtx (XFmode);
16667 })
16668
16669 (define_expand "ldexpsf3"
16670 [(set (match_dup 3)
16671 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16672 (set (match_dup 4)
16673 (float:XF (match_operand:SI 2 "register_operand" "")))
16674 (parallel [(set (match_dup 5)
16675 (unspec:XF [(match_dup 3) (match_dup 4)]
16676 UNSPEC_FSCALE_FRACT))
16677 (set (match_dup 6)
16678 (unspec:XF [(match_dup 3) (match_dup 4)]
16679 UNSPEC_FSCALE_EXP))])
16680 (set (match_operand:SF 0 "register_operand" "")
16681 (float_truncate:SF (match_dup 5)))]
16682 "TARGET_USE_FANCY_MATH_387
16683 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16684 && flag_unsafe_math_optimizations"
16685 {
16686 int i;
16687
16688 for (i=3; i<7; i++)
16689 operands[i] = gen_reg_rtx (XFmode);
16690 })
16691
16692 (define_expand "ldexpxf3"
16693 [(set (match_dup 3)
16694 (float:XF (match_operand:SI 2 "register_operand" "")))
16695 (parallel [(set (match_operand:XF 0 " register_operand" "")
16696 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16697 (match_dup 3)]
16698 UNSPEC_FSCALE_FRACT))
16699 (set (match_dup 4)
16700 (unspec:XF [(match_dup 1) (match_dup 3)]
16701 UNSPEC_FSCALE_EXP))])]
16702 "TARGET_USE_FANCY_MATH_387
16703 && flag_unsafe_math_optimizations"
16704 {
16705 int i;
16706
16707 for (i=3; i<5; i++)
16708 operands[i] = gen_reg_rtx (XFmode);
16709 })
16710 \f
16711
16712 (define_insn "frndintxf2"
16713 [(set (match_operand:XF 0 "register_operand" "=f")
16714 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16715 UNSPEC_FRNDINT))]
16716 "TARGET_USE_FANCY_MATH_387
16717 && flag_unsafe_math_optimizations"
16718 "frndint"
16719 [(set_attr "type" "fpspc")
16720 (set_attr "mode" "XF")])
16721
16722 (define_expand "rintdf2"
16723 [(use (match_operand:DF 0 "register_operand" ""))
16724 (use (match_operand:DF 1 "register_operand" ""))]
16725 "TARGET_USE_FANCY_MATH_387
16726 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16727 && flag_unsafe_math_optimizations"
16728 {
16729 rtx op0 = gen_reg_rtx (XFmode);
16730 rtx op1 = gen_reg_rtx (XFmode);
16731
16732 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16733 emit_insn (gen_frndintxf2 (op0, op1));
16734
16735 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16736 DONE;
16737 })
16738
16739 (define_expand "rintsf2"
16740 [(use (match_operand:SF 0 "register_operand" ""))
16741 (use (match_operand:SF 1 "register_operand" ""))]
16742 "TARGET_USE_FANCY_MATH_387
16743 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16744 && flag_unsafe_math_optimizations"
16745 {
16746 rtx op0 = gen_reg_rtx (XFmode);
16747 rtx op1 = gen_reg_rtx (XFmode);
16748
16749 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16750 emit_insn (gen_frndintxf2 (op0, op1));
16751
16752 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16753 DONE;
16754 })
16755
16756 (define_expand "rintxf2"
16757 [(use (match_operand:XF 0 "register_operand" ""))
16758 (use (match_operand:XF 1 "register_operand" ""))]
16759 "TARGET_USE_FANCY_MATH_387
16760 && flag_unsafe_math_optimizations"
16761 {
16762 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16763 DONE;
16764 })
16765
16766 (define_insn_and_split "*fistdi2_1"
16767 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16768 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16769 UNSPEC_FIST))]
16770 "TARGET_USE_FANCY_MATH_387
16771 && flag_unsafe_math_optimizations
16772 && !(reload_completed || reload_in_progress)"
16773 "#"
16774 "&& 1"
16775 [(const_int 0)]
16776 {
16777 if (memory_operand (operands[0], VOIDmode))
16778 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16779 else
16780 {
16781 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16782 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16783 operands[2]));
16784 }
16785 DONE;
16786 }
16787 [(set_attr "type" "fpspc")
16788 (set_attr "mode" "DI")])
16789
16790 (define_insn "fistdi2"
16791 [(set (match_operand:DI 0 "memory_operand" "=m")
16792 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16793 UNSPEC_FIST))
16794 (clobber (match_scratch:XF 2 "=&1f"))]
16795 "TARGET_USE_FANCY_MATH_387
16796 && flag_unsafe_math_optimizations"
16797 "* return output_fix_trunc (insn, operands, 0);"
16798 [(set_attr "type" "fpspc")
16799 (set_attr "mode" "DI")])
16800
16801 (define_insn "fistdi2_with_temp"
16802 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16803 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16804 UNSPEC_FIST))
16805 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16806 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16807 "TARGET_USE_FANCY_MATH_387
16808 && flag_unsafe_math_optimizations"
16809 "#"
16810 [(set_attr "type" "fpspc")
16811 (set_attr "mode" "DI")])
16812
16813 (define_split
16814 [(set (match_operand:DI 0 "register_operand" "")
16815 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16816 UNSPEC_FIST))
16817 (clobber (match_operand:DI 2 "memory_operand" ""))
16818 (clobber (match_scratch 3 ""))]
16819 "reload_completed"
16820 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16821 (clobber (match_dup 3))])
16822 (set (match_dup 0) (match_dup 2))]
16823 "")
16824
16825 (define_split
16826 [(set (match_operand:DI 0 "memory_operand" "")
16827 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16828 UNSPEC_FIST))
16829 (clobber (match_operand:DI 2 "memory_operand" ""))
16830 (clobber (match_scratch 3 ""))]
16831 "reload_completed"
16832 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16833 (clobber (match_dup 3))])]
16834 "")
16835
16836 (define_insn_and_split "*fist<mode>2_1"
16837 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16838 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16839 UNSPEC_FIST))]
16840 "TARGET_USE_FANCY_MATH_387
16841 && flag_unsafe_math_optimizations
16842 && !(reload_completed || reload_in_progress)"
16843 "#"
16844 "&& 1"
16845 [(const_int 0)]
16846 {
16847 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16848 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16849 operands[2]));
16850 DONE;
16851 }
16852 [(set_attr "type" "fpspc")
16853 (set_attr "mode" "<MODE>")])
16854
16855 (define_insn "fist<mode>2"
16856 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16857 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16858 UNSPEC_FIST))]
16859 "TARGET_USE_FANCY_MATH_387
16860 && flag_unsafe_math_optimizations"
16861 "* return output_fix_trunc (insn, operands, 0);"
16862 [(set_attr "type" "fpspc")
16863 (set_attr "mode" "<MODE>")])
16864
16865 (define_insn "fist<mode>2_with_temp"
16866 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16867 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16868 UNSPEC_FIST))
16869 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16870 "TARGET_USE_FANCY_MATH_387
16871 && flag_unsafe_math_optimizations"
16872 "#"
16873 [(set_attr "type" "fpspc")
16874 (set_attr "mode" "<MODE>")])
16875
16876 (define_split
16877 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16878 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16879 UNSPEC_FIST))
16880 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16881 "reload_completed"
16882 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16883 UNSPEC_FIST))
16884 (set (match_dup 0) (match_dup 2))]
16885 "")
16886
16887 (define_split
16888 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16889 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16890 UNSPEC_FIST))
16891 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16892 "reload_completed"
16893 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16894 UNSPEC_FIST))]
16895 "")
16896
16897 (define_expand "lrint<mode>2"
16898 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16899 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16900 UNSPEC_FIST))]
16901 "TARGET_USE_FANCY_MATH_387
16902 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16903 && flag_unsafe_math_optimizations"
16904 "")
16905
16906 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16907 (define_insn_and_split "frndintxf2_floor"
16908 [(set (match_operand:XF 0 "register_operand" "=f")
16909 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16910 UNSPEC_FRNDINT_FLOOR))
16911 (clobber (reg:CC FLAGS_REG))]
16912 "TARGET_USE_FANCY_MATH_387
16913 && flag_unsafe_math_optimizations
16914 && !(reload_completed || reload_in_progress)"
16915 "#"
16916 "&& 1"
16917 [(const_int 0)]
16918 {
16919 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16920
16921 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16922 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16923
16924 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16925 operands[2], operands[3]));
16926 DONE;
16927 }
16928 [(set_attr "type" "frndint")
16929 (set_attr "i387_cw" "floor")
16930 (set_attr "mode" "XF")])
16931
16932 (define_insn "frndintxf2_floor_i387"
16933 [(set (match_operand:XF 0 "register_operand" "=f")
16934 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16935 UNSPEC_FRNDINT_FLOOR))
16936 (use (match_operand:HI 2 "memory_operand" "m"))
16937 (use (match_operand:HI 3 "memory_operand" "m"))]
16938 "TARGET_USE_FANCY_MATH_387
16939 && flag_unsafe_math_optimizations"
16940 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16941 [(set_attr "type" "frndint")
16942 (set_attr "i387_cw" "floor")
16943 (set_attr "mode" "XF")])
16944
16945 (define_expand "floorxf2"
16946 [(use (match_operand:XF 0 "register_operand" ""))
16947 (use (match_operand:XF 1 "register_operand" ""))]
16948 "TARGET_USE_FANCY_MATH_387
16949 && flag_unsafe_math_optimizations"
16950 {
16951 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16952 DONE;
16953 })
16954
16955 (define_expand "floordf2"
16956 [(use (match_operand:DF 0 "register_operand" ""))
16957 (use (match_operand:DF 1 "register_operand" ""))]
16958 "TARGET_USE_FANCY_MATH_387
16959 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16960 && flag_unsafe_math_optimizations"
16961 {
16962 rtx op0 = gen_reg_rtx (XFmode);
16963 rtx op1 = gen_reg_rtx (XFmode);
16964
16965 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16966 emit_insn (gen_frndintxf2_floor (op0, op1));
16967
16968 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16969 DONE;
16970 })
16971
16972 (define_expand "floorsf2"
16973 [(use (match_operand:SF 0 "register_operand" ""))
16974 (use (match_operand:SF 1 "register_operand" ""))]
16975 "TARGET_USE_FANCY_MATH_387
16976 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16977 && flag_unsafe_math_optimizations"
16978 {
16979 rtx op0 = gen_reg_rtx (XFmode);
16980 rtx op1 = gen_reg_rtx (XFmode);
16981
16982 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16983 emit_insn (gen_frndintxf2_floor (op0, op1));
16984
16985 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16986 DONE;
16987 })
16988
16989 (define_insn_and_split "*fist<mode>2_floor_1"
16990 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16991 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16992 UNSPEC_FIST_FLOOR))
16993 (clobber (reg:CC FLAGS_REG))]
16994 "TARGET_USE_FANCY_MATH_387
16995 && flag_unsafe_math_optimizations
16996 && !(reload_completed || reload_in_progress)"
16997 "#"
16998 "&& 1"
16999 [(const_int 0)]
17000 {
17001 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17002
17003 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17004 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17005 if (memory_operand (operands[0], VOIDmode))
17006 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17007 operands[2], operands[3]));
17008 else
17009 {
17010 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17011 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17012 operands[2], operands[3],
17013 operands[4]));
17014 }
17015 DONE;
17016 }
17017 [(set_attr "type" "fistp")
17018 (set_attr "i387_cw" "floor")
17019 (set_attr "mode" "<MODE>")])
17020
17021 (define_insn "fistdi2_floor"
17022 [(set (match_operand:DI 0 "memory_operand" "=m")
17023 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17024 UNSPEC_FIST_FLOOR))
17025 (use (match_operand:HI 2 "memory_operand" "m"))
17026 (use (match_operand:HI 3 "memory_operand" "m"))
17027 (clobber (match_scratch:XF 4 "=&1f"))]
17028 "TARGET_USE_FANCY_MATH_387
17029 && flag_unsafe_math_optimizations"
17030 "* return output_fix_trunc (insn, operands, 0);"
17031 [(set_attr "type" "fistp")
17032 (set_attr "i387_cw" "floor")
17033 (set_attr "mode" "DI")])
17034
17035 (define_insn "fistdi2_floor_with_temp"
17036 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17037 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17038 UNSPEC_FIST_FLOOR))
17039 (use (match_operand:HI 2 "memory_operand" "m,m"))
17040 (use (match_operand:HI 3 "memory_operand" "m,m"))
17041 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17042 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17043 "TARGET_USE_FANCY_MATH_387
17044 && flag_unsafe_math_optimizations"
17045 "#"
17046 [(set_attr "type" "fistp")
17047 (set_attr "i387_cw" "floor")
17048 (set_attr "mode" "DI")])
17049
17050 (define_split
17051 [(set (match_operand:DI 0 "register_operand" "")
17052 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17053 UNSPEC_FIST_FLOOR))
17054 (use (match_operand:HI 2 "memory_operand" ""))
17055 (use (match_operand:HI 3 "memory_operand" ""))
17056 (clobber (match_operand:DI 4 "memory_operand" ""))
17057 (clobber (match_scratch 5 ""))]
17058 "reload_completed"
17059 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17060 (use (match_dup 2))
17061 (use (match_dup 3))
17062 (clobber (match_dup 5))])
17063 (set (match_dup 0) (match_dup 4))]
17064 "")
17065
17066 (define_split
17067 [(set (match_operand:DI 0 "memory_operand" "")
17068 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17069 UNSPEC_FIST_FLOOR))
17070 (use (match_operand:HI 2 "memory_operand" ""))
17071 (use (match_operand:HI 3 "memory_operand" ""))
17072 (clobber (match_operand:DI 4 "memory_operand" ""))
17073 (clobber (match_scratch 5 ""))]
17074 "reload_completed"
17075 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17076 (use (match_dup 2))
17077 (use (match_dup 3))
17078 (clobber (match_dup 5))])]
17079 "")
17080
17081 (define_insn "fist<mode>2_floor"
17082 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17083 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17084 UNSPEC_FIST_FLOOR))
17085 (use (match_operand:HI 2 "memory_operand" "m"))
17086 (use (match_operand:HI 3 "memory_operand" "m"))]
17087 "TARGET_USE_FANCY_MATH_387
17088 && flag_unsafe_math_optimizations"
17089 "* return output_fix_trunc (insn, operands, 0);"
17090 [(set_attr "type" "fistp")
17091 (set_attr "i387_cw" "floor")
17092 (set_attr "mode" "<MODE>")])
17093
17094 (define_insn "fist<mode>2_floor_with_temp"
17095 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17096 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17097 UNSPEC_FIST_FLOOR))
17098 (use (match_operand:HI 2 "memory_operand" "m,m"))
17099 (use (match_operand:HI 3 "memory_operand" "m,m"))
17100 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17101 "TARGET_USE_FANCY_MATH_387
17102 && flag_unsafe_math_optimizations"
17103 "#"
17104 [(set_attr "type" "fistp")
17105 (set_attr "i387_cw" "floor")
17106 (set_attr "mode" "<MODE>")])
17107
17108 (define_split
17109 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17110 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17111 UNSPEC_FIST_FLOOR))
17112 (use (match_operand:HI 2 "memory_operand" ""))
17113 (use (match_operand:HI 3 "memory_operand" ""))
17114 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17115 "reload_completed"
17116 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17117 UNSPEC_FIST_FLOOR))
17118 (use (match_dup 2))
17119 (use (match_dup 3))])
17120 (set (match_dup 0) (match_dup 4))]
17121 "")
17122
17123 (define_split
17124 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17125 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17126 UNSPEC_FIST_FLOOR))
17127 (use (match_operand:HI 2 "memory_operand" ""))
17128 (use (match_operand:HI 3 "memory_operand" ""))
17129 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17130 "reload_completed"
17131 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17132 UNSPEC_FIST_FLOOR))
17133 (use (match_dup 2))
17134 (use (match_dup 3))])]
17135 "")
17136
17137 (define_expand "lfloor<mode>2"
17138 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17139 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17140 UNSPEC_FIST_FLOOR))
17141 (clobber (reg:CC FLAGS_REG))])]
17142 "TARGET_USE_FANCY_MATH_387
17143 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17144 && flag_unsafe_math_optimizations"
17145 "")
17146
17147 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17148 (define_insn_and_split "frndintxf2_ceil"
17149 [(set (match_operand:XF 0 "register_operand" "=f")
17150 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17151 UNSPEC_FRNDINT_CEIL))
17152 (clobber (reg:CC FLAGS_REG))]
17153 "TARGET_USE_FANCY_MATH_387
17154 && flag_unsafe_math_optimizations
17155 && !(reload_completed || reload_in_progress)"
17156 "#"
17157 "&& 1"
17158 [(const_int 0)]
17159 {
17160 ix86_optimize_mode_switching[I387_CEIL] = 1;
17161
17162 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17163 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17164
17165 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17166 operands[2], operands[3]));
17167 DONE;
17168 }
17169 [(set_attr "type" "frndint")
17170 (set_attr "i387_cw" "ceil")
17171 (set_attr "mode" "XF")])
17172
17173 (define_insn "frndintxf2_ceil_i387"
17174 [(set (match_operand:XF 0 "register_operand" "=f")
17175 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17176 UNSPEC_FRNDINT_CEIL))
17177 (use (match_operand:HI 2 "memory_operand" "m"))
17178 (use (match_operand:HI 3 "memory_operand" "m"))]
17179 "TARGET_USE_FANCY_MATH_387
17180 && flag_unsafe_math_optimizations"
17181 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17182 [(set_attr "type" "frndint")
17183 (set_attr "i387_cw" "ceil")
17184 (set_attr "mode" "XF")])
17185
17186 (define_expand "ceilxf2"
17187 [(use (match_operand:XF 0 "register_operand" ""))
17188 (use (match_operand:XF 1 "register_operand" ""))]
17189 "TARGET_USE_FANCY_MATH_387
17190 && flag_unsafe_math_optimizations"
17191 {
17192 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17193 DONE;
17194 })
17195
17196 (define_expand "ceildf2"
17197 [(use (match_operand:DF 0 "register_operand" ""))
17198 (use (match_operand:DF 1 "register_operand" ""))]
17199 "TARGET_USE_FANCY_MATH_387
17200 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17201 && flag_unsafe_math_optimizations"
17202 {
17203 rtx op0 = gen_reg_rtx (XFmode);
17204 rtx op1 = gen_reg_rtx (XFmode);
17205
17206 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17207 emit_insn (gen_frndintxf2_ceil (op0, op1));
17208
17209 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17210 DONE;
17211 })
17212
17213 (define_expand "ceilsf2"
17214 [(use (match_operand:SF 0 "register_operand" ""))
17215 (use (match_operand:SF 1 "register_operand" ""))]
17216 "TARGET_USE_FANCY_MATH_387
17217 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17218 && flag_unsafe_math_optimizations"
17219 {
17220 rtx op0 = gen_reg_rtx (XFmode);
17221 rtx op1 = gen_reg_rtx (XFmode);
17222
17223 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17224 emit_insn (gen_frndintxf2_ceil (op0, op1));
17225
17226 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17227 DONE;
17228 })
17229
17230 (define_insn_and_split "*fist<mode>2_ceil_1"
17231 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17232 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17233 UNSPEC_FIST_CEIL))
17234 (clobber (reg:CC FLAGS_REG))]
17235 "TARGET_USE_FANCY_MATH_387
17236 && flag_unsafe_math_optimizations
17237 && !(reload_completed || reload_in_progress)"
17238 "#"
17239 "&& 1"
17240 [(const_int 0)]
17241 {
17242 ix86_optimize_mode_switching[I387_CEIL] = 1;
17243
17244 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17245 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17246 if (memory_operand (operands[0], VOIDmode))
17247 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17248 operands[2], operands[3]));
17249 else
17250 {
17251 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17252 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17253 operands[2], operands[3],
17254 operands[4]));
17255 }
17256 DONE;
17257 }
17258 [(set_attr "type" "fistp")
17259 (set_attr "i387_cw" "ceil")
17260 (set_attr "mode" "<MODE>")])
17261
17262 (define_insn "fistdi2_ceil"
17263 [(set (match_operand:DI 0 "memory_operand" "=m")
17264 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17265 UNSPEC_FIST_CEIL))
17266 (use (match_operand:HI 2 "memory_operand" "m"))
17267 (use (match_operand:HI 3 "memory_operand" "m"))
17268 (clobber (match_scratch:XF 4 "=&1f"))]
17269 "TARGET_USE_FANCY_MATH_387
17270 && flag_unsafe_math_optimizations"
17271 "* return output_fix_trunc (insn, operands, 0);"
17272 [(set_attr "type" "fistp")
17273 (set_attr "i387_cw" "ceil")
17274 (set_attr "mode" "DI")])
17275
17276 (define_insn "fistdi2_ceil_with_temp"
17277 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17278 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17279 UNSPEC_FIST_CEIL))
17280 (use (match_operand:HI 2 "memory_operand" "m,m"))
17281 (use (match_operand:HI 3 "memory_operand" "m,m"))
17282 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17283 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17284 "TARGET_USE_FANCY_MATH_387
17285 && flag_unsafe_math_optimizations"
17286 "#"
17287 [(set_attr "type" "fistp")
17288 (set_attr "i387_cw" "ceil")
17289 (set_attr "mode" "DI")])
17290
17291 (define_split
17292 [(set (match_operand:DI 0 "register_operand" "")
17293 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17294 UNSPEC_FIST_CEIL))
17295 (use (match_operand:HI 2 "memory_operand" ""))
17296 (use (match_operand:HI 3 "memory_operand" ""))
17297 (clobber (match_operand:DI 4 "memory_operand" ""))
17298 (clobber (match_scratch 5 ""))]
17299 "reload_completed"
17300 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17301 (use (match_dup 2))
17302 (use (match_dup 3))
17303 (clobber (match_dup 5))])
17304 (set (match_dup 0) (match_dup 4))]
17305 "")
17306
17307 (define_split
17308 [(set (match_operand:DI 0 "memory_operand" "")
17309 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17310 UNSPEC_FIST_CEIL))
17311 (use (match_operand:HI 2 "memory_operand" ""))
17312 (use (match_operand:HI 3 "memory_operand" ""))
17313 (clobber (match_operand:DI 4 "memory_operand" ""))
17314 (clobber (match_scratch 5 ""))]
17315 "reload_completed"
17316 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17317 (use (match_dup 2))
17318 (use (match_dup 3))
17319 (clobber (match_dup 5))])]
17320 "")
17321
17322 (define_insn "fist<mode>2_ceil"
17323 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17324 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17325 UNSPEC_FIST_CEIL))
17326 (use (match_operand:HI 2 "memory_operand" "m"))
17327 (use (match_operand:HI 3 "memory_operand" "m"))]
17328 "TARGET_USE_FANCY_MATH_387
17329 && flag_unsafe_math_optimizations"
17330 "* return output_fix_trunc (insn, operands, 0);"
17331 [(set_attr "type" "fistp")
17332 (set_attr "i387_cw" "ceil")
17333 (set_attr "mode" "<MODE>")])
17334
17335 (define_insn "fist<mode>2_ceil_with_temp"
17336 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17337 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17338 UNSPEC_FIST_CEIL))
17339 (use (match_operand:HI 2 "memory_operand" "m,m"))
17340 (use (match_operand:HI 3 "memory_operand" "m,m"))
17341 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17342 "TARGET_USE_FANCY_MATH_387
17343 && flag_unsafe_math_optimizations"
17344 "#"
17345 [(set_attr "type" "fistp")
17346 (set_attr "i387_cw" "ceil")
17347 (set_attr "mode" "<MODE>")])
17348
17349 (define_split
17350 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17351 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17352 UNSPEC_FIST_CEIL))
17353 (use (match_operand:HI 2 "memory_operand" ""))
17354 (use (match_operand:HI 3 "memory_operand" ""))
17355 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17356 "reload_completed"
17357 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17358 UNSPEC_FIST_CEIL))
17359 (use (match_dup 2))
17360 (use (match_dup 3))])
17361 (set (match_dup 0) (match_dup 4))]
17362 "")
17363
17364 (define_split
17365 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17366 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17367 UNSPEC_FIST_CEIL))
17368 (use (match_operand:HI 2 "memory_operand" ""))
17369 (use (match_operand:HI 3 "memory_operand" ""))
17370 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17371 "reload_completed"
17372 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17373 UNSPEC_FIST_CEIL))
17374 (use (match_dup 2))
17375 (use (match_dup 3))])]
17376 "")
17377
17378 (define_expand "lceil<mode>2"
17379 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17380 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17381 UNSPEC_FIST_CEIL))
17382 (clobber (reg:CC FLAGS_REG))])]
17383 "TARGET_USE_FANCY_MATH_387
17384 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17385 && flag_unsafe_math_optimizations"
17386 "")
17387
17388 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17389 (define_insn_and_split "frndintxf2_trunc"
17390 [(set (match_operand:XF 0 "register_operand" "=f")
17391 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17392 UNSPEC_FRNDINT_TRUNC))
17393 (clobber (reg:CC FLAGS_REG))]
17394 "TARGET_USE_FANCY_MATH_387
17395 && flag_unsafe_math_optimizations
17396 && !(reload_completed || reload_in_progress)"
17397 "#"
17398 "&& 1"
17399 [(const_int 0)]
17400 {
17401 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17402
17403 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17404 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17405
17406 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17407 operands[2], operands[3]));
17408 DONE;
17409 }
17410 [(set_attr "type" "frndint")
17411 (set_attr "i387_cw" "trunc")
17412 (set_attr "mode" "XF")])
17413
17414 (define_insn "frndintxf2_trunc_i387"
17415 [(set (match_operand:XF 0 "register_operand" "=f")
17416 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17417 UNSPEC_FRNDINT_TRUNC))
17418 (use (match_operand:HI 2 "memory_operand" "m"))
17419 (use (match_operand:HI 3 "memory_operand" "m"))]
17420 "TARGET_USE_FANCY_MATH_387
17421 && flag_unsafe_math_optimizations"
17422 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17423 [(set_attr "type" "frndint")
17424 (set_attr "i387_cw" "trunc")
17425 (set_attr "mode" "XF")])
17426
17427 (define_expand "btruncxf2"
17428 [(use (match_operand:XF 0 "register_operand" ""))
17429 (use (match_operand:XF 1 "register_operand" ""))]
17430 "TARGET_USE_FANCY_MATH_387
17431 && flag_unsafe_math_optimizations"
17432 {
17433 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17434 DONE;
17435 })
17436
17437 (define_expand "btruncdf2"
17438 [(use (match_operand:DF 0 "register_operand" ""))
17439 (use (match_operand:DF 1 "register_operand" ""))]
17440 "TARGET_USE_FANCY_MATH_387
17441 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17442 && flag_unsafe_math_optimizations"
17443 {
17444 rtx op0 = gen_reg_rtx (XFmode);
17445 rtx op1 = gen_reg_rtx (XFmode);
17446
17447 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17448 emit_insn (gen_frndintxf2_trunc (op0, op1));
17449
17450 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17451 DONE;
17452 })
17453
17454 (define_expand "btruncsf2"
17455 [(use (match_operand:SF 0 "register_operand" ""))
17456 (use (match_operand:SF 1 "register_operand" ""))]
17457 "TARGET_USE_FANCY_MATH_387
17458 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17459 && flag_unsafe_math_optimizations"
17460 {
17461 rtx op0 = gen_reg_rtx (XFmode);
17462 rtx op1 = gen_reg_rtx (XFmode);
17463
17464 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17465 emit_insn (gen_frndintxf2_trunc (op0, op1));
17466
17467 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17468 DONE;
17469 })
17470
17471 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17472 (define_insn_and_split "frndintxf2_mask_pm"
17473 [(set (match_operand:XF 0 "register_operand" "=f")
17474 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17475 UNSPEC_FRNDINT_MASK_PM))
17476 (clobber (reg:CC FLAGS_REG))]
17477 "TARGET_USE_FANCY_MATH_387
17478 && flag_unsafe_math_optimizations
17479 && !(reload_completed || reload_in_progress)"
17480 "#"
17481 "&& 1"
17482 [(const_int 0)]
17483 {
17484 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17485
17486 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17487 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17488
17489 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17490 operands[2], operands[3]));
17491 DONE;
17492 }
17493 [(set_attr "type" "frndint")
17494 (set_attr "i387_cw" "mask_pm")
17495 (set_attr "mode" "XF")])
17496
17497 (define_insn "frndintxf2_mask_pm_i387"
17498 [(set (match_operand:XF 0 "register_operand" "=f")
17499 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17500 UNSPEC_FRNDINT_MASK_PM))
17501 (use (match_operand:HI 2 "memory_operand" "m"))
17502 (use (match_operand:HI 3 "memory_operand" "m"))]
17503 "TARGET_USE_FANCY_MATH_387
17504 && flag_unsafe_math_optimizations"
17505 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17506 [(set_attr "type" "frndint")
17507 (set_attr "i387_cw" "mask_pm")
17508 (set_attr "mode" "XF")])
17509
17510 (define_expand "nearbyintxf2"
17511 [(use (match_operand:XF 0 "register_operand" ""))
17512 (use (match_operand:XF 1 "register_operand" ""))]
17513 "TARGET_USE_FANCY_MATH_387
17514 && flag_unsafe_math_optimizations"
17515 {
17516 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17517
17518 DONE;
17519 })
17520
17521 (define_expand "nearbyintdf2"
17522 [(use (match_operand:DF 0 "register_operand" ""))
17523 (use (match_operand:DF 1 "register_operand" ""))]
17524 "TARGET_USE_FANCY_MATH_387
17525 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17526 && flag_unsafe_math_optimizations"
17527 {
17528 rtx op0 = gen_reg_rtx (XFmode);
17529 rtx op1 = gen_reg_rtx (XFmode);
17530
17531 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17532 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17533
17534 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17535 DONE;
17536 })
17537
17538 (define_expand "nearbyintsf2"
17539 [(use (match_operand:SF 0 "register_operand" ""))
17540 (use (match_operand:SF 1 "register_operand" ""))]
17541 "TARGET_USE_FANCY_MATH_387
17542 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17543 && flag_unsafe_math_optimizations"
17544 {
17545 rtx op0 = gen_reg_rtx (XFmode);
17546 rtx op1 = gen_reg_rtx (XFmode);
17547
17548 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17549 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17550
17551 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17552 DONE;
17553 })
17554
17555 \f
17556 ;; Block operation instructions
17557
17558 (define_insn "cld"
17559 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17560 ""
17561 "cld"
17562 [(set_attr "type" "cld")])
17563
17564 (define_expand "movmemsi"
17565 [(use (match_operand:BLK 0 "memory_operand" ""))
17566 (use (match_operand:BLK 1 "memory_operand" ""))
17567 (use (match_operand:SI 2 "nonmemory_operand" ""))
17568 (use (match_operand:SI 3 "const_int_operand" ""))]
17569 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17570 {
17571 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17572 DONE;
17573 else
17574 FAIL;
17575 })
17576
17577 (define_expand "movmemdi"
17578 [(use (match_operand:BLK 0 "memory_operand" ""))
17579 (use (match_operand:BLK 1 "memory_operand" ""))
17580 (use (match_operand:DI 2 "nonmemory_operand" ""))
17581 (use (match_operand:DI 3 "const_int_operand" ""))]
17582 "TARGET_64BIT"
17583 {
17584 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17585 DONE;
17586 else
17587 FAIL;
17588 })
17589
17590 ;; Most CPUs don't like single string operations
17591 ;; Handle this case here to simplify previous expander.
17592
17593 (define_expand "strmov"
17594 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17595 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17596 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17597 (clobber (reg:CC FLAGS_REG))])
17598 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17599 (clobber (reg:CC FLAGS_REG))])]
17600 ""
17601 {
17602 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17603
17604 /* If .md ever supports :P for Pmode, these can be directly
17605 in the pattern above. */
17606 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17607 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17608
17609 if (TARGET_SINGLE_STRINGOP || optimize_size)
17610 {
17611 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17612 operands[2], operands[3],
17613 operands[5], operands[6]));
17614 DONE;
17615 }
17616
17617 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17618 })
17619
17620 (define_expand "strmov_singleop"
17621 [(parallel [(set (match_operand 1 "memory_operand" "")
17622 (match_operand 3 "memory_operand" ""))
17623 (set (match_operand 0 "register_operand" "")
17624 (match_operand 4 "" ""))
17625 (set (match_operand 2 "register_operand" "")
17626 (match_operand 5 "" ""))
17627 (use (reg:SI DIRFLAG_REG))])]
17628 "TARGET_SINGLE_STRINGOP || optimize_size"
17629 "")
17630
17631 (define_insn "*strmovdi_rex_1"
17632 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17633 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17634 (set (match_operand:DI 0 "register_operand" "=D")
17635 (plus:DI (match_dup 2)
17636 (const_int 8)))
17637 (set (match_operand:DI 1 "register_operand" "=S")
17638 (plus:DI (match_dup 3)
17639 (const_int 8)))
17640 (use (reg:SI DIRFLAG_REG))]
17641 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17642 "movsq"
17643 [(set_attr "type" "str")
17644 (set_attr "mode" "DI")
17645 (set_attr "memory" "both")])
17646
17647 (define_insn "*strmovsi_1"
17648 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17649 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17650 (set (match_operand:SI 0 "register_operand" "=D")
17651 (plus:SI (match_dup 2)
17652 (const_int 4)))
17653 (set (match_operand:SI 1 "register_operand" "=S")
17654 (plus:SI (match_dup 3)
17655 (const_int 4)))
17656 (use (reg:SI DIRFLAG_REG))]
17657 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17658 "{movsl|movsd}"
17659 [(set_attr "type" "str")
17660 (set_attr "mode" "SI")
17661 (set_attr "memory" "both")])
17662
17663 (define_insn "*strmovsi_rex_1"
17664 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17665 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17666 (set (match_operand:DI 0 "register_operand" "=D")
17667 (plus:DI (match_dup 2)
17668 (const_int 4)))
17669 (set (match_operand:DI 1 "register_operand" "=S")
17670 (plus:DI (match_dup 3)
17671 (const_int 4)))
17672 (use (reg:SI DIRFLAG_REG))]
17673 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17674 "{movsl|movsd}"
17675 [(set_attr "type" "str")
17676 (set_attr "mode" "SI")
17677 (set_attr "memory" "both")])
17678
17679 (define_insn "*strmovhi_1"
17680 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17681 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17682 (set (match_operand:SI 0 "register_operand" "=D")
17683 (plus:SI (match_dup 2)
17684 (const_int 2)))
17685 (set (match_operand:SI 1 "register_operand" "=S")
17686 (plus:SI (match_dup 3)
17687 (const_int 2)))
17688 (use (reg:SI DIRFLAG_REG))]
17689 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17690 "movsw"
17691 [(set_attr "type" "str")
17692 (set_attr "memory" "both")
17693 (set_attr "mode" "HI")])
17694
17695 (define_insn "*strmovhi_rex_1"
17696 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17697 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17698 (set (match_operand:DI 0 "register_operand" "=D")
17699 (plus:DI (match_dup 2)
17700 (const_int 2)))
17701 (set (match_operand:DI 1 "register_operand" "=S")
17702 (plus:DI (match_dup 3)
17703 (const_int 2)))
17704 (use (reg:SI DIRFLAG_REG))]
17705 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17706 "movsw"
17707 [(set_attr "type" "str")
17708 (set_attr "memory" "both")
17709 (set_attr "mode" "HI")])
17710
17711 (define_insn "*strmovqi_1"
17712 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17713 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17714 (set (match_operand:SI 0 "register_operand" "=D")
17715 (plus:SI (match_dup 2)
17716 (const_int 1)))
17717 (set (match_operand:SI 1 "register_operand" "=S")
17718 (plus:SI (match_dup 3)
17719 (const_int 1)))
17720 (use (reg:SI DIRFLAG_REG))]
17721 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17722 "movsb"
17723 [(set_attr "type" "str")
17724 (set_attr "memory" "both")
17725 (set_attr "mode" "QI")])
17726
17727 (define_insn "*strmovqi_rex_1"
17728 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17729 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17730 (set (match_operand:DI 0 "register_operand" "=D")
17731 (plus:DI (match_dup 2)
17732 (const_int 1)))
17733 (set (match_operand:DI 1 "register_operand" "=S")
17734 (plus:DI (match_dup 3)
17735 (const_int 1)))
17736 (use (reg:SI DIRFLAG_REG))]
17737 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17738 "movsb"
17739 [(set_attr "type" "str")
17740 (set_attr "memory" "both")
17741 (set_attr "mode" "QI")])
17742
17743 (define_expand "rep_mov"
17744 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17745 (set (match_operand 0 "register_operand" "")
17746 (match_operand 5 "" ""))
17747 (set (match_operand 2 "register_operand" "")
17748 (match_operand 6 "" ""))
17749 (set (match_operand 1 "memory_operand" "")
17750 (match_operand 3 "memory_operand" ""))
17751 (use (match_dup 4))
17752 (use (reg:SI DIRFLAG_REG))])]
17753 ""
17754 "")
17755
17756 (define_insn "*rep_movdi_rex64"
17757 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17758 (set (match_operand:DI 0 "register_operand" "=D")
17759 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17760 (const_int 3))
17761 (match_operand:DI 3 "register_operand" "0")))
17762 (set (match_operand:DI 1 "register_operand" "=S")
17763 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17764 (match_operand:DI 4 "register_operand" "1")))
17765 (set (mem:BLK (match_dup 3))
17766 (mem:BLK (match_dup 4)))
17767 (use (match_dup 5))
17768 (use (reg:SI DIRFLAG_REG))]
17769 "TARGET_64BIT"
17770 "{rep\;movsq|rep movsq}"
17771 [(set_attr "type" "str")
17772 (set_attr "prefix_rep" "1")
17773 (set_attr "memory" "both")
17774 (set_attr "mode" "DI")])
17775
17776 (define_insn "*rep_movsi"
17777 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17778 (set (match_operand:SI 0 "register_operand" "=D")
17779 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17780 (const_int 2))
17781 (match_operand:SI 3 "register_operand" "0")))
17782 (set (match_operand:SI 1 "register_operand" "=S")
17783 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17784 (match_operand:SI 4 "register_operand" "1")))
17785 (set (mem:BLK (match_dup 3))
17786 (mem:BLK (match_dup 4)))
17787 (use (match_dup 5))
17788 (use (reg:SI DIRFLAG_REG))]
17789 "!TARGET_64BIT"
17790 "{rep\;movsl|rep movsd}"
17791 [(set_attr "type" "str")
17792 (set_attr "prefix_rep" "1")
17793 (set_attr "memory" "both")
17794 (set_attr "mode" "SI")])
17795
17796 (define_insn "*rep_movsi_rex64"
17797 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17798 (set (match_operand:DI 0 "register_operand" "=D")
17799 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17800 (const_int 2))
17801 (match_operand:DI 3 "register_operand" "0")))
17802 (set (match_operand:DI 1 "register_operand" "=S")
17803 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17804 (match_operand:DI 4 "register_operand" "1")))
17805 (set (mem:BLK (match_dup 3))
17806 (mem:BLK (match_dup 4)))
17807 (use (match_dup 5))
17808 (use (reg:SI DIRFLAG_REG))]
17809 "TARGET_64BIT"
17810 "{rep\;movsl|rep movsd}"
17811 [(set_attr "type" "str")
17812 (set_attr "prefix_rep" "1")
17813 (set_attr "memory" "both")
17814 (set_attr "mode" "SI")])
17815
17816 (define_insn "*rep_movqi"
17817 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17818 (set (match_operand:SI 0 "register_operand" "=D")
17819 (plus:SI (match_operand:SI 3 "register_operand" "0")
17820 (match_operand:SI 5 "register_operand" "2")))
17821 (set (match_operand:SI 1 "register_operand" "=S")
17822 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17823 (set (mem:BLK (match_dup 3))
17824 (mem:BLK (match_dup 4)))
17825 (use (match_dup 5))
17826 (use (reg:SI DIRFLAG_REG))]
17827 "!TARGET_64BIT"
17828 "{rep\;movsb|rep movsb}"
17829 [(set_attr "type" "str")
17830 (set_attr "prefix_rep" "1")
17831 (set_attr "memory" "both")
17832 (set_attr "mode" "SI")])
17833
17834 (define_insn "*rep_movqi_rex64"
17835 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17836 (set (match_operand:DI 0 "register_operand" "=D")
17837 (plus:DI (match_operand:DI 3 "register_operand" "0")
17838 (match_operand:DI 5 "register_operand" "2")))
17839 (set (match_operand:DI 1 "register_operand" "=S")
17840 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17841 (set (mem:BLK (match_dup 3))
17842 (mem:BLK (match_dup 4)))
17843 (use (match_dup 5))
17844 (use (reg:SI DIRFLAG_REG))]
17845 "TARGET_64BIT"
17846 "{rep\;movsb|rep movsb}"
17847 [(set_attr "type" "str")
17848 (set_attr "prefix_rep" "1")
17849 (set_attr "memory" "both")
17850 (set_attr "mode" "SI")])
17851
17852 (define_expand "setmemsi"
17853 [(use (match_operand:BLK 0 "memory_operand" ""))
17854 (use (match_operand:SI 1 "nonmemory_operand" ""))
17855 (use (match_operand 2 "const_int_operand" ""))
17856 (use (match_operand 3 "const_int_operand" ""))]
17857 ""
17858 {
17859 /* If value to set is not zero, use the library routine. */
17860 if (operands[2] != const0_rtx)
17861 FAIL;
17862
17863 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17864 DONE;
17865 else
17866 FAIL;
17867 })
17868
17869 (define_expand "setmemdi"
17870 [(use (match_operand:BLK 0 "memory_operand" ""))
17871 (use (match_operand:DI 1 "nonmemory_operand" ""))
17872 (use (match_operand 2 "const_int_operand" ""))
17873 (use (match_operand 3 "const_int_operand" ""))]
17874 "TARGET_64BIT"
17875 {
17876 /* If value to set is not zero, use the library routine. */
17877 if (operands[2] != const0_rtx)
17878 FAIL;
17879
17880 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17881 DONE;
17882 else
17883 FAIL;
17884 })
17885
17886 ;; Most CPUs don't like single string operations
17887 ;; Handle this case here to simplify previous expander.
17888
17889 (define_expand "strset"
17890 [(set (match_operand 1 "memory_operand" "")
17891 (match_operand 2 "register_operand" ""))
17892 (parallel [(set (match_operand 0 "register_operand" "")
17893 (match_dup 3))
17894 (clobber (reg:CC FLAGS_REG))])]
17895 ""
17896 {
17897 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17898 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17899
17900 /* If .md ever supports :P for Pmode, this can be directly
17901 in the pattern above. */
17902 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17903 GEN_INT (GET_MODE_SIZE (GET_MODE
17904 (operands[2]))));
17905 if (TARGET_SINGLE_STRINGOP || optimize_size)
17906 {
17907 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17908 operands[3]));
17909 DONE;
17910 }
17911 })
17912
17913 (define_expand "strset_singleop"
17914 [(parallel [(set (match_operand 1 "memory_operand" "")
17915 (match_operand 2 "register_operand" ""))
17916 (set (match_operand 0 "register_operand" "")
17917 (match_operand 3 "" ""))
17918 (use (reg:SI DIRFLAG_REG))])]
17919 "TARGET_SINGLE_STRINGOP || optimize_size"
17920 "")
17921
17922 (define_insn "*strsetdi_rex_1"
17923 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17924 (match_operand:DI 2 "register_operand" "a"))
17925 (set (match_operand:DI 0 "register_operand" "=D")
17926 (plus:DI (match_dup 1)
17927 (const_int 8)))
17928 (use (reg:SI DIRFLAG_REG))]
17929 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17930 "stosq"
17931 [(set_attr "type" "str")
17932 (set_attr "memory" "store")
17933 (set_attr "mode" "DI")])
17934
17935 (define_insn "*strsetsi_1"
17936 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17937 (match_operand:SI 2 "register_operand" "a"))
17938 (set (match_operand:SI 0 "register_operand" "=D")
17939 (plus:SI (match_dup 1)
17940 (const_int 4)))
17941 (use (reg:SI DIRFLAG_REG))]
17942 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17943 "{stosl|stosd}"
17944 [(set_attr "type" "str")
17945 (set_attr "memory" "store")
17946 (set_attr "mode" "SI")])
17947
17948 (define_insn "*strsetsi_rex_1"
17949 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17950 (match_operand:SI 2 "register_operand" "a"))
17951 (set (match_operand:DI 0 "register_operand" "=D")
17952 (plus:DI (match_dup 1)
17953 (const_int 4)))
17954 (use (reg:SI DIRFLAG_REG))]
17955 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17956 "{stosl|stosd}"
17957 [(set_attr "type" "str")
17958 (set_attr "memory" "store")
17959 (set_attr "mode" "SI")])
17960
17961 (define_insn "*strsethi_1"
17962 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17963 (match_operand:HI 2 "register_operand" "a"))
17964 (set (match_operand:SI 0 "register_operand" "=D")
17965 (plus:SI (match_dup 1)
17966 (const_int 2)))
17967 (use (reg:SI DIRFLAG_REG))]
17968 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17969 "stosw"
17970 [(set_attr "type" "str")
17971 (set_attr "memory" "store")
17972 (set_attr "mode" "HI")])
17973
17974 (define_insn "*strsethi_rex_1"
17975 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17976 (match_operand:HI 2 "register_operand" "a"))
17977 (set (match_operand:DI 0 "register_operand" "=D")
17978 (plus:DI (match_dup 1)
17979 (const_int 2)))
17980 (use (reg:SI DIRFLAG_REG))]
17981 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17982 "stosw"
17983 [(set_attr "type" "str")
17984 (set_attr "memory" "store")
17985 (set_attr "mode" "HI")])
17986
17987 (define_insn "*strsetqi_1"
17988 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17989 (match_operand:QI 2 "register_operand" "a"))
17990 (set (match_operand:SI 0 "register_operand" "=D")
17991 (plus:SI (match_dup 1)
17992 (const_int 1)))
17993 (use (reg:SI DIRFLAG_REG))]
17994 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17995 "stosb"
17996 [(set_attr "type" "str")
17997 (set_attr "memory" "store")
17998 (set_attr "mode" "QI")])
17999
18000 (define_insn "*strsetqi_rex_1"
18001 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18002 (match_operand:QI 2 "register_operand" "a"))
18003 (set (match_operand:DI 0 "register_operand" "=D")
18004 (plus:DI (match_dup 1)
18005 (const_int 1)))
18006 (use (reg:SI DIRFLAG_REG))]
18007 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18008 "stosb"
18009 [(set_attr "type" "str")
18010 (set_attr "memory" "store")
18011 (set_attr "mode" "QI")])
18012
18013 (define_expand "rep_stos"
18014 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18015 (set (match_operand 0 "register_operand" "")
18016 (match_operand 4 "" ""))
18017 (set (match_operand 2 "memory_operand" "") (const_int 0))
18018 (use (match_operand 3 "register_operand" ""))
18019 (use (match_dup 1))
18020 (use (reg:SI DIRFLAG_REG))])]
18021 ""
18022 "")
18023
18024 (define_insn "*rep_stosdi_rex64"
18025 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18026 (set (match_operand:DI 0 "register_operand" "=D")
18027 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18028 (const_int 3))
18029 (match_operand:DI 3 "register_operand" "0")))
18030 (set (mem:BLK (match_dup 3))
18031 (const_int 0))
18032 (use (match_operand:DI 2 "register_operand" "a"))
18033 (use (match_dup 4))
18034 (use (reg:SI DIRFLAG_REG))]
18035 "TARGET_64BIT"
18036 "{rep\;stosq|rep stosq}"
18037 [(set_attr "type" "str")
18038 (set_attr "prefix_rep" "1")
18039 (set_attr "memory" "store")
18040 (set_attr "mode" "DI")])
18041
18042 (define_insn "*rep_stossi"
18043 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18044 (set (match_operand:SI 0 "register_operand" "=D")
18045 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18046 (const_int 2))
18047 (match_operand:SI 3 "register_operand" "0")))
18048 (set (mem:BLK (match_dup 3))
18049 (const_int 0))
18050 (use (match_operand:SI 2 "register_operand" "a"))
18051 (use (match_dup 4))
18052 (use (reg:SI DIRFLAG_REG))]
18053 "!TARGET_64BIT"
18054 "{rep\;stosl|rep stosd}"
18055 [(set_attr "type" "str")
18056 (set_attr "prefix_rep" "1")
18057 (set_attr "memory" "store")
18058 (set_attr "mode" "SI")])
18059
18060 (define_insn "*rep_stossi_rex64"
18061 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18062 (set (match_operand:DI 0 "register_operand" "=D")
18063 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18064 (const_int 2))
18065 (match_operand:DI 3 "register_operand" "0")))
18066 (set (mem:BLK (match_dup 3))
18067 (const_int 0))
18068 (use (match_operand:SI 2 "register_operand" "a"))
18069 (use (match_dup 4))
18070 (use (reg:SI DIRFLAG_REG))]
18071 "TARGET_64BIT"
18072 "{rep\;stosl|rep stosd}"
18073 [(set_attr "type" "str")
18074 (set_attr "prefix_rep" "1")
18075 (set_attr "memory" "store")
18076 (set_attr "mode" "SI")])
18077
18078 (define_insn "*rep_stosqi"
18079 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18080 (set (match_operand:SI 0 "register_operand" "=D")
18081 (plus:SI (match_operand:SI 3 "register_operand" "0")
18082 (match_operand:SI 4 "register_operand" "1")))
18083 (set (mem:BLK (match_dup 3))
18084 (const_int 0))
18085 (use (match_operand:QI 2 "register_operand" "a"))
18086 (use (match_dup 4))
18087 (use (reg:SI DIRFLAG_REG))]
18088 "!TARGET_64BIT"
18089 "{rep\;stosb|rep stosb}"
18090 [(set_attr "type" "str")
18091 (set_attr "prefix_rep" "1")
18092 (set_attr "memory" "store")
18093 (set_attr "mode" "QI")])
18094
18095 (define_insn "*rep_stosqi_rex64"
18096 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18097 (set (match_operand:DI 0 "register_operand" "=D")
18098 (plus:DI (match_operand:DI 3 "register_operand" "0")
18099 (match_operand:DI 4 "register_operand" "1")))
18100 (set (mem:BLK (match_dup 3))
18101 (const_int 0))
18102 (use (match_operand:QI 2 "register_operand" "a"))
18103 (use (match_dup 4))
18104 (use (reg:SI DIRFLAG_REG))]
18105 "TARGET_64BIT"
18106 "{rep\;stosb|rep stosb}"
18107 [(set_attr "type" "str")
18108 (set_attr "prefix_rep" "1")
18109 (set_attr "memory" "store")
18110 (set_attr "mode" "QI")])
18111
18112 (define_expand "cmpstrnsi"
18113 [(set (match_operand:SI 0 "register_operand" "")
18114 (compare:SI (match_operand:BLK 1 "general_operand" "")
18115 (match_operand:BLK 2 "general_operand" "")))
18116 (use (match_operand 3 "general_operand" ""))
18117 (use (match_operand 4 "immediate_operand" ""))]
18118 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18119 {
18120 rtx addr1, addr2, out, outlow, count, countreg, align;
18121
18122 /* Can't use this if the user has appropriated esi or edi. */
18123 if (global_regs[4] || global_regs[5])
18124 FAIL;
18125
18126 out = operands[0];
18127 if (GET_CODE (out) != REG)
18128 out = gen_reg_rtx (SImode);
18129
18130 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18131 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18132 if (addr1 != XEXP (operands[1], 0))
18133 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18134 if (addr2 != XEXP (operands[2], 0))
18135 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18136
18137 count = operands[3];
18138 countreg = ix86_zero_extend_to_Pmode (count);
18139
18140 /* %%% Iff we are testing strict equality, we can use known alignment
18141 to good advantage. This may be possible with combine, particularly
18142 once cc0 is dead. */
18143 align = operands[4];
18144
18145 emit_insn (gen_cld ());
18146 if (GET_CODE (count) == CONST_INT)
18147 {
18148 if (INTVAL (count) == 0)
18149 {
18150 emit_move_insn (operands[0], const0_rtx);
18151 DONE;
18152 }
18153 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18154 operands[1], operands[2]));
18155 }
18156 else
18157 {
18158 if (TARGET_64BIT)
18159 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18160 else
18161 emit_insn (gen_cmpsi_1 (countreg, countreg));
18162 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18163 operands[1], operands[2]));
18164 }
18165
18166 outlow = gen_lowpart (QImode, out);
18167 emit_insn (gen_cmpintqi (outlow));
18168 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18169
18170 if (operands[0] != out)
18171 emit_move_insn (operands[0], out);
18172
18173 DONE;
18174 })
18175
18176 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18177
18178 (define_expand "cmpintqi"
18179 [(set (match_dup 1)
18180 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18181 (set (match_dup 2)
18182 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18183 (parallel [(set (match_operand:QI 0 "register_operand" "")
18184 (minus:QI (match_dup 1)
18185 (match_dup 2)))
18186 (clobber (reg:CC FLAGS_REG))])]
18187 ""
18188 "operands[1] = gen_reg_rtx (QImode);
18189 operands[2] = gen_reg_rtx (QImode);")
18190
18191 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18192 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18193
18194 (define_expand "cmpstrnqi_nz_1"
18195 [(parallel [(set (reg:CC FLAGS_REG)
18196 (compare:CC (match_operand 4 "memory_operand" "")
18197 (match_operand 5 "memory_operand" "")))
18198 (use (match_operand 2 "register_operand" ""))
18199 (use (match_operand:SI 3 "immediate_operand" ""))
18200 (use (reg:SI DIRFLAG_REG))
18201 (clobber (match_operand 0 "register_operand" ""))
18202 (clobber (match_operand 1 "register_operand" ""))
18203 (clobber (match_dup 2))])]
18204 ""
18205 "")
18206
18207 (define_insn "*cmpstrnqi_nz_1"
18208 [(set (reg:CC FLAGS_REG)
18209 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18210 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18211 (use (match_operand:SI 6 "register_operand" "2"))
18212 (use (match_operand:SI 3 "immediate_operand" "i"))
18213 (use (reg:SI DIRFLAG_REG))
18214 (clobber (match_operand:SI 0 "register_operand" "=S"))
18215 (clobber (match_operand:SI 1 "register_operand" "=D"))
18216 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18217 "!TARGET_64BIT"
18218 "repz{\;| }cmpsb"
18219 [(set_attr "type" "str")
18220 (set_attr "mode" "QI")
18221 (set_attr "prefix_rep" "1")])
18222
18223 (define_insn "*cmpstrnqi_nz_rex_1"
18224 [(set (reg:CC FLAGS_REG)
18225 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18226 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18227 (use (match_operand:DI 6 "register_operand" "2"))
18228 (use (match_operand:SI 3 "immediate_operand" "i"))
18229 (use (reg:SI DIRFLAG_REG))
18230 (clobber (match_operand:DI 0 "register_operand" "=S"))
18231 (clobber (match_operand:DI 1 "register_operand" "=D"))
18232 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18233 "TARGET_64BIT"
18234 "repz{\;| }cmpsb"
18235 [(set_attr "type" "str")
18236 (set_attr "mode" "QI")
18237 (set_attr "prefix_rep" "1")])
18238
18239 ;; The same, but the count is not known to not be zero.
18240
18241 (define_expand "cmpstrnqi_1"
18242 [(parallel [(set (reg:CC FLAGS_REG)
18243 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18244 (const_int 0))
18245 (compare:CC (match_operand 4 "memory_operand" "")
18246 (match_operand 5 "memory_operand" ""))
18247 (const_int 0)))
18248 (use (match_operand:SI 3 "immediate_operand" ""))
18249 (use (reg:CC FLAGS_REG))
18250 (use (reg:SI DIRFLAG_REG))
18251 (clobber (match_operand 0 "register_operand" ""))
18252 (clobber (match_operand 1 "register_operand" ""))
18253 (clobber (match_dup 2))])]
18254 ""
18255 "")
18256
18257 (define_insn "*cmpstrnqi_1"
18258 [(set (reg:CC FLAGS_REG)
18259 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18260 (const_int 0))
18261 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18262 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18263 (const_int 0)))
18264 (use (match_operand:SI 3 "immediate_operand" "i"))
18265 (use (reg:CC FLAGS_REG))
18266 (use (reg:SI DIRFLAG_REG))
18267 (clobber (match_operand:SI 0 "register_operand" "=S"))
18268 (clobber (match_operand:SI 1 "register_operand" "=D"))
18269 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18270 "!TARGET_64BIT"
18271 "repz{\;| }cmpsb"
18272 [(set_attr "type" "str")
18273 (set_attr "mode" "QI")
18274 (set_attr "prefix_rep" "1")])
18275
18276 (define_insn "*cmpstrnqi_rex_1"
18277 [(set (reg:CC FLAGS_REG)
18278 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18279 (const_int 0))
18280 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18281 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18282 (const_int 0)))
18283 (use (match_operand:SI 3 "immediate_operand" "i"))
18284 (use (reg:CC FLAGS_REG))
18285 (use (reg:SI DIRFLAG_REG))
18286 (clobber (match_operand:DI 0 "register_operand" "=S"))
18287 (clobber (match_operand:DI 1 "register_operand" "=D"))
18288 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18289 "TARGET_64BIT"
18290 "repz{\;| }cmpsb"
18291 [(set_attr "type" "str")
18292 (set_attr "mode" "QI")
18293 (set_attr "prefix_rep" "1")])
18294
18295 (define_expand "strlensi"
18296 [(set (match_operand:SI 0 "register_operand" "")
18297 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18298 (match_operand:QI 2 "immediate_operand" "")
18299 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18300 ""
18301 {
18302 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18303 DONE;
18304 else
18305 FAIL;
18306 })
18307
18308 (define_expand "strlendi"
18309 [(set (match_operand:DI 0 "register_operand" "")
18310 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18311 (match_operand:QI 2 "immediate_operand" "")
18312 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18313 ""
18314 {
18315 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18316 DONE;
18317 else
18318 FAIL;
18319 })
18320
18321 (define_expand "strlenqi_1"
18322 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18323 (use (reg:SI DIRFLAG_REG))
18324 (clobber (match_operand 1 "register_operand" ""))
18325 (clobber (reg:CC FLAGS_REG))])]
18326 ""
18327 "")
18328
18329 (define_insn "*strlenqi_1"
18330 [(set (match_operand:SI 0 "register_operand" "=&c")
18331 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18332 (match_operand:QI 2 "register_operand" "a")
18333 (match_operand:SI 3 "immediate_operand" "i")
18334 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18335 (use (reg:SI DIRFLAG_REG))
18336 (clobber (match_operand:SI 1 "register_operand" "=D"))
18337 (clobber (reg:CC FLAGS_REG))]
18338 "!TARGET_64BIT"
18339 "repnz{\;| }scasb"
18340 [(set_attr "type" "str")
18341 (set_attr "mode" "QI")
18342 (set_attr "prefix_rep" "1")])
18343
18344 (define_insn "*strlenqi_rex_1"
18345 [(set (match_operand:DI 0 "register_operand" "=&c")
18346 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18347 (match_operand:QI 2 "register_operand" "a")
18348 (match_operand:DI 3 "immediate_operand" "i")
18349 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18350 (use (reg:SI DIRFLAG_REG))
18351 (clobber (match_operand:DI 1 "register_operand" "=D"))
18352 (clobber (reg:CC FLAGS_REG))]
18353 "TARGET_64BIT"
18354 "repnz{\;| }scasb"
18355 [(set_attr "type" "str")
18356 (set_attr "mode" "QI")
18357 (set_attr "prefix_rep" "1")])
18358
18359 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18360 ;; handled in combine, but it is not currently up to the task.
18361 ;; When used for their truth value, the cmpstrn* expanders generate
18362 ;; code like this:
18363 ;;
18364 ;; repz cmpsb
18365 ;; seta %al
18366 ;; setb %dl
18367 ;; cmpb %al, %dl
18368 ;; jcc label
18369 ;;
18370 ;; The intermediate three instructions are unnecessary.
18371
18372 ;; This one handles cmpstrn*_nz_1...
18373 (define_peephole2
18374 [(parallel[
18375 (set (reg:CC FLAGS_REG)
18376 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18377 (mem:BLK (match_operand 5 "register_operand" ""))))
18378 (use (match_operand 6 "register_operand" ""))
18379 (use (match_operand:SI 3 "immediate_operand" ""))
18380 (use (reg:SI DIRFLAG_REG))
18381 (clobber (match_operand 0 "register_operand" ""))
18382 (clobber (match_operand 1 "register_operand" ""))
18383 (clobber (match_operand 2 "register_operand" ""))])
18384 (set (match_operand:QI 7 "register_operand" "")
18385 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18386 (set (match_operand:QI 8 "register_operand" "")
18387 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18388 (set (reg FLAGS_REG)
18389 (compare (match_dup 7) (match_dup 8)))
18390 ]
18391 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18392 [(parallel[
18393 (set (reg:CC FLAGS_REG)
18394 (compare:CC (mem:BLK (match_dup 4))
18395 (mem:BLK (match_dup 5))))
18396 (use (match_dup 6))
18397 (use (match_dup 3))
18398 (use (reg:SI DIRFLAG_REG))
18399 (clobber (match_dup 0))
18400 (clobber (match_dup 1))
18401 (clobber (match_dup 2))])]
18402 "")
18403
18404 ;; ...and this one handles cmpstrn*_1.
18405 (define_peephole2
18406 [(parallel[
18407 (set (reg:CC FLAGS_REG)
18408 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18409 (const_int 0))
18410 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18411 (mem:BLK (match_operand 5 "register_operand" "")))
18412 (const_int 0)))
18413 (use (match_operand:SI 3 "immediate_operand" ""))
18414 (use (reg:CC FLAGS_REG))
18415 (use (reg:SI DIRFLAG_REG))
18416 (clobber (match_operand 0 "register_operand" ""))
18417 (clobber (match_operand 1 "register_operand" ""))
18418 (clobber (match_operand 2 "register_operand" ""))])
18419 (set (match_operand:QI 7 "register_operand" "")
18420 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18421 (set (match_operand:QI 8 "register_operand" "")
18422 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18423 (set (reg FLAGS_REG)
18424 (compare (match_dup 7) (match_dup 8)))
18425 ]
18426 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18427 [(parallel[
18428 (set (reg:CC FLAGS_REG)
18429 (if_then_else:CC (ne (match_dup 6)
18430 (const_int 0))
18431 (compare:CC (mem:BLK (match_dup 4))
18432 (mem:BLK (match_dup 5)))
18433 (const_int 0)))
18434 (use (match_dup 3))
18435 (use (reg:CC FLAGS_REG))
18436 (use (reg:SI DIRFLAG_REG))
18437 (clobber (match_dup 0))
18438 (clobber (match_dup 1))
18439 (clobber (match_dup 2))])]
18440 "")
18441
18442
18443 \f
18444 ;; Conditional move instructions.
18445
18446 (define_expand "movdicc"
18447 [(set (match_operand:DI 0 "register_operand" "")
18448 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18449 (match_operand:DI 2 "general_operand" "")
18450 (match_operand:DI 3 "general_operand" "")))]
18451 "TARGET_64BIT"
18452 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18453
18454 (define_insn "x86_movdicc_0_m1_rex64"
18455 [(set (match_operand:DI 0 "register_operand" "=r")
18456 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18457 (const_int -1)
18458 (const_int 0)))
18459 (clobber (reg:CC FLAGS_REG))]
18460 "TARGET_64BIT"
18461 "sbb{q}\t%0, %0"
18462 ; Since we don't have the proper number of operands for an alu insn,
18463 ; fill in all the blanks.
18464 [(set_attr "type" "alu")
18465 (set_attr "pent_pair" "pu")
18466 (set_attr "memory" "none")
18467 (set_attr "imm_disp" "false")
18468 (set_attr "mode" "DI")
18469 (set_attr "length_immediate" "0")])
18470
18471 (define_insn "*movdicc_c_rex64"
18472 [(set (match_operand:DI 0 "register_operand" "=r,r")
18473 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18474 [(reg FLAGS_REG) (const_int 0)])
18475 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18476 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18477 "TARGET_64BIT && TARGET_CMOVE
18478 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18479 "@
18480 cmov%O2%C1\t{%2, %0|%0, %2}
18481 cmov%O2%c1\t{%3, %0|%0, %3}"
18482 [(set_attr "type" "icmov")
18483 (set_attr "mode" "DI")])
18484
18485 (define_expand "movsicc"
18486 [(set (match_operand:SI 0 "register_operand" "")
18487 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18488 (match_operand:SI 2 "general_operand" "")
18489 (match_operand:SI 3 "general_operand" "")))]
18490 ""
18491 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18492
18493 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18494 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18495 ;; So just document what we're doing explicitly.
18496
18497 (define_insn "x86_movsicc_0_m1"
18498 [(set (match_operand:SI 0 "register_operand" "=r")
18499 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18500 (const_int -1)
18501 (const_int 0)))
18502 (clobber (reg:CC FLAGS_REG))]
18503 ""
18504 "sbb{l}\t%0, %0"
18505 ; Since we don't have the proper number of operands for an alu insn,
18506 ; fill in all the blanks.
18507 [(set_attr "type" "alu")
18508 (set_attr "pent_pair" "pu")
18509 (set_attr "memory" "none")
18510 (set_attr "imm_disp" "false")
18511 (set_attr "mode" "SI")
18512 (set_attr "length_immediate" "0")])
18513
18514 (define_insn "*movsicc_noc"
18515 [(set (match_operand:SI 0 "register_operand" "=r,r")
18516 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18517 [(reg FLAGS_REG) (const_int 0)])
18518 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18519 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18520 "TARGET_CMOVE
18521 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18522 "@
18523 cmov%O2%C1\t{%2, %0|%0, %2}
18524 cmov%O2%c1\t{%3, %0|%0, %3}"
18525 [(set_attr "type" "icmov")
18526 (set_attr "mode" "SI")])
18527
18528 (define_expand "movhicc"
18529 [(set (match_operand:HI 0 "register_operand" "")
18530 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18531 (match_operand:HI 2 "general_operand" "")
18532 (match_operand:HI 3 "general_operand" "")))]
18533 "TARGET_HIMODE_MATH"
18534 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18535
18536 (define_insn "*movhicc_noc"
18537 [(set (match_operand:HI 0 "register_operand" "=r,r")
18538 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18539 [(reg FLAGS_REG) (const_int 0)])
18540 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18541 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18542 "TARGET_CMOVE
18543 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18544 "@
18545 cmov%O2%C1\t{%2, %0|%0, %2}
18546 cmov%O2%c1\t{%3, %0|%0, %3}"
18547 [(set_attr "type" "icmov")
18548 (set_attr "mode" "HI")])
18549
18550 (define_expand "movqicc"
18551 [(set (match_operand:QI 0 "register_operand" "")
18552 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18553 (match_operand:QI 2 "general_operand" "")
18554 (match_operand:QI 3 "general_operand" "")))]
18555 "TARGET_QIMODE_MATH"
18556 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18557
18558 (define_insn_and_split "*movqicc_noc"
18559 [(set (match_operand:QI 0 "register_operand" "=r,r")
18560 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18561 [(match_operand 4 "flags_reg_operand" "")
18562 (const_int 0)])
18563 (match_operand:QI 2 "register_operand" "r,0")
18564 (match_operand:QI 3 "register_operand" "0,r")))]
18565 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18566 "#"
18567 "&& reload_completed"
18568 [(set (match_dup 0)
18569 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18570 (match_dup 2)
18571 (match_dup 3)))]
18572 "operands[0] = gen_lowpart (SImode, operands[0]);
18573 operands[2] = gen_lowpart (SImode, operands[2]);
18574 operands[3] = gen_lowpart (SImode, operands[3]);"
18575 [(set_attr "type" "icmov")
18576 (set_attr "mode" "SI")])
18577
18578 (define_expand "movsfcc"
18579 [(set (match_operand:SF 0 "register_operand" "")
18580 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18581 (match_operand:SF 2 "register_operand" "")
18582 (match_operand:SF 3 "register_operand" "")))]
18583 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18584 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18585
18586 (define_insn "*movsfcc_1_387"
18587 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18588 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18589 [(reg FLAGS_REG) (const_int 0)])
18590 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18591 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18592 "TARGET_80387 && TARGET_CMOVE
18593 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18594 "@
18595 fcmov%F1\t{%2, %0|%0, %2}
18596 fcmov%f1\t{%3, %0|%0, %3}
18597 cmov%O2%C1\t{%2, %0|%0, %2}
18598 cmov%O2%c1\t{%3, %0|%0, %3}"
18599 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18600 (set_attr "mode" "SF,SF,SI,SI")])
18601
18602 (define_expand "movdfcc"
18603 [(set (match_operand:DF 0 "register_operand" "")
18604 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18605 (match_operand:DF 2 "register_operand" "")
18606 (match_operand:DF 3 "register_operand" "")))]
18607 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18608 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18609
18610 (define_insn "*movdfcc_1"
18611 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18612 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18613 [(reg FLAGS_REG) (const_int 0)])
18614 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18615 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18616 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18617 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18618 "@
18619 fcmov%F1\t{%2, %0|%0, %2}
18620 fcmov%f1\t{%3, %0|%0, %3}
18621 #
18622 #"
18623 [(set_attr "type" "fcmov,fcmov,multi,multi")
18624 (set_attr "mode" "DF")])
18625
18626 (define_insn "*movdfcc_1_rex64"
18627 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18628 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18629 [(reg FLAGS_REG) (const_int 0)])
18630 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18631 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18632 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18633 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18634 "@
18635 fcmov%F1\t{%2, %0|%0, %2}
18636 fcmov%f1\t{%3, %0|%0, %3}
18637 cmov%O2%C1\t{%2, %0|%0, %2}
18638 cmov%O2%c1\t{%3, %0|%0, %3}"
18639 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18640 (set_attr "mode" "DF")])
18641
18642 (define_split
18643 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18644 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18645 [(match_operand 4 "flags_reg_operand" "")
18646 (const_int 0)])
18647 (match_operand:DF 2 "nonimmediate_operand" "")
18648 (match_operand:DF 3 "nonimmediate_operand" "")))]
18649 "!TARGET_64BIT && reload_completed"
18650 [(set (match_dup 2)
18651 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18652 (match_dup 5)
18653 (match_dup 7)))
18654 (set (match_dup 3)
18655 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18656 (match_dup 6)
18657 (match_dup 8)))]
18658 "split_di (operands+2, 1, operands+5, operands+6);
18659 split_di (operands+3, 1, operands+7, operands+8);
18660 split_di (operands, 1, operands+2, operands+3);")
18661
18662 (define_expand "movxfcc"
18663 [(set (match_operand:XF 0 "register_operand" "")
18664 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18665 (match_operand:XF 2 "register_operand" "")
18666 (match_operand:XF 3 "register_operand" "")))]
18667 "TARGET_80387 && TARGET_CMOVE"
18668 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18669
18670 (define_insn "*movxfcc_1"
18671 [(set (match_operand:XF 0 "register_operand" "=f,f")
18672 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18673 [(reg FLAGS_REG) (const_int 0)])
18674 (match_operand:XF 2 "register_operand" "f,0")
18675 (match_operand:XF 3 "register_operand" "0,f")))]
18676 "TARGET_80387 && TARGET_CMOVE"
18677 "@
18678 fcmov%F1\t{%2, %0|%0, %2}
18679 fcmov%f1\t{%3, %0|%0, %3}"
18680 [(set_attr "type" "fcmov")
18681 (set_attr "mode" "XF")])
18682
18683 ;; These versions of the min/max patterns are intentionally ignorant of
18684 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18685 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18686 ;; are undefined in this condition, we're certain this is correct.
18687
18688 (define_insn "sminsf3"
18689 [(set (match_operand:SF 0 "register_operand" "=x")
18690 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18691 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18692 "TARGET_SSE_MATH"
18693 "minss\t{%2, %0|%0, %2}"
18694 [(set_attr "type" "sseadd")
18695 (set_attr "mode" "SF")])
18696
18697 (define_insn "smaxsf3"
18698 [(set (match_operand:SF 0 "register_operand" "=x")
18699 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18700 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18701 "TARGET_SSE_MATH"
18702 "maxss\t{%2, %0|%0, %2}"
18703 [(set_attr "type" "sseadd")
18704 (set_attr "mode" "SF")])
18705
18706 (define_insn "smindf3"
18707 [(set (match_operand:DF 0 "register_operand" "=x")
18708 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18709 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18710 "TARGET_SSE2 && TARGET_SSE_MATH"
18711 "minsd\t{%2, %0|%0, %2}"
18712 [(set_attr "type" "sseadd")
18713 (set_attr "mode" "DF")])
18714
18715 (define_insn "smaxdf3"
18716 [(set (match_operand:DF 0 "register_operand" "=x")
18717 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18718 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18719 "TARGET_SSE2 && TARGET_SSE_MATH"
18720 "maxsd\t{%2, %0|%0, %2}"
18721 [(set_attr "type" "sseadd")
18722 (set_attr "mode" "DF")])
18723
18724 ;; These versions of the min/max patterns implement exactly the operations
18725 ;; min = (op1 < op2 ? op1 : op2)
18726 ;; max = (!(op1 < op2) ? op1 : op2)
18727 ;; Their operands are not commutative, and thus they may be used in the
18728 ;; presence of -0.0 and NaN.
18729
18730 (define_insn "*ieee_sminsf3"
18731 [(set (match_operand:SF 0 "register_operand" "=x")
18732 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18733 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18734 UNSPEC_IEEE_MIN))]
18735 "TARGET_SSE_MATH"
18736 "minss\t{%2, %0|%0, %2}"
18737 [(set_attr "type" "sseadd")
18738 (set_attr "mode" "SF")])
18739
18740 (define_insn "*ieee_smaxsf3"
18741 [(set (match_operand:SF 0 "register_operand" "=x")
18742 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18743 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18744 UNSPEC_IEEE_MAX))]
18745 "TARGET_SSE_MATH"
18746 "maxss\t{%2, %0|%0, %2}"
18747 [(set_attr "type" "sseadd")
18748 (set_attr "mode" "SF")])
18749
18750 (define_insn "*ieee_smindf3"
18751 [(set (match_operand:DF 0 "register_operand" "=x")
18752 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18753 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18754 UNSPEC_IEEE_MIN))]
18755 "TARGET_SSE2 && TARGET_SSE_MATH"
18756 "minsd\t{%2, %0|%0, %2}"
18757 [(set_attr "type" "sseadd")
18758 (set_attr "mode" "DF")])
18759
18760 (define_insn "*ieee_smaxdf3"
18761 [(set (match_operand:DF 0 "register_operand" "=x")
18762 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18763 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18764 UNSPEC_IEEE_MAX))]
18765 "TARGET_SSE2 && TARGET_SSE_MATH"
18766 "maxsd\t{%2, %0|%0, %2}"
18767 [(set_attr "type" "sseadd")
18768 (set_attr "mode" "DF")])
18769
18770 ;; Conditional addition patterns
18771 (define_expand "addqicc"
18772 [(match_operand:QI 0 "register_operand" "")
18773 (match_operand 1 "comparison_operator" "")
18774 (match_operand:QI 2 "register_operand" "")
18775 (match_operand:QI 3 "const_int_operand" "")]
18776 ""
18777 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18778
18779 (define_expand "addhicc"
18780 [(match_operand:HI 0 "register_operand" "")
18781 (match_operand 1 "comparison_operator" "")
18782 (match_operand:HI 2 "register_operand" "")
18783 (match_operand:HI 3 "const_int_operand" "")]
18784 ""
18785 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18786
18787 (define_expand "addsicc"
18788 [(match_operand:SI 0 "register_operand" "")
18789 (match_operand 1 "comparison_operator" "")
18790 (match_operand:SI 2 "register_operand" "")
18791 (match_operand:SI 3 "const_int_operand" "")]
18792 ""
18793 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18794
18795 (define_expand "adddicc"
18796 [(match_operand:DI 0 "register_operand" "")
18797 (match_operand 1 "comparison_operator" "")
18798 (match_operand:DI 2 "register_operand" "")
18799 (match_operand:DI 3 "const_int_operand" "")]
18800 "TARGET_64BIT"
18801 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18802
18803 \f
18804 ;; Misc patterns (?)
18805
18806 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18807 ;; Otherwise there will be nothing to keep
18808 ;;
18809 ;; [(set (reg ebp) (reg esp))]
18810 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18811 ;; (clobber (eflags)]
18812 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18813 ;;
18814 ;; in proper program order.
18815 (define_insn "pro_epilogue_adjust_stack_1"
18816 [(set (match_operand:SI 0 "register_operand" "=r,r")
18817 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18818 (match_operand:SI 2 "immediate_operand" "i,i")))
18819 (clobber (reg:CC FLAGS_REG))
18820 (clobber (mem:BLK (scratch)))]
18821 "!TARGET_64BIT"
18822 {
18823 switch (get_attr_type (insn))
18824 {
18825 case TYPE_IMOV:
18826 return "mov{l}\t{%1, %0|%0, %1}";
18827
18828 case TYPE_ALU:
18829 if (GET_CODE (operands[2]) == CONST_INT
18830 && (INTVAL (operands[2]) == 128
18831 || (INTVAL (operands[2]) < 0
18832 && INTVAL (operands[2]) != -128)))
18833 {
18834 operands[2] = GEN_INT (-INTVAL (operands[2]));
18835 return "sub{l}\t{%2, %0|%0, %2}";
18836 }
18837 return "add{l}\t{%2, %0|%0, %2}";
18838
18839 case TYPE_LEA:
18840 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18841 return "lea{l}\t{%a2, %0|%0, %a2}";
18842
18843 default:
18844 gcc_unreachable ();
18845 }
18846 }
18847 [(set (attr "type")
18848 (cond [(eq_attr "alternative" "0")
18849 (const_string "alu")
18850 (match_operand:SI 2 "const0_operand" "")
18851 (const_string "imov")
18852 ]
18853 (const_string "lea")))
18854 (set_attr "mode" "SI")])
18855
18856 (define_insn "pro_epilogue_adjust_stack_rex64"
18857 [(set (match_operand:DI 0 "register_operand" "=r,r")
18858 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18859 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18860 (clobber (reg:CC FLAGS_REG))
18861 (clobber (mem:BLK (scratch)))]
18862 "TARGET_64BIT"
18863 {
18864 switch (get_attr_type (insn))
18865 {
18866 case TYPE_IMOV:
18867 return "mov{q}\t{%1, %0|%0, %1}";
18868
18869 case TYPE_ALU:
18870 if (GET_CODE (operands[2]) == CONST_INT
18871 /* Avoid overflows. */
18872 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18873 && (INTVAL (operands[2]) == 128
18874 || (INTVAL (operands[2]) < 0
18875 && INTVAL (operands[2]) != -128)))
18876 {
18877 operands[2] = GEN_INT (-INTVAL (operands[2]));
18878 return "sub{q}\t{%2, %0|%0, %2}";
18879 }
18880 return "add{q}\t{%2, %0|%0, %2}";
18881
18882 case TYPE_LEA:
18883 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18884 return "lea{q}\t{%a2, %0|%0, %a2}";
18885
18886 default:
18887 gcc_unreachable ();
18888 }
18889 }
18890 [(set (attr "type")
18891 (cond [(eq_attr "alternative" "0")
18892 (const_string "alu")
18893 (match_operand:DI 2 "const0_operand" "")
18894 (const_string "imov")
18895 ]
18896 (const_string "lea")))
18897 (set_attr "mode" "DI")])
18898
18899 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18900 [(set (match_operand:DI 0 "register_operand" "=r,r")
18901 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18902 (match_operand:DI 3 "immediate_operand" "i,i")))
18903 (use (match_operand:DI 2 "register_operand" "r,r"))
18904 (clobber (reg:CC FLAGS_REG))
18905 (clobber (mem:BLK (scratch)))]
18906 "TARGET_64BIT"
18907 {
18908 switch (get_attr_type (insn))
18909 {
18910 case TYPE_ALU:
18911 return "add{q}\t{%2, %0|%0, %2}";
18912
18913 case TYPE_LEA:
18914 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18915 return "lea{q}\t{%a2, %0|%0, %a2}";
18916
18917 default:
18918 gcc_unreachable ();
18919 }
18920 }
18921 [(set_attr "type" "alu,lea")
18922 (set_attr "mode" "DI")])
18923
18924 (define_expand "allocate_stack_worker"
18925 [(match_operand:SI 0 "register_operand" "")]
18926 "TARGET_STACK_PROBE"
18927 {
18928 if (reload_completed)
18929 {
18930 if (TARGET_64BIT)
18931 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18932 else
18933 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18934 }
18935 else
18936 {
18937 if (TARGET_64BIT)
18938 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18939 else
18940 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18941 }
18942 DONE;
18943 })
18944
18945 (define_insn "allocate_stack_worker_1"
18946 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18947 UNSPECV_STACK_PROBE)
18948 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18949 (clobber (match_scratch:SI 1 "=0"))
18950 (clobber (reg:CC FLAGS_REG))]
18951 "!TARGET_64BIT && TARGET_STACK_PROBE"
18952 "call\t__alloca"
18953 [(set_attr "type" "multi")
18954 (set_attr "length" "5")])
18955
18956 (define_expand "allocate_stack_worker_postreload"
18957 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18958 UNSPECV_STACK_PROBE)
18959 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18960 (clobber (match_dup 0))
18961 (clobber (reg:CC FLAGS_REG))])]
18962 ""
18963 "")
18964
18965 (define_insn "allocate_stack_worker_rex64"
18966 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18967 UNSPECV_STACK_PROBE)
18968 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18969 (clobber (match_scratch:DI 1 "=0"))
18970 (clobber (reg:CC FLAGS_REG))]
18971 "TARGET_64BIT && TARGET_STACK_PROBE"
18972 "call\t__alloca"
18973 [(set_attr "type" "multi")
18974 (set_attr "length" "5")])
18975
18976 (define_expand "allocate_stack_worker_rex64_postreload"
18977 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18978 UNSPECV_STACK_PROBE)
18979 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18980 (clobber (match_dup 0))
18981 (clobber (reg:CC FLAGS_REG))])]
18982 ""
18983 "")
18984
18985 (define_expand "allocate_stack"
18986 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18987 (minus:SI (reg:SI SP_REG)
18988 (match_operand:SI 1 "general_operand" "")))
18989 (clobber (reg:CC FLAGS_REG))])
18990 (parallel [(set (reg:SI SP_REG)
18991 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18992 (clobber (reg:CC FLAGS_REG))])]
18993 "TARGET_STACK_PROBE"
18994 {
18995 #ifdef CHECK_STACK_LIMIT
18996 if (GET_CODE (operands[1]) == CONST_INT
18997 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18998 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18999 operands[1]));
19000 else
19001 #endif
19002 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19003 operands[1])));
19004
19005 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19006 DONE;
19007 })
19008
19009 (define_expand "builtin_setjmp_receiver"
19010 [(label_ref (match_operand 0 "" ""))]
19011 "!TARGET_64BIT && flag_pic"
19012 {
19013 if (TARGET_MACHO)
19014 {
19015 rtx xops[3];
19016 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19017 rtx label_rtx = gen_label_rtx ();
19018 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19019 xops[0] = xops[1] = picreg;
19020 xops[2] = gen_rtx_CONST (SImode,
19021 gen_rtx_MINUS (SImode,
19022 gen_rtx_LABEL_REF (SImode, label_rtx),
19023 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19024 ix86_expand_binary_operator (MINUS, SImode, xops);
19025 }
19026 else
19027 emit_insn (gen_set_got (pic_offset_table_rtx));
19028 DONE;
19029 })
19030 \f
19031 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19032
19033 (define_split
19034 [(set (match_operand 0 "register_operand" "")
19035 (match_operator 3 "promotable_binary_operator"
19036 [(match_operand 1 "register_operand" "")
19037 (match_operand 2 "aligned_operand" "")]))
19038 (clobber (reg:CC FLAGS_REG))]
19039 "! TARGET_PARTIAL_REG_STALL && reload_completed
19040 && ((GET_MODE (operands[0]) == HImode
19041 && ((!optimize_size && !TARGET_FAST_PREFIX)
19042 /* ??? next two lines just !satisfies_constraint_K (...) */
19043 || GET_CODE (operands[2]) != CONST_INT
19044 || satisfies_constraint_K (operands[2])))
19045 || (GET_MODE (operands[0]) == QImode
19046 && (TARGET_PROMOTE_QImode || optimize_size)))"
19047 [(parallel [(set (match_dup 0)
19048 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19049 (clobber (reg:CC FLAGS_REG))])]
19050 "operands[0] = gen_lowpart (SImode, operands[0]);
19051 operands[1] = gen_lowpart (SImode, operands[1]);
19052 if (GET_CODE (operands[3]) != ASHIFT)
19053 operands[2] = gen_lowpart (SImode, operands[2]);
19054 PUT_MODE (operands[3], SImode);")
19055
19056 ; Promote the QImode tests, as i386 has encoding of the AND
19057 ; instruction with 32-bit sign-extended immediate and thus the
19058 ; instruction size is unchanged, except in the %eax case for
19059 ; which it is increased by one byte, hence the ! optimize_size.
19060 (define_split
19061 [(set (match_operand 0 "flags_reg_operand" "")
19062 (match_operator 2 "compare_operator"
19063 [(and (match_operand 3 "aligned_operand" "")
19064 (match_operand 4 "const_int_operand" ""))
19065 (const_int 0)]))
19066 (set (match_operand 1 "register_operand" "")
19067 (and (match_dup 3) (match_dup 4)))]
19068 "! TARGET_PARTIAL_REG_STALL && reload_completed
19069 /* Ensure that the operand will remain sign-extended immediate. */
19070 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19071 && ! optimize_size
19072 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19073 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19074 [(parallel [(set (match_dup 0)
19075 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19076 (const_int 0)]))
19077 (set (match_dup 1)
19078 (and:SI (match_dup 3) (match_dup 4)))])]
19079 {
19080 operands[4]
19081 = gen_int_mode (INTVAL (operands[4])
19082 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19083 operands[1] = gen_lowpart (SImode, operands[1]);
19084 operands[3] = gen_lowpart (SImode, operands[3]);
19085 })
19086
19087 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19088 ; the TEST instruction with 32-bit sign-extended immediate and thus
19089 ; the instruction size would at least double, which is not what we
19090 ; want even with ! optimize_size.
19091 (define_split
19092 [(set (match_operand 0 "flags_reg_operand" "")
19093 (match_operator 1 "compare_operator"
19094 [(and (match_operand:HI 2 "aligned_operand" "")
19095 (match_operand:HI 3 "const_int_operand" ""))
19096 (const_int 0)]))]
19097 "! TARGET_PARTIAL_REG_STALL && reload_completed
19098 /* Ensure that the operand will remain sign-extended immediate. */
19099 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19100 && ! TARGET_FAST_PREFIX
19101 && ! optimize_size"
19102 [(set (match_dup 0)
19103 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19104 (const_int 0)]))]
19105 {
19106 operands[3]
19107 = gen_int_mode (INTVAL (operands[3])
19108 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19109 operands[2] = gen_lowpart (SImode, operands[2]);
19110 })
19111
19112 (define_split
19113 [(set (match_operand 0 "register_operand" "")
19114 (neg (match_operand 1 "register_operand" "")))
19115 (clobber (reg:CC FLAGS_REG))]
19116 "! TARGET_PARTIAL_REG_STALL && reload_completed
19117 && (GET_MODE (operands[0]) == HImode
19118 || (GET_MODE (operands[0]) == QImode
19119 && (TARGET_PROMOTE_QImode || optimize_size)))"
19120 [(parallel [(set (match_dup 0)
19121 (neg:SI (match_dup 1)))
19122 (clobber (reg:CC FLAGS_REG))])]
19123 "operands[0] = gen_lowpart (SImode, operands[0]);
19124 operands[1] = gen_lowpart (SImode, operands[1]);")
19125
19126 (define_split
19127 [(set (match_operand 0 "register_operand" "")
19128 (not (match_operand 1 "register_operand" "")))]
19129 "! TARGET_PARTIAL_REG_STALL && reload_completed
19130 && (GET_MODE (operands[0]) == HImode
19131 || (GET_MODE (operands[0]) == QImode
19132 && (TARGET_PROMOTE_QImode || optimize_size)))"
19133 [(set (match_dup 0)
19134 (not:SI (match_dup 1)))]
19135 "operands[0] = gen_lowpart (SImode, operands[0]);
19136 operands[1] = gen_lowpart (SImode, operands[1]);")
19137
19138 (define_split
19139 [(set (match_operand 0 "register_operand" "")
19140 (if_then_else (match_operator 1 "comparison_operator"
19141 [(reg FLAGS_REG) (const_int 0)])
19142 (match_operand 2 "register_operand" "")
19143 (match_operand 3 "register_operand" "")))]
19144 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19145 && (GET_MODE (operands[0]) == HImode
19146 || (GET_MODE (operands[0]) == QImode
19147 && (TARGET_PROMOTE_QImode || optimize_size)))"
19148 [(set (match_dup 0)
19149 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19150 "operands[0] = gen_lowpart (SImode, operands[0]);
19151 operands[2] = gen_lowpart (SImode, operands[2]);
19152 operands[3] = gen_lowpart (SImode, operands[3]);")
19153
19154 \f
19155 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19156 ;; transform a complex memory operation into two memory to register operations.
19157
19158 ;; Don't push memory operands
19159 (define_peephole2
19160 [(set (match_operand:SI 0 "push_operand" "")
19161 (match_operand:SI 1 "memory_operand" ""))
19162 (match_scratch:SI 2 "r")]
19163 "!optimize_size && !TARGET_PUSH_MEMORY
19164 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19165 [(set (match_dup 2) (match_dup 1))
19166 (set (match_dup 0) (match_dup 2))]
19167 "")
19168
19169 (define_peephole2
19170 [(set (match_operand:DI 0 "push_operand" "")
19171 (match_operand:DI 1 "memory_operand" ""))
19172 (match_scratch:DI 2 "r")]
19173 "!optimize_size && !TARGET_PUSH_MEMORY
19174 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19175 [(set (match_dup 2) (match_dup 1))
19176 (set (match_dup 0) (match_dup 2))]
19177 "")
19178
19179 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19180 ;; SImode pushes.
19181 (define_peephole2
19182 [(set (match_operand:SF 0 "push_operand" "")
19183 (match_operand:SF 1 "memory_operand" ""))
19184 (match_scratch:SF 2 "r")]
19185 "!optimize_size && !TARGET_PUSH_MEMORY
19186 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19187 [(set (match_dup 2) (match_dup 1))
19188 (set (match_dup 0) (match_dup 2))]
19189 "")
19190
19191 (define_peephole2
19192 [(set (match_operand:HI 0 "push_operand" "")
19193 (match_operand:HI 1 "memory_operand" ""))
19194 (match_scratch:HI 2 "r")]
19195 "!optimize_size && !TARGET_PUSH_MEMORY
19196 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19197 [(set (match_dup 2) (match_dup 1))
19198 (set (match_dup 0) (match_dup 2))]
19199 "")
19200
19201 (define_peephole2
19202 [(set (match_operand:QI 0 "push_operand" "")
19203 (match_operand:QI 1 "memory_operand" ""))
19204 (match_scratch:QI 2 "q")]
19205 "!optimize_size && !TARGET_PUSH_MEMORY
19206 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19207 [(set (match_dup 2) (match_dup 1))
19208 (set (match_dup 0) (match_dup 2))]
19209 "")
19210
19211 ;; Don't move an immediate directly to memory when the instruction
19212 ;; gets too big.
19213 (define_peephole2
19214 [(match_scratch:SI 1 "r")
19215 (set (match_operand:SI 0 "memory_operand" "")
19216 (const_int 0))]
19217 "! optimize_size
19218 && ! TARGET_USE_MOV0
19219 && TARGET_SPLIT_LONG_MOVES
19220 && get_attr_length (insn) >= ix86_cost->large_insn
19221 && peep2_regno_dead_p (0, FLAGS_REG)"
19222 [(parallel [(set (match_dup 1) (const_int 0))
19223 (clobber (reg:CC FLAGS_REG))])
19224 (set (match_dup 0) (match_dup 1))]
19225 "")
19226
19227 (define_peephole2
19228 [(match_scratch:HI 1 "r")
19229 (set (match_operand:HI 0 "memory_operand" "")
19230 (const_int 0))]
19231 "! optimize_size
19232 && ! TARGET_USE_MOV0
19233 && TARGET_SPLIT_LONG_MOVES
19234 && get_attr_length (insn) >= ix86_cost->large_insn
19235 && peep2_regno_dead_p (0, FLAGS_REG)"
19236 [(parallel [(set (match_dup 2) (const_int 0))
19237 (clobber (reg:CC FLAGS_REG))])
19238 (set (match_dup 0) (match_dup 1))]
19239 "operands[2] = gen_lowpart (SImode, operands[1]);")
19240
19241 (define_peephole2
19242 [(match_scratch:QI 1 "q")
19243 (set (match_operand:QI 0 "memory_operand" "")
19244 (const_int 0))]
19245 "! optimize_size
19246 && ! TARGET_USE_MOV0
19247 && TARGET_SPLIT_LONG_MOVES
19248 && get_attr_length (insn) >= ix86_cost->large_insn
19249 && peep2_regno_dead_p (0, FLAGS_REG)"
19250 [(parallel [(set (match_dup 2) (const_int 0))
19251 (clobber (reg:CC FLAGS_REG))])
19252 (set (match_dup 0) (match_dup 1))]
19253 "operands[2] = gen_lowpart (SImode, operands[1]);")
19254
19255 (define_peephole2
19256 [(match_scratch:SI 2 "r")
19257 (set (match_operand:SI 0 "memory_operand" "")
19258 (match_operand:SI 1 "immediate_operand" ""))]
19259 "! optimize_size
19260 && get_attr_length (insn) >= ix86_cost->large_insn
19261 && TARGET_SPLIT_LONG_MOVES"
19262 [(set (match_dup 2) (match_dup 1))
19263 (set (match_dup 0) (match_dup 2))]
19264 "")
19265
19266 (define_peephole2
19267 [(match_scratch:HI 2 "r")
19268 (set (match_operand:HI 0 "memory_operand" "")
19269 (match_operand:HI 1 "immediate_operand" ""))]
19270 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19271 && TARGET_SPLIT_LONG_MOVES"
19272 [(set (match_dup 2) (match_dup 1))
19273 (set (match_dup 0) (match_dup 2))]
19274 "")
19275
19276 (define_peephole2
19277 [(match_scratch:QI 2 "q")
19278 (set (match_operand:QI 0 "memory_operand" "")
19279 (match_operand:QI 1 "immediate_operand" ""))]
19280 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19281 && TARGET_SPLIT_LONG_MOVES"
19282 [(set (match_dup 2) (match_dup 1))
19283 (set (match_dup 0) (match_dup 2))]
19284 "")
19285
19286 ;; Don't compare memory with zero, load and use a test instead.
19287 (define_peephole2
19288 [(set (match_operand 0 "flags_reg_operand" "")
19289 (match_operator 1 "compare_operator"
19290 [(match_operand:SI 2 "memory_operand" "")
19291 (const_int 0)]))
19292 (match_scratch:SI 3 "r")]
19293 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19294 [(set (match_dup 3) (match_dup 2))
19295 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19296 "")
19297
19298 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19299 ;; Don't split NOTs with a displacement operand, because resulting XOR
19300 ;; will not be pairable anyway.
19301 ;;
19302 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19303 ;; represented using a modRM byte. The XOR replacement is long decoded,
19304 ;; so this split helps here as well.
19305 ;;
19306 ;; Note: Can't do this as a regular split because we can't get proper
19307 ;; lifetime information then.
19308
19309 (define_peephole2
19310 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19311 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19312 "!optimize_size
19313 && peep2_regno_dead_p (0, FLAGS_REG)
19314 && ((TARGET_PENTIUM
19315 && (GET_CODE (operands[0]) != MEM
19316 || !memory_displacement_operand (operands[0], SImode)))
19317 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19318 [(parallel [(set (match_dup 0)
19319 (xor:SI (match_dup 1) (const_int -1)))
19320 (clobber (reg:CC FLAGS_REG))])]
19321 "")
19322
19323 (define_peephole2
19324 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19325 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19326 "!optimize_size
19327 && peep2_regno_dead_p (0, FLAGS_REG)
19328 && ((TARGET_PENTIUM
19329 && (GET_CODE (operands[0]) != MEM
19330 || !memory_displacement_operand (operands[0], HImode)))
19331 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19332 [(parallel [(set (match_dup 0)
19333 (xor:HI (match_dup 1) (const_int -1)))
19334 (clobber (reg:CC FLAGS_REG))])]
19335 "")
19336
19337 (define_peephole2
19338 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19339 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19340 "!optimize_size
19341 && peep2_regno_dead_p (0, FLAGS_REG)
19342 && ((TARGET_PENTIUM
19343 && (GET_CODE (operands[0]) != MEM
19344 || !memory_displacement_operand (operands[0], QImode)))
19345 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19346 [(parallel [(set (match_dup 0)
19347 (xor:QI (match_dup 1) (const_int -1)))
19348 (clobber (reg:CC FLAGS_REG))])]
19349 "")
19350
19351 ;; Non pairable "test imm, reg" instructions can be translated to
19352 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19353 ;; byte opcode instead of two, have a short form for byte operands),
19354 ;; so do it for other CPUs as well. Given that the value was dead,
19355 ;; this should not create any new dependencies. Pass on the sub-word
19356 ;; versions if we're concerned about partial register stalls.
19357
19358 (define_peephole2
19359 [(set (match_operand 0 "flags_reg_operand" "")
19360 (match_operator 1 "compare_operator"
19361 [(and:SI (match_operand:SI 2 "register_operand" "")
19362 (match_operand:SI 3 "immediate_operand" ""))
19363 (const_int 0)]))]
19364 "ix86_match_ccmode (insn, CCNOmode)
19365 && (true_regnum (operands[2]) != 0
19366 || satisfies_constraint_K (operands[3]))
19367 && peep2_reg_dead_p (1, operands[2])"
19368 [(parallel
19369 [(set (match_dup 0)
19370 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19371 (const_int 0)]))
19372 (set (match_dup 2)
19373 (and:SI (match_dup 2) (match_dup 3)))])]
19374 "")
19375
19376 ;; We don't need to handle HImode case, because it will be promoted to SImode
19377 ;; on ! TARGET_PARTIAL_REG_STALL
19378
19379 (define_peephole2
19380 [(set (match_operand 0 "flags_reg_operand" "")
19381 (match_operator 1 "compare_operator"
19382 [(and:QI (match_operand:QI 2 "register_operand" "")
19383 (match_operand:QI 3 "immediate_operand" ""))
19384 (const_int 0)]))]
19385 "! TARGET_PARTIAL_REG_STALL
19386 && ix86_match_ccmode (insn, CCNOmode)
19387 && true_regnum (operands[2]) != 0
19388 && peep2_reg_dead_p (1, operands[2])"
19389 [(parallel
19390 [(set (match_dup 0)
19391 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19392 (const_int 0)]))
19393 (set (match_dup 2)
19394 (and:QI (match_dup 2) (match_dup 3)))])]
19395 "")
19396
19397 (define_peephole2
19398 [(set (match_operand 0 "flags_reg_operand" "")
19399 (match_operator 1 "compare_operator"
19400 [(and:SI
19401 (zero_extract:SI
19402 (match_operand 2 "ext_register_operand" "")
19403 (const_int 8)
19404 (const_int 8))
19405 (match_operand 3 "const_int_operand" ""))
19406 (const_int 0)]))]
19407 "! TARGET_PARTIAL_REG_STALL
19408 && ix86_match_ccmode (insn, CCNOmode)
19409 && true_regnum (operands[2]) != 0
19410 && peep2_reg_dead_p (1, operands[2])"
19411 [(parallel [(set (match_dup 0)
19412 (match_op_dup 1
19413 [(and:SI
19414 (zero_extract:SI
19415 (match_dup 2)
19416 (const_int 8)
19417 (const_int 8))
19418 (match_dup 3))
19419 (const_int 0)]))
19420 (set (zero_extract:SI (match_dup 2)
19421 (const_int 8)
19422 (const_int 8))
19423 (and:SI
19424 (zero_extract:SI
19425 (match_dup 2)
19426 (const_int 8)
19427 (const_int 8))
19428 (match_dup 3)))])]
19429 "")
19430
19431 ;; Don't do logical operations with memory inputs.
19432 (define_peephole2
19433 [(match_scratch:SI 2 "r")
19434 (parallel [(set (match_operand:SI 0 "register_operand" "")
19435 (match_operator:SI 3 "arith_or_logical_operator"
19436 [(match_dup 0)
19437 (match_operand:SI 1 "memory_operand" "")]))
19438 (clobber (reg:CC FLAGS_REG))])]
19439 "! optimize_size && ! TARGET_READ_MODIFY"
19440 [(set (match_dup 2) (match_dup 1))
19441 (parallel [(set (match_dup 0)
19442 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19443 (clobber (reg:CC FLAGS_REG))])]
19444 "")
19445
19446 (define_peephole2
19447 [(match_scratch:SI 2 "r")
19448 (parallel [(set (match_operand:SI 0 "register_operand" "")
19449 (match_operator:SI 3 "arith_or_logical_operator"
19450 [(match_operand:SI 1 "memory_operand" "")
19451 (match_dup 0)]))
19452 (clobber (reg:CC FLAGS_REG))])]
19453 "! optimize_size && ! TARGET_READ_MODIFY"
19454 [(set (match_dup 2) (match_dup 1))
19455 (parallel [(set (match_dup 0)
19456 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19457 (clobber (reg:CC FLAGS_REG))])]
19458 "")
19459
19460 ; Don't do logical operations with memory outputs
19461 ;
19462 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19463 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19464 ; the same decoder scheduling characteristics as the original.
19465
19466 (define_peephole2
19467 [(match_scratch:SI 2 "r")
19468 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19469 (match_operator:SI 3 "arith_or_logical_operator"
19470 [(match_dup 0)
19471 (match_operand:SI 1 "nonmemory_operand" "")]))
19472 (clobber (reg:CC FLAGS_REG))])]
19473 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19474 [(set (match_dup 2) (match_dup 0))
19475 (parallel [(set (match_dup 2)
19476 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19477 (clobber (reg:CC FLAGS_REG))])
19478 (set (match_dup 0) (match_dup 2))]
19479 "")
19480
19481 (define_peephole2
19482 [(match_scratch:SI 2 "r")
19483 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19484 (match_operator:SI 3 "arith_or_logical_operator"
19485 [(match_operand:SI 1 "nonmemory_operand" "")
19486 (match_dup 0)]))
19487 (clobber (reg:CC FLAGS_REG))])]
19488 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19489 [(set (match_dup 2) (match_dup 0))
19490 (parallel [(set (match_dup 2)
19491 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19492 (clobber (reg:CC FLAGS_REG))])
19493 (set (match_dup 0) (match_dup 2))]
19494 "")
19495
19496 ;; Attempt to always use XOR for zeroing registers.
19497 (define_peephole2
19498 [(set (match_operand 0 "register_operand" "")
19499 (match_operand 1 "const0_operand" ""))]
19500 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19501 && (! TARGET_USE_MOV0 || optimize_size)
19502 && GENERAL_REG_P (operands[0])
19503 && peep2_regno_dead_p (0, FLAGS_REG)"
19504 [(parallel [(set (match_dup 0) (const_int 0))
19505 (clobber (reg:CC FLAGS_REG))])]
19506 {
19507 operands[0] = gen_lowpart (word_mode, operands[0]);
19508 })
19509
19510 (define_peephole2
19511 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19512 (const_int 0))]
19513 "(GET_MODE (operands[0]) == QImode
19514 || GET_MODE (operands[0]) == HImode)
19515 && (! TARGET_USE_MOV0 || optimize_size)
19516 && peep2_regno_dead_p (0, FLAGS_REG)"
19517 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19518 (clobber (reg:CC FLAGS_REG))])])
19519
19520 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19521 (define_peephole2
19522 [(set (match_operand 0 "register_operand" "")
19523 (const_int -1))]
19524 "(GET_MODE (operands[0]) == HImode
19525 || GET_MODE (operands[0]) == SImode
19526 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19527 && (optimize_size || TARGET_PENTIUM)
19528 && peep2_regno_dead_p (0, FLAGS_REG)"
19529 [(parallel [(set (match_dup 0) (const_int -1))
19530 (clobber (reg:CC FLAGS_REG))])]
19531 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19532 operands[0]);")
19533
19534 ;; Attempt to convert simple leas to adds. These can be created by
19535 ;; move expanders.
19536 (define_peephole2
19537 [(set (match_operand:SI 0 "register_operand" "")
19538 (plus:SI (match_dup 0)
19539 (match_operand:SI 1 "nonmemory_operand" "")))]
19540 "peep2_regno_dead_p (0, FLAGS_REG)"
19541 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19542 (clobber (reg:CC FLAGS_REG))])]
19543 "")
19544
19545 (define_peephole2
19546 [(set (match_operand:SI 0 "register_operand" "")
19547 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19548 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19549 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19550 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19551 (clobber (reg:CC FLAGS_REG))])]
19552 "operands[2] = gen_lowpart (SImode, operands[2]);")
19553
19554 (define_peephole2
19555 [(set (match_operand:DI 0 "register_operand" "")
19556 (plus:DI (match_dup 0)
19557 (match_operand:DI 1 "x86_64_general_operand" "")))]
19558 "peep2_regno_dead_p (0, FLAGS_REG)"
19559 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19560 (clobber (reg:CC FLAGS_REG))])]
19561 "")
19562
19563 (define_peephole2
19564 [(set (match_operand:SI 0 "register_operand" "")
19565 (mult:SI (match_dup 0)
19566 (match_operand:SI 1 "const_int_operand" "")))]
19567 "exact_log2 (INTVAL (operands[1])) >= 0
19568 && peep2_regno_dead_p (0, FLAGS_REG)"
19569 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19570 (clobber (reg:CC FLAGS_REG))])]
19571 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19572
19573 (define_peephole2
19574 [(set (match_operand:DI 0 "register_operand" "")
19575 (mult:DI (match_dup 0)
19576 (match_operand:DI 1 "const_int_operand" "")))]
19577 "exact_log2 (INTVAL (operands[1])) >= 0
19578 && peep2_regno_dead_p (0, FLAGS_REG)"
19579 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19580 (clobber (reg:CC FLAGS_REG))])]
19581 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19582
19583 (define_peephole2
19584 [(set (match_operand:SI 0 "register_operand" "")
19585 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19586 (match_operand:DI 2 "const_int_operand" "")) 0))]
19587 "exact_log2 (INTVAL (operands[2])) >= 0
19588 && REGNO (operands[0]) == REGNO (operands[1])
19589 && peep2_regno_dead_p (0, FLAGS_REG)"
19590 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19591 (clobber (reg:CC FLAGS_REG))])]
19592 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19593
19594 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19595 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19596 ;; many CPUs it is also faster, since special hardware to avoid esp
19597 ;; dependencies is present.
19598
19599 ;; While some of these conversions may be done using splitters, we use peepholes
19600 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19601
19602 ;; Convert prologue esp subtractions to push.
19603 ;; We need register to push. In order to keep verify_flow_info happy we have
19604 ;; two choices
19605 ;; - use scratch and clobber it in order to avoid dependencies
19606 ;; - use already live register
19607 ;; We can't use the second way right now, since there is no reliable way how to
19608 ;; verify that given register is live. First choice will also most likely in
19609 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19610 ;; call clobbered registers are dead. We may want to use base pointer as an
19611 ;; alternative when no register is available later.
19612
19613 (define_peephole2
19614 [(match_scratch:SI 0 "r")
19615 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19616 (clobber (reg:CC FLAGS_REG))
19617 (clobber (mem:BLK (scratch)))])]
19618 "optimize_size || !TARGET_SUB_ESP_4"
19619 [(clobber (match_dup 0))
19620 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19621 (clobber (mem:BLK (scratch)))])])
19622
19623 (define_peephole2
19624 [(match_scratch:SI 0 "r")
19625 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19626 (clobber (reg:CC FLAGS_REG))
19627 (clobber (mem:BLK (scratch)))])]
19628 "optimize_size || !TARGET_SUB_ESP_8"
19629 [(clobber (match_dup 0))
19630 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19631 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19632 (clobber (mem:BLK (scratch)))])])
19633
19634 ;; Convert esp subtractions to push.
19635 (define_peephole2
19636 [(match_scratch:SI 0 "r")
19637 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19638 (clobber (reg:CC FLAGS_REG))])]
19639 "optimize_size || !TARGET_SUB_ESP_4"
19640 [(clobber (match_dup 0))
19641 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19642
19643 (define_peephole2
19644 [(match_scratch:SI 0 "r")
19645 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19646 (clobber (reg:CC FLAGS_REG))])]
19647 "optimize_size || !TARGET_SUB_ESP_8"
19648 [(clobber (match_dup 0))
19649 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19650 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19651
19652 ;; Convert epilogue deallocator to pop.
19653 (define_peephole2
19654 [(match_scratch:SI 0 "r")
19655 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19656 (clobber (reg:CC FLAGS_REG))
19657 (clobber (mem:BLK (scratch)))])]
19658 "optimize_size || !TARGET_ADD_ESP_4"
19659 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19660 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19661 (clobber (mem:BLK (scratch)))])]
19662 "")
19663
19664 ;; Two pops case is tricky, since pop causes dependency on destination register.
19665 ;; We use two registers if available.
19666 (define_peephole2
19667 [(match_scratch:SI 0 "r")
19668 (match_scratch:SI 1 "r")
19669 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19670 (clobber (reg:CC FLAGS_REG))
19671 (clobber (mem:BLK (scratch)))])]
19672 "optimize_size || !TARGET_ADD_ESP_8"
19673 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19674 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19675 (clobber (mem:BLK (scratch)))])
19676 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19677 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19678 "")
19679
19680 (define_peephole2
19681 [(match_scratch:SI 0 "r")
19682 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19683 (clobber (reg:CC FLAGS_REG))
19684 (clobber (mem:BLK (scratch)))])]
19685 "optimize_size"
19686 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19687 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19688 (clobber (mem:BLK (scratch)))])
19689 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19690 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19691 "")
19692
19693 ;; Convert esp additions to pop.
19694 (define_peephole2
19695 [(match_scratch:SI 0 "r")
19696 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19697 (clobber (reg:CC FLAGS_REG))])]
19698 ""
19699 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19700 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19701 "")
19702
19703 ;; Two pops case is tricky, since pop causes dependency on destination register.
19704 ;; We use two registers if available.
19705 (define_peephole2
19706 [(match_scratch:SI 0 "r")
19707 (match_scratch:SI 1 "r")
19708 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19709 (clobber (reg:CC FLAGS_REG))])]
19710 ""
19711 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19712 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19713 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19714 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19715 "")
19716
19717 (define_peephole2
19718 [(match_scratch:SI 0 "r")
19719 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19720 (clobber (reg:CC FLAGS_REG))])]
19721 "optimize_size"
19722 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19723 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19724 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19725 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19726 "")
19727 \f
19728 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19729 ;; required and register dies. Similarly for 128 to plus -128.
19730 (define_peephole2
19731 [(set (match_operand 0 "flags_reg_operand" "")
19732 (match_operator 1 "compare_operator"
19733 [(match_operand 2 "register_operand" "")
19734 (match_operand 3 "const_int_operand" "")]))]
19735 "(INTVAL (operands[3]) == -1
19736 || INTVAL (operands[3]) == 1
19737 || INTVAL (operands[3]) == 128)
19738 && ix86_match_ccmode (insn, CCGCmode)
19739 && peep2_reg_dead_p (1, operands[2])"
19740 [(parallel [(set (match_dup 0)
19741 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19742 (clobber (match_dup 2))])]
19743 "")
19744 \f
19745 (define_peephole2
19746 [(match_scratch:DI 0 "r")
19747 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19748 (clobber (reg:CC FLAGS_REG))
19749 (clobber (mem:BLK (scratch)))])]
19750 "optimize_size || !TARGET_SUB_ESP_4"
19751 [(clobber (match_dup 0))
19752 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19753 (clobber (mem:BLK (scratch)))])])
19754
19755 (define_peephole2
19756 [(match_scratch:DI 0 "r")
19757 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19758 (clobber (reg:CC FLAGS_REG))
19759 (clobber (mem:BLK (scratch)))])]
19760 "optimize_size || !TARGET_SUB_ESP_8"
19761 [(clobber (match_dup 0))
19762 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19763 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19764 (clobber (mem:BLK (scratch)))])])
19765
19766 ;; Convert esp subtractions to push.
19767 (define_peephole2
19768 [(match_scratch:DI 0 "r")
19769 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19770 (clobber (reg:CC FLAGS_REG))])]
19771 "optimize_size || !TARGET_SUB_ESP_4"
19772 [(clobber (match_dup 0))
19773 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19774
19775 (define_peephole2
19776 [(match_scratch:DI 0 "r")
19777 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19778 (clobber (reg:CC FLAGS_REG))])]
19779 "optimize_size || !TARGET_SUB_ESP_8"
19780 [(clobber (match_dup 0))
19781 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19782 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19783
19784 ;; Convert epilogue deallocator to pop.
19785 (define_peephole2
19786 [(match_scratch:DI 0 "r")
19787 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19788 (clobber (reg:CC FLAGS_REG))
19789 (clobber (mem:BLK (scratch)))])]
19790 "optimize_size || !TARGET_ADD_ESP_4"
19791 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19792 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19793 (clobber (mem:BLK (scratch)))])]
19794 "")
19795
19796 ;; Two pops case is tricky, since pop causes dependency on destination register.
19797 ;; We use two registers if available.
19798 (define_peephole2
19799 [(match_scratch:DI 0 "r")
19800 (match_scratch:DI 1 "r")
19801 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19802 (clobber (reg:CC FLAGS_REG))
19803 (clobber (mem:BLK (scratch)))])]
19804 "optimize_size || !TARGET_ADD_ESP_8"
19805 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19806 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19807 (clobber (mem:BLK (scratch)))])
19808 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19809 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19810 "")
19811
19812 (define_peephole2
19813 [(match_scratch:DI 0 "r")
19814 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19815 (clobber (reg:CC FLAGS_REG))
19816 (clobber (mem:BLK (scratch)))])]
19817 "optimize_size"
19818 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19819 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19820 (clobber (mem:BLK (scratch)))])
19821 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19822 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19823 "")
19824
19825 ;; Convert esp additions to pop.
19826 (define_peephole2
19827 [(match_scratch:DI 0 "r")
19828 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19829 (clobber (reg:CC FLAGS_REG))])]
19830 ""
19831 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19832 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19833 "")
19834
19835 ;; Two pops case is tricky, since pop causes dependency on destination register.
19836 ;; We use two registers if available.
19837 (define_peephole2
19838 [(match_scratch:DI 0 "r")
19839 (match_scratch:DI 1 "r")
19840 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19841 (clobber (reg:CC FLAGS_REG))])]
19842 ""
19843 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19844 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19845 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19846 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19847 "")
19848
19849 (define_peephole2
19850 [(match_scratch:DI 0 "r")
19851 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19852 (clobber (reg:CC FLAGS_REG))])]
19853 "optimize_size"
19854 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19855 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19856 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19857 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19858 "")
19859 \f
19860 ;; Convert imul by three, five and nine into lea
19861 (define_peephole2
19862 [(parallel
19863 [(set (match_operand:SI 0 "register_operand" "")
19864 (mult:SI (match_operand:SI 1 "register_operand" "")
19865 (match_operand:SI 2 "const_int_operand" "")))
19866 (clobber (reg:CC FLAGS_REG))])]
19867 "INTVAL (operands[2]) == 3
19868 || INTVAL (operands[2]) == 5
19869 || INTVAL (operands[2]) == 9"
19870 [(set (match_dup 0)
19871 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19872 (match_dup 1)))]
19873 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19874
19875 (define_peephole2
19876 [(parallel
19877 [(set (match_operand:SI 0 "register_operand" "")
19878 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19879 (match_operand:SI 2 "const_int_operand" "")))
19880 (clobber (reg:CC FLAGS_REG))])]
19881 "!optimize_size
19882 && (INTVAL (operands[2]) == 3
19883 || INTVAL (operands[2]) == 5
19884 || INTVAL (operands[2]) == 9)"
19885 [(set (match_dup 0) (match_dup 1))
19886 (set (match_dup 0)
19887 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19888 (match_dup 0)))]
19889 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19890
19891 (define_peephole2
19892 [(parallel
19893 [(set (match_operand:DI 0 "register_operand" "")
19894 (mult:DI (match_operand:DI 1 "register_operand" "")
19895 (match_operand:DI 2 "const_int_operand" "")))
19896 (clobber (reg:CC FLAGS_REG))])]
19897 "TARGET_64BIT
19898 && (INTVAL (operands[2]) == 3
19899 || INTVAL (operands[2]) == 5
19900 || INTVAL (operands[2]) == 9)"
19901 [(set (match_dup 0)
19902 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19903 (match_dup 1)))]
19904 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19905
19906 (define_peephole2
19907 [(parallel
19908 [(set (match_operand:DI 0 "register_operand" "")
19909 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19910 (match_operand:DI 2 "const_int_operand" "")))
19911 (clobber (reg:CC FLAGS_REG))])]
19912 "TARGET_64BIT
19913 && !optimize_size
19914 && (INTVAL (operands[2]) == 3
19915 || INTVAL (operands[2]) == 5
19916 || INTVAL (operands[2]) == 9)"
19917 [(set (match_dup 0) (match_dup 1))
19918 (set (match_dup 0)
19919 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19920 (match_dup 0)))]
19921 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19922
19923 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19924 ;; imul $32bit_imm, reg, reg is direct decoded.
19925 (define_peephole2
19926 [(match_scratch:DI 3 "r")
19927 (parallel [(set (match_operand:DI 0 "register_operand" "")
19928 (mult:DI (match_operand:DI 1 "memory_operand" "")
19929 (match_operand:DI 2 "immediate_operand" "")))
19930 (clobber (reg:CC FLAGS_REG))])]
19931 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19932 && !satisfies_constraint_K (operands[2])"
19933 [(set (match_dup 3) (match_dup 1))
19934 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19935 (clobber (reg:CC FLAGS_REG))])]
19936 "")
19937
19938 (define_peephole2
19939 [(match_scratch:SI 3 "r")
19940 (parallel [(set (match_operand:SI 0 "register_operand" "")
19941 (mult:SI (match_operand:SI 1 "memory_operand" "")
19942 (match_operand:SI 2 "immediate_operand" "")))
19943 (clobber (reg:CC FLAGS_REG))])]
19944 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19945 && !satisfies_constraint_K (operands[2])"
19946 [(set (match_dup 3) (match_dup 1))
19947 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19948 (clobber (reg:CC FLAGS_REG))])]
19949 "")
19950
19951 (define_peephole2
19952 [(match_scratch:SI 3 "r")
19953 (parallel [(set (match_operand:DI 0 "register_operand" "")
19954 (zero_extend:DI
19955 (mult:SI (match_operand:SI 1 "memory_operand" "")
19956 (match_operand:SI 2 "immediate_operand" ""))))
19957 (clobber (reg:CC FLAGS_REG))])]
19958 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19959 && !satisfies_constraint_K (operands[2])"
19960 [(set (match_dup 3) (match_dup 1))
19961 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19962 (clobber (reg:CC FLAGS_REG))])]
19963 "")
19964
19965 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19966 ;; Convert it into imul reg, reg
19967 ;; It would be better to force assembler to encode instruction using long
19968 ;; immediate, but there is apparently no way to do so.
19969 (define_peephole2
19970 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19971 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19972 (match_operand:DI 2 "const_int_operand" "")))
19973 (clobber (reg:CC FLAGS_REG))])
19974 (match_scratch:DI 3 "r")]
19975 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19976 && satisfies_constraint_K (operands[2])"
19977 [(set (match_dup 3) (match_dup 2))
19978 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19979 (clobber (reg:CC FLAGS_REG))])]
19980 {
19981 if (!rtx_equal_p (operands[0], operands[1]))
19982 emit_move_insn (operands[0], operands[1]);
19983 })
19984
19985 (define_peephole2
19986 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19987 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19988 (match_operand:SI 2 "const_int_operand" "")))
19989 (clobber (reg:CC FLAGS_REG))])
19990 (match_scratch:SI 3 "r")]
19991 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19992 && satisfies_constraint_K (operands[2])"
19993 [(set (match_dup 3) (match_dup 2))
19994 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19995 (clobber (reg:CC FLAGS_REG))])]
19996 {
19997 if (!rtx_equal_p (operands[0], operands[1]))
19998 emit_move_insn (operands[0], operands[1]);
19999 })
20000
20001 (define_peephole2
20002 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20003 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20004 (match_operand:HI 2 "immediate_operand" "")))
20005 (clobber (reg:CC FLAGS_REG))])
20006 (match_scratch:HI 3 "r")]
20007 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20008 [(set (match_dup 3) (match_dup 2))
20009 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20010 (clobber (reg:CC FLAGS_REG))])]
20011 {
20012 if (!rtx_equal_p (operands[0], operands[1]))
20013 emit_move_insn (operands[0], operands[1]);
20014 })
20015
20016 ;; After splitting up read-modify operations, array accesses with memory
20017 ;; operands might end up in form:
20018 ;; sall $2, %eax
20019 ;; movl 4(%esp), %edx
20020 ;; addl %edx, %eax
20021 ;; instead of pre-splitting:
20022 ;; sall $2, %eax
20023 ;; addl 4(%esp), %eax
20024 ;; Turn it into:
20025 ;; movl 4(%esp), %edx
20026 ;; leal (%edx,%eax,4), %eax
20027
20028 (define_peephole2
20029 [(parallel [(set (match_operand 0 "register_operand" "")
20030 (ashift (match_operand 1 "register_operand" "")
20031 (match_operand 2 "const_int_operand" "")))
20032 (clobber (reg:CC FLAGS_REG))])
20033 (set (match_operand 3 "register_operand")
20034 (match_operand 4 "x86_64_general_operand" ""))
20035 (parallel [(set (match_operand 5 "register_operand" "")
20036 (plus (match_operand 6 "register_operand" "")
20037 (match_operand 7 "register_operand" "")))
20038 (clobber (reg:CC FLAGS_REG))])]
20039 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20040 /* Validate MODE for lea. */
20041 && ((!TARGET_PARTIAL_REG_STALL
20042 && (GET_MODE (operands[0]) == QImode
20043 || GET_MODE (operands[0]) == HImode))
20044 || GET_MODE (operands[0]) == SImode
20045 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20046 /* We reorder load and the shift. */
20047 && !rtx_equal_p (operands[1], operands[3])
20048 && !reg_overlap_mentioned_p (operands[0], operands[4])
20049 /* Last PLUS must consist of operand 0 and 3. */
20050 && !rtx_equal_p (operands[0], operands[3])
20051 && (rtx_equal_p (operands[3], operands[6])
20052 || rtx_equal_p (operands[3], operands[7]))
20053 && (rtx_equal_p (operands[0], operands[6])
20054 || rtx_equal_p (operands[0], operands[7]))
20055 /* The intermediate operand 0 must die or be same as output. */
20056 && (rtx_equal_p (operands[0], operands[5])
20057 || peep2_reg_dead_p (3, operands[0]))"
20058 [(set (match_dup 3) (match_dup 4))
20059 (set (match_dup 0) (match_dup 1))]
20060 {
20061 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20062 int scale = 1 << INTVAL (operands[2]);
20063 rtx index = gen_lowpart (Pmode, operands[1]);
20064 rtx base = gen_lowpart (Pmode, operands[3]);
20065 rtx dest = gen_lowpart (mode, operands[5]);
20066
20067 operands[1] = gen_rtx_PLUS (Pmode, base,
20068 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20069 if (mode != Pmode)
20070 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20071 operands[0] = dest;
20072 })
20073 \f
20074 ;; Call-value patterns last so that the wildcard operand does not
20075 ;; disrupt insn-recog's switch tables.
20076
20077 (define_insn "*call_value_pop_0"
20078 [(set (match_operand 0 "" "")
20079 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20080 (match_operand:SI 2 "" "")))
20081 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20082 (match_operand:SI 3 "immediate_operand" "")))]
20083 "!TARGET_64BIT"
20084 {
20085 if (SIBLING_CALL_P (insn))
20086 return "jmp\t%P1";
20087 else
20088 return "call\t%P1";
20089 }
20090 [(set_attr "type" "callv")])
20091
20092 (define_insn "*call_value_pop_1"
20093 [(set (match_operand 0 "" "")
20094 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20095 (match_operand:SI 2 "" "")))
20096 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20097 (match_operand:SI 3 "immediate_operand" "i")))]
20098 "!TARGET_64BIT"
20099 {
20100 if (constant_call_address_operand (operands[1], Pmode))
20101 {
20102 if (SIBLING_CALL_P (insn))
20103 return "jmp\t%P1";
20104 else
20105 return "call\t%P1";
20106 }
20107 if (SIBLING_CALL_P (insn))
20108 return "jmp\t%A1";
20109 else
20110 return "call\t%A1";
20111 }
20112 [(set_attr "type" "callv")])
20113
20114 (define_insn "*call_value_0"
20115 [(set (match_operand 0 "" "")
20116 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20117 (match_operand:SI 2 "" "")))]
20118 "!TARGET_64BIT"
20119 {
20120 if (SIBLING_CALL_P (insn))
20121 return "jmp\t%P1";
20122 else
20123 return "call\t%P1";
20124 }
20125 [(set_attr "type" "callv")])
20126
20127 (define_insn "*call_value_0_rex64"
20128 [(set (match_operand 0 "" "")
20129 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20130 (match_operand:DI 2 "const_int_operand" "")))]
20131 "TARGET_64BIT"
20132 {
20133 if (SIBLING_CALL_P (insn))
20134 return "jmp\t%P1";
20135 else
20136 return "call\t%P1";
20137 }
20138 [(set_attr "type" "callv")])
20139
20140 (define_insn "*call_value_1"
20141 [(set (match_operand 0 "" "")
20142 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20143 (match_operand:SI 2 "" "")))]
20144 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20145 {
20146 if (constant_call_address_operand (operands[1], Pmode))
20147 return "call\t%P1";
20148 return "call\t%A1";
20149 }
20150 [(set_attr "type" "callv")])
20151
20152 (define_insn "*sibcall_value_1"
20153 [(set (match_operand 0 "" "")
20154 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20155 (match_operand:SI 2 "" "")))]
20156 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20157 {
20158 if (constant_call_address_operand (operands[1], Pmode))
20159 return "jmp\t%P1";
20160 return "jmp\t%A1";
20161 }
20162 [(set_attr "type" "callv")])
20163
20164 (define_insn "*call_value_1_rex64"
20165 [(set (match_operand 0 "" "")
20166 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20167 (match_operand:DI 2 "" "")))]
20168 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20169 {
20170 if (constant_call_address_operand (operands[1], Pmode))
20171 return "call\t%P1";
20172 return "call\t%A1";
20173 }
20174 [(set_attr "type" "callv")])
20175
20176 (define_insn "*sibcall_value_1_rex64"
20177 [(set (match_operand 0 "" "")
20178 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20179 (match_operand:DI 2 "" "")))]
20180 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20181 "jmp\t%P1"
20182 [(set_attr "type" "callv")])
20183
20184 (define_insn "*sibcall_value_1_rex64_v"
20185 [(set (match_operand 0 "" "")
20186 (call (mem:QI (reg:DI 40))
20187 (match_operand:DI 1 "" "")))]
20188 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20189 "jmp\t*%%r11"
20190 [(set_attr "type" "callv")])
20191 \f
20192 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20193 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20194 ;; caught for use by garbage collectors and the like. Using an insn that
20195 ;; maps to SIGILL makes it more likely the program will rightfully die.
20196 ;; Keeping with tradition, "6" is in honor of #UD.
20197 (define_insn "trap"
20198 [(trap_if (const_int 1) (const_int 6))]
20199 ""
20200 { return ASM_SHORT "0x0b0f"; }
20201 [(set_attr "length" "2")])
20202
20203 (define_expand "sse_prologue_save"
20204 [(parallel [(set (match_operand:BLK 0 "" "")
20205 (unspec:BLK [(reg:DI 21)
20206 (reg:DI 22)
20207 (reg:DI 23)
20208 (reg:DI 24)
20209 (reg:DI 25)
20210 (reg:DI 26)
20211 (reg:DI 27)
20212 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20213 (use (match_operand:DI 1 "register_operand" ""))
20214 (use (match_operand:DI 2 "immediate_operand" ""))
20215 (use (label_ref:DI (match_operand 3 "" "")))])]
20216 "TARGET_64BIT"
20217 "")
20218
20219 (define_insn "*sse_prologue_save_insn"
20220 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20221 (match_operand:DI 4 "const_int_operand" "n")))
20222 (unspec:BLK [(reg:DI 21)
20223 (reg:DI 22)
20224 (reg:DI 23)
20225 (reg:DI 24)
20226 (reg:DI 25)
20227 (reg:DI 26)
20228 (reg:DI 27)
20229 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20230 (use (match_operand:DI 1 "register_operand" "r"))
20231 (use (match_operand:DI 2 "const_int_operand" "i"))
20232 (use (label_ref:DI (match_operand 3 "" "X")))]
20233 "TARGET_64BIT
20234 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20235 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20236 "*
20237 {
20238 int i;
20239 operands[0] = gen_rtx_MEM (Pmode,
20240 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20241 output_asm_insn (\"jmp\\t%A1\", operands);
20242 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20243 {
20244 operands[4] = adjust_address (operands[0], DImode, i*16);
20245 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20246 PUT_MODE (operands[4], TImode);
20247 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20248 output_asm_insn (\"rex\", operands);
20249 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20250 }
20251 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20252 CODE_LABEL_NUMBER (operands[3]));
20253 RET;
20254 }
20255 "
20256 [(set_attr "type" "other")
20257 (set_attr "length_immediate" "0")
20258 (set_attr "length_address" "0")
20259 (set_attr "length" "135")
20260 (set_attr "memory" "store")
20261 (set_attr "modrm" "0")
20262 (set_attr "mode" "DI")])
20263
20264 (define_expand "prefetch"
20265 [(prefetch (match_operand 0 "address_operand" "")
20266 (match_operand:SI 1 "const_int_operand" "")
20267 (match_operand:SI 2 "const_int_operand" ""))]
20268 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20269 {
20270 int rw = INTVAL (operands[1]);
20271 int locality = INTVAL (operands[2]);
20272
20273 gcc_assert (rw == 0 || rw == 1);
20274 gcc_assert (locality >= 0 && locality <= 3);
20275 gcc_assert (GET_MODE (operands[0]) == Pmode
20276 || GET_MODE (operands[0]) == VOIDmode);
20277
20278 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20279 supported by SSE counterpart or the SSE prefetch is not available
20280 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20281 of locality. */
20282 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20283 operands[2] = GEN_INT (3);
20284 else
20285 operands[1] = const0_rtx;
20286 })
20287
20288 (define_insn "*prefetch_sse"
20289 [(prefetch (match_operand:SI 0 "address_operand" "p")
20290 (const_int 0)
20291 (match_operand:SI 1 "const_int_operand" ""))]
20292 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20293 {
20294 static const char * const patterns[4] = {
20295 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20296 };
20297
20298 int locality = INTVAL (operands[1]);
20299 gcc_assert (locality >= 0 && locality <= 3);
20300
20301 return patterns[locality];
20302 }
20303 [(set_attr "type" "sse")
20304 (set_attr "memory" "none")])
20305
20306 (define_insn "*prefetch_sse_rex"
20307 [(prefetch (match_operand:DI 0 "address_operand" "p")
20308 (const_int 0)
20309 (match_operand:SI 1 "const_int_operand" ""))]
20310 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20311 {
20312 static const char * const patterns[4] = {
20313 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20314 };
20315
20316 int locality = INTVAL (operands[1]);
20317 gcc_assert (locality >= 0 && locality <= 3);
20318
20319 return patterns[locality];
20320 }
20321 [(set_attr "type" "sse")
20322 (set_attr "memory" "none")])
20323
20324 (define_insn "*prefetch_3dnow"
20325 [(prefetch (match_operand:SI 0 "address_operand" "p")
20326 (match_operand:SI 1 "const_int_operand" "n")
20327 (const_int 3))]
20328 "TARGET_3DNOW && !TARGET_64BIT"
20329 {
20330 if (INTVAL (operands[1]) == 0)
20331 return "prefetch\t%a0";
20332 else
20333 return "prefetchw\t%a0";
20334 }
20335 [(set_attr "type" "mmx")
20336 (set_attr "memory" "none")])
20337
20338 (define_insn "*prefetch_3dnow_rex"
20339 [(prefetch (match_operand:DI 0 "address_operand" "p")
20340 (match_operand:SI 1 "const_int_operand" "n")
20341 (const_int 3))]
20342 "TARGET_3DNOW && TARGET_64BIT"
20343 {
20344 if (INTVAL (operands[1]) == 0)
20345 return "prefetch\t%a0";
20346 else
20347 return "prefetchw\t%a0";
20348 }
20349 [(set_attr "type" "mmx")
20350 (set_attr "memory" "none")])
20351
20352 (define_expand "stack_protect_set"
20353 [(match_operand 0 "memory_operand" "")
20354 (match_operand 1 "memory_operand" "")]
20355 ""
20356 {
20357 #ifdef TARGET_THREAD_SSP_OFFSET
20358 if (TARGET_64BIT)
20359 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20360 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20361 else
20362 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20363 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20364 #else
20365 if (TARGET_64BIT)
20366 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20367 else
20368 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20369 #endif
20370 DONE;
20371 })
20372
20373 (define_insn "stack_protect_set_si"
20374 [(set (match_operand:SI 0 "memory_operand" "=m")
20375 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20376 (set (match_scratch:SI 2 "=&r") (const_int 0))
20377 (clobber (reg:CC FLAGS_REG))]
20378 ""
20379 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20380 [(set_attr "type" "multi")])
20381
20382 (define_insn "stack_protect_set_di"
20383 [(set (match_operand:DI 0 "memory_operand" "=m")
20384 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20385 (set (match_scratch:DI 2 "=&r") (const_int 0))
20386 (clobber (reg:CC FLAGS_REG))]
20387 "TARGET_64BIT"
20388 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20389 [(set_attr "type" "multi")])
20390
20391 (define_insn "stack_tls_protect_set_si"
20392 [(set (match_operand:SI 0 "memory_operand" "=m")
20393 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20394 (set (match_scratch:SI 2 "=&r") (const_int 0))
20395 (clobber (reg:CC FLAGS_REG))]
20396 ""
20397 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20398 [(set_attr "type" "multi")])
20399
20400 (define_insn "stack_tls_protect_set_di"
20401 [(set (match_operand:DI 0 "memory_operand" "=m")
20402 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20403 (set (match_scratch:DI 2 "=&r") (const_int 0))
20404 (clobber (reg:CC FLAGS_REG))]
20405 "TARGET_64BIT"
20406 "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20407 [(set_attr "type" "multi")])
20408
20409 (define_expand "stack_protect_test"
20410 [(match_operand 0 "memory_operand" "")
20411 (match_operand 1 "memory_operand" "")
20412 (match_operand 2 "" "")]
20413 ""
20414 {
20415 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20416 ix86_compare_op0 = operands[0];
20417 ix86_compare_op1 = operands[1];
20418 ix86_compare_emitted = flags;
20419
20420 #ifdef TARGET_THREAD_SSP_OFFSET
20421 if (TARGET_64BIT)
20422 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20423 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20424 else
20425 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20426 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20427 #else
20428 if (TARGET_64BIT)
20429 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20430 else
20431 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20432 #endif
20433 emit_jump_insn (gen_beq (operands[2]));
20434 DONE;
20435 })
20436
20437 (define_insn "stack_protect_test_si"
20438 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20439 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20440 (match_operand:SI 2 "memory_operand" "m")]
20441 UNSPEC_SP_TEST))
20442 (clobber (match_scratch:SI 3 "=&r"))]
20443 ""
20444 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20445 [(set_attr "type" "multi")])
20446
20447 (define_insn "stack_protect_test_di"
20448 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20449 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20450 (match_operand:DI 2 "memory_operand" "m")]
20451 UNSPEC_SP_TEST))
20452 (clobber (match_scratch:DI 3 "=&r"))]
20453 "TARGET_64BIT"
20454 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20455 [(set_attr "type" "multi")])
20456
20457 (define_insn "stack_tls_protect_test_si"
20458 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20459 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20460 (match_operand:SI 2 "const_int_operand" "i")]
20461 UNSPEC_SP_TLS_TEST))
20462 (clobber (match_scratch:SI 3 "=r"))]
20463 ""
20464 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20465 [(set_attr "type" "multi")])
20466
20467 (define_insn "stack_tls_protect_test_di"
20468 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20469 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20470 (match_operand:DI 2 "const_int_operand" "i")]
20471 UNSPEC_SP_TLS_TEST))
20472 (clobber (match_scratch:DI 3 "=r"))]
20473 "TARGET_64BIT"
20474 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20475 [(set_attr "type" "multi")])
20476
20477 (include "sse.md")
20478 (include "mmx.md")
20479 (include "sync.md")