]> gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/i386.md
i386.c (override_options): Revert 2004-11-24 change.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;; operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
66 (UNSPEC_STACK_ALLOC 11)
67 (UNSPEC_SET_GOT 12)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69
70 ; TLS support
71 (UNSPEC_TP 15)
72 (UNSPEC_TLS_GD 16)
73 (UNSPEC_TLS_LD_BASE 17)
74
75 ; Other random patterns
76 (UNSPEC_SCAS 20)
77 (UNSPEC_SIN 21)
78 (UNSPEC_COS 22)
79 (UNSPEC_FNSTSW 24)
80 (UNSPEC_SAHF 25)
81 (UNSPEC_FSTCW 26)
82 (UNSPEC_ADD_CARRY 27)
83 (UNSPEC_FLDCW 28)
84
85 ; For SSE/MMX support:
86 (UNSPEC_FIX 30)
87 (UNSPEC_FIX_NOTRUNC 31)
88 (UNSPEC_MASKMOV 32)
89 (UNSPEC_MOVMSK 33)
90 (UNSPEC_MOVNT 34)
91 (UNSPEC_MOVA 38)
92 (UNSPEC_MOVU 39)
93 (UNSPEC_SHUFFLE 41)
94 (UNSPEC_RCP 42)
95 (UNSPEC_RSQRT 43)
96 (UNSPEC_SFENCE 44)
97 (UNSPEC_NOP 45) ; prevents combiner cleverness
98 (UNSPEC_PAVGUSB 49)
99 (UNSPEC_PFRCP 50)
100 (UNSPEC_PFRCPIT1 51)
101 (UNSPEC_PFRCPIT2 52)
102 (UNSPEC_PFRSQRT 53)
103 (UNSPEC_PFRSQIT1 54)
104 (UNSPEC_PSHUFLW 55)
105 (UNSPEC_PSHUFHW 56)
106 (UNSPEC_MFENCE 59)
107 (UNSPEC_LFENCE 60)
108 (UNSPEC_PSADBW 61)
109 (UNSPEC_ADDSUB 71)
110 (UNSPEC_HADD 72)
111 (UNSPEC_HSUB 73)
112 (UNSPEC_MOVSHDUP 74)
113 (UNSPEC_MOVSLDUP 75)
114 (UNSPEC_LDQQU 76)
115 (UNSPEC_MOVDDUP 77)
116
117 ; x87 Floating point
118 (UNSPEC_FPATAN 65)
119 (UNSPEC_FYL2X 66)
120 (UNSPEC_FYL2XP1 67)
121 (UNSPEC_FRNDINT 68)
122 (UNSPEC_F2XM1 69)
123
124 ; x87 Double output FP
125 (UNSPEC_SINCOS_COS 80)
126 (UNSPEC_SINCOS_SIN 81)
127 (UNSPEC_TAN_ONE 82)
128 (UNSPEC_TAN_TAN 83)
129 (UNSPEC_XTRACT_FRACT 84)
130 (UNSPEC_XTRACT_EXP 85)
131 (UNSPEC_FSCALE_FRACT 86)
132 (UNSPEC_FSCALE_EXP 87)
133 (UNSPEC_FPREM_F 88)
134 (UNSPEC_FPREM_U 89)
135 (UNSPEC_FPREM1_F 90)
136 (UNSPEC_FPREM1_U 91)
137
138 ; x87 Rounding
139 (UNSPEC_FRNDINT_FLOOR 96)
140 (UNSPEC_FRNDINT_CEIL 97)
141 (UNSPEC_FRNDINT_TRUNC 98)
142 (UNSPEC_FRNDINT_MASK_PM 99)
143
144 ; REP instruction
145 (UNSPEC_REP 75)
146
147 (UNSPEC_EH_RETURN 76)
148 ])
149
150 (define_constants
151 [(UNSPECV_BLOCKAGE 0)
152 (UNSPECV_STACK_PROBE 10)
153 (UNSPECV_EMMS 31)
154 (UNSPECV_LDMXCSR 37)
155 (UNSPECV_STMXCSR 40)
156 (UNSPECV_FEMMS 46)
157 (UNSPECV_CLFLUSH 57)
158 (UNSPECV_ALIGN 68)
159 (UNSPECV_MONITOR 69)
160 (UNSPECV_MWAIT 70)
161 ])
162
163 ;; Registers by name.
164 (define_constants
165 [(BP_REG 6)
166 (SP_REG 7)
167 (FLAGS_REG 17)
168 (FPSR_REG 18)
169 (DIRFLAG_REG 19)
170 ])
171
172 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
173 ;; from i386.c.
174
175 ;; In C guard expressions, put expressions which may be compile-time
176 ;; constants first. This allows for better optimization. For
177 ;; example, write "TARGET_64BIT && reload_completed", not
178 ;; "reload_completed && TARGET_64BIT".
179
180 \f
181 ;; Processor type. This attribute must exactly match the processor_type
182 ;; enumeration in i386.h.
183 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
184 (const (symbol_ref "ix86_tune")))
185
186 ;; A basic instruction type. Refinements due to arguments to be
187 ;; provided in other attributes.
188 (define_attr "type"
189 "other,multi,
190 alu,alu1,negnot,imov,imovx,lea,
191 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
192 icmp,test,ibr,setcc,icmov,
193 push,pop,call,callv,leave,
194 str,cld,
195 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
196 sselog,sselog1,sseiadd,sseishft,sseimul,
197 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
198 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
199 (const_string "other"))
200
201 ;; Main data type used by the insn
202 (define_attr "mode"
203 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
204 (const_string "unknown"))
205
206 ;; The CPU unit operations uses.
207 (define_attr "unit" "integer,i387,sse,mmx,unknown"
208 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
209 (const_string "i387")
210 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
211 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
212 (const_string "sse")
213 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
214 (const_string "mmx")
215 (eq_attr "type" "other")
216 (const_string "unknown")]
217 (const_string "integer")))
218
219 ;; The (bounding maximum) length of an instruction immediate.
220 (define_attr "length_immediate" ""
221 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
222 (const_int 0)
223 (eq_attr "unit" "i387,sse,mmx")
224 (const_int 0)
225 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
226 imul,icmp,push,pop")
227 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
228 (eq_attr "type" "imov,test")
229 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
230 (eq_attr "type" "call")
231 (if_then_else (match_operand 0 "constant_call_address_operand" "")
232 (const_int 4)
233 (const_int 0))
234 (eq_attr "type" "callv")
235 (if_then_else (match_operand 1 "constant_call_address_operand" "")
236 (const_int 4)
237 (const_int 0))
238 ;; We don't know the size before shorten_branches. Expect
239 ;; the instruction to fit for better scheduling.
240 (eq_attr "type" "ibr")
241 (const_int 1)
242 ]
243 (symbol_ref "/* Update immediate_length and other attributes! */
244 abort(),1")))
245
246 ;; The (bounding maximum) length of an instruction address.
247 (define_attr "length_address" ""
248 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
249 (const_int 0)
250 (and (eq_attr "type" "call")
251 (match_operand 0 "constant_call_address_operand" ""))
252 (const_int 0)
253 (and (eq_attr "type" "callv")
254 (match_operand 1 "constant_call_address_operand" ""))
255 (const_int 0)
256 ]
257 (symbol_ref "ix86_attr_length_address_default (insn)")))
258
259 ;; Set when length prefix is used.
260 (define_attr "prefix_data16" ""
261 (if_then_else (ior (eq_attr "mode" "HI")
262 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
263 (const_int 1)
264 (const_int 0)))
265
266 ;; Set when string REP prefix is used.
267 (define_attr "prefix_rep" ""
268 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
269 (const_int 1)
270 (const_int 0)))
271
272 ;; Set when 0f opcode prefix is used.
273 (define_attr "prefix_0f" ""
274 (if_then_else
275 (ior (eq_attr "type" "imovx,setcc,icmov")
276 (eq_attr "unit" "sse,mmx"))
277 (const_int 1)
278 (const_int 0)))
279
280 ;; Set when REX opcode prefix is used.
281 (define_attr "prefix_rex" ""
282 (cond [(and (eq_attr "mode" "DI")
283 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
284 (const_int 1)
285 (and (eq_attr "mode" "QI")
286 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
287 (const_int 0)))
288 (const_int 1)
289 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
290 (const_int 0))
291 (const_int 1)
292 ]
293 (const_int 0)))
294
295 ;; Set when modrm byte is used.
296 (define_attr "modrm" ""
297 (cond [(eq_attr "type" "str,cld,leave")
298 (const_int 0)
299 (eq_attr "unit" "i387")
300 (const_int 0)
301 (and (eq_attr "type" "incdec")
302 (ior (match_operand:SI 1 "register_operand" "")
303 (match_operand:HI 1 "register_operand" "")))
304 (const_int 0)
305 (and (eq_attr "type" "push")
306 (not (match_operand 1 "memory_operand" "")))
307 (const_int 0)
308 (and (eq_attr "type" "pop")
309 (not (match_operand 0 "memory_operand" "")))
310 (const_int 0)
311 (and (eq_attr "type" "imov")
312 (and (match_operand 0 "register_operand" "")
313 (match_operand 1 "immediate_operand" "")))
314 (const_int 0)
315 (and (eq_attr "type" "call")
316 (match_operand 0 "constant_call_address_operand" ""))
317 (const_int 0)
318 (and (eq_attr "type" "callv")
319 (match_operand 1 "constant_call_address_operand" ""))
320 (const_int 0)
321 ]
322 (const_int 1)))
323
324 ;; The (bounding maximum) length of an instruction in bytes.
325 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
326 ;; Later we may want to split them and compute proper length as for
327 ;; other insns.
328 (define_attr "length" ""
329 (cond [(eq_attr "type" "other,multi,fistp,frndint")
330 (const_int 16)
331 (eq_attr "type" "fcmp")
332 (const_int 4)
333 (eq_attr "unit" "i387")
334 (plus (const_int 2)
335 (plus (attr "prefix_data16")
336 (attr "length_address")))]
337 (plus (plus (attr "modrm")
338 (plus (attr "prefix_0f")
339 (plus (attr "prefix_rex")
340 (const_int 1))))
341 (plus (attr "prefix_rep")
342 (plus (attr "prefix_data16")
343 (plus (attr "length_immediate")
344 (attr "length_address")))))))
345
346 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
347 ;; `store' if there is a simple memory reference therein, or `unknown'
348 ;; if the instruction is complex.
349
350 (define_attr "memory" "none,load,store,both,unknown"
351 (cond [(eq_attr "type" "other,multi,str")
352 (const_string "unknown")
353 (eq_attr "type" "lea,fcmov,fpspc,cld")
354 (const_string "none")
355 (eq_attr "type" "fistp,leave")
356 (const_string "both")
357 (eq_attr "type" "frndint")
358 (const_string "load")
359 (eq_attr "type" "push")
360 (if_then_else (match_operand 1 "memory_operand" "")
361 (const_string "both")
362 (const_string "store"))
363 (eq_attr "type" "pop")
364 (if_then_else (match_operand 0 "memory_operand" "")
365 (const_string "both")
366 (const_string "load"))
367 (eq_attr "type" "setcc")
368 (if_then_else (match_operand 0 "memory_operand" "")
369 (const_string "store")
370 (const_string "none"))
371 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
372 (if_then_else (ior (match_operand 0 "memory_operand" "")
373 (match_operand 1 "memory_operand" ""))
374 (const_string "load")
375 (const_string "none"))
376 (eq_attr "type" "ibr")
377 (if_then_else (match_operand 0 "memory_operand" "")
378 (const_string "load")
379 (const_string "none"))
380 (eq_attr "type" "call")
381 (if_then_else (match_operand 0 "constant_call_address_operand" "")
382 (const_string "none")
383 (const_string "load"))
384 (eq_attr "type" "callv")
385 (if_then_else (match_operand 1 "constant_call_address_operand" "")
386 (const_string "none")
387 (const_string "load"))
388 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
389 (match_operand 1 "memory_operand" ""))
390 (const_string "both")
391 (and (match_operand 0 "memory_operand" "")
392 (match_operand 1 "memory_operand" ""))
393 (const_string "both")
394 (match_operand 0 "memory_operand" "")
395 (const_string "store")
396 (match_operand 1 "memory_operand" "")
397 (const_string "load")
398 (and (eq_attr "type"
399 "!alu1,negnot,ishift1,
400 imov,imovx,icmp,test,
401 fmov,fcmp,fsgn,
402 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
403 mmx,mmxmov,mmxcmp,mmxcvt")
404 (match_operand 2 "memory_operand" ""))
405 (const_string "load")
406 (and (eq_attr "type" "icmov")
407 (match_operand 3 "memory_operand" ""))
408 (const_string "load")
409 ]
410 (const_string "none")))
411
412 ;; Indicates if an instruction has both an immediate and a displacement.
413
414 (define_attr "imm_disp" "false,true,unknown"
415 (cond [(eq_attr "type" "other,multi")
416 (const_string "unknown")
417 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
418 (and (match_operand 0 "memory_displacement_operand" "")
419 (match_operand 1 "immediate_operand" "")))
420 (const_string "true")
421 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
422 (and (match_operand 0 "memory_displacement_operand" "")
423 (match_operand 2 "immediate_operand" "")))
424 (const_string "true")
425 ]
426 (const_string "false")))
427
428 ;; Indicates if an FP operation has an integer source.
429
430 (define_attr "fp_int_src" "false,true"
431 (const_string "false"))
432
433 ;; Defines rounding mode of an FP operation.
434
435 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
436 (const_string "any"))
437
438 ;; Describe a user's asm statement.
439 (define_asm_attributes
440 [(set_attr "length" "128")
441 (set_attr "type" "multi")])
442 \f
443 ;; Scheduling descriptions
444
445 (include "pentium.md")
446 (include "ppro.md")
447 (include "k6.md")
448 (include "athlon.md")
449
450 \f
451 ;; Operand and operator predicates
452
453 (include "predicates.md")
454
455 \f
456 ;; Compare instructions.
457
458 ;; All compare insns have expanders that save the operands away without
459 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
460 ;; after the cmp) will actually emit the cmpM.
461
462 (define_expand "cmpdi"
463 [(set (reg:CC FLAGS_REG)
464 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
465 (match_operand:DI 1 "x86_64_general_operand" "")))]
466 ""
467 {
468 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
469 operands[0] = force_reg (DImode, operands[0]);
470 ix86_compare_op0 = operands[0];
471 ix86_compare_op1 = operands[1];
472 DONE;
473 })
474
475 (define_expand "cmpsi"
476 [(set (reg:CC FLAGS_REG)
477 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
478 (match_operand:SI 1 "general_operand" "")))]
479 ""
480 {
481 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
482 operands[0] = force_reg (SImode, operands[0]);
483 ix86_compare_op0 = operands[0];
484 ix86_compare_op1 = operands[1];
485 DONE;
486 })
487
488 (define_expand "cmphi"
489 [(set (reg:CC FLAGS_REG)
490 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
491 (match_operand:HI 1 "general_operand" "")))]
492 ""
493 {
494 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
495 operands[0] = force_reg (HImode, operands[0]);
496 ix86_compare_op0 = operands[0];
497 ix86_compare_op1 = operands[1];
498 DONE;
499 })
500
501 (define_expand "cmpqi"
502 [(set (reg:CC FLAGS_REG)
503 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
504 (match_operand:QI 1 "general_operand" "")))]
505 "TARGET_QIMODE_MATH"
506 {
507 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
508 operands[0] = force_reg (QImode, operands[0]);
509 ix86_compare_op0 = operands[0];
510 ix86_compare_op1 = operands[1];
511 DONE;
512 })
513
514 (define_insn "cmpdi_ccno_1_rex64"
515 [(set (reg FLAGS_REG)
516 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
517 (match_operand:DI 1 "const0_operand" "n,n")))]
518 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
519 "@
520 test{q}\t{%0, %0|%0, %0}
521 cmp{q}\t{%1, %0|%0, %1}"
522 [(set_attr "type" "test,icmp")
523 (set_attr "length_immediate" "0,1")
524 (set_attr "mode" "DI")])
525
526 (define_insn "*cmpdi_minus_1_rex64"
527 [(set (reg FLAGS_REG)
528 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
529 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
530 (const_int 0)))]
531 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
532 "cmp{q}\t{%1, %0|%0, %1}"
533 [(set_attr "type" "icmp")
534 (set_attr "mode" "DI")])
535
536 (define_expand "cmpdi_1_rex64"
537 [(set (reg:CC FLAGS_REG)
538 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
539 (match_operand:DI 1 "general_operand" "")))]
540 "TARGET_64BIT"
541 "")
542
543 (define_insn "cmpdi_1_insn_rex64"
544 [(set (reg FLAGS_REG)
545 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
546 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
547 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
548 "cmp{q}\t{%1, %0|%0, %1}"
549 [(set_attr "type" "icmp")
550 (set_attr "mode" "DI")])
551
552
553 (define_insn "*cmpsi_ccno_1"
554 [(set (reg FLAGS_REG)
555 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
556 (match_operand:SI 1 "const0_operand" "n,n")))]
557 "ix86_match_ccmode (insn, CCNOmode)"
558 "@
559 test{l}\t{%0, %0|%0, %0}
560 cmp{l}\t{%1, %0|%0, %1}"
561 [(set_attr "type" "test,icmp")
562 (set_attr "length_immediate" "0,1")
563 (set_attr "mode" "SI")])
564
565 (define_insn "*cmpsi_minus_1"
566 [(set (reg FLAGS_REG)
567 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
568 (match_operand:SI 1 "general_operand" "ri,mr"))
569 (const_int 0)))]
570 "ix86_match_ccmode (insn, CCGOCmode)"
571 "cmp{l}\t{%1, %0|%0, %1}"
572 [(set_attr "type" "icmp")
573 (set_attr "mode" "SI")])
574
575 (define_expand "cmpsi_1"
576 [(set (reg:CC FLAGS_REG)
577 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
578 (match_operand:SI 1 "general_operand" "ri,mr")))]
579 ""
580 "")
581
582 (define_insn "*cmpsi_1_insn"
583 [(set (reg FLAGS_REG)
584 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
585 (match_operand:SI 1 "general_operand" "ri,mr")))]
586 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
587 && ix86_match_ccmode (insn, CCmode)"
588 "cmp{l}\t{%1, %0|%0, %1}"
589 [(set_attr "type" "icmp")
590 (set_attr "mode" "SI")])
591
592 (define_insn "*cmphi_ccno_1"
593 [(set (reg FLAGS_REG)
594 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
595 (match_operand:HI 1 "const0_operand" "n,n")))]
596 "ix86_match_ccmode (insn, CCNOmode)"
597 "@
598 test{w}\t{%0, %0|%0, %0}
599 cmp{w}\t{%1, %0|%0, %1}"
600 [(set_attr "type" "test,icmp")
601 (set_attr "length_immediate" "0,1")
602 (set_attr "mode" "HI")])
603
604 (define_insn "*cmphi_minus_1"
605 [(set (reg FLAGS_REG)
606 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
607 (match_operand:HI 1 "general_operand" "ri,mr"))
608 (const_int 0)))]
609 "ix86_match_ccmode (insn, CCGOCmode)"
610 "cmp{w}\t{%1, %0|%0, %1}"
611 [(set_attr "type" "icmp")
612 (set_attr "mode" "HI")])
613
614 (define_insn "*cmphi_1"
615 [(set (reg FLAGS_REG)
616 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
617 (match_operand:HI 1 "general_operand" "ri,mr")))]
618 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
619 && ix86_match_ccmode (insn, CCmode)"
620 "cmp{w}\t{%1, %0|%0, %1}"
621 [(set_attr "type" "icmp")
622 (set_attr "mode" "HI")])
623
624 (define_insn "*cmpqi_ccno_1"
625 [(set (reg FLAGS_REG)
626 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
627 (match_operand:QI 1 "const0_operand" "n,n")))]
628 "ix86_match_ccmode (insn, CCNOmode)"
629 "@
630 test{b}\t{%0, %0|%0, %0}
631 cmp{b}\t{$0, %0|%0, 0}"
632 [(set_attr "type" "test,icmp")
633 (set_attr "length_immediate" "0,1")
634 (set_attr "mode" "QI")])
635
636 (define_insn "*cmpqi_1"
637 [(set (reg FLAGS_REG)
638 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
639 (match_operand:QI 1 "general_operand" "qi,mq")))]
640 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
641 && ix86_match_ccmode (insn, CCmode)"
642 "cmp{b}\t{%1, %0|%0, %1}"
643 [(set_attr "type" "icmp")
644 (set_attr "mode" "QI")])
645
646 (define_insn "*cmpqi_minus_1"
647 [(set (reg FLAGS_REG)
648 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
649 (match_operand:QI 1 "general_operand" "qi,mq"))
650 (const_int 0)))]
651 "ix86_match_ccmode (insn, CCGOCmode)"
652 "cmp{b}\t{%1, %0|%0, %1}"
653 [(set_attr "type" "icmp")
654 (set_attr "mode" "QI")])
655
656 (define_insn "*cmpqi_ext_1"
657 [(set (reg FLAGS_REG)
658 (compare
659 (match_operand:QI 0 "general_operand" "Qm")
660 (subreg:QI
661 (zero_extract:SI
662 (match_operand 1 "ext_register_operand" "Q")
663 (const_int 8)
664 (const_int 8)) 0)))]
665 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
666 "cmp{b}\t{%h1, %0|%0, %h1}"
667 [(set_attr "type" "icmp")
668 (set_attr "mode" "QI")])
669
670 (define_insn "*cmpqi_ext_1_rex64"
671 [(set (reg FLAGS_REG)
672 (compare
673 (match_operand:QI 0 "register_operand" "Q")
674 (subreg:QI
675 (zero_extract:SI
676 (match_operand 1 "ext_register_operand" "Q")
677 (const_int 8)
678 (const_int 8)) 0)))]
679 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
680 "cmp{b}\t{%h1, %0|%0, %h1}"
681 [(set_attr "type" "icmp")
682 (set_attr "mode" "QI")])
683
684 (define_insn "*cmpqi_ext_2"
685 [(set (reg FLAGS_REG)
686 (compare
687 (subreg:QI
688 (zero_extract:SI
689 (match_operand 0 "ext_register_operand" "Q")
690 (const_int 8)
691 (const_int 8)) 0)
692 (match_operand:QI 1 "const0_operand" "n")))]
693 "ix86_match_ccmode (insn, CCNOmode)"
694 "test{b}\t%h0, %h0"
695 [(set_attr "type" "test")
696 (set_attr "length_immediate" "0")
697 (set_attr "mode" "QI")])
698
699 (define_expand "cmpqi_ext_3"
700 [(set (reg:CC FLAGS_REG)
701 (compare:CC
702 (subreg:QI
703 (zero_extract:SI
704 (match_operand 0 "ext_register_operand" "")
705 (const_int 8)
706 (const_int 8)) 0)
707 (match_operand:QI 1 "general_operand" "")))]
708 ""
709 "")
710
711 (define_insn "cmpqi_ext_3_insn"
712 [(set (reg FLAGS_REG)
713 (compare
714 (subreg:QI
715 (zero_extract:SI
716 (match_operand 0 "ext_register_operand" "Q")
717 (const_int 8)
718 (const_int 8)) 0)
719 (match_operand:QI 1 "general_operand" "Qmn")))]
720 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721 "cmp{b}\t{%1, %h0|%h0, %1}"
722 [(set_attr "type" "icmp")
723 (set_attr "mode" "QI")])
724
725 (define_insn "cmpqi_ext_3_insn_rex64"
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 "nonmemory_operand" "Qn")))]
734 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735 "cmp{b}\t{%1, %h0|%h0, %1}"
736 [(set_attr "type" "icmp")
737 (set_attr "mode" "QI")])
738
739 (define_insn "*cmpqi_ext_4"
740 [(set (reg FLAGS_REG)
741 (compare
742 (subreg:QI
743 (zero_extract:SI
744 (match_operand 0 "ext_register_operand" "Q")
745 (const_int 8)
746 (const_int 8)) 0)
747 (subreg:QI
748 (zero_extract:SI
749 (match_operand 1 "ext_register_operand" "Q")
750 (const_int 8)
751 (const_int 8)) 0)))]
752 "ix86_match_ccmode (insn, CCmode)"
753 "cmp{b}\t{%h1, %h0|%h0, %h1}"
754 [(set_attr "type" "icmp")
755 (set_attr "mode" "QI")])
756
757 ;; These implement float point compares.
758 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
759 ;; which would allow mix and match FP modes on the compares. Which is what
760 ;; the old patterns did, but with many more of them.
761
762 (define_expand "cmpxf"
763 [(set (reg:CC FLAGS_REG)
764 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
765 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
766 "TARGET_80387"
767 {
768 ix86_compare_op0 = operands[0];
769 ix86_compare_op1 = operands[1];
770 DONE;
771 })
772
773 (define_expand "cmpdf"
774 [(set (reg:CC FLAGS_REG)
775 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
776 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
777 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
778 {
779 ix86_compare_op0 = operands[0];
780 ix86_compare_op1 = operands[1];
781 DONE;
782 })
783
784 (define_expand "cmpsf"
785 [(set (reg:CC FLAGS_REG)
786 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
787 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
788 "TARGET_80387 || TARGET_SSE_MATH"
789 {
790 ix86_compare_op0 = operands[0];
791 ix86_compare_op1 = operands[1];
792 DONE;
793 })
794
795 ;; FP compares, step 1:
796 ;; Set the FP condition codes.
797 ;;
798 ;; CCFPmode compare with exceptions
799 ;; CCFPUmode compare with no exceptions
800
801 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
802 ;; used to manage the reg stack popping would not be preserved.
803
804 (define_insn "*cmpfp_0_sf"
805 [(set (match_operand:HI 0 "register_operand" "=a")
806 (unspec:HI
807 [(compare:CCFP
808 (match_operand:SF 1 "register_operand" "f")
809 (match_operand:SF 2 "const0_operand" "X"))]
810 UNSPEC_FNSTSW))]
811 "TARGET_80387"
812 "* return output_fp_compare (insn, operands, 0, 0);"
813 [(set_attr "type" "multi")
814 (set_attr "mode" "SF")])
815
816 (define_insn "*cmpfp_0_df"
817 [(set (match_operand:HI 0 "register_operand" "=a")
818 (unspec:HI
819 [(compare:CCFP
820 (match_operand:DF 1 "register_operand" "f")
821 (match_operand:DF 2 "const0_operand" "X"))]
822 UNSPEC_FNSTSW))]
823 "TARGET_80387"
824 "* return output_fp_compare (insn, operands, 0, 0);"
825 [(set_attr "type" "multi")
826 (set_attr "mode" "DF")])
827
828 (define_insn "*cmpfp_0_xf"
829 [(set (match_operand:HI 0 "register_operand" "=a")
830 (unspec:HI
831 [(compare:CCFP
832 (match_operand:XF 1 "register_operand" "f")
833 (match_operand:XF 2 "const0_operand" "X"))]
834 UNSPEC_FNSTSW))]
835 "TARGET_80387"
836 "* return output_fp_compare (insn, operands, 0, 0);"
837 [(set_attr "type" "multi")
838 (set_attr "mode" "XF")])
839
840 (define_insn "*cmpfp_sf"
841 [(set (match_operand:HI 0 "register_operand" "=a")
842 (unspec:HI
843 [(compare:CCFP
844 (match_operand:SF 1 "register_operand" "f")
845 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
846 UNSPEC_FNSTSW))]
847 "TARGET_80387"
848 "* return output_fp_compare (insn, operands, 0, 0);"
849 [(set_attr "type" "multi")
850 (set_attr "mode" "SF")])
851
852 (define_insn "*cmpfp_df"
853 [(set (match_operand:HI 0 "register_operand" "=a")
854 (unspec:HI
855 [(compare:CCFP
856 (match_operand:DF 1 "register_operand" "f")
857 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
858 UNSPEC_FNSTSW))]
859 "TARGET_80387"
860 "* return output_fp_compare (insn, operands, 0, 0);"
861 [(set_attr "type" "multi")
862 (set_attr "mode" "DF")])
863
864 (define_insn "*cmpfp_xf"
865 [(set (match_operand:HI 0 "register_operand" "=a")
866 (unspec:HI
867 [(compare:CCFP
868 (match_operand:XF 1 "register_operand" "f")
869 (match_operand:XF 2 "register_operand" "f"))]
870 UNSPEC_FNSTSW))]
871 "TARGET_80387"
872 "* return output_fp_compare (insn, operands, 0, 0);"
873 [(set_attr "type" "multi")
874 (set_attr "mode" "XF")])
875
876 (define_insn "*cmpfp_u"
877 [(set (match_operand:HI 0 "register_operand" "=a")
878 (unspec:HI
879 [(compare:CCFPU
880 (match_operand 1 "register_operand" "f")
881 (match_operand 2 "register_operand" "f"))]
882 UNSPEC_FNSTSW))]
883 "TARGET_80387
884 && FLOAT_MODE_P (GET_MODE (operands[1]))
885 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
886 "* return output_fp_compare (insn, operands, 0, 1);"
887 [(set_attr "type" "multi")
888 (set (attr "mode")
889 (cond [(match_operand:SF 1 "" "")
890 (const_string "SF")
891 (match_operand:DF 1 "" "")
892 (const_string "DF")
893 ]
894 (const_string "XF")))])
895
896 (define_insn "*cmpfp_si"
897 [(set (match_operand:HI 0 "register_operand" "=a")
898 (unspec:HI
899 [(compare:CCFP
900 (match_operand 1 "register_operand" "f")
901 (match_operator 3 "float_operator"
902 [(match_operand:SI 2 "memory_operand" "m")]))]
903 UNSPEC_FNSTSW))]
904 "TARGET_80387 && TARGET_USE_FIOP
905 && FLOAT_MODE_P (GET_MODE (operands[1]))
906 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
907 "* return output_fp_compare (insn, operands, 0, 0);"
908 [(set_attr "type" "multi")
909 (set_attr "fp_int_src" "true")
910 (set_attr "mode" "SI")])
911
912 ;; FP compares, step 2
913 ;; Move the fpsw to ax.
914
915 (define_insn "x86_fnstsw_1"
916 [(set (match_operand:HI 0 "register_operand" "=a")
917 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
918 "TARGET_80387"
919 "fnstsw\t%0"
920 [(set_attr "length" "2")
921 (set_attr "mode" "SI")
922 (set_attr "unit" "i387")])
923
924 ;; FP compares, step 3
925 ;; Get ax into flags, general case.
926
927 (define_insn "x86_sahf_1"
928 [(set (reg:CC FLAGS_REG)
929 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
930 "!TARGET_64BIT"
931 "sahf"
932 [(set_attr "length" "1")
933 (set_attr "athlon_decode" "vector")
934 (set_attr "mode" "SI")])
935
936 ;; Pentium Pro can do steps 1 through 3 in one go.
937
938 (define_insn "*cmpfp_i_mixed"
939 [(set (reg:CCFP FLAGS_REG)
940 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
941 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
942 "TARGET_MIX_SSE_I387
943 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
944 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945 "* return output_fp_compare (insn, operands, 1, 0);"
946 [(set_attr "type" "fcmp,ssecomi")
947 (set (attr "mode")
948 (if_then_else (match_operand:SF 1 "" "")
949 (const_string "SF")
950 (const_string "DF")))
951 (set_attr "athlon_decode" "vector")])
952
953 (define_insn "*cmpfp_i_sse"
954 [(set (reg:CCFP FLAGS_REG)
955 (compare:CCFP (match_operand 0 "register_operand" "x")
956 (match_operand 1 "nonimmediate_operand" "xm")))]
957 "TARGET_SSE_MATH
958 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
959 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
960 "* return output_fp_compare (insn, operands, 1, 0);"
961 [(set_attr "type" "ssecomi")
962 (set (attr "mode")
963 (if_then_else (match_operand:SF 1 "" "")
964 (const_string "SF")
965 (const_string "DF")))
966 (set_attr "athlon_decode" "vector")])
967
968 (define_insn "*cmpfp_i_i387"
969 [(set (reg:CCFP FLAGS_REG)
970 (compare:CCFP (match_operand 0 "register_operand" "f")
971 (match_operand 1 "register_operand" "f")))]
972 "TARGET_80387 && TARGET_CMOVE
973 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
974 && 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")
978 (set (attr "mode")
979 (cond [(match_operand:SF 1 "" "")
980 (const_string "SF")
981 (match_operand:DF 1 "" "")
982 (const_string "DF")
983 ]
984 (const_string "XF")))
985 (set_attr "athlon_decode" "vector")])
986
987 (define_insn "*cmpfp_iu_mixed"
988 [(set (reg:CCFPU FLAGS_REG)
989 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
990 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
991 "TARGET_MIX_SSE_I387
992 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
993 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
994 "* return output_fp_compare (insn, operands, 1, 1);"
995 [(set_attr "type" "fcmp,ssecomi")
996 (set (attr "mode")
997 (if_then_else (match_operand:SF 1 "" "")
998 (const_string "SF")
999 (const_string "DF")))
1000 (set_attr "athlon_decode" "vector")])
1001
1002 (define_insn "*cmpfp_iu_sse"
1003 [(set (reg:CCFPU FLAGS_REG)
1004 (compare:CCFPU (match_operand 0 "register_operand" "x")
1005 (match_operand 1 "nonimmediate_operand" "xm")))]
1006 "TARGET_SSE_MATH
1007 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1008 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1009 "* return output_fp_compare (insn, operands, 1, 1);"
1010 [(set_attr "type" "ssecomi")
1011 (set (attr "mode")
1012 (if_then_else (match_operand:SF 1 "" "")
1013 (const_string "SF")
1014 (const_string "DF")))
1015 (set_attr "athlon_decode" "vector")])
1016
1017 (define_insn "*cmpfp_iu_387"
1018 [(set (reg:CCFPU FLAGS_REG)
1019 (compare:CCFPU (match_operand 0 "register_operand" "f")
1020 (match_operand 1 "register_operand" "f")))]
1021 "TARGET_80387 && TARGET_CMOVE
1022 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1023 && 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")
1027 (set (attr "mode")
1028 (cond [(match_operand:SF 1 "" "")
1029 (const_string "SF")
1030 (match_operand:DF 1 "" "")
1031 (const_string "DF")
1032 ]
1033 (const_string "XF")))
1034 (set_attr "athlon_decode" "vector")])
1035 \f
1036 ;; Move instructions.
1037
1038 ;; General case of fullword move.
1039
1040 (define_expand "movsi"
1041 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1042 (match_operand:SI 1 "general_operand" ""))]
1043 ""
1044 "ix86_expand_move (SImode, operands); DONE;")
1045
1046 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1047 ;; general_operand.
1048 ;;
1049 ;; %%% We don't use a post-inc memory reference because x86 is not a
1050 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1051 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1052 ;; targets without our curiosities, and it is just as easy to represent
1053 ;; this differently.
1054
1055 (define_insn "*pushsi2"
1056 [(set (match_operand:SI 0 "push_operand" "=<")
1057 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1058 "!TARGET_64BIT"
1059 "push{l}\t%1"
1060 [(set_attr "type" "push")
1061 (set_attr "mode" "SI")])
1062
1063 ;; For 64BIT abi we always round up to 8 bytes.
1064 (define_insn "*pushsi2_rex64"
1065 [(set (match_operand:SI 0 "push_operand" "=X")
1066 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1067 "TARGET_64BIT"
1068 "push{q}\t%q1"
1069 [(set_attr "type" "push")
1070 (set_attr "mode" "SI")])
1071
1072 (define_insn "*pushsi2_prologue"
1073 [(set (match_operand:SI 0 "push_operand" "=<")
1074 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1075 (clobber (mem:BLK (scratch)))]
1076 "!TARGET_64BIT"
1077 "push{l}\t%1"
1078 [(set_attr "type" "push")
1079 (set_attr "mode" "SI")])
1080
1081 (define_insn "*popsi1_epilogue"
1082 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1083 (mem:SI (reg:SI SP_REG)))
1084 (set (reg:SI SP_REG)
1085 (plus:SI (reg:SI SP_REG) (const_int 4)))
1086 (clobber (mem:BLK (scratch)))]
1087 "!TARGET_64BIT"
1088 "pop{l}\t%0"
1089 [(set_attr "type" "pop")
1090 (set_attr "mode" "SI")])
1091
1092 (define_insn "popsi1"
1093 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1094 (mem:SI (reg:SI SP_REG)))
1095 (set (reg:SI SP_REG)
1096 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1097 "!TARGET_64BIT"
1098 "pop{l}\t%0"
1099 [(set_attr "type" "pop")
1100 (set_attr "mode" "SI")])
1101
1102 (define_insn "*movsi_xor"
1103 [(set (match_operand:SI 0 "register_operand" "=r")
1104 (match_operand:SI 1 "const0_operand" "i"))
1105 (clobber (reg:CC FLAGS_REG))]
1106 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1107 "xor{l}\t{%0, %0|%0, %0}"
1108 [(set_attr "type" "alu1")
1109 (set_attr "mode" "SI")
1110 (set_attr "length_immediate" "0")])
1111
1112 (define_insn "*movsi_or"
1113 [(set (match_operand:SI 0 "register_operand" "=r")
1114 (match_operand:SI 1 "immediate_operand" "i"))
1115 (clobber (reg:CC FLAGS_REG))]
1116 "reload_completed
1117 && operands[1] == constm1_rtx
1118 && (TARGET_PENTIUM || optimize_size)"
1119 {
1120 operands[1] = constm1_rtx;
1121 return "or{l}\t{%1, %0|%0, %1}";
1122 }
1123 [(set_attr "type" "alu1")
1124 (set_attr "mode" "SI")
1125 (set_attr "length_immediate" "1")])
1126
1127 (define_insn "*movsi_1"
1128 [(set (match_operand:SI 0 "nonimmediate_operand"
1129 "=r ,m ,!*y,!rm,!*y,!*x,!rm,!*x")
1130 (match_operand:SI 1 "general_operand"
1131 "rinm,rin,*y ,*y ,rm ,*x ,*x ,rm"))]
1132 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1133 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1134 {
1135 switch (get_attr_type (insn))
1136 {
1137 case TYPE_SSEMOV:
1138 if (get_attr_mode (insn) == MODE_TI)
1139 return "movdqa\t{%1, %0|%0, %1}";
1140 return "movd\t{%1, %0|%0, %1}";
1141
1142 case TYPE_MMXMOV:
1143 if (get_attr_mode (insn) == MODE_DI)
1144 return "movq\t{%1, %0|%0, %1}";
1145 return "movd\t{%1, %0|%0, %1}";
1146
1147 case TYPE_LEA:
1148 return "lea{l}\t{%1, %0|%0, %1}";
1149
1150 default:
1151 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1152 abort();
1153 return "mov{l}\t{%1, %0|%0, %1}";
1154 }
1155 }
1156 [(set (attr "type")
1157 (cond [(eq_attr "alternative" "2,3,4")
1158 (const_string "mmxmov")
1159 (eq_attr "alternative" "5,6,7")
1160 (const_string "ssemov")
1161 (and (ne (symbol_ref "flag_pic") (const_int 0))
1162 (match_operand:SI 1 "symbolic_operand" ""))
1163 (const_string "lea")
1164 ]
1165 (const_string "imov")))
1166 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1167
1168 (define_insn "*movsi_1_nointernunit"
1169 [(set (match_operand:SI 0 "nonimmediate_operand"
1170 "=r ,m ,!*y,!m,!*y,!*x,!m,!*x")
1171 (match_operand:SI 1 "general_operand"
1172 "rinm,rin,*y ,*y,m ,*x ,*x,m"))]
1173 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1174 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1175 {
1176 switch (get_attr_type (insn))
1177 {
1178 case TYPE_SSEMOV:
1179 if (get_attr_mode (insn) == MODE_TI)
1180 return "movdqa\t{%1, %0|%0, %1}";
1181 return "movd\t{%1, %0|%0, %1}";
1182
1183 case TYPE_MMXMOV:
1184 if (get_attr_mode (insn) == MODE_DI)
1185 return "movq\t{%1, %0|%0, %1}";
1186 return "movd\t{%1, %0|%0, %1}";
1187
1188 case TYPE_LEA:
1189 return "lea{l}\t{%1, %0|%0, %1}";
1190
1191 default:
1192 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1193 abort();
1194 return "mov{l}\t{%1, %0|%0, %1}";
1195 }
1196 }
1197 [(set (attr "type")
1198 (cond [(eq_attr "alternative" "2,3,4")
1199 (const_string "mmxmov")
1200 (eq_attr "alternative" "5,6,7")
1201 (const_string "ssemov")
1202 (and (ne (symbol_ref "flag_pic") (const_int 0))
1203 (match_operand:SI 1 "symbolic_operand" ""))
1204 (const_string "lea")
1205 ]
1206 (const_string "imov")))
1207 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1208
1209 ;; Stores and loads of ax to arbitrary constant address.
1210 ;; We fake an second form of instruction to force reload to load address
1211 ;; into register when rax is not available
1212 (define_insn "*movabssi_1_rex64"
1213 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1214 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1215 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1216 "@
1217 movabs{l}\t{%1, %P0|%P0, %1}
1218 mov{l}\t{%1, %a0|%a0, %1}"
1219 [(set_attr "type" "imov")
1220 (set_attr "modrm" "0,*")
1221 (set_attr "length_address" "8,0")
1222 (set_attr "length_immediate" "0,*")
1223 (set_attr "memory" "store")
1224 (set_attr "mode" "SI")])
1225
1226 (define_insn "*movabssi_2_rex64"
1227 [(set (match_operand:SI 0 "register_operand" "=a,r")
1228 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1229 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1230 "@
1231 movabs{l}\t{%P1, %0|%0, %P1}
1232 mov{l}\t{%a1, %0|%0, %a1}"
1233 [(set_attr "type" "imov")
1234 (set_attr "modrm" "0,*")
1235 (set_attr "length_address" "8,0")
1236 (set_attr "length_immediate" "0")
1237 (set_attr "memory" "load")
1238 (set_attr "mode" "SI")])
1239
1240 (define_insn "*swapsi"
1241 [(set (match_operand:SI 0 "register_operand" "+r")
1242 (match_operand:SI 1 "register_operand" "+r"))
1243 (set (match_dup 1)
1244 (match_dup 0))]
1245 ""
1246 "xchg{l}\t%1, %0"
1247 [(set_attr "type" "imov")
1248 (set_attr "mode" "SI")
1249 (set_attr "pent_pair" "np")
1250 (set_attr "athlon_decode" "vector")])
1251
1252 (define_expand "movhi"
1253 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1254 (match_operand:HI 1 "general_operand" ""))]
1255 ""
1256 "ix86_expand_move (HImode, operands); DONE;")
1257
1258 (define_insn "*pushhi2"
1259 [(set (match_operand:HI 0 "push_operand" "=<,<")
1260 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1261 "!TARGET_64BIT"
1262 "@
1263 push{w}\t{|WORD PTR }%1
1264 push{w}\t%1"
1265 [(set_attr "type" "push")
1266 (set_attr "mode" "HI")])
1267
1268 ;; For 64BIT abi we always round up to 8 bytes.
1269 (define_insn "*pushhi2_rex64"
1270 [(set (match_operand:HI 0 "push_operand" "=X")
1271 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1272 "TARGET_64BIT"
1273 "push{q}\t%q1"
1274 [(set_attr "type" "push")
1275 (set_attr "mode" "QI")])
1276
1277 (define_insn "*movhi_1"
1278 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1279 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1280 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1281 {
1282 switch (get_attr_type (insn))
1283 {
1284 case TYPE_IMOVX:
1285 /* movzwl is faster than movw on p2 due to partial word stalls,
1286 though not as fast as an aligned movl. */
1287 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1288 default:
1289 if (get_attr_mode (insn) == MODE_SI)
1290 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1291 else
1292 return "mov{w}\t{%1, %0|%0, %1}";
1293 }
1294 }
1295 [(set (attr "type")
1296 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1297 (const_string "imov")
1298 (and (eq_attr "alternative" "0")
1299 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1300 (const_int 0))
1301 (eq (symbol_ref "TARGET_HIMODE_MATH")
1302 (const_int 0))))
1303 (const_string "imov")
1304 (and (eq_attr "alternative" "1,2")
1305 (match_operand:HI 1 "aligned_operand" ""))
1306 (const_string "imov")
1307 (and (ne (symbol_ref "TARGET_MOVX")
1308 (const_int 0))
1309 (eq_attr "alternative" "0,2"))
1310 (const_string "imovx")
1311 ]
1312 (const_string "imov")))
1313 (set (attr "mode")
1314 (cond [(eq_attr "type" "imovx")
1315 (const_string "SI")
1316 (and (eq_attr "alternative" "1,2")
1317 (match_operand:HI 1 "aligned_operand" ""))
1318 (const_string "SI")
1319 (and (eq_attr "alternative" "0")
1320 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1321 (const_int 0))
1322 (eq (symbol_ref "TARGET_HIMODE_MATH")
1323 (const_int 0))))
1324 (const_string "SI")
1325 ]
1326 (const_string "HI")))])
1327
1328 ;; Stores and loads of ax to arbitrary constant address.
1329 ;; We fake an second form of instruction to force reload to load address
1330 ;; into register when rax is not available
1331 (define_insn "*movabshi_1_rex64"
1332 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1333 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1334 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1335 "@
1336 movabs{w}\t{%1, %P0|%P0, %1}
1337 mov{w}\t{%1, %a0|%a0, %1}"
1338 [(set_attr "type" "imov")
1339 (set_attr "modrm" "0,*")
1340 (set_attr "length_address" "8,0")
1341 (set_attr "length_immediate" "0,*")
1342 (set_attr "memory" "store")
1343 (set_attr "mode" "HI")])
1344
1345 (define_insn "*movabshi_2_rex64"
1346 [(set (match_operand:HI 0 "register_operand" "=a,r")
1347 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1348 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1349 "@
1350 movabs{w}\t{%P1, %0|%0, %P1}
1351 mov{w}\t{%a1, %0|%0, %a1}"
1352 [(set_attr "type" "imov")
1353 (set_attr "modrm" "0,*")
1354 (set_attr "length_address" "8,0")
1355 (set_attr "length_immediate" "0")
1356 (set_attr "memory" "load")
1357 (set_attr "mode" "HI")])
1358
1359 (define_insn "*swaphi_1"
1360 [(set (match_operand:HI 0 "register_operand" "+r")
1361 (match_operand:HI 1 "register_operand" "+r"))
1362 (set (match_dup 1)
1363 (match_dup 0))]
1364 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1365 "xchg{l}\t%k1, %k0"
1366 [(set_attr "type" "imov")
1367 (set_attr "mode" "SI")
1368 (set_attr "pent_pair" "np")
1369 (set_attr "athlon_decode" "vector")])
1370
1371 (define_insn "*swaphi_2"
1372 [(set (match_operand:HI 0 "register_operand" "+r")
1373 (match_operand:HI 1 "register_operand" "+r"))
1374 (set (match_dup 1)
1375 (match_dup 0))]
1376 "TARGET_PARTIAL_REG_STALL"
1377 "xchg{w}\t%1, %0"
1378 [(set_attr "type" "imov")
1379 (set_attr "mode" "HI")
1380 (set_attr "pent_pair" "np")
1381 (set_attr "athlon_decode" "vector")])
1382
1383 (define_expand "movstricthi"
1384 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1385 (match_operand:HI 1 "general_operand" ""))]
1386 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1387 {
1388 /* Don't generate memory->memory moves, go through a register */
1389 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1390 operands[1] = force_reg (HImode, operands[1]);
1391 })
1392
1393 (define_insn "*movstricthi_1"
1394 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1395 (match_operand:HI 1 "general_operand" "rn,m"))]
1396 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1397 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1398 "mov{w}\t{%1, %0|%0, %1}"
1399 [(set_attr "type" "imov")
1400 (set_attr "mode" "HI")])
1401
1402 (define_insn "*movstricthi_xor"
1403 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1404 (match_operand:HI 1 "const0_operand" "i"))
1405 (clobber (reg:CC FLAGS_REG))]
1406 "reload_completed
1407 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1408 "xor{w}\t{%0, %0|%0, %0}"
1409 [(set_attr "type" "alu1")
1410 (set_attr "mode" "HI")
1411 (set_attr "length_immediate" "0")])
1412
1413 (define_expand "movqi"
1414 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1415 (match_operand:QI 1 "general_operand" ""))]
1416 ""
1417 "ix86_expand_move (QImode, operands); DONE;")
1418
1419 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1420 ;; "push a byte". But actually we use pushw, which has the effect
1421 ;; of rounding the amount pushed up to a halfword.
1422
1423 (define_insn "*pushqi2"
1424 [(set (match_operand:QI 0 "push_operand" "=X,X")
1425 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1426 "!TARGET_64BIT"
1427 "@
1428 push{w}\t{|word ptr }%1
1429 push{w}\t%w1"
1430 [(set_attr "type" "push")
1431 (set_attr "mode" "HI")])
1432
1433 ;; For 64BIT abi we always round up to 8 bytes.
1434 (define_insn "*pushqi2_rex64"
1435 [(set (match_operand:QI 0 "push_operand" "=X")
1436 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1437 "TARGET_64BIT"
1438 "push{q}\t%q1"
1439 [(set_attr "type" "push")
1440 (set_attr "mode" "QI")])
1441
1442 ;; Situation is quite tricky about when to choose full sized (SImode) move
1443 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1444 ;; partial register dependency machines (such as AMD Athlon), where QImode
1445 ;; moves issue extra dependency and for partial register stalls machines
1446 ;; that don't use QImode patterns (and QImode move cause stall on the next
1447 ;; instruction).
1448 ;;
1449 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1450 ;; register stall machines with, where we use QImode instructions, since
1451 ;; partial register stall can be caused there. Then we use movzx.
1452 (define_insn "*movqi_1"
1453 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1454 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1455 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1456 {
1457 switch (get_attr_type (insn))
1458 {
1459 case TYPE_IMOVX:
1460 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1461 abort ();
1462 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1463 default:
1464 if (get_attr_mode (insn) == MODE_SI)
1465 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1466 else
1467 return "mov{b}\t{%1, %0|%0, %1}";
1468 }
1469 }
1470 [(set (attr "type")
1471 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1472 (const_string "imov")
1473 (and (eq_attr "alternative" "3")
1474 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1475 (const_int 0))
1476 (eq (symbol_ref "TARGET_QIMODE_MATH")
1477 (const_int 0))))
1478 (const_string "imov")
1479 (eq_attr "alternative" "3,5")
1480 (const_string "imovx")
1481 (and (ne (symbol_ref "TARGET_MOVX")
1482 (const_int 0))
1483 (eq_attr "alternative" "2"))
1484 (const_string "imovx")
1485 ]
1486 (const_string "imov")))
1487 (set (attr "mode")
1488 (cond [(eq_attr "alternative" "3,4,5")
1489 (const_string "SI")
1490 (eq_attr "alternative" "6")
1491 (const_string "QI")
1492 (eq_attr "type" "imovx")
1493 (const_string "SI")
1494 (and (eq_attr "type" "imov")
1495 (and (eq_attr "alternative" "0,1")
1496 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1497 (const_int 0))))
1498 (const_string "SI")
1499 ;; Avoid partial register stalls when not using QImode arithmetic
1500 (and (eq_attr "type" "imov")
1501 (and (eq_attr "alternative" "0,1")
1502 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1503 (const_int 0))
1504 (eq (symbol_ref "TARGET_QIMODE_MATH")
1505 (const_int 0)))))
1506 (const_string "SI")
1507 ]
1508 (const_string "QI")))])
1509
1510 (define_expand "reload_outqi"
1511 [(parallel [(match_operand:QI 0 "" "=m")
1512 (match_operand:QI 1 "register_operand" "r")
1513 (match_operand:QI 2 "register_operand" "=&q")])]
1514 ""
1515 {
1516 rtx op0, op1, op2;
1517 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1518
1519 if (reg_overlap_mentioned_p (op2, op0))
1520 abort ();
1521 if (! q_regs_operand (op1, QImode))
1522 {
1523 emit_insn (gen_movqi (op2, op1));
1524 op1 = op2;
1525 }
1526 emit_insn (gen_movqi (op0, op1));
1527 DONE;
1528 })
1529
1530 (define_insn "*swapqi_1"
1531 [(set (match_operand:QI 0 "register_operand" "+r")
1532 (match_operand:QI 1 "register_operand" "+r"))
1533 (set (match_dup 1)
1534 (match_dup 0))]
1535 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1536 "xchg{l}\t%k1, %k0"
1537 [(set_attr "type" "imov")
1538 (set_attr "mode" "SI")
1539 (set_attr "pent_pair" "np")
1540 (set_attr "athlon_decode" "vector")])
1541
1542 (define_insn "*swapqi_2"
1543 [(set (match_operand:QI 0 "register_operand" "+q")
1544 (match_operand:QI 1 "register_operand" "+q"))
1545 (set (match_dup 1)
1546 (match_dup 0))]
1547 "TARGET_PARTIAL_REG_STALL"
1548 "xchg{b}\t%1, %0"
1549 [(set_attr "type" "imov")
1550 (set_attr "mode" "QI")
1551 (set_attr "pent_pair" "np")
1552 (set_attr "athlon_decode" "vector")])
1553
1554 (define_expand "movstrictqi"
1555 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1556 (match_operand:QI 1 "general_operand" ""))]
1557 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1558 {
1559 /* Don't generate memory->memory moves, go through a register. */
1560 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1561 operands[1] = force_reg (QImode, operands[1]);
1562 })
1563
1564 (define_insn "*movstrictqi_1"
1565 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1566 (match_operand:QI 1 "general_operand" "*qn,m"))]
1567 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1568 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1569 "mov{b}\t{%1, %0|%0, %1}"
1570 [(set_attr "type" "imov")
1571 (set_attr "mode" "QI")])
1572
1573 (define_insn "*movstrictqi_xor"
1574 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1575 (match_operand:QI 1 "const0_operand" "i"))
1576 (clobber (reg:CC FLAGS_REG))]
1577 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1578 "xor{b}\t{%0, %0|%0, %0}"
1579 [(set_attr "type" "alu1")
1580 (set_attr "mode" "QI")
1581 (set_attr "length_immediate" "0")])
1582
1583 (define_insn "*movsi_extv_1"
1584 [(set (match_operand:SI 0 "register_operand" "=R")
1585 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1586 (const_int 8)
1587 (const_int 8)))]
1588 ""
1589 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1590 [(set_attr "type" "imovx")
1591 (set_attr "mode" "SI")])
1592
1593 (define_insn "*movhi_extv_1"
1594 [(set (match_operand:HI 0 "register_operand" "=R")
1595 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1596 (const_int 8)
1597 (const_int 8)))]
1598 ""
1599 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1600 [(set_attr "type" "imovx")
1601 (set_attr "mode" "SI")])
1602
1603 (define_insn "*movqi_extv_1"
1604 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1605 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1606 (const_int 8)
1607 (const_int 8)))]
1608 "!TARGET_64BIT"
1609 {
1610 switch (get_attr_type (insn))
1611 {
1612 case TYPE_IMOVX:
1613 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1614 default:
1615 return "mov{b}\t{%h1, %0|%0, %h1}";
1616 }
1617 }
1618 [(set (attr "type")
1619 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1620 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1621 (ne (symbol_ref "TARGET_MOVX")
1622 (const_int 0))))
1623 (const_string "imovx")
1624 (const_string "imov")))
1625 (set (attr "mode")
1626 (if_then_else (eq_attr "type" "imovx")
1627 (const_string "SI")
1628 (const_string "QI")))])
1629
1630 (define_insn "*movqi_extv_1_rex64"
1631 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1632 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1633 (const_int 8)
1634 (const_int 8)))]
1635 "TARGET_64BIT"
1636 {
1637 switch (get_attr_type (insn))
1638 {
1639 case TYPE_IMOVX:
1640 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1641 default:
1642 return "mov{b}\t{%h1, %0|%0, %h1}";
1643 }
1644 }
1645 [(set (attr "type")
1646 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1647 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1648 (ne (symbol_ref "TARGET_MOVX")
1649 (const_int 0))))
1650 (const_string "imovx")
1651 (const_string "imov")))
1652 (set (attr "mode")
1653 (if_then_else (eq_attr "type" "imovx")
1654 (const_string "SI")
1655 (const_string "QI")))])
1656
1657 ;; Stores and loads of ax to arbitrary constant address.
1658 ;; We fake an second form of instruction to force reload to load address
1659 ;; into register when rax is not available
1660 (define_insn "*movabsqi_1_rex64"
1661 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1662 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1663 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1664 "@
1665 movabs{b}\t{%1, %P0|%P0, %1}
1666 mov{b}\t{%1, %a0|%a0, %1}"
1667 [(set_attr "type" "imov")
1668 (set_attr "modrm" "0,*")
1669 (set_attr "length_address" "8,0")
1670 (set_attr "length_immediate" "0,*")
1671 (set_attr "memory" "store")
1672 (set_attr "mode" "QI")])
1673
1674 (define_insn "*movabsqi_2_rex64"
1675 [(set (match_operand:QI 0 "register_operand" "=a,r")
1676 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1677 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1678 "@
1679 movabs{b}\t{%P1, %0|%0, %P1}
1680 mov{b}\t{%a1, %0|%0, %a1}"
1681 [(set_attr "type" "imov")
1682 (set_attr "modrm" "0,*")
1683 (set_attr "length_address" "8,0")
1684 (set_attr "length_immediate" "0")
1685 (set_attr "memory" "load")
1686 (set_attr "mode" "QI")])
1687
1688 (define_insn "*movsi_extzv_1"
1689 [(set (match_operand:SI 0 "register_operand" "=R")
1690 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1691 (const_int 8)
1692 (const_int 8)))]
1693 ""
1694 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1695 [(set_attr "type" "imovx")
1696 (set_attr "mode" "SI")])
1697
1698 (define_insn "*movqi_extzv_2"
1699 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1700 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1701 (const_int 8)
1702 (const_int 8)) 0))]
1703 "!TARGET_64BIT"
1704 {
1705 switch (get_attr_type (insn))
1706 {
1707 case TYPE_IMOVX:
1708 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1709 default:
1710 return "mov{b}\t{%h1, %0|%0, %h1}";
1711 }
1712 }
1713 [(set (attr "type")
1714 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1715 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1716 (ne (symbol_ref "TARGET_MOVX")
1717 (const_int 0))))
1718 (const_string "imovx")
1719 (const_string "imov")))
1720 (set (attr "mode")
1721 (if_then_else (eq_attr "type" "imovx")
1722 (const_string "SI")
1723 (const_string "QI")))])
1724
1725 (define_insn "*movqi_extzv_2_rex64"
1726 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1727 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1728 (const_int 8)
1729 (const_int 8)) 0))]
1730 "TARGET_64BIT"
1731 {
1732 switch (get_attr_type (insn))
1733 {
1734 case TYPE_IMOVX:
1735 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1736 default:
1737 return "mov{b}\t{%h1, %0|%0, %h1}";
1738 }
1739 }
1740 [(set (attr "type")
1741 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1742 (ne (symbol_ref "TARGET_MOVX")
1743 (const_int 0)))
1744 (const_string "imovx")
1745 (const_string "imov")))
1746 (set (attr "mode")
1747 (if_then_else (eq_attr "type" "imovx")
1748 (const_string "SI")
1749 (const_string "QI")))])
1750
1751 (define_insn "movsi_insv_1"
1752 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1753 (const_int 8)
1754 (const_int 8))
1755 (match_operand:SI 1 "general_operand" "Qmn"))]
1756 "!TARGET_64BIT"
1757 "mov{b}\t{%b1, %h0|%h0, %b1}"
1758 [(set_attr "type" "imov")
1759 (set_attr "mode" "QI")])
1760
1761 (define_insn "movdi_insv_1_rex64"
1762 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1763 (const_int 8)
1764 (const_int 8))
1765 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1766 "TARGET_64BIT"
1767 "mov{b}\t{%b1, %h0|%h0, %b1}"
1768 [(set_attr "type" "imov")
1769 (set_attr "mode" "QI")])
1770
1771 (define_insn "*movqi_insv_2"
1772 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1773 (const_int 8)
1774 (const_int 8))
1775 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1776 (const_int 8)))]
1777 ""
1778 "mov{b}\t{%h1, %h0|%h0, %h1}"
1779 [(set_attr "type" "imov")
1780 (set_attr "mode" "QI")])
1781
1782 (define_expand "movdi"
1783 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1784 (match_operand:DI 1 "general_operand" ""))]
1785 ""
1786 "ix86_expand_move (DImode, operands); DONE;")
1787
1788 (define_insn "*pushdi"
1789 [(set (match_operand:DI 0 "push_operand" "=<")
1790 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1791 "!TARGET_64BIT"
1792 "#")
1793
1794 (define_insn "*pushdi2_rex64"
1795 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1796 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1797 "TARGET_64BIT"
1798 "@
1799 push{q}\t%1
1800 #"
1801 [(set_attr "type" "push,multi")
1802 (set_attr "mode" "DI")])
1803
1804 ;; Convert impossible pushes of immediate to existing instructions.
1805 ;; First try to get scratch register and go through it. In case this
1806 ;; fails, push sign extended lower part first and then overwrite
1807 ;; upper part by 32bit move.
1808 (define_peephole2
1809 [(match_scratch:DI 2 "r")
1810 (set (match_operand:DI 0 "push_operand" "")
1811 (match_operand:DI 1 "immediate_operand" ""))]
1812 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1813 && !x86_64_immediate_operand (operands[1], DImode)"
1814 [(set (match_dup 2) (match_dup 1))
1815 (set (match_dup 0) (match_dup 2))]
1816 "")
1817
1818 ;; We need to define this as both peepholer and splitter for case
1819 ;; peephole2 pass is not run.
1820 ;; "&& 1" is needed to keep it from matching the previous pattern.
1821 (define_peephole2
1822 [(set (match_operand:DI 0 "push_operand" "")
1823 (match_operand:DI 1 "immediate_operand" ""))]
1824 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1825 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1826 [(set (match_dup 0) (match_dup 1))
1827 (set (match_dup 2) (match_dup 3))]
1828 "split_di (operands + 1, 1, operands + 2, operands + 3);
1829 operands[1] = gen_lowpart (DImode, operands[2]);
1830 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1831 GEN_INT (4)));
1832 ")
1833
1834 (define_split
1835 [(set (match_operand:DI 0 "push_operand" "")
1836 (match_operand:DI 1 "immediate_operand" ""))]
1837 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1838 && !symbolic_operand (operands[1], DImode)
1839 && !x86_64_immediate_operand (operands[1], DImode)"
1840 [(set (match_dup 0) (match_dup 1))
1841 (set (match_dup 2) (match_dup 3))]
1842 "split_di (operands + 1, 1, operands + 2, operands + 3);
1843 operands[1] = gen_lowpart (DImode, operands[2]);
1844 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1845 GEN_INT (4)));
1846 ")
1847
1848 (define_insn "*pushdi2_prologue_rex64"
1849 [(set (match_operand:DI 0 "push_operand" "=<")
1850 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1851 (clobber (mem:BLK (scratch)))]
1852 "TARGET_64BIT"
1853 "push{q}\t%1"
1854 [(set_attr "type" "push")
1855 (set_attr "mode" "DI")])
1856
1857 (define_insn "*popdi1_epilogue_rex64"
1858 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1859 (mem:DI (reg:DI SP_REG)))
1860 (set (reg:DI SP_REG)
1861 (plus:DI (reg:DI SP_REG) (const_int 8)))
1862 (clobber (mem:BLK (scratch)))]
1863 "TARGET_64BIT"
1864 "pop{q}\t%0"
1865 [(set_attr "type" "pop")
1866 (set_attr "mode" "DI")])
1867
1868 (define_insn "popdi1"
1869 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1870 (mem:DI (reg:DI SP_REG)))
1871 (set (reg:DI SP_REG)
1872 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1873 "TARGET_64BIT"
1874 "pop{q}\t%0"
1875 [(set_attr "type" "pop")
1876 (set_attr "mode" "DI")])
1877
1878 (define_insn "*movdi_xor_rex64"
1879 [(set (match_operand:DI 0 "register_operand" "=r")
1880 (match_operand:DI 1 "const0_operand" "i"))
1881 (clobber (reg:CC FLAGS_REG))]
1882 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1883 && reload_completed"
1884 "xor{l}\t{%k0, %k0|%k0, %k0}"
1885 [(set_attr "type" "alu1")
1886 (set_attr "mode" "SI")
1887 (set_attr "length_immediate" "0")])
1888
1889 (define_insn "*movdi_or_rex64"
1890 [(set (match_operand:DI 0 "register_operand" "=r")
1891 (match_operand:DI 1 "const_int_operand" "i"))
1892 (clobber (reg:CC FLAGS_REG))]
1893 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1894 && reload_completed
1895 && operands[1] == constm1_rtx"
1896 {
1897 operands[1] = constm1_rtx;
1898 return "or{q}\t{%1, %0|%0, %1}";
1899 }
1900 [(set_attr "type" "alu1")
1901 (set_attr "mode" "DI")
1902 (set_attr "length_immediate" "1")])
1903
1904 (define_insn "*movdi_2"
1905 [(set (match_operand:DI 0 "nonimmediate_operand"
1906 "=r ,o ,m*y,*y,m ,*Y,*Y,m ,*x,*x")
1907 (match_operand:DI 1 "general_operand"
1908 "riFo,riF,*y ,m ,*Y,*Y,m ,*x,*x,m "))]
1909 "!TARGET_64BIT
1910 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1911 "@
1912 #
1913 #
1914 movq\t{%1, %0|%0, %1}
1915 movq\t{%1, %0|%0, %1}
1916 movq\t{%1, %0|%0, %1}
1917 movdqa\t{%1, %0|%0, %1}
1918 movq\t{%1, %0|%0, %1}
1919 movlps\t{%1, %0|%0, %1}
1920 movaps\t{%1, %0|%0, %1}
1921 movlps\t{%1, %0|%0, %1}"
1922 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov")
1923 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,V2SF,V4SF,V2SF")])
1924
1925 (define_split
1926 [(set (match_operand:DI 0 "push_operand" "")
1927 (match_operand:DI 1 "general_operand" ""))]
1928 "!TARGET_64BIT && reload_completed
1929 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1930 [(const_int 0)]
1931 "ix86_split_long_move (operands); DONE;")
1932
1933 ;; %%% This multiword shite has got to go.
1934 (define_split
1935 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1936 (match_operand:DI 1 "general_operand" ""))]
1937 "!TARGET_64BIT && reload_completed
1938 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1939 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1940 [(const_int 0)]
1941 "ix86_split_long_move (operands); DONE;")
1942
1943 (define_insn "*movdi_1_rex64"
1944 [(set (match_operand:DI 0 "nonimmediate_operand"
1945 "=r,r ,r,mr,!mr,!*y,!rm,!*y,!*x,!rm,!*x,!*x,!*y")
1946 (match_operand:DI 1 "general_operand"
1947 "Z ,rem,i,re,n ,*y ,*y ,rm ,*x ,*x ,rm ,*y ,*x"))]
1948 "TARGET_64BIT
1949 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1950 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1951 {
1952 switch (get_attr_type (insn))
1953 {
1954 case TYPE_SSECVT:
1955 if (which_alternative == 11)
1956 return "movq2dq\t{%1, %0|%0, %1}";
1957 else
1958 return "movdq2q\t{%1, %0|%0, %1}";
1959 case TYPE_SSEMOV:
1960 if (get_attr_mode (insn) == MODE_TI)
1961 return "movdqa\t{%1, %0|%0, %1}";
1962 /* FALLTHRU */
1963 case TYPE_MMXMOV:
1964 /* Moves from and into integer register is done using movd opcode with
1965 REX prefix. */
1966 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1967 return "movd\t{%1, %0|%0, %1}";
1968 return "movq\t{%1, %0|%0, %1}";
1969 case TYPE_MULTI:
1970 return "#";
1971 case TYPE_LEA:
1972 return "lea{q}\t{%a1, %0|%0, %a1}";
1973 default:
1974 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1975 abort ();
1976 if (get_attr_mode (insn) == MODE_SI)
1977 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1978 else if (which_alternative == 2)
1979 return "movabs{q}\t{%1, %0|%0, %1}";
1980 else
1981 return "mov{q}\t{%1, %0|%0, %1}";
1982 }
1983 }
1984 [(set (attr "type")
1985 (cond [(eq_attr "alternative" "5,6,7")
1986 (const_string "mmxmov")
1987 (eq_attr "alternative" "8,9,10")
1988 (const_string "ssemov")
1989 (eq_attr "alternative" "11,12")
1990 (const_string "ssecvt")
1991 (eq_attr "alternative" "4")
1992 (const_string "multi")
1993 (and (ne (symbol_ref "flag_pic") (const_int 0))
1994 (match_operand:DI 1 "symbolic_operand" ""))
1995 (const_string "lea")
1996 ]
1997 (const_string "imov")))
1998 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1999 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
2000 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
2001
2002 (define_insn "*movdi_1_rex64_nointerunit"
2003 [(set (match_operand:DI 0 "nonimmediate_operand"
2004 "=r,r ,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2005 (match_operand:DI 1 "general_operand"
2006 "Z,rem,i,re,n ,*y ,*y,m ,*Y ,*Y,m"))]
2007 "TARGET_64BIT
2008 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2009 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2010 {
2011 switch (get_attr_type (insn))
2012 {
2013 case TYPE_SSEMOV:
2014 if (get_attr_mode (insn) == MODE_TI)
2015 return "movdqa\t{%1, %0|%0, %1}";
2016 /* FALLTHRU */
2017 case TYPE_MMXMOV:
2018 return "movq\t{%1, %0|%0, %1}";
2019 case TYPE_MULTI:
2020 return "#";
2021 case TYPE_LEA:
2022 return "lea{q}\t{%a1, %0|%0, %a1}";
2023 default:
2024 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2025 abort ();
2026 if (get_attr_mode (insn) == MODE_SI)
2027 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028 else if (which_alternative == 2)
2029 return "movabs{q}\t{%1, %0|%0, %1}";
2030 else
2031 return "mov{q}\t{%1, %0|%0, %1}";
2032 }
2033 }
2034 [(set (attr "type")
2035 (cond [(eq_attr "alternative" "5,6,7")
2036 (const_string "mmxmov")
2037 (eq_attr "alternative" "8,9,10")
2038 (const_string "ssemov")
2039 (eq_attr "alternative" "4")
2040 (const_string "multi")
2041 (and (ne (symbol_ref "flag_pic") (const_int 0))
2042 (match_operand:DI 1 "symbolic_operand" ""))
2043 (const_string "lea")
2044 ]
2045 (const_string "imov")))
2046 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2047 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2048 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2049
2050 ;; Stores and loads of ax to arbitrary constant address.
2051 ;; We fake an second form of instruction to force reload to load address
2052 ;; into register when rax is not available
2053 (define_insn "*movabsdi_1_rex64"
2054 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2055 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2056 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2057 "@
2058 movabs{q}\t{%1, %P0|%P0, %1}
2059 mov{q}\t{%1, %a0|%a0, %1}"
2060 [(set_attr "type" "imov")
2061 (set_attr "modrm" "0,*")
2062 (set_attr "length_address" "8,0")
2063 (set_attr "length_immediate" "0,*")
2064 (set_attr "memory" "store")
2065 (set_attr "mode" "DI")])
2066
2067 (define_insn "*movabsdi_2_rex64"
2068 [(set (match_operand:DI 0 "register_operand" "=a,r")
2069 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2070 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2071 "@
2072 movabs{q}\t{%P1, %0|%0, %P1}
2073 mov{q}\t{%a1, %0|%0, %a1}"
2074 [(set_attr "type" "imov")
2075 (set_attr "modrm" "0,*")
2076 (set_attr "length_address" "8,0")
2077 (set_attr "length_immediate" "0")
2078 (set_attr "memory" "load")
2079 (set_attr "mode" "DI")])
2080
2081 ;; Convert impossible stores of immediate to existing instructions.
2082 ;; First try to get scratch register and go through it. In case this
2083 ;; fails, move by 32bit parts.
2084 (define_peephole2
2085 [(match_scratch:DI 2 "r")
2086 (set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode)"
2090 [(set (match_dup 2) (match_dup 1))
2091 (set (match_dup 0) (match_dup 2))]
2092 "")
2093
2094 ;; We need to define this as both peepholer and splitter for case
2095 ;; peephole2 pass is not run.
2096 ;; "&& 1" is needed to keep it from matching the previous pattern.
2097 (define_peephole2
2098 [(set (match_operand:DI 0 "memory_operand" "")
2099 (match_operand:DI 1 "immediate_operand" ""))]
2100 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2101 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2102 [(set (match_dup 2) (match_dup 3))
2103 (set (match_dup 4) (match_dup 5))]
2104 "split_di (operands, 2, operands + 2, operands + 4);")
2105
2106 (define_split
2107 [(set (match_operand:DI 0 "memory_operand" "")
2108 (match_operand:DI 1 "immediate_operand" ""))]
2109 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2110 && !symbolic_operand (operands[1], DImode)
2111 && !x86_64_immediate_operand (operands[1], DImode)"
2112 [(set (match_dup 2) (match_dup 3))
2113 (set (match_dup 4) (match_dup 5))]
2114 "split_di (operands, 2, operands + 2, operands + 4);")
2115
2116 (define_insn "*swapdi_rex64"
2117 [(set (match_operand:DI 0 "register_operand" "+r")
2118 (match_operand:DI 1 "register_operand" "+r"))
2119 (set (match_dup 1)
2120 (match_dup 0))]
2121 "TARGET_64BIT"
2122 "xchg{q}\t%1, %0"
2123 [(set_attr "type" "imov")
2124 (set_attr "mode" "DI")
2125 (set_attr "pent_pair" "np")
2126 (set_attr "athlon_decode" "vector")])
2127
2128 (define_expand "movti"
2129 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2130 (match_operand:TI 1 "nonimmediate_operand" ""))]
2131 "TARGET_SSE || TARGET_64BIT"
2132 {
2133 if (TARGET_64BIT)
2134 ix86_expand_move (TImode, operands);
2135 else
2136 ix86_expand_vector_move (TImode, operands);
2137 DONE;
2138 })
2139
2140 (define_insn "*movti_internal"
2141 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2142 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2143 "TARGET_SSE && !TARGET_64BIT
2144 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2145 {
2146 switch (which_alternative)
2147 {
2148 case 0:
2149 if (get_attr_mode (insn) == MODE_V4SF)
2150 return "xorps\t%0, %0";
2151 else
2152 return "pxor\t%0, %0";
2153 case 1:
2154 case 2:
2155 if (get_attr_mode (insn) == MODE_V4SF)
2156 return "movaps\t{%1, %0|%0, %1}";
2157 else
2158 return "movdqa\t{%1, %0|%0, %1}";
2159 default:
2160 abort ();
2161 }
2162 }
2163 [(set_attr "type" "ssemov,ssemov,ssemov")
2164 (set (attr "mode")
2165 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2166 (const_string "V4SF")
2167
2168 (eq_attr "alternative" "0,1")
2169 (if_then_else
2170 (ne (symbol_ref "optimize_size")
2171 (const_int 0))
2172 (const_string "V4SF")
2173 (const_string "TI"))
2174 (eq_attr "alternative" "2")
2175 (if_then_else
2176 (ne (symbol_ref "optimize_size")
2177 (const_int 0))
2178 (const_string "V4SF")
2179 (const_string "TI"))]
2180 (const_string "TI")))])
2181
2182 (define_insn "*movti_rex64"
2183 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2184 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2185 "TARGET_64BIT
2186 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2187 {
2188 switch (which_alternative)
2189 {
2190 case 0:
2191 case 1:
2192 return "#";
2193 case 2:
2194 if (get_attr_mode (insn) == MODE_V4SF)
2195 return "xorps\t%0, %0";
2196 else
2197 return "pxor\t%0, %0";
2198 case 3:
2199 case 4:
2200 if (get_attr_mode (insn) == MODE_V4SF)
2201 return "movaps\t{%1, %0|%0, %1}";
2202 else
2203 return "movdqa\t{%1, %0|%0, %1}";
2204 default:
2205 abort ();
2206 }
2207 }
2208 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2209 (set (attr "mode")
2210 (cond [(eq_attr "alternative" "2,3")
2211 (if_then_else
2212 (ne (symbol_ref "optimize_size")
2213 (const_int 0))
2214 (const_string "V4SF")
2215 (const_string "TI"))
2216 (eq_attr "alternative" "4")
2217 (if_then_else
2218 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2219 (const_int 0))
2220 (ne (symbol_ref "optimize_size")
2221 (const_int 0)))
2222 (const_string "V4SF")
2223 (const_string "TI"))]
2224 (const_string "DI")))])
2225
2226 (define_split
2227 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2228 (match_operand:TI 1 "general_operand" ""))]
2229 "reload_completed && !SSE_REG_P (operands[0])
2230 && !SSE_REG_P (operands[1])"
2231 [(const_int 0)]
2232 "ix86_split_long_move (operands); DONE;")
2233
2234 (define_expand "movsf"
2235 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2236 (match_operand:SF 1 "general_operand" ""))]
2237 ""
2238 "ix86_expand_move (SFmode, operands); DONE;")
2239
2240 (define_insn "*pushsf"
2241 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2242 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2243 "!TARGET_64BIT"
2244 {
2245 switch (which_alternative)
2246 {
2247 case 1:
2248 return "push{l}\t%1";
2249
2250 default:
2251 /* This insn should be already split before reg-stack. */
2252 abort ();
2253 }
2254 }
2255 [(set_attr "type" "multi,push,multi")
2256 (set_attr "mode" "SF,SI,SF")])
2257
2258 (define_insn "*pushsf_rex64"
2259 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2260 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2261 "TARGET_64BIT"
2262 {
2263 switch (which_alternative)
2264 {
2265 case 1:
2266 return "push{q}\t%q1";
2267
2268 default:
2269 /* This insn should be already split before reg-stack. */
2270 abort ();
2271 }
2272 }
2273 [(set_attr "type" "multi,push,multi")
2274 (set_attr "mode" "SF,DI,SF")])
2275
2276 (define_split
2277 [(set (match_operand:SF 0 "push_operand" "")
2278 (match_operand:SF 1 "memory_operand" ""))]
2279 "reload_completed
2280 && GET_CODE (operands[1]) == MEM
2281 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2282 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2283 [(set (match_dup 0)
2284 (match_dup 1))]
2285 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2286
2287
2288 ;; %%% Kill this when call knows how to work this out.
2289 (define_split
2290 [(set (match_operand:SF 0 "push_operand" "")
2291 (match_operand:SF 1 "any_fp_register_operand" ""))]
2292 "!TARGET_64BIT"
2293 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2294 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2295
2296 (define_split
2297 [(set (match_operand:SF 0 "push_operand" "")
2298 (match_operand:SF 1 "any_fp_register_operand" ""))]
2299 "TARGET_64BIT"
2300 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2301 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2302
2303 (define_insn "*movsf_1"
2304 [(set (match_operand:SF 0 "nonimmediate_operand"
2305 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2306 (match_operand:SF 1 "general_operand"
2307 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2308 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2309 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2310 && (reload_in_progress || reload_completed
2311 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2312 || GET_CODE (operands[1]) != CONST_DOUBLE
2313 || memory_operand (operands[0], SFmode))"
2314 {
2315 switch (which_alternative)
2316 {
2317 case 0:
2318 return output_387_reg_move (insn, operands);
2319
2320 case 1:
2321 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2322 return "fstp%z0\t%y0";
2323 else
2324 return "fst%z0\t%y0";
2325
2326 case 2:
2327 return standard_80387_constant_opcode (operands[1]);
2328
2329 case 3:
2330 case 4:
2331 return "mov{l}\t{%1, %0|%0, %1}";
2332 case 5:
2333 if (get_attr_mode (insn) == MODE_TI)
2334 return "pxor\t%0, %0";
2335 else
2336 return "xorps\t%0, %0";
2337 case 6:
2338 if (get_attr_mode (insn) == MODE_V4SF)
2339 return "movaps\t{%1, %0|%0, %1}";
2340 else
2341 return "movss\t{%1, %0|%0, %1}";
2342 case 7:
2343 case 8:
2344 return "movss\t{%1, %0|%0, %1}";
2345
2346 case 9:
2347 case 10:
2348 return "movd\t{%1, %0|%0, %1}";
2349
2350 case 11:
2351 return "movq\t{%1, %0|%0, %1}";
2352
2353 default:
2354 abort();
2355 }
2356 }
2357 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2358 (set (attr "mode")
2359 (cond [(eq_attr "alternative" "3,4,9,10")
2360 (const_string "SI")
2361 (eq_attr "alternative" "5")
2362 (if_then_else
2363 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2364 (const_int 0))
2365 (ne (symbol_ref "TARGET_SSE2")
2366 (const_int 0)))
2367 (eq (symbol_ref "optimize_size")
2368 (const_int 0)))
2369 (const_string "TI")
2370 (const_string "V4SF"))
2371 /* For architectures resolving dependencies on
2372 whole SSE registers use APS move to break dependency
2373 chains, otherwise use short move to avoid extra work.
2374
2375 Do the same for architectures resolving dependencies on
2376 the parts. While in DF mode it is better to always handle
2377 just register parts, the SF mode is different due to lack
2378 of instructions to load just part of the register. It is
2379 better to maintain the whole registers in single format
2380 to avoid problems on using packed logical operations. */
2381 (eq_attr "alternative" "6")
2382 (if_then_else
2383 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2384 (const_int 0))
2385 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2386 (const_int 0)))
2387 (const_string "V4SF")
2388 (const_string "SF"))
2389 (eq_attr "alternative" "11")
2390 (const_string "DI")]
2391 (const_string "SF")))])
2392
2393 (define_insn "*movsf_1_nointerunit"
2394 [(set (match_operand:SF 0 "nonimmediate_operand"
2395 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!m,!*y")
2396 (match_operand:SF 1 "general_operand"
2397 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,m ,*y,*y"))]
2398 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2399 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2400 && (reload_in_progress || reload_completed
2401 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2402 || GET_CODE (operands[1]) != CONST_DOUBLE
2403 || memory_operand (operands[0], SFmode))"
2404 {
2405 switch (which_alternative)
2406 {
2407 case 0:
2408 return output_387_reg_move (insn, operands);
2409
2410 case 1:
2411 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2412 return "fstp%z0\t%y0";
2413 else
2414 return "fst%z0\t%y0";
2415
2416 case 2:
2417 return standard_80387_constant_opcode (operands[1]);
2418
2419 case 3:
2420 case 4:
2421 return "mov{l}\t{%1, %0|%0, %1}";
2422 case 5:
2423 if (get_attr_mode (insn) == MODE_TI)
2424 return "pxor\t%0, %0";
2425 else
2426 return "xorps\t%0, %0";
2427 case 6:
2428 if (get_attr_mode (insn) == MODE_V4SF)
2429 return "movaps\t{%1, %0|%0, %1}";
2430 else
2431 return "movss\t{%1, %0|%0, %1}";
2432 case 7:
2433 case 8:
2434 return "movss\t{%1, %0|%0, %1}";
2435
2436 case 9:
2437 case 10:
2438 return "movd\t{%1, %0|%0, %1}";
2439
2440 case 11:
2441 return "movq\t{%1, %0|%0, %1}";
2442
2443 default:
2444 abort();
2445 }
2446 }
2447 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2448 (set (attr "mode")
2449 (cond [(eq_attr "alternative" "3,4,9,10")
2450 (const_string "SI")
2451 (eq_attr "alternative" "5")
2452 (if_then_else
2453 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2454 (const_int 0))
2455 (ne (symbol_ref "TARGET_SSE2")
2456 (const_int 0)))
2457 (eq (symbol_ref "optimize_size")
2458 (const_int 0)))
2459 (const_string "TI")
2460 (const_string "V4SF"))
2461 /* For architectures resolving dependencies on
2462 whole SSE registers use APS move to break dependency
2463 chains, otherwise use short move to avoid extra work.
2464
2465 Do the same for architectures resolving dependencies on
2466 the parts. While in DF mode it is better to always handle
2467 just register parts, the SF mode is different due to lack
2468 of instructions to load just part of the register. It is
2469 better to maintain the whole registers in single format
2470 to avoid problems on using packed logical operations. */
2471 (eq_attr "alternative" "6")
2472 (if_then_else
2473 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2474 (const_int 0))
2475 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2476 (const_int 0)))
2477 (const_string "V4SF")
2478 (const_string "SF"))
2479 (eq_attr "alternative" "11")
2480 (const_string "DI")]
2481 (const_string "SF")))])
2482
2483 (define_insn "*swapsf"
2484 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2485 (match_operand:SF 1 "fp_register_operand" "+f"))
2486 (set (match_dup 1)
2487 (match_dup 0))]
2488 "reload_completed || TARGET_80387"
2489 {
2490 if (STACK_TOP_P (operands[0]))
2491 return "fxch\t%1";
2492 else
2493 return "fxch\t%0";
2494 }
2495 [(set_attr "type" "fxch")
2496 (set_attr "mode" "SF")])
2497
2498 (define_expand "movdf"
2499 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2500 (match_operand:DF 1 "general_operand" ""))]
2501 ""
2502 "ix86_expand_move (DFmode, operands); DONE;")
2503
2504 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2505 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2506 ;; On the average, pushdf using integers can be still shorter. Allow this
2507 ;; pattern for optimize_size too.
2508
2509 (define_insn "*pushdf_nointeger"
2510 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2511 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2512 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2513 {
2514 /* This insn should be already split before reg-stack. */
2515 abort ();
2516 }
2517 [(set_attr "type" "multi")
2518 (set_attr "mode" "DF,SI,SI,DF")])
2519
2520 (define_insn "*pushdf_integer"
2521 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2522 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2523 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2524 {
2525 /* This insn should be already split before reg-stack. */
2526 abort ();
2527 }
2528 [(set_attr "type" "multi")
2529 (set_attr "mode" "DF,SI,DF")])
2530
2531 ;; %%% Kill this when call knows how to work this out.
2532 (define_split
2533 [(set (match_operand:DF 0 "push_operand" "")
2534 (match_operand:DF 1 "any_fp_register_operand" ""))]
2535 "!TARGET_64BIT && reload_completed"
2536 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2537 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2538 "")
2539
2540 (define_split
2541 [(set (match_operand:DF 0 "push_operand" "")
2542 (match_operand:DF 1 "any_fp_register_operand" ""))]
2543 "TARGET_64BIT && reload_completed"
2544 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2545 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2546 "")
2547
2548 (define_split
2549 [(set (match_operand:DF 0 "push_operand" "")
2550 (match_operand:DF 1 "general_operand" ""))]
2551 "reload_completed"
2552 [(const_int 0)]
2553 "ix86_split_long_move (operands); DONE;")
2554
2555 ;; Moving is usually shorter when only FP registers are used. This separate
2556 ;; movdf pattern avoids the use of integer registers for FP operations
2557 ;; when optimizing for size.
2558
2559 (define_insn "*movdf_nointeger"
2560 [(set (match_operand:DF 0 "nonimmediate_operand"
2561 "=f#Y,m ,f#Y,*r ,o ,Y#f*x,Y#f*x,Y#f*x ,m ")
2562 (match_operand:DF 1 "general_operand"
2563 "fm#Y,f#Y,G ,*roF,F*r,C ,Y#f*x,HmY#f*x,Y#f*x"))]
2564 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2565 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2566 && (reload_in_progress || reload_completed
2567 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2568 || GET_CODE (operands[1]) != CONST_DOUBLE
2569 || memory_operand (operands[0], DFmode))"
2570 {
2571 switch (which_alternative)
2572 {
2573 case 0:
2574 return output_387_reg_move (insn, operands);
2575
2576 case 1:
2577 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2578 return "fstp%z0\t%y0";
2579 else
2580 return "fst%z0\t%y0";
2581
2582 case 2:
2583 return standard_80387_constant_opcode (operands[1]);
2584
2585 case 3:
2586 case 4:
2587 return "#";
2588 case 5:
2589 switch (get_attr_mode (insn))
2590 {
2591 case MODE_V4SF:
2592 return "xorps\t%0, %0";
2593 case MODE_V2DF:
2594 return "xorpd\t%0, %0";
2595 case MODE_TI:
2596 return "pxor\t%0, %0";
2597 default:
2598 abort ();
2599 }
2600 case 6:
2601 case 7:
2602 case 8:
2603 switch (get_attr_mode (insn))
2604 {
2605 case MODE_V4SF:
2606 return "movaps\t{%1, %0|%0, %1}";
2607 case MODE_V2DF:
2608 return "movapd\t{%1, %0|%0, %1}";
2609 case MODE_TI:
2610 return "movdqa\t{%1, %0|%0, %1}";
2611 case MODE_DI:
2612 return "movq\t{%1, %0|%0, %1}";
2613 case MODE_DF:
2614 return "movsd\t{%1, %0|%0, %1}";
2615 case MODE_V1DF:
2616 return "movlpd\t{%1, %0|%0, %1}";
2617 case MODE_V2SF:
2618 return "movlps\t{%1, %0|%0, %1}";
2619 default:
2620 abort ();
2621 }
2622
2623 default:
2624 abort();
2625 }
2626 }
2627 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2628 (set (attr "mode")
2629 (cond [(eq_attr "alternative" "0,1,2")
2630 (const_string "DF")
2631 (eq_attr "alternative" "3,4")
2632 (const_string "SI")
2633
2634 /* For SSE1, we have many fewer alternatives. */
2635 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2636 (cond [(eq_attr "alternative" "5,6")
2637 (const_string "V4SF")
2638 ]
2639 (const_string "V2SF"))
2640
2641 /* xorps is one byte shorter. */
2642 (eq_attr "alternative" "5")
2643 (cond [(ne (symbol_ref "optimize_size")
2644 (const_int 0))
2645 (const_string "V4SF")
2646 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2647 (const_int 0))
2648 (const_string "TI")
2649 ]
2650 (const_string "V2DF"))
2651
2652 /* For architectures resolving dependencies on
2653 whole SSE registers use APD move to break dependency
2654 chains, otherwise use short move to avoid extra work.
2655
2656 movaps encodes one byte shorter. */
2657 (eq_attr "alternative" "6")
2658 (cond
2659 [(ne (symbol_ref "optimize_size")
2660 (const_int 0))
2661 (const_string "V4SF")
2662 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2663 (const_int 0))
2664 (const_string "V2DF")
2665 ]
2666 (const_string "DF"))
2667 /* For architectures resolving dependencies on register
2668 parts we may avoid extra work to zero out upper part
2669 of register. */
2670 (eq_attr "alternative" "7")
2671 (if_then_else
2672 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2673 (const_int 0))
2674 (const_string "V1DF")
2675 (const_string "DF"))
2676 ]
2677 (const_string "DF")))])
2678
2679 (define_insn "*movdf_integer"
2680 [(set (match_operand:DF 0 "nonimmediate_operand"
2681 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y#rf*x,Y#rf*x,Y#rf*x,m")
2682 (match_operand:DF 1 "general_operand"
2683 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y#rf*x,m ,Y#rf*x"))]
2684 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2685 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2686 && (reload_in_progress || reload_completed
2687 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2688 || GET_CODE (operands[1]) != CONST_DOUBLE
2689 || memory_operand (operands[0], DFmode))"
2690 {
2691 switch (which_alternative)
2692 {
2693 case 0:
2694 return output_387_reg_move (insn, operands);
2695
2696 case 1:
2697 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2698 return "fstp%z0\t%y0";
2699 else
2700 return "fst%z0\t%y0";
2701
2702 case 2:
2703 return standard_80387_constant_opcode (operands[1]);
2704
2705 case 3:
2706 case 4:
2707 return "#";
2708
2709 case 5:
2710 switch (get_attr_mode (insn))
2711 {
2712 case MODE_V4SF:
2713 return "xorps\t%0, %0";
2714 case MODE_V2DF:
2715 return "xorpd\t%0, %0";
2716 case MODE_TI:
2717 return "pxor\t%0, %0";
2718 default:
2719 abort ();
2720 }
2721 case 6:
2722 case 7:
2723 case 8:
2724 switch (get_attr_mode (insn))
2725 {
2726 case MODE_V4SF:
2727 return "movaps\t{%1, %0|%0, %1}";
2728 case MODE_V2DF:
2729 return "movapd\t{%1, %0|%0, %1}";
2730 case MODE_TI:
2731 return "movdqa\t{%1, %0|%0, %1}";
2732 case MODE_DI:
2733 return "movq\t{%1, %0|%0, %1}";
2734 case MODE_DF:
2735 return "movsd\t{%1, %0|%0, %1}";
2736 case MODE_V1DF:
2737 return "movlpd\t{%1, %0|%0, %1}";
2738 case MODE_V2SF:
2739 return "movlps\t{%1, %0|%0, %1}";
2740 default:
2741 abort ();
2742 }
2743
2744 default:
2745 abort();
2746 }
2747 }
2748 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2749 (set (attr "mode")
2750 (cond [(eq_attr "alternative" "0,1,2")
2751 (const_string "DF")
2752 (eq_attr "alternative" "3,4")
2753 (const_string "SI")
2754
2755 /* For SSE1, we have many fewer alternatives. */
2756 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2757 (cond [(eq_attr "alternative" "5,6")
2758 (const_string "V4SF")
2759 ]
2760 (const_string "V2SF"))
2761
2762 /* xorps is one byte shorter. */
2763 (eq_attr "alternative" "5")
2764 (cond [(ne (symbol_ref "optimize_size")
2765 (const_int 0))
2766 (const_string "V4SF")
2767 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2768 (const_int 0))
2769 (const_string "TI")
2770 ]
2771 (const_string "V2DF"))
2772
2773 /* For architectures resolving dependencies on
2774 whole SSE registers use APD move to break dependency
2775 chains, otherwise use short move to avoid extra work.
2776
2777 movaps encodes one byte shorter. */
2778 (eq_attr "alternative" "6")
2779 (cond
2780 [(ne (symbol_ref "optimize_size")
2781 (const_int 0))
2782 (const_string "V4SF")
2783 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2784 (const_int 0))
2785 (const_string "V2DF")
2786 ]
2787 (const_string "DF"))
2788 /* For architectures resolving dependencies on register
2789 parts we may avoid extra work to zero out upper part
2790 of register. */
2791 (eq_attr "alternative" "7")
2792 (if_then_else
2793 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2794 (const_int 0))
2795 (const_string "V1DF")
2796 (const_string "DF"))
2797 ]
2798 (const_string "DF")))])
2799
2800 (define_split
2801 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2802 (match_operand:DF 1 "general_operand" ""))]
2803 "reload_completed
2804 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2805 && ! (ANY_FP_REG_P (operands[0]) ||
2806 (GET_CODE (operands[0]) == SUBREG
2807 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2808 && ! (ANY_FP_REG_P (operands[1]) ||
2809 (GET_CODE (operands[1]) == SUBREG
2810 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2811 [(const_int 0)]
2812 "ix86_split_long_move (operands); DONE;")
2813
2814 (define_insn "*swapdf"
2815 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2816 (match_operand:DF 1 "fp_register_operand" "+f"))
2817 (set (match_dup 1)
2818 (match_dup 0))]
2819 "reload_completed || TARGET_80387"
2820 {
2821 if (STACK_TOP_P (operands[0]))
2822 return "fxch\t%1";
2823 else
2824 return "fxch\t%0";
2825 }
2826 [(set_attr "type" "fxch")
2827 (set_attr "mode" "DF")])
2828
2829 (define_expand "movxf"
2830 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2831 (match_operand:XF 1 "general_operand" ""))]
2832 ""
2833 "ix86_expand_move (XFmode, operands); DONE;")
2834
2835 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2836 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2837 ;; Pushing using integer instructions is longer except for constants
2838 ;; and direct memory references.
2839 ;; (assuming that any given constant is pushed only once, but this ought to be
2840 ;; handled elsewhere).
2841
2842 (define_insn "*pushxf_nointeger"
2843 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2844 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2845 "optimize_size"
2846 {
2847 /* This insn should be already split before reg-stack. */
2848 abort ();
2849 }
2850 [(set_attr "type" "multi")
2851 (set_attr "mode" "XF,SI,SI")])
2852
2853 (define_insn "*pushxf_integer"
2854 [(set (match_operand:XF 0 "push_operand" "=<,<")
2855 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2856 "!optimize_size"
2857 {
2858 /* This insn should be already split before reg-stack. */
2859 abort ();
2860 }
2861 [(set_attr "type" "multi")
2862 (set_attr "mode" "XF,SI")])
2863
2864 (define_split
2865 [(set (match_operand 0 "push_operand" "")
2866 (match_operand 1 "general_operand" ""))]
2867 "reload_completed
2868 && (GET_MODE (operands[0]) == XFmode
2869 || GET_MODE (operands[0]) == DFmode)
2870 && !ANY_FP_REG_P (operands[1])"
2871 [(const_int 0)]
2872 "ix86_split_long_move (operands); DONE;")
2873
2874 (define_split
2875 [(set (match_operand:XF 0 "push_operand" "")
2876 (match_operand:XF 1 "any_fp_register_operand" ""))]
2877 "!TARGET_64BIT"
2878 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2879 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2880 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2881
2882 (define_split
2883 [(set (match_operand:XF 0 "push_operand" "")
2884 (match_operand:XF 1 "any_fp_register_operand" ""))]
2885 "TARGET_64BIT"
2886 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2887 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2888 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2889
2890 ;; Do not use integer registers when optimizing for size
2891 (define_insn "*movxf_nointeger"
2892 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2893 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2894 "optimize_size
2895 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2896 && (reload_in_progress || reload_completed
2897 || GET_CODE (operands[1]) != CONST_DOUBLE
2898 || memory_operand (operands[0], XFmode))"
2899 {
2900 switch (which_alternative)
2901 {
2902 case 0:
2903 return output_387_reg_move (insn, operands);
2904
2905 case 1:
2906 /* There is no non-popping store to memory for XFmode. So if
2907 we need one, follow the store with a load. */
2908 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2909 return "fstp%z0\t%y0\;fld%z0\t%y0";
2910 else
2911 return "fstp%z0\t%y0";
2912
2913 case 2:
2914 return standard_80387_constant_opcode (operands[1]);
2915
2916 case 3: case 4:
2917 return "#";
2918 }
2919 abort();
2920 }
2921 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2922 (set_attr "mode" "XF,XF,XF,SI,SI")])
2923
2924 (define_insn "*movxf_integer"
2925 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2926 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2927 "!optimize_size
2928 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2929 && (reload_in_progress || reload_completed
2930 || GET_CODE (operands[1]) != CONST_DOUBLE
2931 || memory_operand (operands[0], XFmode))"
2932 {
2933 switch (which_alternative)
2934 {
2935 case 0:
2936 return output_387_reg_move (insn, operands);
2937
2938 case 1:
2939 /* There is no non-popping store to memory for XFmode. So if
2940 we need one, follow the store with a load. */
2941 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2942 return "fstp%z0\t%y0\;fld%z0\t%y0";
2943 else
2944 return "fstp%z0\t%y0";
2945
2946 case 2:
2947 return standard_80387_constant_opcode (operands[1]);
2948
2949 case 3: case 4:
2950 return "#";
2951 }
2952 abort();
2953 }
2954 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2955 (set_attr "mode" "XF,XF,XF,SI,SI")])
2956
2957 (define_split
2958 [(set (match_operand 0 "nonimmediate_operand" "")
2959 (match_operand 1 "general_operand" ""))]
2960 "reload_completed
2961 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2962 && GET_MODE (operands[0]) == XFmode
2963 && ! (ANY_FP_REG_P (operands[0]) ||
2964 (GET_CODE (operands[0]) == SUBREG
2965 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2966 && ! (ANY_FP_REG_P (operands[1]) ||
2967 (GET_CODE (operands[1]) == SUBREG
2968 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2969 [(const_int 0)]
2970 "ix86_split_long_move (operands); DONE;")
2971
2972 (define_split
2973 [(set (match_operand 0 "register_operand" "")
2974 (match_operand 1 "memory_operand" ""))]
2975 "reload_completed
2976 && GET_CODE (operands[1]) == MEM
2977 && (GET_MODE (operands[0]) == XFmode
2978 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2979 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2980 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2981 [(set (match_dup 0) (match_dup 1))]
2982 {
2983 rtx c = get_pool_constant (XEXP (operands[1], 0));
2984 rtx r = operands[0];
2985
2986 if (GET_CODE (r) == SUBREG)
2987 r = SUBREG_REG (r);
2988
2989 if (SSE_REG_P (r))
2990 {
2991 if (!standard_sse_constant_p (c))
2992 FAIL;
2993 }
2994 else if (FP_REG_P (r))
2995 {
2996 if (!standard_80387_constant_p (c))
2997 FAIL;
2998 }
2999 else if (MMX_REG_P (r))
3000 FAIL;
3001
3002 operands[1] = c;
3003 })
3004
3005 (define_insn "swapxf"
3006 [(set (match_operand:XF 0 "register_operand" "+f")
3007 (match_operand:XF 1 "register_operand" "+f"))
3008 (set (match_dup 1)
3009 (match_dup 0))]
3010 "TARGET_80387"
3011 {
3012 if (STACK_TOP_P (operands[0]))
3013 return "fxch\t%1";
3014 else
3015 return "fxch\t%0";
3016 }
3017 [(set_attr "type" "fxch")
3018 (set_attr "mode" "XF")])
3019
3020 (define_expand "movtf"
3021 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3022 (match_operand:TF 1 "nonimmediate_operand" ""))]
3023 "TARGET_64BIT"
3024 {
3025 ix86_expand_move (TFmode, operands);
3026 DONE;
3027 })
3028
3029 (define_insn "*movtf_internal"
3030 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3031 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3032 "TARGET_64BIT
3033 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3034 {
3035 switch (which_alternative)
3036 {
3037 case 0:
3038 case 1:
3039 return "#";
3040 case 2:
3041 if (get_attr_mode (insn) == MODE_V4SF)
3042 return "xorps\t%0, %0";
3043 else
3044 return "pxor\t%0, %0";
3045 case 3:
3046 case 4:
3047 if (get_attr_mode (insn) == MODE_V4SF)
3048 return "movaps\t{%1, %0|%0, %1}";
3049 else
3050 return "movdqa\t{%1, %0|%0, %1}";
3051 default:
3052 abort ();
3053 }
3054 }
3055 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
3056 (set (attr "mode")
3057 (cond [(eq_attr "alternative" "2,3")
3058 (if_then_else
3059 (ne (symbol_ref "optimize_size")
3060 (const_int 0))
3061 (const_string "V4SF")
3062 (const_string "TI"))
3063 (eq_attr "alternative" "4")
3064 (if_then_else
3065 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3066 (const_int 0))
3067 (ne (symbol_ref "optimize_size")
3068 (const_int 0)))
3069 (const_string "V4SF")
3070 (const_string "TI"))]
3071 (const_string "DI")))])
3072
3073 (define_split
3074 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3075 (match_operand:TF 1 "general_operand" ""))]
3076 "reload_completed && !SSE_REG_P (operands[0])
3077 && !SSE_REG_P (operands[1])"
3078 [(const_int 0)]
3079 "ix86_split_long_move (operands); DONE;")
3080 \f
3081 ;; Zero extension instructions
3082
3083 (define_expand "zero_extendhisi2"
3084 [(set (match_operand:SI 0 "register_operand" "")
3085 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3086 ""
3087 {
3088 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3089 {
3090 operands[1] = force_reg (HImode, operands[1]);
3091 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3092 DONE;
3093 }
3094 })
3095
3096 (define_insn "zero_extendhisi2_and"
3097 [(set (match_operand:SI 0 "register_operand" "=r")
3098 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3099 (clobber (reg:CC FLAGS_REG))]
3100 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3101 "#"
3102 [(set_attr "type" "alu1")
3103 (set_attr "mode" "SI")])
3104
3105 (define_split
3106 [(set (match_operand:SI 0 "register_operand" "")
3107 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3108 (clobber (reg:CC FLAGS_REG))]
3109 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3110 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3111 (clobber (reg:CC FLAGS_REG))])]
3112 "")
3113
3114 (define_insn "*zero_extendhisi2_movzwl"
3115 [(set (match_operand:SI 0 "register_operand" "=r")
3116 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3117 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3118 "movz{wl|x}\t{%1, %0|%0, %1}"
3119 [(set_attr "type" "imovx")
3120 (set_attr "mode" "SI")])
3121
3122 (define_expand "zero_extendqihi2"
3123 [(parallel
3124 [(set (match_operand:HI 0 "register_operand" "")
3125 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3126 (clobber (reg:CC FLAGS_REG))])]
3127 ""
3128 "")
3129
3130 (define_insn "*zero_extendqihi2_and"
3131 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3132 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3133 (clobber (reg:CC FLAGS_REG))]
3134 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3135 "#"
3136 [(set_attr "type" "alu1")
3137 (set_attr "mode" "HI")])
3138
3139 (define_insn "*zero_extendqihi2_movzbw_and"
3140 [(set (match_operand:HI 0 "register_operand" "=r,r")
3141 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3142 (clobber (reg:CC FLAGS_REG))]
3143 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3144 "#"
3145 [(set_attr "type" "imovx,alu1")
3146 (set_attr "mode" "HI")])
3147
3148 (define_insn "*zero_extendqihi2_movzbw"
3149 [(set (match_operand:HI 0 "register_operand" "=r")
3150 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3151 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3152 "movz{bw|x}\t{%1, %0|%0, %1}"
3153 [(set_attr "type" "imovx")
3154 (set_attr "mode" "HI")])
3155
3156 ;; For the movzbw case strip only the clobber
3157 (define_split
3158 [(set (match_operand:HI 0 "register_operand" "")
3159 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3160 (clobber (reg:CC FLAGS_REG))]
3161 "reload_completed
3162 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3163 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3164 [(set (match_operand:HI 0 "register_operand" "")
3165 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3166
3167 ;; When source and destination does not overlap, clear destination
3168 ;; first and then do the movb
3169 (define_split
3170 [(set (match_operand:HI 0 "register_operand" "")
3171 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3172 (clobber (reg:CC FLAGS_REG))]
3173 "reload_completed
3174 && ANY_QI_REG_P (operands[0])
3175 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3176 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3177 [(set (match_dup 0) (const_int 0))
3178 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3179 "operands[2] = gen_lowpart (QImode, operands[0]);")
3180
3181 ;; Rest is handled by single and.
3182 (define_split
3183 [(set (match_operand:HI 0 "register_operand" "")
3184 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3185 (clobber (reg:CC FLAGS_REG))]
3186 "reload_completed
3187 && true_regnum (operands[0]) == true_regnum (operands[1])"
3188 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3189 (clobber (reg:CC FLAGS_REG))])]
3190 "")
3191
3192 (define_expand "zero_extendqisi2"
3193 [(parallel
3194 [(set (match_operand:SI 0 "register_operand" "")
3195 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3196 (clobber (reg:CC FLAGS_REG))])]
3197 ""
3198 "")
3199
3200 (define_insn "*zero_extendqisi2_and"
3201 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3202 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3203 (clobber (reg:CC FLAGS_REG))]
3204 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3205 "#"
3206 [(set_attr "type" "alu1")
3207 (set_attr "mode" "SI")])
3208
3209 (define_insn "*zero_extendqisi2_movzbw_and"
3210 [(set (match_operand:SI 0 "register_operand" "=r,r")
3211 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3212 (clobber (reg:CC FLAGS_REG))]
3213 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3214 "#"
3215 [(set_attr "type" "imovx,alu1")
3216 (set_attr "mode" "SI")])
3217
3218 (define_insn "*zero_extendqisi2_movzbw"
3219 [(set (match_operand:SI 0 "register_operand" "=r")
3220 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3221 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3222 "movz{bl|x}\t{%1, %0|%0, %1}"
3223 [(set_attr "type" "imovx")
3224 (set_attr "mode" "SI")])
3225
3226 ;; For the movzbl case strip only the clobber
3227 (define_split
3228 [(set (match_operand:SI 0 "register_operand" "")
3229 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3230 (clobber (reg:CC FLAGS_REG))]
3231 "reload_completed
3232 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3233 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3234 [(set (match_dup 0)
3235 (zero_extend:SI (match_dup 1)))])
3236
3237 ;; When source and destination does not overlap, clear destination
3238 ;; first and then do the movb
3239 (define_split
3240 [(set (match_operand:SI 0 "register_operand" "")
3241 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3242 (clobber (reg:CC FLAGS_REG))]
3243 "reload_completed
3244 && ANY_QI_REG_P (operands[0])
3245 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3246 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3247 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3248 [(set (match_dup 0) (const_int 0))
3249 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3250 "operands[2] = gen_lowpart (QImode, operands[0]);")
3251
3252 ;; Rest is handled by single and.
3253 (define_split
3254 [(set (match_operand:SI 0 "register_operand" "")
3255 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3256 (clobber (reg:CC FLAGS_REG))]
3257 "reload_completed
3258 && true_regnum (operands[0]) == true_regnum (operands[1])"
3259 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3260 (clobber (reg:CC FLAGS_REG))])]
3261 "")
3262
3263 ;; %%% Kill me once multi-word ops are sane.
3264 (define_expand "zero_extendsidi2"
3265 [(set (match_operand:DI 0 "register_operand" "=r")
3266 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3267 ""
3268 "if (!TARGET_64BIT)
3269 {
3270 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3271 DONE;
3272 }
3273 ")
3274
3275 (define_insn "zero_extendsidi2_32"
3276 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3277 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3278 (clobber (reg:CC FLAGS_REG))]
3279 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3280 "@
3281 #
3282 #
3283 #
3284 movd\t{%1, %0|%0, %1}
3285 movd\t{%1, %0|%0, %1}"
3286 [(set_attr "mode" "SI,SI,SI,DI,TI")
3287 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3288
3289 (define_insn "*zero_extendsidi2_32_1"
3290 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3291 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3292 (clobber (reg:CC FLAGS_REG))]
3293 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3294 "@
3295 #
3296 #
3297 #
3298 movd\t{%1, %0|%0, %1}
3299 movd\t{%1, %0|%0, %1}"
3300 [(set_attr "mode" "SI,SI,SI,DI,TI")
3301 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3302
3303 (define_insn "zero_extendsidi2_rex64"
3304 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3305 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3306 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3307 "@
3308 mov\t{%k1, %k0|%k0, %k1}
3309 #
3310 movd\t{%1, %0|%0, %1}
3311 movd\t{%1, %0|%0, %1}"
3312 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3313 (set_attr "mode" "SI,DI,DI,TI")])
3314
3315 (define_insn "*zero_extendsidi2_rex64_1"
3316 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3317 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3318 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3319 "@
3320 mov\t{%k1, %k0|%k0, %k1}
3321 #
3322 movd\t{%1, %0|%0, %1}
3323 movd\t{%1, %0|%0, %1}"
3324 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3325 (set_attr "mode" "SI,DI,SI,SI")])
3326
3327 (define_split
3328 [(set (match_operand:DI 0 "memory_operand" "")
3329 (zero_extend:DI (match_dup 0)))]
3330 "TARGET_64BIT"
3331 [(set (match_dup 4) (const_int 0))]
3332 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3333
3334 (define_split
3335 [(set (match_operand:DI 0 "register_operand" "")
3336 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3337 (clobber (reg:CC FLAGS_REG))]
3338 "!TARGET_64BIT && reload_completed
3339 && true_regnum (operands[0]) == true_regnum (operands[1])"
3340 [(set (match_dup 4) (const_int 0))]
3341 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3342
3343 (define_split
3344 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3345 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3346 (clobber (reg:CC FLAGS_REG))]
3347 "!TARGET_64BIT && reload_completed
3348 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3349 [(set (match_dup 3) (match_dup 1))
3350 (set (match_dup 4) (const_int 0))]
3351 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3352
3353 (define_insn "zero_extendhidi2"
3354 [(set (match_operand:DI 0 "register_operand" "=r,r")
3355 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3356 "TARGET_64BIT"
3357 "@
3358 movz{wl|x}\t{%1, %k0|%k0, %1}
3359 movz{wq|x}\t{%1, %0|%0, %1}"
3360 [(set_attr "type" "imovx")
3361 (set_attr "mode" "SI,DI")])
3362
3363 (define_insn "zero_extendqidi2"
3364 [(set (match_operand:DI 0 "register_operand" "=r,r")
3365 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3366 "TARGET_64BIT"
3367 "@
3368 movz{bl|x}\t{%1, %k0|%k0, %1}
3369 movz{bq|x}\t{%1, %0|%0, %1}"
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "SI,DI")])
3372 \f
3373 ;; Sign extension instructions
3374
3375 (define_expand "extendsidi2"
3376 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3377 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3378 (clobber (reg:CC FLAGS_REG))
3379 (clobber (match_scratch:SI 2 ""))])]
3380 ""
3381 {
3382 if (TARGET_64BIT)
3383 {
3384 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3385 DONE;
3386 }
3387 })
3388
3389 (define_insn "*extendsidi2_1"
3390 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3391 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3392 (clobber (reg:CC FLAGS_REG))
3393 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3394 "!TARGET_64BIT"
3395 "#")
3396
3397 (define_insn "extendsidi2_rex64"
3398 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3399 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3400 "TARGET_64BIT"
3401 "@
3402 {cltq|cdqe}
3403 movs{lq|x}\t{%1,%0|%0, %1}"
3404 [(set_attr "type" "imovx")
3405 (set_attr "mode" "DI")
3406 (set_attr "prefix_0f" "0")
3407 (set_attr "modrm" "0,1")])
3408
3409 (define_insn "extendhidi2"
3410 [(set (match_operand:DI 0 "register_operand" "=r")
3411 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3412 "TARGET_64BIT"
3413 "movs{wq|x}\t{%1,%0|%0, %1}"
3414 [(set_attr "type" "imovx")
3415 (set_attr "mode" "DI")])
3416
3417 (define_insn "extendqidi2"
3418 [(set (match_operand:DI 0 "register_operand" "=r")
3419 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3420 "TARGET_64BIT"
3421 "movs{bq|x}\t{%1,%0|%0, %1}"
3422 [(set_attr "type" "imovx")
3423 (set_attr "mode" "DI")])
3424
3425 ;; Extend to memory case when source register does die.
3426 (define_split
3427 [(set (match_operand:DI 0 "memory_operand" "")
3428 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3429 (clobber (reg:CC FLAGS_REG))
3430 (clobber (match_operand:SI 2 "register_operand" ""))]
3431 "(reload_completed
3432 && dead_or_set_p (insn, operands[1])
3433 && !reg_mentioned_p (operands[1], operands[0]))"
3434 [(set (match_dup 3) (match_dup 1))
3435 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3436 (clobber (reg:CC FLAGS_REG))])
3437 (set (match_dup 4) (match_dup 1))]
3438 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3439
3440 ;; Extend to memory case when source register does not die.
3441 (define_split
3442 [(set (match_operand:DI 0 "memory_operand" "")
3443 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3444 (clobber (reg:CC FLAGS_REG))
3445 (clobber (match_operand:SI 2 "register_operand" ""))]
3446 "reload_completed"
3447 [(const_int 0)]
3448 {
3449 split_di (&operands[0], 1, &operands[3], &operands[4]);
3450
3451 emit_move_insn (operands[3], operands[1]);
3452
3453 /* Generate a cltd if possible and doing so it profitable. */
3454 if (true_regnum (operands[1]) == 0
3455 && true_regnum (operands[2]) == 1
3456 && (optimize_size || TARGET_USE_CLTD))
3457 {
3458 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3459 }
3460 else
3461 {
3462 emit_move_insn (operands[2], operands[1]);
3463 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3464 }
3465 emit_move_insn (operands[4], operands[2]);
3466 DONE;
3467 })
3468
3469 ;; Extend to register case. Optimize case where source and destination
3470 ;; registers match and cases where we can use cltd.
3471 (define_split
3472 [(set (match_operand:DI 0 "register_operand" "")
3473 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3474 (clobber (reg:CC FLAGS_REG))
3475 (clobber (match_scratch:SI 2 ""))]
3476 "reload_completed"
3477 [(const_int 0)]
3478 {
3479 split_di (&operands[0], 1, &operands[3], &operands[4]);
3480
3481 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3482 emit_move_insn (operands[3], operands[1]);
3483
3484 /* Generate a cltd if possible and doing so it profitable. */
3485 if (true_regnum (operands[3]) == 0
3486 && (optimize_size || TARGET_USE_CLTD))
3487 {
3488 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3489 DONE;
3490 }
3491
3492 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3493 emit_move_insn (operands[4], operands[1]);
3494
3495 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3496 DONE;
3497 })
3498
3499 (define_insn "extendhisi2"
3500 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3501 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3502 ""
3503 {
3504 switch (get_attr_prefix_0f (insn))
3505 {
3506 case 0:
3507 return "{cwtl|cwde}";
3508 default:
3509 return "movs{wl|x}\t{%1,%0|%0, %1}";
3510 }
3511 }
3512 [(set_attr "type" "imovx")
3513 (set_attr "mode" "SI")
3514 (set (attr "prefix_0f")
3515 ;; movsx is short decodable while cwtl is vector decoded.
3516 (if_then_else (and (eq_attr "cpu" "!k6")
3517 (eq_attr "alternative" "0"))
3518 (const_string "0")
3519 (const_string "1")))
3520 (set (attr "modrm")
3521 (if_then_else (eq_attr "prefix_0f" "0")
3522 (const_string "0")
3523 (const_string "1")))])
3524
3525 (define_insn "*extendhisi2_zext"
3526 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3527 (zero_extend:DI
3528 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3529 "TARGET_64BIT"
3530 {
3531 switch (get_attr_prefix_0f (insn))
3532 {
3533 case 0:
3534 return "{cwtl|cwde}";
3535 default:
3536 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3537 }
3538 }
3539 [(set_attr "type" "imovx")
3540 (set_attr "mode" "SI")
3541 (set (attr "prefix_0f")
3542 ;; movsx is short decodable while cwtl is vector decoded.
3543 (if_then_else (and (eq_attr "cpu" "!k6")
3544 (eq_attr "alternative" "0"))
3545 (const_string "0")
3546 (const_string "1")))
3547 (set (attr "modrm")
3548 (if_then_else (eq_attr "prefix_0f" "0")
3549 (const_string "0")
3550 (const_string "1")))])
3551
3552 (define_insn "extendqihi2"
3553 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3554 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3555 ""
3556 {
3557 switch (get_attr_prefix_0f (insn))
3558 {
3559 case 0:
3560 return "{cbtw|cbw}";
3561 default:
3562 return "movs{bw|x}\t{%1,%0|%0, %1}";
3563 }
3564 }
3565 [(set_attr "type" "imovx")
3566 (set_attr "mode" "HI")
3567 (set (attr "prefix_0f")
3568 ;; movsx is short decodable while cwtl is vector decoded.
3569 (if_then_else (and (eq_attr "cpu" "!k6")
3570 (eq_attr "alternative" "0"))
3571 (const_string "0")
3572 (const_string "1")))
3573 (set (attr "modrm")
3574 (if_then_else (eq_attr "prefix_0f" "0")
3575 (const_string "0")
3576 (const_string "1")))])
3577
3578 (define_insn "extendqisi2"
3579 [(set (match_operand:SI 0 "register_operand" "=r")
3580 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3581 ""
3582 "movs{bl|x}\t{%1,%0|%0, %1}"
3583 [(set_attr "type" "imovx")
3584 (set_attr "mode" "SI")])
3585
3586 (define_insn "*extendqisi2_zext"
3587 [(set (match_operand:DI 0 "register_operand" "=r")
3588 (zero_extend:DI
3589 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3590 "TARGET_64BIT"
3591 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3592 [(set_attr "type" "imovx")
3593 (set_attr "mode" "SI")])
3594 \f
3595 ;; Conversions between float and double.
3596
3597 ;; These are all no-ops in the model used for the 80387. So just
3598 ;; emit moves.
3599
3600 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3601 (define_insn "*dummy_extendsfdf2"
3602 [(set (match_operand:DF 0 "push_operand" "=<")
3603 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3604 "0"
3605 "#")
3606
3607 (define_split
3608 [(set (match_operand:DF 0 "push_operand" "")
3609 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3610 "!TARGET_64BIT"
3611 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3612 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3613
3614 (define_split
3615 [(set (match_operand:DF 0 "push_operand" "")
3616 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3617 "TARGET_64BIT"
3618 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3619 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3620
3621 (define_insn "*dummy_extendsfxf2"
3622 [(set (match_operand:XF 0 "push_operand" "=<")
3623 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3624 "0"
3625 "#")
3626
3627 (define_split
3628 [(set (match_operand:XF 0 "push_operand" "")
3629 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3630 ""
3631 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3632 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3633 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3634
3635 (define_split
3636 [(set (match_operand:XF 0 "push_operand" "")
3637 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3638 "TARGET_64BIT"
3639 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3640 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3641 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3642
3643 (define_split
3644 [(set (match_operand:XF 0 "push_operand" "")
3645 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3646 ""
3647 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3648 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3649 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3650
3651 (define_split
3652 [(set (match_operand:XF 0 "push_operand" "")
3653 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3654 "TARGET_64BIT"
3655 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3656 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3657 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3658
3659 (define_expand "extendsfdf2"
3660 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3661 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3662 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3663 {
3664 /* ??? Needed for compress_float_constant since all fp constants
3665 are LEGITIMATE_CONSTANT_P. */
3666 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3667 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3668 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3669 operands[1] = force_reg (SFmode, operands[1]);
3670 })
3671
3672 (define_insn "*extendsfdf2_mixed"
3673 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3674 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3675 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3676 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3677 {
3678 switch (which_alternative)
3679 {
3680 case 0:
3681 return output_387_reg_move (insn, operands);
3682
3683 case 1:
3684 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685 return "fstp%z0\t%y0";
3686 else
3687 return "fst%z0\t%y0";
3688
3689 case 2:
3690 return "cvtss2sd\t{%1, %0|%0, %1}";
3691
3692 default:
3693 abort ();
3694 }
3695 }
3696 [(set_attr "type" "fmov,fmov,ssecvt")
3697 (set_attr "mode" "SF,XF,DF")])
3698
3699 (define_insn "*extendsfdf2_sse"
3700 [(set (match_operand:DF 0 "register_operand" "=Y")
3701 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3702 "TARGET_SSE2 && TARGET_SSE_MATH
3703 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3704 "cvtss2sd\t{%1, %0|%0, %1}"
3705 [(set_attr "type" "ssecvt")
3706 (set_attr "mode" "DF")])
3707
3708 (define_insn "*extendsfdf2_i387"
3709 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3710 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3711 "TARGET_80387
3712 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3713 {
3714 switch (which_alternative)
3715 {
3716 case 0:
3717 return output_387_reg_move (insn, operands);
3718
3719 case 1:
3720 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3721 return "fstp%z0\t%y0";
3722 else
3723 return "fst%z0\t%y0";
3724
3725 default:
3726 abort ();
3727 }
3728 }
3729 [(set_attr "type" "fmov")
3730 (set_attr "mode" "SF,XF")])
3731
3732 (define_expand "extendsfxf2"
3733 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3734 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3735 "TARGET_80387"
3736 {
3737 /* ??? Needed for compress_float_constant since all fp constants
3738 are LEGITIMATE_CONSTANT_P. */
3739 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3740 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3741 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3742 operands[1] = force_reg (SFmode, operands[1]);
3743 })
3744
3745 (define_insn "*extendsfxf2_i387"
3746 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3747 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3748 "TARGET_80387
3749 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3750 {
3751 switch (which_alternative)
3752 {
3753 case 0:
3754 return output_387_reg_move (insn, operands);
3755
3756 case 1:
3757 /* There is no non-popping store to memory for XFmode. So if
3758 we need one, follow the store with a load. */
3759 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3760 return "fstp%z0\t%y0";
3761 else
3762 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3763
3764 default:
3765 abort ();
3766 }
3767 }
3768 [(set_attr "type" "fmov")
3769 (set_attr "mode" "SF,XF")])
3770
3771 (define_expand "extenddfxf2"
3772 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3773 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3774 "TARGET_80387"
3775 {
3776 /* ??? Needed for compress_float_constant since all fp constants
3777 are LEGITIMATE_CONSTANT_P. */
3778 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3779 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3780 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3781 operands[1] = force_reg (DFmode, operands[1]);
3782 })
3783
3784 (define_insn "*extenddfxf2_i387"
3785 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3786 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3787 "TARGET_80387
3788 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3789 {
3790 switch (which_alternative)
3791 {
3792 case 0:
3793 return output_387_reg_move (insn, operands);
3794
3795 case 1:
3796 /* There is no non-popping store to memory for XFmode. So if
3797 we need one, follow the store with a load. */
3798 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3799 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3800 else
3801 return "fstp%z0\t%y0";
3802
3803 default:
3804 abort ();
3805 }
3806 }
3807 [(set_attr "type" "fmov")
3808 (set_attr "mode" "DF,XF")])
3809
3810 ;; %%% This seems bad bad news.
3811 ;; This cannot output into an f-reg because there is no way to be sure
3812 ;; of truncating in that case. Otherwise this is just like a simple move
3813 ;; insn. So we pretend we can output to a reg in order to get better
3814 ;; register preferencing, but we really use a stack slot.
3815
3816 ;; Conversion from DFmode to SFmode.
3817
3818 (define_expand "truncdfsf2"
3819 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3820 (float_truncate:SF
3821 (match_operand:DF 1 "nonimmediate_operand" "")))]
3822 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3823 {
3824 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3825 operands[1] = force_reg (DFmode, operands[1]);
3826
3827 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3828 ;
3829 else if (flag_unsafe_math_optimizations)
3830 ;
3831 else
3832 {
3833 rtx temp = assign_386_stack_local (SFmode, 0);
3834 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3835 DONE;
3836 }
3837 })
3838
3839 (define_expand "truncdfsf2_with_temp"
3840 [(parallel [(set (match_operand:SF 0 "" "")
3841 (float_truncate:SF (match_operand:DF 1 "" "")))
3842 (clobber (match_operand:SF 2 "" ""))])]
3843 "")
3844
3845 (define_insn "*truncdfsf_fast_mixed"
3846 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3847 (float_truncate:SF
3848 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3849 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3850 {
3851 switch (which_alternative)
3852 {
3853 case 0:
3854 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3855 return "fstp%z0\t%y0";
3856 else
3857 return "fst%z0\t%y0";
3858 case 1:
3859 return output_387_reg_move (insn, operands);
3860 case 2:
3861 return "cvtsd2ss\t{%1, %0|%0, %1}";
3862 default:
3863 abort ();
3864 }
3865 }
3866 [(set_attr "type" "fmov,fmov,ssecvt")
3867 (set_attr "mode" "SF")])
3868
3869 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3870 ;; because nothing we do here is unsafe.
3871 (define_insn "*truncdfsf_fast_sse"
3872 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3873 (float_truncate:SF
3874 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3875 "TARGET_SSE2 && TARGET_SSE_MATH"
3876 "cvtsd2ss\t{%1, %0|%0, %1}"
3877 [(set_attr "type" "ssecvt")
3878 (set_attr "mode" "SF")])
3879
3880 (define_insn "*truncdfsf_fast_i387"
3881 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3882 (float_truncate:SF
3883 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3884 "TARGET_80387 && flag_unsafe_math_optimizations"
3885 "* return output_387_reg_move (insn, operands);"
3886 [(set_attr "type" "fmov")
3887 (set_attr "mode" "SF")])
3888
3889 (define_insn "*truncdfsf_mixed"
3890 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3891 (float_truncate:SF
3892 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3893 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3894 "TARGET_MIX_SSE_I387"
3895 {
3896 switch (which_alternative)
3897 {
3898 case 0:
3899 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3900 return "fstp%z0\t%y0";
3901 else
3902 return "fst%z0\t%y0";
3903 case 1:
3904 return "#";
3905 case 2:
3906 return "cvtsd2ss\t{%1, %0|%0, %1}";
3907 default:
3908 abort ();
3909 }
3910 }
3911 [(set_attr "type" "fmov,multi,ssecvt")
3912 (set_attr "mode" "SF")])
3913
3914 (define_insn "*truncdfsf_i387"
3915 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3916 (float_truncate:SF
3917 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3918 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3919 "TARGET_80387"
3920 {
3921 switch (which_alternative)
3922 {
3923 case 0:
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 case 1:
3929 return "#";
3930 default:
3931 abort ();
3932 }
3933 }
3934 [(set_attr "type" "fmov,multi")
3935 (set_attr "mode" "SF")])
3936
3937 (define_split
3938 [(set (match_operand:SF 0 "register_operand" "")
3939 (float_truncate:SF
3940 (match_operand:DF 1 "fp_register_operand" "")))
3941 (clobber (match_operand 2 "" ""))]
3942 "reload_completed"
3943 [(set (match_dup 2) (match_dup 1))
3944 (set (match_dup 0) (match_dup 2))]
3945 {
3946 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3947 })
3948
3949 ;; Conversion from XFmode to SFmode.
3950
3951 (define_expand "truncxfsf2"
3952 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3953 (float_truncate:SF
3954 (match_operand:XF 1 "register_operand" "")))
3955 (clobber (match_dup 2))])]
3956 "TARGET_80387"
3957 {
3958 if (flag_unsafe_math_optimizations)
3959 {
3960 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3961 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3962 if (reg != operands[0])
3963 emit_move_insn (operands[0], reg);
3964 DONE;
3965 }
3966 else
3967 operands[2] = assign_386_stack_local (SFmode, 0);
3968 })
3969
3970 (define_insn "*truncxfsf2_mixed"
3971 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3972 (float_truncate:SF
3973 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3974 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3975 "TARGET_MIX_SSE_I387"
3976 {
3977 switch (which_alternative)
3978 {
3979 case 0:
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 default:
3985 abort();
3986 }
3987 }
3988 [(set_attr "type" "fmov,multi,multi,multi")
3989 (set_attr "mode" "SF")])
3990
3991 (define_insn "truncxfsf2_i387_noop"
3992 [(set (match_operand:SF 0 "register_operand" "=f")
3993 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3994 "TARGET_80387 && flag_unsafe_math_optimizations"
3995 {
3996 return output_387_reg_move (insn, operands);
3997 }
3998 [(set_attr "type" "fmov")
3999 (set_attr "mode" "SF")])
4000
4001 (define_insn "*truncxfsf2_i387"
4002 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
4003 (float_truncate:SF
4004 (match_operand:XF 1 "register_operand" "f,f,f")))
4005 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
4006 "TARGET_80387"
4007 {
4008 switch (which_alternative)
4009 {
4010 case 0:
4011 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4012 return "fstp%z0\t%y0";
4013 else
4014 return "fst%z0\t%y0";
4015 default:
4016 abort ();
4017 }
4018 }
4019 [(set_attr "type" "fmov,multi,multi")
4020 (set_attr "mode" "SF")])
4021
4022 (define_insn "*truncxfsf2_i387_1"
4023 [(set (match_operand:SF 0 "memory_operand" "=m")
4024 (float_truncate:SF
4025 (match_operand:XF 1 "register_operand" "f")))]
4026 "TARGET_80387"
4027 {
4028 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4029 return "fstp%z0\t%y0";
4030 else
4031 return "fst%z0\t%y0";
4032 }
4033 [(set_attr "type" "fmov")
4034 (set_attr "mode" "SF")])
4035
4036 (define_split
4037 [(set (match_operand:SF 0 "register_operand" "")
4038 (float_truncate:SF
4039 (match_operand:XF 1 "register_operand" "")))
4040 (clobber (match_operand:SF 2 "memory_operand" ""))]
4041 "TARGET_80387 && reload_completed"
4042 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4043 (set (match_dup 0) (match_dup 2))]
4044 "")
4045
4046 (define_split
4047 [(set (match_operand:SF 0 "memory_operand" "")
4048 (float_truncate:SF
4049 (match_operand:XF 1 "register_operand" "")))
4050 (clobber (match_operand:SF 2 "memory_operand" ""))]
4051 "TARGET_80387"
4052 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4053 "")
4054
4055 ;; Conversion from XFmode to DFmode.
4056
4057 (define_expand "truncxfdf2"
4058 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4059 (float_truncate:DF
4060 (match_operand:XF 1 "register_operand" "")))
4061 (clobber (match_dup 2))])]
4062 "TARGET_80387"
4063 {
4064 if (flag_unsafe_math_optimizations)
4065 {
4066 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4067 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4068 if (reg != operands[0])
4069 emit_move_insn (operands[0], reg);
4070 DONE;
4071 }
4072 else
4073 operands[2] = assign_386_stack_local (DFmode, 0);
4074 })
4075
4076 (define_insn "*truncxfdf2_mixed"
4077 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4078 (float_truncate:DF
4079 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4080 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4081 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4082 {
4083 switch (which_alternative)
4084 {
4085 case 0:
4086 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4087 return "fstp%z0\t%y0";
4088 else
4089 return "fst%z0\t%y0";
4090 default:
4091 abort();
4092 }
4093 abort ();
4094 }
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "mode" "DF")])
4097
4098 (define_insn "truncxfdf2_i387_noop"
4099 [(set (match_operand:DF 0 "register_operand" "=f")
4100 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4101 "TARGET_80387 && flag_unsafe_math_optimizations"
4102 {
4103 return output_387_reg_move (insn, operands);
4104 }
4105 [(set_attr "type" "fmov")
4106 (set_attr "mode" "DF")])
4107
4108 (define_insn "*truncxfdf2_i387"
4109 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
4110 (float_truncate:DF
4111 (match_operand:XF 1 "register_operand" "f,f,f")))
4112 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4113 "TARGET_80387"
4114 {
4115 switch (which_alternative)
4116 {
4117 case 0:
4118 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4119 return "fstp%z0\t%y0";
4120 else
4121 return "fst%z0\t%y0";
4122 default:
4123 abort ();
4124 }
4125 }
4126 [(set_attr "type" "fmov,multi,multi")
4127 (set_attr "mode" "DF")])
4128
4129 (define_insn "*truncxfdf2_i387_1"
4130 [(set (match_operand:DF 0 "memory_operand" "=m")
4131 (float_truncate:DF
4132 (match_operand:XF 1 "register_operand" "f")))]
4133 "TARGET_80387"
4134 {
4135 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4136 return "fstp%z0\t%y0";
4137 else
4138 return "fst%z0\t%y0";
4139 }
4140 [(set_attr "type" "fmov")
4141 (set_attr "mode" "DF")])
4142
4143 (define_split
4144 [(set (match_operand:DF 0 "register_operand" "")
4145 (float_truncate:DF
4146 (match_operand:XF 1 "register_operand" "")))
4147 (clobber (match_operand:DF 2 "memory_operand" ""))]
4148 "TARGET_80387 && reload_completed"
4149 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4150 (set (match_dup 0) (match_dup 2))]
4151 "")
4152
4153 (define_split
4154 [(set (match_operand:DF 0 "memory_operand" "")
4155 (float_truncate:DF
4156 (match_operand:XF 1 "register_operand" "")))
4157 (clobber (match_operand:DF 2 "memory_operand" ""))]
4158 "TARGET_80387"
4159 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4160 "")
4161 \f
4162 ;; %%% Break up all these bad boys.
4163
4164 ;; Signed conversion to DImode.
4165
4166 (define_expand "fix_truncxfdi2"
4167 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4168 (fix:DI (match_operand:XF 1 "register_operand" "")))
4169 (clobber (reg:CC FLAGS_REG))])]
4170 "TARGET_80387"
4171 "")
4172
4173 (define_expand "fix_truncdfdi2"
4174 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4175 (fix:DI (match_operand:DF 1 "register_operand" "")))
4176 (clobber (reg:CC FLAGS_REG))])]
4177 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2)"
4178 {
4179 if (TARGET_64BIT && TARGET_SSE2)
4180 {
4181 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4182 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4183 if (out != operands[0])
4184 emit_move_insn (operands[0], out);
4185 DONE;
4186 }
4187 })
4188
4189 (define_expand "fix_truncsfdi2"
4190 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4191 (fix:DI (match_operand:SF 1 "register_operand" "")))
4192 (clobber (reg:CC FLAGS_REG))])]
4193 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE)"
4194 {
4195 if (TARGET_64BIT && TARGET_SSE)
4196 {
4197 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4198 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4199 if (out != operands[0])
4200 emit_move_insn (operands[0], out);
4201 DONE;
4202 }
4203 })
4204
4205 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4206 ;; of the machinery.
4207 (define_insn_and_split "*fix_truncdi_i387"
4208 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4209 (fix:DI (match_operand 1 "register_operand" "f,f")))
4210 (clobber (reg:CC FLAGS_REG))]
4211 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4212 && !reload_completed && !reload_in_progress
4213 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4214 "#"
4215 "&& 1"
4216 [(const_int 0)]
4217 {
4218 ix86_optimize_mode_switching = 1;
4219 operands[2] = assign_386_stack_local (HImode, 1);
4220 operands[3] = assign_386_stack_local (HImode, 2);
4221 if (memory_operand (operands[0], VOIDmode))
4222 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4223 operands[2], operands[3]));
4224 else
4225 {
4226 operands[4] = assign_386_stack_local (DImode, 0);
4227 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4228 operands[2], operands[3],
4229 operands[4]));
4230 }
4231 DONE;
4232 }
4233 [(set_attr "type" "fistp")
4234 (set_attr "i387_cw" "trunc")
4235 (set_attr "mode" "DI")])
4236
4237 (define_insn "fix_truncdi_nomemory"
4238 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4239 (fix:DI (match_operand 1 "register_operand" "f,f")))
4240 (use (match_operand:HI 2 "memory_operand" "m,m"))
4241 (use (match_operand:HI 3 "memory_operand" "m,m"))
4242 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4243 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4244 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4245 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4246 "#"
4247 [(set_attr "type" "fistp")
4248 (set_attr "i387_cw" "trunc")
4249 (set_attr "mode" "DI")])
4250
4251 (define_insn "fix_truncdi_memory"
4252 [(set (match_operand:DI 0 "memory_operand" "=m")
4253 (fix:DI (match_operand 1 "register_operand" "f")))
4254 (use (match_operand:HI 2 "memory_operand" "m"))
4255 (use (match_operand:HI 3 "memory_operand" "m"))
4256 (clobber (match_scratch:DF 4 "=&1f"))]
4257 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4258 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4259 "* return output_fix_trunc (insn, operands);"
4260 [(set_attr "type" "fistp")
4261 (set_attr "i387_cw" "trunc")
4262 (set_attr "mode" "DI")])
4263
4264 (define_split
4265 [(set (match_operand:DI 0 "register_operand" "")
4266 (fix:DI (match_operand 1 "register_operand" "")))
4267 (use (match_operand:HI 2 "memory_operand" ""))
4268 (use (match_operand:HI 3 "memory_operand" ""))
4269 (clobber (match_operand:DI 4 "memory_operand" ""))
4270 (clobber (match_scratch 5 ""))]
4271 "reload_completed"
4272 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4273 (use (match_dup 2))
4274 (use (match_dup 3))
4275 (clobber (match_dup 5))])
4276 (set (match_dup 0) (match_dup 4))]
4277 "")
4278
4279 (define_split
4280 [(set (match_operand:DI 0 "memory_operand" "")
4281 (fix:DI (match_operand 1 "register_operand" "")))
4282 (use (match_operand:HI 2 "memory_operand" ""))
4283 (use (match_operand:HI 3 "memory_operand" ""))
4284 (clobber (match_operand:DI 4 "memory_operand" ""))
4285 (clobber (match_scratch 5 ""))]
4286 "reload_completed"
4287 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4288 (use (match_dup 2))
4289 (use (match_dup 3))
4290 (clobber (match_dup 5))])]
4291 "")
4292
4293 ;; When SSE available, it is always faster to use it!
4294 (define_insn "fix_truncsfdi_sse"
4295 [(set (match_operand:DI 0 "register_operand" "=r,r")
4296 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4297 "TARGET_64BIT && TARGET_SSE"
4298 "cvttss2si{q}\t{%1, %0|%0, %1}"
4299 [(set_attr "type" "sseicvt")
4300 (set_attr "mode" "SF")
4301 (set_attr "athlon_decode" "double,vector")])
4302
4303 ;; Avoid vector decoded form of the instruction.
4304 (define_peephole2
4305 [(match_scratch:SF 2 "x")
4306 (set (match_operand:DI 0 "register_operand" "")
4307 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4308 "TARGET_K8 && !optimize_size"
4309 [(set (match_dup 2) (match_dup 1))
4310 (set (match_dup 0) (fix:DI (match_dup 2)))]
4311 "")
4312
4313 (define_insn "fix_truncdfdi_sse"
4314 [(set (match_operand:DI 0 "register_operand" "=r,r")
4315 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4316 "TARGET_64BIT && TARGET_SSE2"
4317 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4318 [(set_attr "type" "sseicvt,sseicvt")
4319 (set_attr "mode" "DF")
4320 (set_attr "athlon_decode" "double,vector")])
4321
4322 ;; Avoid vector decoded form of the instruction.
4323 (define_peephole2
4324 [(match_scratch:DF 2 "Y")
4325 (set (match_operand:DI 0 "register_operand" "")
4326 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4327 "TARGET_K8 && !optimize_size"
4328 [(set (match_dup 2) (match_dup 1))
4329 (set (match_dup 0) (fix:DI (match_dup 2)))]
4330 "")
4331
4332 ;; Signed conversion to SImode.
4333
4334 (define_expand "fix_truncxfsi2"
4335 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4336 (fix:SI (match_operand:XF 1 "register_operand" "")))
4337 (clobber (reg:CC FLAGS_REG))])]
4338 "TARGET_80387"
4339 "")
4340
4341 (define_expand "fix_truncdfsi2"
4342 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4343 (fix:SI (match_operand:DF 1 "register_operand" "")))
4344 (clobber (reg:CC FLAGS_REG))])]
4345 "TARGET_80387 || TARGET_SSE2"
4346 {
4347 if (TARGET_SSE2)
4348 {
4349 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4350 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4351 if (out != operands[0])
4352 emit_move_insn (operands[0], out);
4353 DONE;
4354 }
4355 })
4356
4357 (define_expand "fix_truncsfsi2"
4358 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4359 (fix:SI (match_operand:SF 1 "register_operand" "")))
4360 (clobber (reg:CC FLAGS_REG))])]
4361 "TARGET_80387 || TARGET_SSE"
4362 {
4363 if (TARGET_SSE)
4364 {
4365 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4366 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4367 if (out != operands[0])
4368 emit_move_insn (operands[0], out);
4369 DONE;
4370 }
4371 })
4372
4373 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4374 ;; of the machinery.
4375 (define_insn_and_split "*fix_truncsi_i387"
4376 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4377 (fix:SI (match_operand 1 "register_operand" "f,f")))
4378 (clobber (reg:CC FLAGS_REG))]
4379 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4380 && !reload_completed && !reload_in_progress
4381 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4382 "#"
4383 "&& 1"
4384 [(const_int 0)]
4385 {
4386 ix86_optimize_mode_switching = 1;
4387 operands[2] = assign_386_stack_local (HImode, 1);
4388 operands[3] = assign_386_stack_local (HImode, 2);
4389 if (memory_operand (operands[0], VOIDmode))
4390 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4391 operands[2], operands[3]));
4392 else
4393 {
4394 operands[4] = assign_386_stack_local (SImode, 0);
4395 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4396 operands[2], operands[3],
4397 operands[4]));
4398 }
4399 DONE;
4400 }
4401 [(set_attr "type" "fistp")
4402 (set_attr "i387_cw" "trunc")
4403 (set_attr "mode" "SI")])
4404
4405 (define_insn "fix_truncsi_nomemory"
4406 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4407 (fix:SI (match_operand 1 "register_operand" "f,f")))
4408 (use (match_operand:HI 2 "memory_operand" "m,m"))
4409 (use (match_operand:HI 3 "memory_operand" "m,m"))
4410 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4411 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4412 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4413 "#"
4414 [(set_attr "type" "fistp")
4415 (set_attr "i387_cw" "trunc")
4416 (set_attr "mode" "SI")])
4417
4418 (define_insn "fix_truncsi_memory"
4419 [(set (match_operand:SI 0 "memory_operand" "=m")
4420 (fix:SI (match_operand 1 "register_operand" "f")))
4421 (use (match_operand:HI 2 "memory_operand" "m"))
4422 (use (match_operand:HI 3 "memory_operand" "m"))]
4423 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4424 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4425 "* return output_fix_trunc (insn, operands);"
4426 [(set_attr "type" "fistp")
4427 (set_attr "i387_cw" "trunc")
4428 (set_attr "mode" "SI")])
4429
4430 ;; When SSE available, it is always faster to use it!
4431 (define_insn "fix_truncsfsi_sse"
4432 [(set (match_operand:SI 0 "register_operand" "=r,r")
4433 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4434 "TARGET_SSE"
4435 "cvttss2si\t{%1, %0|%0, %1}"
4436 [(set_attr "type" "sseicvt")
4437 (set_attr "mode" "DF")
4438 (set_attr "athlon_decode" "double,vector")])
4439
4440 ;; Avoid vector decoded form of the instruction.
4441 (define_peephole2
4442 [(match_scratch:SF 2 "x")
4443 (set (match_operand:SI 0 "register_operand" "")
4444 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4445 "TARGET_K8 && !optimize_size"
4446 [(set (match_dup 2) (match_dup 1))
4447 (set (match_dup 0) (fix:SI (match_dup 2)))]
4448 "")
4449
4450 (define_insn "fix_truncdfsi_sse"
4451 [(set (match_operand:SI 0 "register_operand" "=r,r")
4452 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4453 "TARGET_SSE2"
4454 "cvttsd2si\t{%1, %0|%0, %1}"
4455 [(set_attr "type" "sseicvt")
4456 (set_attr "mode" "DF")
4457 (set_attr "athlon_decode" "double,vector")])
4458
4459 ;; Avoid vector decoded form of the instruction.
4460 (define_peephole2
4461 [(match_scratch:DF 2 "Y")
4462 (set (match_operand:SI 0 "register_operand" "")
4463 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4464 "TARGET_K8 && !optimize_size"
4465 [(set (match_dup 2) (match_dup 1))
4466 (set (match_dup 0) (fix:SI (match_dup 2)))]
4467 "")
4468
4469 (define_split
4470 [(set (match_operand:SI 0 "register_operand" "")
4471 (fix:SI (match_operand 1 "register_operand" "")))
4472 (use (match_operand:HI 2 "memory_operand" ""))
4473 (use (match_operand:HI 3 "memory_operand" ""))
4474 (clobber (match_operand:SI 4 "memory_operand" ""))]
4475 "reload_completed"
4476 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4477 (use (match_dup 2))
4478 (use (match_dup 3))])
4479 (set (match_dup 0) (match_dup 4))]
4480 "")
4481
4482 (define_split
4483 [(set (match_operand:SI 0 "memory_operand" "")
4484 (fix:SI (match_operand 1 "register_operand" "")))
4485 (use (match_operand:HI 2 "memory_operand" ""))
4486 (use (match_operand:HI 3 "memory_operand" ""))
4487 (clobber (match_operand:SI 4 "memory_operand" ""))]
4488 "reload_completed"
4489 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4490 (use (match_dup 2))
4491 (use (match_dup 3))])]
4492 "")
4493
4494 ;; Signed conversion to HImode.
4495
4496 (define_expand "fix_truncxfhi2"
4497 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4498 (fix:HI (match_operand:XF 1 "register_operand" "")))
4499 (clobber (reg:CC FLAGS_REG))])]
4500 "TARGET_80387"
4501 "")
4502
4503 (define_expand "fix_truncdfhi2"
4504 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4505 (fix:HI (match_operand:DF 1 "register_operand" "")))
4506 (clobber (reg:CC FLAGS_REG))])]
4507 "TARGET_80387 && !TARGET_SSE2"
4508 "")
4509
4510 (define_expand "fix_truncsfhi2"
4511 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4512 (fix:HI (match_operand:SF 1 "register_operand" "")))
4513 (clobber (reg:CC FLAGS_REG))])]
4514 "TARGET_80387 && !TARGET_SSE"
4515 "")
4516
4517 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4518 ;; of the machinery.
4519 (define_insn_and_split "*fix_trunchi_i387"
4520 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4521 (fix:HI (match_operand 1 "register_operand" "f,f")))
4522 (clobber (reg:CC FLAGS_REG))]
4523 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4524 && !reload_completed && !reload_in_progress
4525 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4526 "#"
4527 "&& 1"
4528 [(const_int 0)]
4529 {
4530 ix86_optimize_mode_switching = 1;
4531 operands[2] = assign_386_stack_local (HImode, 1);
4532 operands[3] = assign_386_stack_local (HImode, 2);
4533 if (memory_operand (operands[0], VOIDmode))
4534 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4535 operands[2], operands[3]));
4536 else
4537 {
4538 operands[4] = assign_386_stack_local (HImode, 0);
4539 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4540 operands[2], operands[3],
4541 operands[4]));
4542 }
4543 DONE;
4544 }
4545 [(set_attr "type" "fistp")
4546 (set_attr "i387_cw" "trunc")
4547 (set_attr "mode" "HI")])
4548
4549 (define_insn "fix_trunchi_nomemory"
4550 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4551 (fix:HI (match_operand 1 "register_operand" "f,f")))
4552 (use (match_operand:HI 2 "memory_operand" "m,m"))
4553 (use (match_operand:HI 3 "memory_operand" "m,m"))
4554 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4555 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4556 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4557 "#"
4558 [(set_attr "type" "fistp")
4559 (set_attr "i387_cw" "trunc")
4560 (set_attr "mode" "HI")])
4561
4562 (define_insn "fix_trunchi_memory"
4563 [(set (match_operand:HI 0 "memory_operand" "=m")
4564 (fix:HI (match_operand 1 "register_operand" "f")))
4565 (use (match_operand:HI 2 "memory_operand" "m"))
4566 (use (match_operand:HI 3 "memory_operand" "m"))]
4567 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4569 "* return output_fix_trunc (insn, operands);"
4570 [(set_attr "type" "fistp")
4571 (set_attr "i387_cw" "trunc")
4572 (set_attr "mode" "HI")])
4573
4574 (define_split
4575 [(set (match_operand:HI 0 "memory_operand" "")
4576 (fix:HI (match_operand 1 "register_operand" "")))
4577 (use (match_operand:HI 2 "memory_operand" ""))
4578 (use (match_operand:HI 3 "memory_operand" ""))
4579 (clobber (match_operand:HI 4 "memory_operand" ""))]
4580 "reload_completed"
4581 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4582 (use (match_dup 2))
4583 (use (match_dup 3))])]
4584 "")
4585
4586 (define_split
4587 [(set (match_operand:HI 0 "register_operand" "")
4588 (fix:HI (match_operand 1 "register_operand" "")))
4589 (use (match_operand:HI 2 "memory_operand" ""))
4590 (use (match_operand:HI 3 "memory_operand" ""))
4591 (clobber (match_operand:HI 4 "memory_operand" ""))]
4592 "reload_completed"
4593 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4594 (use (match_dup 2))
4595 (use (match_dup 3))
4596 (clobber (match_dup 4))])
4597 (set (match_dup 0) (match_dup 4))]
4598 "")
4599
4600 (define_insn "x86_fnstcw_1"
4601 [(set (match_operand:HI 0 "memory_operand" "=m")
4602 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4603 "TARGET_80387"
4604 "fnstcw\t%0"
4605 [(set_attr "length" "2")
4606 (set_attr "mode" "HI")
4607 (set_attr "unit" "i387")])
4608
4609 (define_insn "x86_fldcw_1"
4610 [(set (reg:HI FPSR_REG)
4611 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4612 "TARGET_80387"
4613 "fldcw\t%0"
4614 [(set_attr "length" "2")
4615 (set_attr "mode" "HI")
4616 (set_attr "unit" "i387")
4617 (set_attr "athlon_decode" "vector")])
4618 \f
4619 ;; Conversion between fixed point and floating point.
4620
4621 ;; Even though we only accept memory inputs, the backend _really_
4622 ;; wants to be able to do this between registers.
4623
4624 (define_expand "floathisf2"
4625 [(set (match_operand:SF 0 "register_operand" "")
4626 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4627 "TARGET_80387 || TARGET_SSE_MATH"
4628 {
4629 if (TARGET_SSE_MATH)
4630 {
4631 emit_insn (gen_floatsisf2 (operands[0],
4632 convert_to_mode (SImode, operands[1], 0)));
4633 DONE;
4634 }
4635 })
4636
4637 (define_insn "*floathisf2_i387"
4638 [(set (match_operand:SF 0 "register_operand" "=f,f")
4639 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4640 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4641 "@
4642 fild%z1\t%1
4643 #"
4644 [(set_attr "type" "fmov,multi")
4645 (set_attr "mode" "SF")
4646 (set_attr "fp_int_src" "true")])
4647
4648 (define_expand "floatsisf2"
4649 [(set (match_operand:SF 0 "register_operand" "")
4650 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4651 "TARGET_80387 || TARGET_SSE_MATH"
4652 "")
4653
4654 (define_insn "*floatsisf2_mixed"
4655 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4656 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4657 "TARGET_MIX_SSE_I387"
4658 "@
4659 fild%z1\t%1
4660 #
4661 cvtsi2ss\t{%1, %0|%0, %1}
4662 cvtsi2ss\t{%1, %0|%0, %1}"
4663 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4664 (set_attr "mode" "SF")
4665 (set_attr "athlon_decode" "*,*,vector,double")
4666 (set_attr "fp_int_src" "true")])
4667
4668 (define_insn "*floatsisf2_sse"
4669 [(set (match_operand:SF 0 "register_operand" "=x,x")
4670 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4671 "TARGET_SSE_MATH"
4672 "cvtsi2ss\t{%1, %0|%0, %1}"
4673 [(set_attr "type" "sseicvt")
4674 (set_attr "mode" "SF")
4675 (set_attr "athlon_decode" "vector,double")
4676 (set_attr "fp_int_src" "true")])
4677
4678 (define_insn "*floatsisf2_i387"
4679 [(set (match_operand:SF 0 "register_operand" "=f,f")
4680 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4681 "TARGET_80387"
4682 "@
4683 fild%z1\t%1
4684 #"
4685 [(set_attr "type" "fmov,multi")
4686 (set_attr "mode" "SF")
4687 (set_attr "fp_int_src" "true")])
4688
4689 (define_expand "floatdisf2"
4690 [(set (match_operand:SF 0 "register_operand" "")
4691 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4692 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4693 "")
4694
4695 (define_insn "*floatdisf2_mixed"
4696 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4697 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4698 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4699 "@
4700 fild%z1\t%1
4701 #
4702 cvtsi2ss{q}\t{%1, %0|%0, %1}
4703 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4704 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4705 (set_attr "mode" "SF")
4706 (set_attr "athlon_decode" "*,*,vector,double")
4707 (set_attr "fp_int_src" "true")])
4708
4709 (define_insn "*floatdisf2_sse"
4710 [(set (match_operand:SF 0 "register_operand" "=x,x")
4711 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4712 "TARGET_64BIT && TARGET_SSE_MATH"
4713 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4714 [(set_attr "type" "sseicvt")
4715 (set_attr "mode" "SF")
4716 (set_attr "athlon_decode" "vector,double")
4717 (set_attr "fp_int_src" "true")])
4718
4719 (define_insn "*floatdisf2_i387"
4720 [(set (match_operand:SF 0 "register_operand" "=f,f")
4721 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4722 "TARGET_80387"
4723 "@
4724 fild%z1\t%1
4725 #"
4726 [(set_attr "type" "fmov,multi")
4727 (set_attr "mode" "SF")
4728 (set_attr "fp_int_src" "true")])
4729
4730 (define_expand "floathidf2"
4731 [(set (match_operand:DF 0 "register_operand" "")
4732 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4733 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4734 {
4735 if (TARGET_SSE2 && TARGET_SSE_MATH)
4736 {
4737 emit_insn (gen_floatsidf2 (operands[0],
4738 convert_to_mode (SImode, operands[1], 0)));
4739 DONE;
4740 }
4741 })
4742
4743 (define_insn "*floathidf2_i387"
4744 [(set (match_operand:DF 0 "register_operand" "=f,f")
4745 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4746 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4747 "@
4748 fild%z1\t%1
4749 #"
4750 [(set_attr "type" "fmov,multi")
4751 (set_attr "mode" "DF")
4752 (set_attr "fp_int_src" "true")])
4753
4754 (define_expand "floatsidf2"
4755 [(set (match_operand:DF 0 "register_operand" "")
4756 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4757 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4758 "")
4759
4760 (define_insn "*floatsidf2_mixed"
4761 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4762 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4763 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4764 "@
4765 fild%z1\t%1
4766 #
4767 cvtsi2sd\t{%1, %0|%0, %1}
4768 cvtsi2sd\t{%1, %0|%0, %1}"
4769 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4770 (set_attr "mode" "DF")
4771 (set_attr "athlon_decode" "*,*,double,direct")
4772 (set_attr "fp_int_src" "true")])
4773
4774 (define_insn "*floatsidf2_sse"
4775 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4776 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4777 "TARGET_SSE2 && TARGET_SSE_MATH"
4778 "cvtsi2sd\t{%1, %0|%0, %1}"
4779 [(set_attr "type" "sseicvt")
4780 (set_attr "mode" "DF")
4781 (set_attr "athlon_decode" "double,direct")
4782 (set_attr "fp_int_src" "true")])
4783
4784 (define_insn "*floatsidf2_i387"
4785 [(set (match_operand:DF 0 "register_operand" "=f,f")
4786 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4787 "TARGET_80387"
4788 "@
4789 fild%z1\t%1
4790 #"
4791 [(set_attr "type" "fmov,multi")
4792 (set_attr "mode" "DF")
4793 (set_attr "fp_int_src" "true")])
4794
4795 (define_expand "floatdidf2"
4796 [(set (match_operand:DF 0 "register_operand" "")
4797 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4798 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4799 "")
4800
4801 (define_insn "*floatdidf2_mixed"
4802 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4803 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4804 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4805 "@
4806 fild%z1\t%1
4807 #
4808 cvtsi2sd{q}\t{%1, %0|%0, %1}
4809 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4810 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4811 (set_attr "mode" "DF")
4812 (set_attr "athlon_decode" "*,*,double,direct")
4813 (set_attr "fp_int_src" "true")])
4814
4815 (define_insn "*floatdidf2_sse"
4816 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4817 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4818 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4819 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4820 [(set_attr "type" "sseicvt")
4821 (set_attr "mode" "DF")
4822 (set_attr "athlon_decode" "double,direct")
4823 (set_attr "fp_int_src" "true")])
4824
4825 (define_insn "*floatdidf2_i387"
4826 [(set (match_operand:DF 0 "register_operand" "=f,f")
4827 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4828 "TARGET_80387"
4829 "@
4830 fild%z1\t%1
4831 #"
4832 [(set_attr "type" "fmov,multi")
4833 (set_attr "mode" "DF")
4834 (set_attr "fp_int_src" "true")])
4835
4836 (define_insn "floathixf2"
4837 [(set (match_operand:XF 0 "register_operand" "=f,f")
4838 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4839 "TARGET_80387"
4840 "@
4841 fild%z1\t%1
4842 #"
4843 [(set_attr "type" "fmov,multi")
4844 (set_attr "mode" "XF")
4845 (set_attr "fp_int_src" "true")])
4846
4847 (define_insn "floatsixf2"
4848 [(set (match_operand:XF 0 "register_operand" "=f,f")
4849 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4850 "TARGET_80387"
4851 "@
4852 fild%z1\t%1
4853 #"
4854 [(set_attr "type" "fmov,multi")
4855 (set_attr "mode" "XF")
4856 (set_attr "fp_int_src" "true")])
4857
4858 (define_insn "floatdixf2"
4859 [(set (match_operand:XF 0 "register_operand" "=f,f")
4860 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4861 "TARGET_80387"
4862 "@
4863 fild%z1\t%1
4864 #"
4865 [(set_attr "type" "fmov,multi")
4866 (set_attr "mode" "XF")
4867 (set_attr "fp_int_src" "true")])
4868
4869 ;; %%% Kill these when reload knows how to do it.
4870 (define_split
4871 [(set (match_operand 0 "fp_register_operand" "")
4872 (float (match_operand 1 "register_operand" "")))]
4873 "reload_completed
4874 && TARGET_80387
4875 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4876 [(const_int 0)]
4877 {
4878 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4879 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4880 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4881 ix86_free_from_memory (GET_MODE (operands[1]));
4882 DONE;
4883 })
4884
4885 (define_expand "floatunssisf2"
4886 [(use (match_operand:SF 0 "register_operand" ""))
4887 (use (match_operand:SI 1 "register_operand" ""))]
4888 "!TARGET_64BIT && TARGET_SSE_MATH"
4889 "x86_emit_floatuns (operands); DONE;")
4890
4891 (define_expand "floatunsdisf2"
4892 [(use (match_operand:SF 0 "register_operand" ""))
4893 (use (match_operand:DI 1 "register_operand" ""))]
4894 "TARGET_64BIT && TARGET_SSE_MATH"
4895 "x86_emit_floatuns (operands); DONE;")
4896
4897 (define_expand "floatunsdidf2"
4898 [(use (match_operand:DF 0 "register_operand" ""))
4899 (use (match_operand:DI 1 "register_operand" ""))]
4900 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4901 "x86_emit_floatuns (operands); DONE;")
4902 \f
4903 ;; SSE extract/set expanders
4904
4905 \f
4906 ;; Add instructions
4907
4908 ;; %%% splits for addsidi3
4909 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4910 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4911 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4912
4913 (define_expand "adddi3"
4914 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4915 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4916 (match_operand:DI 2 "x86_64_general_operand" "")))
4917 (clobber (reg:CC FLAGS_REG))]
4918 ""
4919 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4920
4921 (define_insn "*adddi3_1"
4922 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4923 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4924 (match_operand:DI 2 "general_operand" "roiF,riF")))
4925 (clobber (reg:CC FLAGS_REG))]
4926 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4927 "#")
4928
4929 (define_split
4930 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4931 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4932 (match_operand:DI 2 "general_operand" "")))
4933 (clobber (reg:CC FLAGS_REG))]
4934 "!TARGET_64BIT && reload_completed"
4935 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4936 UNSPEC_ADD_CARRY))
4937 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4938 (parallel [(set (match_dup 3)
4939 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4940 (match_dup 4))
4941 (match_dup 5)))
4942 (clobber (reg:CC FLAGS_REG))])]
4943 "split_di (operands+0, 1, operands+0, operands+3);
4944 split_di (operands+1, 1, operands+1, operands+4);
4945 split_di (operands+2, 1, operands+2, operands+5);")
4946
4947 (define_insn "adddi3_carry_rex64"
4948 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4949 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4950 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4951 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4952 (clobber (reg:CC FLAGS_REG))]
4953 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4954 "adc{q}\t{%2, %0|%0, %2}"
4955 [(set_attr "type" "alu")
4956 (set_attr "pent_pair" "pu")
4957 (set_attr "mode" "DI")])
4958
4959 (define_insn "*adddi3_cc_rex64"
4960 [(set (reg:CC FLAGS_REG)
4961 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4962 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4963 UNSPEC_ADD_CARRY))
4964 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4965 (plus:DI (match_dup 1) (match_dup 2)))]
4966 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4967 "add{q}\t{%2, %0|%0, %2}"
4968 [(set_attr "type" "alu")
4969 (set_attr "mode" "DI")])
4970
4971 (define_insn "addqi3_carry"
4972 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4973 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4974 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4975 (match_operand:QI 2 "general_operand" "qi,qm")))
4976 (clobber (reg:CC FLAGS_REG))]
4977 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4978 "adc{b}\t{%2, %0|%0, %2}"
4979 [(set_attr "type" "alu")
4980 (set_attr "pent_pair" "pu")
4981 (set_attr "mode" "QI")])
4982
4983 (define_insn "addhi3_carry"
4984 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4985 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4986 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4987 (match_operand:HI 2 "general_operand" "ri,rm")))
4988 (clobber (reg:CC FLAGS_REG))]
4989 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4990 "adc{w}\t{%2, %0|%0, %2}"
4991 [(set_attr "type" "alu")
4992 (set_attr "pent_pair" "pu")
4993 (set_attr "mode" "HI")])
4994
4995 (define_insn "addsi3_carry"
4996 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4997 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4998 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4999 (match_operand:SI 2 "general_operand" "ri,rm")))
5000 (clobber (reg:CC FLAGS_REG))]
5001 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5002 "adc{l}\t{%2, %0|%0, %2}"
5003 [(set_attr "type" "alu")
5004 (set_attr "pent_pair" "pu")
5005 (set_attr "mode" "SI")])
5006
5007 (define_insn "*addsi3_carry_zext"
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5009 (zero_extend:DI
5010 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5011 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5012 (match_operand:SI 2 "general_operand" "rim"))))
5013 (clobber (reg:CC FLAGS_REG))]
5014 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5015 "adc{l}\t{%2, %k0|%k0, %2}"
5016 [(set_attr "type" "alu")
5017 (set_attr "pent_pair" "pu")
5018 (set_attr "mode" "SI")])
5019
5020 (define_insn "*addsi3_cc"
5021 [(set (reg:CC FLAGS_REG)
5022 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5023 (match_operand:SI 2 "general_operand" "ri,rm")]
5024 UNSPEC_ADD_CARRY))
5025 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5026 (plus:SI (match_dup 1) (match_dup 2)))]
5027 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5028 "add{l}\t{%2, %0|%0, %2}"
5029 [(set_attr "type" "alu")
5030 (set_attr "mode" "SI")])
5031
5032 (define_insn "addqi3_cc"
5033 [(set (reg:CC FLAGS_REG)
5034 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5035 (match_operand:QI 2 "general_operand" "qi,qm")]
5036 UNSPEC_ADD_CARRY))
5037 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5038 (plus:QI (match_dup 1) (match_dup 2)))]
5039 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5040 "add{b}\t{%2, %0|%0, %2}"
5041 [(set_attr "type" "alu")
5042 (set_attr "mode" "QI")])
5043
5044 (define_expand "addsi3"
5045 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5046 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5047 (match_operand:SI 2 "general_operand" "")))
5048 (clobber (reg:CC FLAGS_REG))])]
5049 ""
5050 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5051
5052 (define_insn "*lea_1"
5053 [(set (match_operand:SI 0 "register_operand" "=r")
5054 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5055 "!TARGET_64BIT"
5056 "lea{l}\t{%a1, %0|%0, %a1}"
5057 [(set_attr "type" "lea")
5058 (set_attr "mode" "SI")])
5059
5060 (define_insn "*lea_1_rex64"
5061 [(set (match_operand:SI 0 "register_operand" "=r")
5062 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5063 "TARGET_64BIT"
5064 "lea{l}\t{%a1, %0|%0, %a1}"
5065 [(set_attr "type" "lea")
5066 (set_attr "mode" "SI")])
5067
5068 (define_insn "*lea_1_zext"
5069 [(set (match_operand:DI 0 "register_operand" "=r")
5070 (zero_extend:DI
5071 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5072 "TARGET_64BIT"
5073 "lea{l}\t{%a1, %k0|%k0, %a1}"
5074 [(set_attr "type" "lea")
5075 (set_attr "mode" "SI")])
5076
5077 (define_insn "*lea_2_rex64"
5078 [(set (match_operand:DI 0 "register_operand" "=r")
5079 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5080 "TARGET_64BIT"
5081 "lea{q}\t{%a1, %0|%0, %a1}"
5082 [(set_attr "type" "lea")
5083 (set_attr "mode" "DI")])
5084
5085 ;; The lea patterns for non-Pmodes needs to be matched by several
5086 ;; insns converted to real lea by splitters.
5087
5088 (define_insn_and_split "*lea_general_1"
5089 [(set (match_operand 0 "register_operand" "=r")
5090 (plus (plus (match_operand 1 "index_register_operand" "l")
5091 (match_operand 2 "register_operand" "r"))
5092 (match_operand 3 "immediate_operand" "i")))]
5093 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5094 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5095 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5096 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5097 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5098 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5099 || GET_MODE (operands[3]) == VOIDmode)"
5100 "#"
5101 "&& reload_completed"
5102 [(const_int 0)]
5103 {
5104 rtx pat;
5105 operands[0] = gen_lowpart (SImode, operands[0]);
5106 operands[1] = gen_lowpart (Pmode, operands[1]);
5107 operands[2] = gen_lowpart (Pmode, operands[2]);
5108 operands[3] = gen_lowpart (Pmode, operands[3]);
5109 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5110 operands[3]);
5111 if (Pmode != SImode)
5112 pat = gen_rtx_SUBREG (SImode, pat, 0);
5113 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5114 DONE;
5115 }
5116 [(set_attr "type" "lea")
5117 (set_attr "mode" "SI")])
5118
5119 (define_insn_and_split "*lea_general_1_zext"
5120 [(set (match_operand:DI 0 "register_operand" "=r")
5121 (zero_extend:DI
5122 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5123 (match_operand:SI 2 "register_operand" "r"))
5124 (match_operand:SI 3 "immediate_operand" "i"))))]
5125 "TARGET_64BIT"
5126 "#"
5127 "&& reload_completed"
5128 [(set (match_dup 0)
5129 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5130 (match_dup 2))
5131 (match_dup 3)) 0)))]
5132 {
5133 operands[1] = gen_lowpart (Pmode, operands[1]);
5134 operands[2] = gen_lowpart (Pmode, operands[2]);
5135 operands[3] = gen_lowpart (Pmode, operands[3]);
5136 }
5137 [(set_attr "type" "lea")
5138 (set_attr "mode" "SI")])
5139
5140 (define_insn_and_split "*lea_general_2"
5141 [(set (match_operand 0 "register_operand" "=r")
5142 (plus (mult (match_operand 1 "index_register_operand" "l")
5143 (match_operand 2 "const248_operand" "i"))
5144 (match_operand 3 "nonmemory_operand" "ri")))]
5145 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5146 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5147 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5148 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5149 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5150 || GET_MODE (operands[3]) == VOIDmode)"
5151 "#"
5152 "&& reload_completed"
5153 [(const_int 0)]
5154 {
5155 rtx pat;
5156 operands[0] = gen_lowpart (SImode, operands[0]);
5157 operands[1] = gen_lowpart (Pmode, operands[1]);
5158 operands[3] = gen_lowpart (Pmode, operands[3]);
5159 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5160 operands[3]);
5161 if (Pmode != SImode)
5162 pat = gen_rtx_SUBREG (SImode, pat, 0);
5163 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5164 DONE;
5165 }
5166 [(set_attr "type" "lea")
5167 (set_attr "mode" "SI")])
5168
5169 (define_insn_and_split "*lea_general_2_zext"
5170 [(set (match_operand:DI 0 "register_operand" "=r")
5171 (zero_extend:DI
5172 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5173 (match_operand:SI 2 "const248_operand" "n"))
5174 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5175 "TARGET_64BIT"
5176 "#"
5177 "&& reload_completed"
5178 [(set (match_dup 0)
5179 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5180 (match_dup 2))
5181 (match_dup 3)) 0)))]
5182 {
5183 operands[1] = gen_lowpart (Pmode, operands[1]);
5184 operands[3] = gen_lowpart (Pmode, operands[3]);
5185 }
5186 [(set_attr "type" "lea")
5187 (set_attr "mode" "SI")])
5188
5189 (define_insn_and_split "*lea_general_3"
5190 [(set (match_operand 0 "register_operand" "=r")
5191 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5192 (match_operand 2 "const248_operand" "i"))
5193 (match_operand 3 "register_operand" "r"))
5194 (match_operand 4 "immediate_operand" "i")))]
5195 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5196 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5197 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5198 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5199 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5200 "#"
5201 "&& reload_completed"
5202 [(const_int 0)]
5203 {
5204 rtx pat;
5205 operands[0] = gen_lowpart (SImode, operands[0]);
5206 operands[1] = gen_lowpart (Pmode, operands[1]);
5207 operands[3] = gen_lowpart (Pmode, operands[3]);
5208 operands[4] = gen_lowpart (Pmode, operands[4]);
5209 pat = gen_rtx_PLUS (Pmode,
5210 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5211 operands[2]),
5212 operands[3]),
5213 operands[4]);
5214 if (Pmode != SImode)
5215 pat = gen_rtx_SUBREG (SImode, pat, 0);
5216 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5217 DONE;
5218 }
5219 [(set_attr "type" "lea")
5220 (set_attr "mode" "SI")])
5221
5222 (define_insn_and_split "*lea_general_3_zext"
5223 [(set (match_operand:DI 0 "register_operand" "=r")
5224 (zero_extend:DI
5225 (plus:SI (plus:SI (mult:SI
5226 (match_operand:SI 1 "index_register_operand" "l")
5227 (match_operand:SI 2 "const248_operand" "n"))
5228 (match_operand:SI 3 "register_operand" "r"))
5229 (match_operand:SI 4 "immediate_operand" "i"))))]
5230 "TARGET_64BIT"
5231 "#"
5232 "&& reload_completed"
5233 [(set (match_dup 0)
5234 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5235 (match_dup 2))
5236 (match_dup 3))
5237 (match_dup 4)) 0)))]
5238 {
5239 operands[1] = gen_lowpart (Pmode, operands[1]);
5240 operands[3] = gen_lowpart (Pmode, operands[3]);
5241 operands[4] = gen_lowpart (Pmode, operands[4]);
5242 }
5243 [(set_attr "type" "lea")
5244 (set_attr "mode" "SI")])
5245
5246 (define_insn "*adddi_1_rex64"
5247 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5248 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5249 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5250 (clobber (reg:CC FLAGS_REG))]
5251 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5252 {
5253 switch (get_attr_type (insn))
5254 {
5255 case TYPE_LEA:
5256 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5257 return "lea{q}\t{%a2, %0|%0, %a2}";
5258
5259 case TYPE_INCDEC:
5260 if (! rtx_equal_p (operands[0], operands[1]))
5261 abort ();
5262 if (operands[2] == const1_rtx)
5263 return "inc{q}\t%0";
5264 else if (operands[2] == constm1_rtx)
5265 return "dec{q}\t%0";
5266 else
5267 abort ();
5268
5269 default:
5270 if (! rtx_equal_p (operands[0], operands[1]))
5271 abort ();
5272
5273 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5274 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5275 if (GET_CODE (operands[2]) == CONST_INT
5276 /* Avoid overflows. */
5277 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5278 && (INTVAL (operands[2]) == 128
5279 || (INTVAL (operands[2]) < 0
5280 && INTVAL (operands[2]) != -128)))
5281 {
5282 operands[2] = GEN_INT (-INTVAL (operands[2]));
5283 return "sub{q}\t{%2, %0|%0, %2}";
5284 }
5285 return "add{q}\t{%2, %0|%0, %2}";
5286 }
5287 }
5288 [(set (attr "type")
5289 (cond [(eq_attr "alternative" "2")
5290 (const_string "lea")
5291 ; Current assemblers are broken and do not allow @GOTOFF in
5292 ; ought but a memory context.
5293 (match_operand:DI 2 "pic_symbolic_operand" "")
5294 (const_string "lea")
5295 (match_operand:DI 2 "incdec_operand" "")
5296 (const_string "incdec")
5297 ]
5298 (const_string "alu")))
5299 (set_attr "mode" "DI")])
5300
5301 ;; Convert lea to the lea pattern to avoid flags dependency.
5302 (define_split
5303 [(set (match_operand:DI 0 "register_operand" "")
5304 (plus:DI (match_operand:DI 1 "register_operand" "")
5305 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5306 (clobber (reg:CC FLAGS_REG))]
5307 "TARGET_64BIT && reload_completed
5308 && true_regnum (operands[0]) != true_regnum (operands[1])"
5309 [(set (match_dup 0)
5310 (plus:DI (match_dup 1)
5311 (match_dup 2)))]
5312 "")
5313
5314 (define_insn "*adddi_2_rex64"
5315 [(set (reg FLAGS_REG)
5316 (compare
5317 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5318 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5319 (const_int 0)))
5320 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5321 (plus:DI (match_dup 1) (match_dup 2)))]
5322 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5323 && ix86_binary_operator_ok (PLUS, DImode, operands)
5324 /* Current assemblers are broken and do not allow @GOTOFF in
5325 ought but a memory context. */
5326 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5327 {
5328 switch (get_attr_type (insn))
5329 {
5330 case TYPE_INCDEC:
5331 if (! rtx_equal_p (operands[0], operands[1]))
5332 abort ();
5333 if (operands[2] == const1_rtx)
5334 return "inc{q}\t%0";
5335 else if (operands[2] == constm1_rtx)
5336 return "dec{q}\t%0";
5337 else
5338 abort ();
5339
5340 default:
5341 if (! rtx_equal_p (operands[0], operands[1]))
5342 abort ();
5343 /* ???? We ought to handle there the 32bit case too
5344 - do we need new constraint? */
5345 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5346 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5347 if (GET_CODE (operands[2]) == CONST_INT
5348 /* Avoid overflows. */
5349 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5350 && (INTVAL (operands[2]) == 128
5351 || (INTVAL (operands[2]) < 0
5352 && INTVAL (operands[2]) != -128)))
5353 {
5354 operands[2] = GEN_INT (-INTVAL (operands[2]));
5355 return "sub{q}\t{%2, %0|%0, %2}";
5356 }
5357 return "add{q}\t{%2, %0|%0, %2}";
5358 }
5359 }
5360 [(set (attr "type")
5361 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5362 (const_string "incdec")
5363 (const_string "alu")))
5364 (set_attr "mode" "DI")])
5365
5366 (define_insn "*adddi_3_rex64"
5367 [(set (reg FLAGS_REG)
5368 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5369 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5370 (clobber (match_scratch:DI 0 "=r"))]
5371 "TARGET_64BIT
5372 && ix86_match_ccmode (insn, CCZmode)
5373 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5374 /* Current assemblers are broken and do not allow @GOTOFF in
5375 ought but a memory context. */
5376 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5377 {
5378 switch (get_attr_type (insn))
5379 {
5380 case TYPE_INCDEC:
5381 if (! rtx_equal_p (operands[0], operands[1]))
5382 abort ();
5383 if (operands[2] == const1_rtx)
5384 return "inc{q}\t%0";
5385 else if (operands[2] == constm1_rtx)
5386 return "dec{q}\t%0";
5387 else
5388 abort ();
5389
5390 default:
5391 if (! rtx_equal_p (operands[0], operands[1]))
5392 abort ();
5393 /* ???? We ought to handle there the 32bit case too
5394 - do we need new constraint? */
5395 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5396 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5397 if (GET_CODE (operands[2]) == CONST_INT
5398 /* Avoid overflows. */
5399 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5400 && (INTVAL (operands[2]) == 128
5401 || (INTVAL (operands[2]) < 0
5402 && INTVAL (operands[2]) != -128)))
5403 {
5404 operands[2] = GEN_INT (-INTVAL (operands[2]));
5405 return "sub{q}\t{%2, %0|%0, %2}";
5406 }
5407 return "add{q}\t{%2, %0|%0, %2}";
5408 }
5409 }
5410 [(set (attr "type")
5411 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5412 (const_string "incdec")
5413 (const_string "alu")))
5414 (set_attr "mode" "DI")])
5415
5416 ; For comparisons against 1, -1 and 128, we may generate better code
5417 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5418 ; is matched then. We can't accept general immediate, because for
5419 ; case of overflows, the result is messed up.
5420 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5421 ; when negated.
5422 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5423 ; only for comparisons not depending on it.
5424 (define_insn "*adddi_4_rex64"
5425 [(set (reg FLAGS_REG)
5426 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5427 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5428 (clobber (match_scratch:DI 0 "=rm"))]
5429 "TARGET_64BIT
5430 && ix86_match_ccmode (insn, CCGCmode)"
5431 {
5432 switch (get_attr_type (insn))
5433 {
5434 case TYPE_INCDEC:
5435 if (operands[2] == constm1_rtx)
5436 return "inc{q}\t%0";
5437 else if (operands[2] == const1_rtx)
5438 return "dec{q}\t%0";
5439 else
5440 abort();
5441
5442 default:
5443 if (! rtx_equal_p (operands[0], operands[1]))
5444 abort ();
5445 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5446 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5447 if ((INTVAL (operands[2]) == -128
5448 || (INTVAL (operands[2]) > 0
5449 && INTVAL (operands[2]) != 128))
5450 /* Avoid overflows. */
5451 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5452 return "sub{q}\t{%2, %0|%0, %2}";
5453 operands[2] = GEN_INT (-INTVAL (operands[2]));
5454 return "add{q}\t{%2, %0|%0, %2}";
5455 }
5456 }
5457 [(set (attr "type")
5458 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5459 (const_string "incdec")
5460 (const_string "alu")))
5461 (set_attr "mode" "DI")])
5462
5463 (define_insn "*adddi_5_rex64"
5464 [(set (reg FLAGS_REG)
5465 (compare
5466 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5467 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5468 (const_int 0)))
5469 (clobber (match_scratch:DI 0 "=r"))]
5470 "TARGET_64BIT
5471 && ix86_match_ccmode (insn, CCGOCmode)
5472 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5473 /* Current assemblers are broken and do not allow @GOTOFF in
5474 ought but a memory context. */
5475 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5476 {
5477 switch (get_attr_type (insn))
5478 {
5479 case TYPE_INCDEC:
5480 if (! rtx_equal_p (operands[0], operands[1]))
5481 abort ();
5482 if (operands[2] == const1_rtx)
5483 return "inc{q}\t%0";
5484 else if (operands[2] == constm1_rtx)
5485 return "dec{q}\t%0";
5486 else
5487 abort();
5488
5489 default:
5490 if (! rtx_equal_p (operands[0], operands[1]))
5491 abort ();
5492 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5493 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5494 if (GET_CODE (operands[2]) == CONST_INT
5495 /* Avoid overflows. */
5496 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5497 && (INTVAL (operands[2]) == 128
5498 || (INTVAL (operands[2]) < 0
5499 && INTVAL (operands[2]) != -128)))
5500 {
5501 operands[2] = GEN_INT (-INTVAL (operands[2]));
5502 return "sub{q}\t{%2, %0|%0, %2}";
5503 }
5504 return "add{q}\t{%2, %0|%0, %2}";
5505 }
5506 }
5507 [(set (attr "type")
5508 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5509 (const_string "incdec")
5510 (const_string "alu")))
5511 (set_attr "mode" "DI")])
5512
5513
5514 (define_insn "*addsi_1"
5515 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5516 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5517 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5518 (clobber (reg:CC FLAGS_REG))]
5519 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5520 {
5521 switch (get_attr_type (insn))
5522 {
5523 case TYPE_LEA:
5524 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5525 return "lea{l}\t{%a2, %0|%0, %a2}";
5526
5527 case TYPE_INCDEC:
5528 if (! rtx_equal_p (operands[0], operands[1]))
5529 abort ();
5530 if (operands[2] == const1_rtx)
5531 return "inc{l}\t%0";
5532 else if (operands[2] == constm1_rtx)
5533 return "dec{l}\t%0";
5534 else
5535 abort();
5536
5537 default:
5538 if (! rtx_equal_p (operands[0], operands[1]))
5539 abort ();
5540
5541 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5542 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5543 if (GET_CODE (operands[2]) == CONST_INT
5544 && (INTVAL (operands[2]) == 128
5545 || (INTVAL (operands[2]) < 0
5546 && INTVAL (operands[2]) != -128)))
5547 {
5548 operands[2] = GEN_INT (-INTVAL (operands[2]));
5549 return "sub{l}\t{%2, %0|%0, %2}";
5550 }
5551 return "add{l}\t{%2, %0|%0, %2}";
5552 }
5553 }
5554 [(set (attr "type")
5555 (cond [(eq_attr "alternative" "2")
5556 (const_string "lea")
5557 ; Current assemblers are broken and do not allow @GOTOFF in
5558 ; ought but a memory context.
5559 (match_operand:SI 2 "pic_symbolic_operand" "")
5560 (const_string "lea")
5561 (match_operand:SI 2 "incdec_operand" "")
5562 (const_string "incdec")
5563 ]
5564 (const_string "alu")))
5565 (set_attr "mode" "SI")])
5566
5567 ;; Convert lea to the lea pattern to avoid flags dependency.
5568 (define_split
5569 [(set (match_operand 0 "register_operand" "")
5570 (plus (match_operand 1 "register_operand" "")
5571 (match_operand 2 "nonmemory_operand" "")))
5572 (clobber (reg:CC FLAGS_REG))]
5573 "reload_completed
5574 && true_regnum (operands[0]) != true_regnum (operands[1])"
5575 [(const_int 0)]
5576 {
5577 rtx pat;
5578 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5579 may confuse gen_lowpart. */
5580 if (GET_MODE (operands[0]) != Pmode)
5581 {
5582 operands[1] = gen_lowpart (Pmode, operands[1]);
5583 operands[2] = gen_lowpart (Pmode, operands[2]);
5584 }
5585 operands[0] = gen_lowpart (SImode, operands[0]);
5586 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5587 if (Pmode != SImode)
5588 pat = gen_rtx_SUBREG (SImode, pat, 0);
5589 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5590 DONE;
5591 })
5592
5593 ;; It may seem that nonimmediate operand is proper one for operand 1.
5594 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5595 ;; we take care in ix86_binary_operator_ok to not allow two memory
5596 ;; operands so proper swapping will be done in reload. This allow
5597 ;; patterns constructed from addsi_1 to match.
5598 (define_insn "addsi_1_zext"
5599 [(set (match_operand:DI 0 "register_operand" "=r,r")
5600 (zero_extend:DI
5601 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5602 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5603 (clobber (reg:CC FLAGS_REG))]
5604 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5605 {
5606 switch (get_attr_type (insn))
5607 {
5608 case TYPE_LEA:
5609 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5610 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5611
5612 case TYPE_INCDEC:
5613 if (operands[2] == const1_rtx)
5614 return "inc{l}\t%k0";
5615 else if (operands[2] == constm1_rtx)
5616 return "dec{l}\t%k0";
5617 else
5618 abort();
5619
5620 default:
5621 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5622 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5623 if (GET_CODE (operands[2]) == CONST_INT
5624 && (INTVAL (operands[2]) == 128
5625 || (INTVAL (operands[2]) < 0
5626 && INTVAL (operands[2]) != -128)))
5627 {
5628 operands[2] = GEN_INT (-INTVAL (operands[2]));
5629 return "sub{l}\t{%2, %k0|%k0, %2}";
5630 }
5631 return "add{l}\t{%2, %k0|%k0, %2}";
5632 }
5633 }
5634 [(set (attr "type")
5635 (cond [(eq_attr "alternative" "1")
5636 (const_string "lea")
5637 ; Current assemblers are broken and do not allow @GOTOFF in
5638 ; ought but a memory context.
5639 (match_operand:SI 2 "pic_symbolic_operand" "")
5640 (const_string "lea")
5641 (match_operand:SI 2 "incdec_operand" "")
5642 (const_string "incdec")
5643 ]
5644 (const_string "alu")))
5645 (set_attr "mode" "SI")])
5646
5647 ;; Convert lea to the lea pattern to avoid flags dependency.
5648 (define_split
5649 [(set (match_operand:DI 0 "register_operand" "")
5650 (zero_extend:DI
5651 (plus:SI (match_operand:SI 1 "register_operand" "")
5652 (match_operand:SI 2 "nonmemory_operand" ""))))
5653 (clobber (reg:CC FLAGS_REG))]
5654 "TARGET_64BIT && reload_completed
5655 && true_regnum (operands[0]) != true_regnum (operands[1])"
5656 [(set (match_dup 0)
5657 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5658 {
5659 operands[1] = gen_lowpart (Pmode, operands[1]);
5660 operands[2] = gen_lowpart (Pmode, operands[2]);
5661 })
5662
5663 (define_insn "*addsi_2"
5664 [(set (reg FLAGS_REG)
5665 (compare
5666 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5667 (match_operand:SI 2 "general_operand" "rmni,rni"))
5668 (const_int 0)))
5669 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5670 (plus:SI (match_dup 1) (match_dup 2)))]
5671 "ix86_match_ccmode (insn, CCGOCmode)
5672 && ix86_binary_operator_ok (PLUS, SImode, operands)
5673 /* Current assemblers are broken and do not allow @GOTOFF in
5674 ought but a memory context. */
5675 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5676 {
5677 switch (get_attr_type (insn))
5678 {
5679 case TYPE_INCDEC:
5680 if (! rtx_equal_p (operands[0], operands[1]))
5681 abort ();
5682 if (operands[2] == const1_rtx)
5683 return "inc{l}\t%0";
5684 else if (operands[2] == constm1_rtx)
5685 return "dec{l}\t%0";
5686 else
5687 abort();
5688
5689 default:
5690 if (! rtx_equal_p (operands[0], operands[1]))
5691 abort ();
5692 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5693 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5694 if (GET_CODE (operands[2]) == CONST_INT
5695 && (INTVAL (operands[2]) == 128
5696 || (INTVAL (operands[2]) < 0
5697 && INTVAL (operands[2]) != -128)))
5698 {
5699 operands[2] = GEN_INT (-INTVAL (operands[2]));
5700 return "sub{l}\t{%2, %0|%0, %2}";
5701 }
5702 return "add{l}\t{%2, %0|%0, %2}";
5703 }
5704 }
5705 [(set (attr "type")
5706 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5707 (const_string "incdec")
5708 (const_string "alu")))
5709 (set_attr "mode" "SI")])
5710
5711 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5712 (define_insn "*addsi_2_zext"
5713 [(set (reg FLAGS_REG)
5714 (compare
5715 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5716 (match_operand:SI 2 "general_operand" "rmni"))
5717 (const_int 0)))
5718 (set (match_operand:DI 0 "register_operand" "=r")
5719 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5720 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5721 && ix86_binary_operator_ok (PLUS, SImode, operands)
5722 /* Current assemblers are broken and do not allow @GOTOFF in
5723 ought but a memory context. */
5724 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5725 {
5726 switch (get_attr_type (insn))
5727 {
5728 case TYPE_INCDEC:
5729 if (operands[2] == const1_rtx)
5730 return "inc{l}\t%k0";
5731 else if (operands[2] == constm1_rtx)
5732 return "dec{l}\t%k0";
5733 else
5734 abort();
5735
5736 default:
5737 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5738 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5739 if (GET_CODE (operands[2]) == CONST_INT
5740 && (INTVAL (operands[2]) == 128
5741 || (INTVAL (operands[2]) < 0
5742 && INTVAL (operands[2]) != -128)))
5743 {
5744 operands[2] = GEN_INT (-INTVAL (operands[2]));
5745 return "sub{l}\t{%2, %k0|%k0, %2}";
5746 }
5747 return "add{l}\t{%2, %k0|%k0, %2}";
5748 }
5749 }
5750 [(set (attr "type")
5751 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5752 (const_string "incdec")
5753 (const_string "alu")))
5754 (set_attr "mode" "SI")])
5755
5756 (define_insn "*addsi_3"
5757 [(set (reg FLAGS_REG)
5758 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5759 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5760 (clobber (match_scratch:SI 0 "=r"))]
5761 "ix86_match_ccmode (insn, CCZmode)
5762 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5763 /* Current assemblers are broken and do not allow @GOTOFF in
5764 ought but a memory context. */
5765 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5766 {
5767 switch (get_attr_type (insn))
5768 {
5769 case TYPE_INCDEC:
5770 if (! rtx_equal_p (operands[0], operands[1]))
5771 abort ();
5772 if (operands[2] == const1_rtx)
5773 return "inc{l}\t%0";
5774 else if (operands[2] == constm1_rtx)
5775 return "dec{l}\t%0";
5776 else
5777 abort();
5778
5779 default:
5780 if (! rtx_equal_p (operands[0], operands[1]))
5781 abort ();
5782 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5783 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5784 if (GET_CODE (operands[2]) == CONST_INT
5785 && (INTVAL (operands[2]) == 128
5786 || (INTVAL (operands[2]) < 0
5787 && INTVAL (operands[2]) != -128)))
5788 {
5789 operands[2] = GEN_INT (-INTVAL (operands[2]));
5790 return "sub{l}\t{%2, %0|%0, %2}";
5791 }
5792 return "add{l}\t{%2, %0|%0, %2}";
5793 }
5794 }
5795 [(set (attr "type")
5796 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5797 (const_string "incdec")
5798 (const_string "alu")))
5799 (set_attr "mode" "SI")])
5800
5801 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5802 (define_insn "*addsi_3_zext"
5803 [(set (reg FLAGS_REG)
5804 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5805 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5806 (set (match_operand:DI 0 "register_operand" "=r")
5807 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5808 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5809 && ix86_binary_operator_ok (PLUS, SImode, operands)
5810 /* Current assemblers are broken and do not allow @GOTOFF in
5811 ought but a memory context. */
5812 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5813 {
5814 switch (get_attr_type (insn))
5815 {
5816 case TYPE_INCDEC:
5817 if (operands[2] == const1_rtx)
5818 return "inc{l}\t%k0";
5819 else if (operands[2] == constm1_rtx)
5820 return "dec{l}\t%k0";
5821 else
5822 abort();
5823
5824 default:
5825 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5826 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5827 if (GET_CODE (operands[2]) == CONST_INT
5828 && (INTVAL (operands[2]) == 128
5829 || (INTVAL (operands[2]) < 0
5830 && INTVAL (operands[2]) != -128)))
5831 {
5832 operands[2] = GEN_INT (-INTVAL (operands[2]));
5833 return "sub{l}\t{%2, %k0|%k0, %2}";
5834 }
5835 return "add{l}\t{%2, %k0|%k0, %2}";
5836 }
5837 }
5838 [(set (attr "type")
5839 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5840 (const_string "incdec")
5841 (const_string "alu")))
5842 (set_attr "mode" "SI")])
5843
5844 ; For comparisons against 1, -1 and 128, we may generate better code
5845 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5846 ; is matched then. We can't accept general immediate, because for
5847 ; case of overflows, the result is messed up.
5848 ; This pattern also don't hold of 0x80000000, since the value overflows
5849 ; when negated.
5850 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5851 ; only for comparisons not depending on it.
5852 (define_insn "*addsi_4"
5853 [(set (reg FLAGS_REG)
5854 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5855 (match_operand:SI 2 "const_int_operand" "n")))
5856 (clobber (match_scratch:SI 0 "=rm"))]
5857 "ix86_match_ccmode (insn, CCGCmode)
5858 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5859 {
5860 switch (get_attr_type (insn))
5861 {
5862 case TYPE_INCDEC:
5863 if (operands[2] == constm1_rtx)
5864 return "inc{l}\t%0";
5865 else if (operands[2] == const1_rtx)
5866 return "dec{l}\t%0";
5867 else
5868 abort();
5869
5870 default:
5871 if (! rtx_equal_p (operands[0], operands[1]))
5872 abort ();
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 ((INTVAL (operands[2]) == -128
5876 || (INTVAL (operands[2]) > 0
5877 && INTVAL (operands[2]) != 128)))
5878 return "sub{l}\t{%2, %0|%0, %2}";
5879 operands[2] = GEN_INT (-INTVAL (operands[2]));
5880 return "add{l}\t{%2, %0|%0, %2}";
5881 }
5882 }
5883 [(set (attr "type")
5884 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5885 (const_string "incdec")
5886 (const_string "alu")))
5887 (set_attr "mode" "SI")])
5888
5889 (define_insn "*addsi_5"
5890 [(set (reg FLAGS_REG)
5891 (compare
5892 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5893 (match_operand:SI 2 "general_operand" "rmni"))
5894 (const_int 0)))
5895 (clobber (match_scratch:SI 0 "=r"))]
5896 "ix86_match_ccmode (insn, CCGOCmode)
5897 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5898 /* Current assemblers are broken and do not allow @GOTOFF in
5899 ought but a memory context. */
5900 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5901 {
5902 switch (get_attr_type (insn))
5903 {
5904 case TYPE_INCDEC:
5905 if (! rtx_equal_p (operands[0], operands[1]))
5906 abort ();
5907 if (operands[2] == const1_rtx)
5908 return "inc{l}\t%0";
5909 else if (operands[2] == constm1_rtx)
5910 return "dec{l}\t%0";
5911 else
5912 abort();
5913
5914 default:
5915 if (! rtx_equal_p (operands[0], operands[1]))
5916 abort ();
5917 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5918 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5919 if (GET_CODE (operands[2]) == CONST_INT
5920 && (INTVAL (operands[2]) == 128
5921 || (INTVAL (operands[2]) < 0
5922 && INTVAL (operands[2]) != -128)))
5923 {
5924 operands[2] = GEN_INT (-INTVAL (operands[2]));
5925 return "sub{l}\t{%2, %0|%0, %2}";
5926 }
5927 return "add{l}\t{%2, %0|%0, %2}";
5928 }
5929 }
5930 [(set (attr "type")
5931 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5932 (const_string "incdec")
5933 (const_string "alu")))
5934 (set_attr "mode" "SI")])
5935
5936 (define_expand "addhi3"
5937 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5938 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5939 (match_operand:HI 2 "general_operand" "")))
5940 (clobber (reg:CC FLAGS_REG))])]
5941 "TARGET_HIMODE_MATH"
5942 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5943
5944 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5945 ;; type optimizations enabled by define-splits. This is not important
5946 ;; for PII, and in fact harmful because of partial register stalls.
5947
5948 (define_insn "*addhi_1_lea"
5949 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5950 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5951 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5952 (clobber (reg:CC FLAGS_REG))]
5953 "!TARGET_PARTIAL_REG_STALL
5954 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5955 {
5956 switch (get_attr_type (insn))
5957 {
5958 case TYPE_LEA:
5959 return "#";
5960 case TYPE_INCDEC:
5961 if (operands[2] == const1_rtx)
5962 return "inc{w}\t%0";
5963 else if (operands[2] == constm1_rtx)
5964 return "dec{w}\t%0";
5965 abort();
5966
5967 default:
5968 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5969 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5970 if (GET_CODE (operands[2]) == CONST_INT
5971 && (INTVAL (operands[2]) == 128
5972 || (INTVAL (operands[2]) < 0
5973 && INTVAL (operands[2]) != -128)))
5974 {
5975 operands[2] = GEN_INT (-INTVAL (operands[2]));
5976 return "sub{w}\t{%2, %0|%0, %2}";
5977 }
5978 return "add{w}\t{%2, %0|%0, %2}";
5979 }
5980 }
5981 [(set (attr "type")
5982 (if_then_else (eq_attr "alternative" "2")
5983 (const_string "lea")
5984 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5985 (const_string "incdec")
5986 (const_string "alu"))))
5987 (set_attr "mode" "HI,HI,SI")])
5988
5989 (define_insn "*addhi_1"
5990 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5991 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5992 (match_operand:HI 2 "general_operand" "ri,rm")))
5993 (clobber (reg:CC FLAGS_REG))]
5994 "TARGET_PARTIAL_REG_STALL
5995 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5996 {
5997 switch (get_attr_type (insn))
5998 {
5999 case TYPE_INCDEC:
6000 if (operands[2] == const1_rtx)
6001 return "inc{w}\t%0";
6002 else if (operands[2] == constm1_rtx)
6003 return "dec{w}\t%0";
6004 abort();
6005
6006 default:
6007 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6008 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6009 if (GET_CODE (operands[2]) == CONST_INT
6010 && (INTVAL (operands[2]) == 128
6011 || (INTVAL (operands[2]) < 0
6012 && INTVAL (operands[2]) != -128)))
6013 {
6014 operands[2] = GEN_INT (-INTVAL (operands[2]));
6015 return "sub{w}\t{%2, %0|%0, %2}";
6016 }
6017 return "add{w}\t{%2, %0|%0, %2}";
6018 }
6019 }
6020 [(set (attr "type")
6021 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6022 (const_string "incdec")
6023 (const_string "alu")))
6024 (set_attr "mode" "HI")])
6025
6026 (define_insn "*addhi_2"
6027 [(set (reg FLAGS_REG)
6028 (compare
6029 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6030 (match_operand:HI 2 "general_operand" "rmni,rni"))
6031 (const_int 0)))
6032 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6033 (plus:HI (match_dup 1) (match_dup 2)))]
6034 "ix86_match_ccmode (insn, CCGOCmode)
6035 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6036 {
6037 switch (get_attr_type (insn))
6038 {
6039 case TYPE_INCDEC:
6040 if (operands[2] == const1_rtx)
6041 return "inc{w}\t%0";
6042 else if (operands[2] == constm1_rtx)
6043 return "dec{w}\t%0";
6044 abort();
6045
6046 default:
6047 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6048 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6049 if (GET_CODE (operands[2]) == CONST_INT
6050 && (INTVAL (operands[2]) == 128
6051 || (INTVAL (operands[2]) < 0
6052 && INTVAL (operands[2]) != -128)))
6053 {
6054 operands[2] = GEN_INT (-INTVAL (operands[2]));
6055 return "sub{w}\t{%2, %0|%0, %2}";
6056 }
6057 return "add{w}\t{%2, %0|%0, %2}";
6058 }
6059 }
6060 [(set (attr "type")
6061 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6062 (const_string "incdec")
6063 (const_string "alu")))
6064 (set_attr "mode" "HI")])
6065
6066 (define_insn "*addhi_3"
6067 [(set (reg FLAGS_REG)
6068 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6069 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6070 (clobber (match_scratch:HI 0 "=r"))]
6071 "ix86_match_ccmode (insn, CCZmode)
6072 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6073 {
6074 switch (get_attr_type (insn))
6075 {
6076 case TYPE_INCDEC:
6077 if (operands[2] == const1_rtx)
6078 return "inc{w}\t%0";
6079 else if (operands[2] == constm1_rtx)
6080 return "dec{w}\t%0";
6081 abort();
6082
6083 default:
6084 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6085 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6086 if (GET_CODE (operands[2]) == CONST_INT
6087 && (INTVAL (operands[2]) == 128
6088 || (INTVAL (operands[2]) < 0
6089 && INTVAL (operands[2]) != -128)))
6090 {
6091 operands[2] = GEN_INT (-INTVAL (operands[2]));
6092 return "sub{w}\t{%2, %0|%0, %2}";
6093 }
6094 return "add{w}\t{%2, %0|%0, %2}";
6095 }
6096 }
6097 [(set (attr "type")
6098 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6099 (const_string "incdec")
6100 (const_string "alu")))
6101 (set_attr "mode" "HI")])
6102
6103 ; See comments above addsi_4 for details.
6104 (define_insn "*addhi_4"
6105 [(set (reg FLAGS_REG)
6106 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6107 (match_operand:HI 2 "const_int_operand" "n")))
6108 (clobber (match_scratch:HI 0 "=rm"))]
6109 "ix86_match_ccmode (insn, CCGCmode)
6110 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6111 {
6112 switch (get_attr_type (insn))
6113 {
6114 case TYPE_INCDEC:
6115 if (operands[2] == constm1_rtx)
6116 return "inc{w}\t%0";
6117 else if (operands[2] == const1_rtx)
6118 return "dec{w}\t%0";
6119 else
6120 abort();
6121
6122 default:
6123 if (! rtx_equal_p (operands[0], operands[1]))
6124 abort ();
6125 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6127 if ((INTVAL (operands[2]) == -128
6128 || (INTVAL (operands[2]) > 0
6129 && INTVAL (operands[2]) != 128)))
6130 return "sub{w}\t{%2, %0|%0, %2}";
6131 operands[2] = GEN_INT (-INTVAL (operands[2]));
6132 return "add{w}\t{%2, %0|%0, %2}";
6133 }
6134 }
6135 [(set (attr "type")
6136 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6137 (const_string "incdec")
6138 (const_string "alu")))
6139 (set_attr "mode" "SI")])
6140
6141
6142 (define_insn "*addhi_5"
6143 [(set (reg FLAGS_REG)
6144 (compare
6145 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6146 (match_operand:HI 2 "general_operand" "rmni"))
6147 (const_int 0)))
6148 (clobber (match_scratch:HI 0 "=r"))]
6149 "ix86_match_ccmode (insn, CCGOCmode)
6150 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6151 {
6152 switch (get_attr_type (insn))
6153 {
6154 case TYPE_INCDEC:
6155 if (operands[2] == const1_rtx)
6156 return "inc{w}\t%0";
6157 else if (operands[2] == constm1_rtx)
6158 return "dec{w}\t%0";
6159 abort();
6160
6161 default:
6162 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6163 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6164 if (GET_CODE (operands[2]) == CONST_INT
6165 && (INTVAL (operands[2]) == 128
6166 || (INTVAL (operands[2]) < 0
6167 && INTVAL (operands[2]) != -128)))
6168 {
6169 operands[2] = GEN_INT (-INTVAL (operands[2]));
6170 return "sub{w}\t{%2, %0|%0, %2}";
6171 }
6172 return "add{w}\t{%2, %0|%0, %2}";
6173 }
6174 }
6175 [(set (attr "type")
6176 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6177 (const_string "incdec")
6178 (const_string "alu")))
6179 (set_attr "mode" "HI")])
6180
6181 (define_expand "addqi3"
6182 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6183 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6184 (match_operand:QI 2 "general_operand" "")))
6185 (clobber (reg:CC FLAGS_REG))])]
6186 "TARGET_QIMODE_MATH"
6187 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6188
6189 ;; %%% Potential partial reg stall on alternative 2. What to do?
6190 (define_insn "*addqi_1_lea"
6191 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6192 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6193 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6194 (clobber (reg:CC FLAGS_REG))]
6195 "!TARGET_PARTIAL_REG_STALL
6196 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6197 {
6198 int widen = (which_alternative == 2);
6199 switch (get_attr_type (insn))
6200 {
6201 case TYPE_LEA:
6202 return "#";
6203 case TYPE_INCDEC:
6204 if (operands[2] == const1_rtx)
6205 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6206 else if (operands[2] == constm1_rtx)
6207 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6208 abort();
6209
6210 default:
6211 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6212 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6213 if (GET_CODE (operands[2]) == CONST_INT
6214 && (INTVAL (operands[2]) == 128
6215 || (INTVAL (operands[2]) < 0
6216 && INTVAL (operands[2]) != -128)))
6217 {
6218 operands[2] = GEN_INT (-INTVAL (operands[2]));
6219 if (widen)
6220 return "sub{l}\t{%2, %k0|%k0, %2}";
6221 else
6222 return "sub{b}\t{%2, %0|%0, %2}";
6223 }
6224 if (widen)
6225 return "add{l}\t{%k2, %k0|%k0, %k2}";
6226 else
6227 return "add{b}\t{%2, %0|%0, %2}";
6228 }
6229 }
6230 [(set (attr "type")
6231 (if_then_else (eq_attr "alternative" "3")
6232 (const_string "lea")
6233 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6234 (const_string "incdec")
6235 (const_string "alu"))))
6236 (set_attr "mode" "QI,QI,SI,SI")])
6237
6238 (define_insn "*addqi_1"
6239 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6240 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6241 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6242 (clobber (reg:CC FLAGS_REG))]
6243 "TARGET_PARTIAL_REG_STALL
6244 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6245 {
6246 int widen = (which_alternative == 2);
6247 switch (get_attr_type (insn))
6248 {
6249 case TYPE_INCDEC:
6250 if (operands[2] == const1_rtx)
6251 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6252 else if (operands[2] == constm1_rtx)
6253 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6254 abort();
6255
6256 default:
6257 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6258 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6259 if (GET_CODE (operands[2]) == CONST_INT
6260 && (INTVAL (operands[2]) == 128
6261 || (INTVAL (operands[2]) < 0
6262 && INTVAL (operands[2]) != -128)))
6263 {
6264 operands[2] = GEN_INT (-INTVAL (operands[2]));
6265 if (widen)
6266 return "sub{l}\t{%2, %k0|%k0, %2}";
6267 else
6268 return "sub{b}\t{%2, %0|%0, %2}";
6269 }
6270 if (widen)
6271 return "add{l}\t{%k2, %k0|%k0, %k2}";
6272 else
6273 return "add{b}\t{%2, %0|%0, %2}";
6274 }
6275 }
6276 [(set (attr "type")
6277 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6278 (const_string "incdec")
6279 (const_string "alu")))
6280 (set_attr "mode" "QI,QI,SI")])
6281
6282 (define_insn "*addqi_1_slp"
6283 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6284 (plus:QI (match_dup 0)
6285 (match_operand:QI 1 "general_operand" "qn,qnm")))
6286 (clobber (reg:CC FLAGS_REG))]
6287 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6288 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6289 {
6290 switch (get_attr_type (insn))
6291 {
6292 case TYPE_INCDEC:
6293 if (operands[1] == const1_rtx)
6294 return "inc{b}\t%0";
6295 else if (operands[1] == constm1_rtx)
6296 return "dec{b}\t%0";
6297 abort();
6298
6299 default:
6300 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6301 if (GET_CODE (operands[1]) == CONST_INT
6302 && INTVAL (operands[1]) < 0)
6303 {
6304 operands[1] = GEN_INT (-INTVAL (operands[1]));
6305 return "sub{b}\t{%1, %0|%0, %1}";
6306 }
6307 return "add{b}\t{%1, %0|%0, %1}";
6308 }
6309 }
6310 [(set (attr "type")
6311 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6312 (const_string "incdec")
6313 (const_string "alu1")))
6314 (set (attr "memory")
6315 (if_then_else (match_operand 1 "memory_operand" "")
6316 (const_string "load")
6317 (const_string "none")))
6318 (set_attr "mode" "QI")])
6319
6320 (define_insn "*addqi_2"
6321 [(set (reg FLAGS_REG)
6322 (compare
6323 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6324 (match_operand:QI 2 "general_operand" "qmni,qni"))
6325 (const_int 0)))
6326 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6327 (plus:QI (match_dup 1) (match_dup 2)))]
6328 "ix86_match_ccmode (insn, CCGOCmode)
6329 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6330 {
6331 switch (get_attr_type (insn))
6332 {
6333 case TYPE_INCDEC:
6334 if (operands[2] == const1_rtx)
6335 return "inc{b}\t%0";
6336 else if (operands[2] == constm1_rtx
6337 || (GET_CODE (operands[2]) == CONST_INT
6338 && INTVAL (operands[2]) == 255))
6339 return "dec{b}\t%0";
6340 abort();
6341
6342 default:
6343 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6344 if (GET_CODE (operands[2]) == CONST_INT
6345 && INTVAL (operands[2]) < 0)
6346 {
6347 operands[2] = GEN_INT (-INTVAL (operands[2]));
6348 return "sub{b}\t{%2, %0|%0, %2}";
6349 }
6350 return "add{b}\t{%2, %0|%0, %2}";
6351 }
6352 }
6353 [(set (attr "type")
6354 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6355 (const_string "incdec")
6356 (const_string "alu")))
6357 (set_attr "mode" "QI")])
6358
6359 (define_insn "*addqi_3"
6360 [(set (reg FLAGS_REG)
6361 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6362 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6363 (clobber (match_scratch:QI 0 "=q"))]
6364 "ix86_match_ccmode (insn, CCZmode)
6365 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6366 {
6367 switch (get_attr_type (insn))
6368 {
6369 case TYPE_INCDEC:
6370 if (operands[2] == const1_rtx)
6371 return "inc{b}\t%0";
6372 else if (operands[2] == constm1_rtx
6373 || (GET_CODE (operands[2]) == CONST_INT
6374 && INTVAL (operands[2]) == 255))
6375 return "dec{b}\t%0";
6376 abort();
6377
6378 default:
6379 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6380 if (GET_CODE (operands[2]) == CONST_INT
6381 && INTVAL (operands[2]) < 0)
6382 {
6383 operands[2] = GEN_INT (-INTVAL (operands[2]));
6384 return "sub{b}\t{%2, %0|%0, %2}";
6385 }
6386 return "add{b}\t{%2, %0|%0, %2}";
6387 }
6388 }
6389 [(set (attr "type")
6390 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6391 (const_string "incdec")
6392 (const_string "alu")))
6393 (set_attr "mode" "QI")])
6394
6395 ; See comments above addsi_4 for details.
6396 (define_insn "*addqi_4"
6397 [(set (reg FLAGS_REG)
6398 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6399 (match_operand:QI 2 "const_int_operand" "n")))
6400 (clobber (match_scratch:QI 0 "=qm"))]
6401 "ix86_match_ccmode (insn, CCGCmode)
6402 && (INTVAL (operands[2]) & 0xff) != 0x80"
6403 {
6404 switch (get_attr_type (insn))
6405 {
6406 case TYPE_INCDEC:
6407 if (operands[2] == constm1_rtx
6408 || (GET_CODE (operands[2]) == CONST_INT
6409 && INTVAL (operands[2]) == 255))
6410 return "inc{b}\t%0";
6411 else if (operands[2] == const1_rtx)
6412 return "dec{b}\t%0";
6413 else
6414 abort();
6415
6416 default:
6417 if (! rtx_equal_p (operands[0], operands[1]))
6418 abort ();
6419 if (INTVAL (operands[2]) < 0)
6420 {
6421 operands[2] = GEN_INT (-INTVAL (operands[2]));
6422 return "add{b}\t{%2, %0|%0, %2}";
6423 }
6424 return "sub{b}\t{%2, %0|%0, %2}";
6425 }
6426 }
6427 [(set (attr "type")
6428 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6429 (const_string "incdec")
6430 (const_string "alu")))
6431 (set_attr "mode" "QI")])
6432
6433
6434 (define_insn "*addqi_5"
6435 [(set (reg FLAGS_REG)
6436 (compare
6437 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6438 (match_operand:QI 2 "general_operand" "qmni"))
6439 (const_int 0)))
6440 (clobber (match_scratch:QI 0 "=q"))]
6441 "ix86_match_ccmode (insn, CCGOCmode)
6442 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6443 {
6444 switch (get_attr_type (insn))
6445 {
6446 case TYPE_INCDEC:
6447 if (operands[2] == const1_rtx)
6448 return "inc{b}\t%0";
6449 else if (operands[2] == constm1_rtx
6450 || (GET_CODE (operands[2]) == CONST_INT
6451 && INTVAL (operands[2]) == 255))
6452 return "dec{b}\t%0";
6453 abort();
6454
6455 default:
6456 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6457 if (GET_CODE (operands[2]) == CONST_INT
6458 && INTVAL (operands[2]) < 0)
6459 {
6460 operands[2] = GEN_INT (-INTVAL (operands[2]));
6461 return "sub{b}\t{%2, %0|%0, %2}";
6462 }
6463 return "add{b}\t{%2, %0|%0, %2}";
6464 }
6465 }
6466 [(set (attr "type")
6467 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6468 (const_string "incdec")
6469 (const_string "alu")))
6470 (set_attr "mode" "QI")])
6471
6472
6473 (define_insn "addqi_ext_1"
6474 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6475 (const_int 8)
6476 (const_int 8))
6477 (plus:SI
6478 (zero_extract:SI
6479 (match_operand 1 "ext_register_operand" "0")
6480 (const_int 8)
6481 (const_int 8))
6482 (match_operand:QI 2 "general_operand" "Qmn")))
6483 (clobber (reg:CC FLAGS_REG))]
6484 "!TARGET_64BIT"
6485 {
6486 switch (get_attr_type (insn))
6487 {
6488 case TYPE_INCDEC:
6489 if (operands[2] == const1_rtx)
6490 return "inc{b}\t%h0";
6491 else if (operands[2] == constm1_rtx
6492 || (GET_CODE (operands[2]) == CONST_INT
6493 && INTVAL (operands[2]) == 255))
6494 return "dec{b}\t%h0";
6495 abort();
6496
6497 default:
6498 return "add{b}\t{%2, %h0|%h0, %2}";
6499 }
6500 }
6501 [(set (attr "type")
6502 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6503 (const_string "incdec")
6504 (const_string "alu")))
6505 (set_attr "mode" "QI")])
6506
6507 (define_insn "*addqi_ext_1_rex64"
6508 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6509 (const_int 8)
6510 (const_int 8))
6511 (plus:SI
6512 (zero_extract:SI
6513 (match_operand 1 "ext_register_operand" "0")
6514 (const_int 8)
6515 (const_int 8))
6516 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6517 (clobber (reg:CC FLAGS_REG))]
6518 "TARGET_64BIT"
6519 {
6520 switch (get_attr_type (insn))
6521 {
6522 case TYPE_INCDEC:
6523 if (operands[2] == const1_rtx)
6524 return "inc{b}\t%h0";
6525 else if (operands[2] == constm1_rtx
6526 || (GET_CODE (operands[2]) == CONST_INT
6527 && INTVAL (operands[2]) == 255))
6528 return "dec{b}\t%h0";
6529 abort();
6530
6531 default:
6532 return "add{b}\t{%2, %h0|%h0, %2}";
6533 }
6534 }
6535 [(set (attr "type")
6536 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6537 (const_string "incdec")
6538 (const_string "alu")))
6539 (set_attr "mode" "QI")])
6540
6541 (define_insn "*addqi_ext_2"
6542 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6543 (const_int 8)
6544 (const_int 8))
6545 (plus:SI
6546 (zero_extract:SI
6547 (match_operand 1 "ext_register_operand" "%0")
6548 (const_int 8)
6549 (const_int 8))
6550 (zero_extract:SI
6551 (match_operand 2 "ext_register_operand" "Q")
6552 (const_int 8)
6553 (const_int 8))))
6554 (clobber (reg:CC FLAGS_REG))]
6555 ""
6556 "add{b}\t{%h2, %h0|%h0, %h2}"
6557 [(set_attr "type" "alu")
6558 (set_attr "mode" "QI")])
6559
6560 ;; The patterns that match these are at the end of this file.
6561
6562 (define_expand "addxf3"
6563 [(set (match_operand:XF 0 "register_operand" "")
6564 (plus:XF (match_operand:XF 1 "register_operand" "")
6565 (match_operand:XF 2 "register_operand" "")))]
6566 "TARGET_80387"
6567 "")
6568
6569 (define_expand "adddf3"
6570 [(set (match_operand:DF 0 "register_operand" "")
6571 (plus:DF (match_operand:DF 1 "register_operand" "")
6572 (match_operand:DF 2 "nonimmediate_operand" "")))]
6573 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6574 "")
6575
6576 (define_expand "addsf3"
6577 [(set (match_operand:SF 0 "register_operand" "")
6578 (plus:SF (match_operand:SF 1 "register_operand" "")
6579 (match_operand:SF 2 "nonimmediate_operand" "")))]
6580 "TARGET_80387 || TARGET_SSE_MATH"
6581 "")
6582 \f
6583 ;; Subtract instructions
6584
6585 ;; %%% splits for subsidi3
6586
6587 (define_expand "subdi3"
6588 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6589 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6590 (match_operand:DI 2 "x86_64_general_operand" "")))
6591 (clobber (reg:CC FLAGS_REG))])]
6592 ""
6593 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6594
6595 (define_insn "*subdi3_1"
6596 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6597 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6598 (match_operand:DI 2 "general_operand" "roiF,riF")))
6599 (clobber (reg:CC FLAGS_REG))]
6600 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6601 "#")
6602
6603 (define_split
6604 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6605 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6606 (match_operand:DI 2 "general_operand" "")))
6607 (clobber (reg:CC FLAGS_REG))]
6608 "!TARGET_64BIT && reload_completed"
6609 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6610 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6611 (parallel [(set (match_dup 3)
6612 (minus:SI (match_dup 4)
6613 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6614 (match_dup 5))))
6615 (clobber (reg:CC FLAGS_REG))])]
6616 "split_di (operands+0, 1, operands+0, operands+3);
6617 split_di (operands+1, 1, operands+1, operands+4);
6618 split_di (operands+2, 1, operands+2, operands+5);")
6619
6620 (define_insn "subdi3_carry_rex64"
6621 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6622 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6623 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6624 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6625 (clobber (reg:CC FLAGS_REG))]
6626 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6627 "sbb{q}\t{%2, %0|%0, %2}"
6628 [(set_attr "type" "alu")
6629 (set_attr "pent_pair" "pu")
6630 (set_attr "mode" "DI")])
6631
6632 (define_insn "*subdi_1_rex64"
6633 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6634 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6635 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6636 (clobber (reg:CC FLAGS_REG))]
6637 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6638 "sub{q}\t{%2, %0|%0, %2}"
6639 [(set_attr "type" "alu")
6640 (set_attr "mode" "DI")])
6641
6642 (define_insn "*subdi_2_rex64"
6643 [(set (reg FLAGS_REG)
6644 (compare
6645 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6646 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6647 (const_int 0)))
6648 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6649 (minus:DI (match_dup 1) (match_dup 2)))]
6650 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6651 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6652 "sub{q}\t{%2, %0|%0, %2}"
6653 [(set_attr "type" "alu")
6654 (set_attr "mode" "DI")])
6655
6656 (define_insn "*subdi_3_rex63"
6657 [(set (reg FLAGS_REG)
6658 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6659 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6660 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6661 (minus:DI (match_dup 1) (match_dup 2)))]
6662 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6663 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6664 "sub{q}\t{%2, %0|%0, %2}"
6665 [(set_attr "type" "alu")
6666 (set_attr "mode" "DI")])
6667
6668 (define_insn "subqi3_carry"
6669 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6670 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6671 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6672 (match_operand:QI 2 "general_operand" "qi,qm"))))
6673 (clobber (reg:CC FLAGS_REG))]
6674 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6675 "sbb{b}\t{%2, %0|%0, %2}"
6676 [(set_attr "type" "alu")
6677 (set_attr "pent_pair" "pu")
6678 (set_attr "mode" "QI")])
6679
6680 (define_insn "subhi3_carry"
6681 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6682 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6683 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6684 (match_operand:HI 2 "general_operand" "ri,rm"))))
6685 (clobber (reg:CC FLAGS_REG))]
6686 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6687 "sbb{w}\t{%2, %0|%0, %2}"
6688 [(set_attr "type" "alu")
6689 (set_attr "pent_pair" "pu")
6690 (set_attr "mode" "HI")])
6691
6692 (define_insn "subsi3_carry"
6693 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6694 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6695 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6696 (match_operand:SI 2 "general_operand" "ri,rm"))))
6697 (clobber (reg:CC FLAGS_REG))]
6698 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6699 "sbb{l}\t{%2, %0|%0, %2}"
6700 [(set_attr "type" "alu")
6701 (set_attr "pent_pair" "pu")
6702 (set_attr "mode" "SI")])
6703
6704 (define_insn "subsi3_carry_zext"
6705 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6706 (zero_extend:DI
6707 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6708 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6709 (match_operand:SI 2 "general_operand" "ri,rm")))))
6710 (clobber (reg:CC FLAGS_REG))]
6711 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6712 "sbb{l}\t{%2, %k0|%k0, %2}"
6713 [(set_attr "type" "alu")
6714 (set_attr "pent_pair" "pu")
6715 (set_attr "mode" "SI")])
6716
6717 (define_expand "subsi3"
6718 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6719 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6720 (match_operand:SI 2 "general_operand" "")))
6721 (clobber (reg:CC FLAGS_REG))])]
6722 ""
6723 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6724
6725 (define_insn "*subsi_1"
6726 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6727 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6728 (match_operand:SI 2 "general_operand" "ri,rm")))
6729 (clobber (reg:CC FLAGS_REG))]
6730 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6731 "sub{l}\t{%2, %0|%0, %2}"
6732 [(set_attr "type" "alu")
6733 (set_attr "mode" "SI")])
6734
6735 (define_insn "*subsi_1_zext"
6736 [(set (match_operand:DI 0 "register_operand" "=r")
6737 (zero_extend:DI
6738 (minus:SI (match_operand:SI 1 "register_operand" "0")
6739 (match_operand:SI 2 "general_operand" "rim"))))
6740 (clobber (reg:CC FLAGS_REG))]
6741 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6742 "sub{l}\t{%2, %k0|%k0, %2}"
6743 [(set_attr "type" "alu")
6744 (set_attr "mode" "SI")])
6745
6746 (define_insn "*subsi_2"
6747 [(set (reg FLAGS_REG)
6748 (compare
6749 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6750 (match_operand:SI 2 "general_operand" "ri,rm"))
6751 (const_int 0)))
6752 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6753 (minus:SI (match_dup 1) (match_dup 2)))]
6754 "ix86_match_ccmode (insn, CCGOCmode)
6755 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6756 "sub{l}\t{%2, %0|%0, %2}"
6757 [(set_attr "type" "alu")
6758 (set_attr "mode" "SI")])
6759
6760 (define_insn "*subsi_2_zext"
6761 [(set (reg FLAGS_REG)
6762 (compare
6763 (minus:SI (match_operand:SI 1 "register_operand" "0")
6764 (match_operand:SI 2 "general_operand" "rim"))
6765 (const_int 0)))
6766 (set (match_operand:DI 0 "register_operand" "=r")
6767 (zero_extend:DI
6768 (minus:SI (match_dup 1)
6769 (match_dup 2))))]
6770 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6771 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6772 "sub{l}\t{%2, %k0|%k0, %2}"
6773 [(set_attr "type" "alu")
6774 (set_attr "mode" "SI")])
6775
6776 (define_insn "*subsi_3"
6777 [(set (reg FLAGS_REG)
6778 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6779 (match_operand:SI 2 "general_operand" "ri,rm")))
6780 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6781 (minus:SI (match_dup 1) (match_dup 2)))]
6782 "ix86_match_ccmode (insn, CCmode)
6783 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6784 "sub{l}\t{%2, %0|%0, %2}"
6785 [(set_attr "type" "alu")
6786 (set_attr "mode" "SI")])
6787
6788 (define_insn "*subsi_3_zext"
6789 [(set (reg FLAGS_REG)
6790 (compare (match_operand:SI 1 "register_operand" "0")
6791 (match_operand:SI 2 "general_operand" "rim")))
6792 (set (match_operand:DI 0 "register_operand" "=r")
6793 (zero_extend:DI
6794 (minus:SI (match_dup 1)
6795 (match_dup 2))))]
6796 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6797 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6798 "sub{q}\t{%2, %0|%0, %2}"
6799 [(set_attr "type" "alu")
6800 (set_attr "mode" "DI")])
6801
6802 (define_expand "subhi3"
6803 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6804 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6805 (match_operand:HI 2 "general_operand" "")))
6806 (clobber (reg:CC FLAGS_REG))])]
6807 "TARGET_HIMODE_MATH"
6808 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6809
6810 (define_insn "*subhi_1"
6811 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6812 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6813 (match_operand:HI 2 "general_operand" "ri,rm")))
6814 (clobber (reg:CC FLAGS_REG))]
6815 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6816 "sub{w}\t{%2, %0|%0, %2}"
6817 [(set_attr "type" "alu")
6818 (set_attr "mode" "HI")])
6819
6820 (define_insn "*subhi_2"
6821 [(set (reg FLAGS_REG)
6822 (compare
6823 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6824 (match_operand:HI 2 "general_operand" "ri,rm"))
6825 (const_int 0)))
6826 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6827 (minus:HI (match_dup 1) (match_dup 2)))]
6828 "ix86_match_ccmode (insn, CCGOCmode)
6829 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6830 "sub{w}\t{%2, %0|%0, %2}"
6831 [(set_attr "type" "alu")
6832 (set_attr "mode" "HI")])
6833
6834 (define_insn "*subhi_3"
6835 [(set (reg FLAGS_REG)
6836 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6837 (match_operand:HI 2 "general_operand" "ri,rm")))
6838 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6839 (minus:HI (match_dup 1) (match_dup 2)))]
6840 "ix86_match_ccmode (insn, CCmode)
6841 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6842 "sub{w}\t{%2, %0|%0, %2}"
6843 [(set_attr "type" "alu")
6844 (set_attr "mode" "HI")])
6845
6846 (define_expand "subqi3"
6847 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6848 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6849 (match_operand:QI 2 "general_operand" "")))
6850 (clobber (reg:CC FLAGS_REG))])]
6851 "TARGET_QIMODE_MATH"
6852 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6853
6854 (define_insn "*subqi_1"
6855 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6856 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6857 (match_operand:QI 2 "general_operand" "qn,qmn")))
6858 (clobber (reg:CC FLAGS_REG))]
6859 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6860 "sub{b}\t{%2, %0|%0, %2}"
6861 [(set_attr "type" "alu")
6862 (set_attr "mode" "QI")])
6863
6864 (define_insn "*subqi_1_slp"
6865 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6866 (minus:QI (match_dup 0)
6867 (match_operand:QI 1 "general_operand" "qn,qmn")))
6868 (clobber (reg:CC FLAGS_REG))]
6869 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6870 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6871 "sub{b}\t{%1, %0|%0, %1}"
6872 [(set_attr "type" "alu1")
6873 (set_attr "mode" "QI")])
6874
6875 (define_insn "*subqi_2"
6876 [(set (reg FLAGS_REG)
6877 (compare
6878 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6879 (match_operand:QI 2 "general_operand" "qi,qm"))
6880 (const_int 0)))
6881 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6882 (minus:HI (match_dup 1) (match_dup 2)))]
6883 "ix86_match_ccmode (insn, CCGOCmode)
6884 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6885 "sub{b}\t{%2, %0|%0, %2}"
6886 [(set_attr "type" "alu")
6887 (set_attr "mode" "QI")])
6888
6889 (define_insn "*subqi_3"
6890 [(set (reg FLAGS_REG)
6891 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6892 (match_operand:QI 2 "general_operand" "qi,qm")))
6893 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6894 (minus:HI (match_dup 1) (match_dup 2)))]
6895 "ix86_match_ccmode (insn, CCmode)
6896 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6897 "sub{b}\t{%2, %0|%0, %2}"
6898 [(set_attr "type" "alu")
6899 (set_attr "mode" "QI")])
6900
6901 ;; The patterns that match these are at the end of this file.
6902
6903 (define_expand "subxf3"
6904 [(set (match_operand:XF 0 "register_operand" "")
6905 (minus:XF (match_operand:XF 1 "register_operand" "")
6906 (match_operand:XF 2 "register_operand" "")))]
6907 "TARGET_80387"
6908 "")
6909
6910 (define_expand "subdf3"
6911 [(set (match_operand:DF 0 "register_operand" "")
6912 (minus:DF (match_operand:DF 1 "register_operand" "")
6913 (match_operand:DF 2 "nonimmediate_operand" "")))]
6914 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6915 "")
6916
6917 (define_expand "subsf3"
6918 [(set (match_operand:SF 0 "register_operand" "")
6919 (minus:SF (match_operand:SF 1 "register_operand" "")
6920 (match_operand:SF 2 "nonimmediate_operand" "")))]
6921 "TARGET_80387 || TARGET_SSE_MATH"
6922 "")
6923 \f
6924 ;; Multiply instructions
6925
6926 (define_expand "muldi3"
6927 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6928 (mult:DI (match_operand:DI 1 "register_operand" "")
6929 (match_operand:DI 2 "x86_64_general_operand" "")))
6930 (clobber (reg:CC FLAGS_REG))])]
6931 "TARGET_64BIT"
6932 "")
6933
6934 (define_insn "*muldi3_1_rex64"
6935 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6936 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6937 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6938 (clobber (reg:CC FLAGS_REG))]
6939 "TARGET_64BIT
6940 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6941 "@
6942 imul{q}\t{%2, %1, %0|%0, %1, %2}
6943 imul{q}\t{%2, %1, %0|%0, %1, %2}
6944 imul{q}\t{%2, %0|%0, %2}"
6945 [(set_attr "type" "imul")
6946 (set_attr "prefix_0f" "0,0,1")
6947 (set (attr "athlon_decode")
6948 (cond [(eq_attr "cpu" "athlon")
6949 (const_string "vector")
6950 (eq_attr "alternative" "1")
6951 (const_string "vector")
6952 (and (eq_attr "alternative" "2")
6953 (match_operand 1 "memory_operand" ""))
6954 (const_string "vector")]
6955 (const_string "direct")))
6956 (set_attr "mode" "DI")])
6957
6958 (define_expand "mulsi3"
6959 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6960 (mult:SI (match_operand:SI 1 "register_operand" "")
6961 (match_operand:SI 2 "general_operand" "")))
6962 (clobber (reg:CC FLAGS_REG))])]
6963 ""
6964 "")
6965
6966 (define_insn "*mulsi3_1"
6967 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6968 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6969 (match_operand:SI 2 "general_operand" "K,i,mr")))
6970 (clobber (reg:CC FLAGS_REG))]
6971 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6972 "@
6973 imul{l}\t{%2, %1, %0|%0, %1, %2}
6974 imul{l}\t{%2, %1, %0|%0, %1, %2}
6975 imul{l}\t{%2, %0|%0, %2}"
6976 [(set_attr "type" "imul")
6977 (set_attr "prefix_0f" "0,0,1")
6978 (set (attr "athlon_decode")
6979 (cond [(eq_attr "cpu" "athlon")
6980 (const_string "vector")
6981 (eq_attr "alternative" "1")
6982 (const_string "vector")
6983 (and (eq_attr "alternative" "2")
6984 (match_operand 1 "memory_operand" ""))
6985 (const_string "vector")]
6986 (const_string "direct")))
6987 (set_attr "mode" "SI")])
6988
6989 (define_insn "*mulsi3_1_zext"
6990 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6991 (zero_extend:DI
6992 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6993 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6994 (clobber (reg:CC FLAGS_REG))]
6995 "TARGET_64BIT
6996 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6997 "@
6998 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6999 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7000 imul{l}\t{%2, %k0|%k0, %2}"
7001 [(set_attr "type" "imul")
7002 (set_attr "prefix_0f" "0,0,1")
7003 (set (attr "athlon_decode")
7004 (cond [(eq_attr "cpu" "athlon")
7005 (const_string "vector")
7006 (eq_attr "alternative" "1")
7007 (const_string "vector")
7008 (and (eq_attr "alternative" "2")
7009 (match_operand 1 "memory_operand" ""))
7010 (const_string "vector")]
7011 (const_string "direct")))
7012 (set_attr "mode" "SI")])
7013
7014 (define_expand "mulhi3"
7015 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7016 (mult:HI (match_operand:HI 1 "register_operand" "")
7017 (match_operand:HI 2 "general_operand" "")))
7018 (clobber (reg:CC FLAGS_REG))])]
7019 "TARGET_HIMODE_MATH"
7020 "")
7021
7022 (define_insn "*mulhi3_1"
7023 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7024 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7025 (match_operand:HI 2 "general_operand" "K,i,mr")))
7026 (clobber (reg:CC FLAGS_REG))]
7027 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7028 "@
7029 imul{w}\t{%2, %1, %0|%0, %1, %2}
7030 imul{w}\t{%2, %1, %0|%0, %1, %2}
7031 imul{w}\t{%2, %0|%0, %2}"
7032 [(set_attr "type" "imul")
7033 (set_attr "prefix_0f" "0,0,1")
7034 (set (attr "athlon_decode")
7035 (cond [(eq_attr "cpu" "athlon")
7036 (const_string "vector")
7037 (eq_attr "alternative" "1,2")
7038 (const_string "vector")]
7039 (const_string "direct")))
7040 (set_attr "mode" "HI")])
7041
7042 (define_expand "mulqi3"
7043 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7044 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7045 (match_operand:QI 2 "register_operand" "")))
7046 (clobber (reg:CC FLAGS_REG))])]
7047 "TARGET_QIMODE_MATH"
7048 "")
7049
7050 (define_insn "*mulqi3_1"
7051 [(set (match_operand:QI 0 "register_operand" "=a")
7052 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7053 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7054 (clobber (reg:CC FLAGS_REG))]
7055 "TARGET_QIMODE_MATH
7056 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7057 "mul{b}\t%2"
7058 [(set_attr "type" "imul")
7059 (set_attr "length_immediate" "0")
7060 (set (attr "athlon_decode")
7061 (if_then_else (eq_attr "cpu" "athlon")
7062 (const_string "vector")
7063 (const_string "direct")))
7064 (set_attr "mode" "QI")])
7065
7066 (define_expand "umulqihi3"
7067 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7068 (mult:HI (zero_extend:HI
7069 (match_operand:QI 1 "nonimmediate_operand" ""))
7070 (zero_extend:HI
7071 (match_operand:QI 2 "register_operand" ""))))
7072 (clobber (reg:CC FLAGS_REG))])]
7073 "TARGET_QIMODE_MATH"
7074 "")
7075
7076 (define_insn "*umulqihi3_1"
7077 [(set (match_operand:HI 0 "register_operand" "=a")
7078 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7079 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7080 (clobber (reg:CC FLAGS_REG))]
7081 "TARGET_QIMODE_MATH
7082 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7083 "mul{b}\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 "direct")))
7090 (set_attr "mode" "QI")])
7091
7092 (define_expand "mulqihi3"
7093 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7094 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7095 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7096 (clobber (reg:CC FLAGS_REG))])]
7097 "TARGET_QIMODE_MATH"
7098 "")
7099
7100 (define_insn "*mulqihi3_insn"
7101 [(set (match_operand:HI 0 "register_operand" "=a")
7102 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7103 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7104 (clobber (reg:CC FLAGS_REG))]
7105 "TARGET_QIMODE_MATH
7106 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7107 "imul{b}\t%2"
7108 [(set_attr "type" "imul")
7109 (set_attr "length_immediate" "0")
7110 (set (attr "athlon_decode")
7111 (if_then_else (eq_attr "cpu" "athlon")
7112 (const_string "vector")
7113 (const_string "direct")))
7114 (set_attr "mode" "QI")])
7115
7116 (define_expand "umulditi3"
7117 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7118 (mult:TI (zero_extend:TI
7119 (match_operand:DI 1 "nonimmediate_operand" ""))
7120 (zero_extend:TI
7121 (match_operand:DI 2 "register_operand" ""))))
7122 (clobber (reg:CC FLAGS_REG))])]
7123 "TARGET_64BIT"
7124 "")
7125
7126 (define_insn "*umulditi3_insn"
7127 [(set (match_operand:TI 0 "register_operand" "=A")
7128 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7129 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7130 (clobber (reg:CC FLAGS_REG))]
7131 "TARGET_64BIT
7132 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7133 "mul{q}\t%2"
7134 [(set_attr "type" "imul")
7135 (set_attr "length_immediate" "0")
7136 (set (attr "athlon_decode")
7137 (if_then_else (eq_attr "cpu" "athlon")
7138 (const_string "vector")
7139 (const_string "double")))
7140 (set_attr "mode" "DI")])
7141
7142 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7143 (define_expand "umulsidi3"
7144 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7145 (mult:DI (zero_extend:DI
7146 (match_operand:SI 1 "nonimmediate_operand" ""))
7147 (zero_extend:DI
7148 (match_operand:SI 2 "register_operand" ""))))
7149 (clobber (reg:CC FLAGS_REG))])]
7150 "!TARGET_64BIT"
7151 "")
7152
7153 (define_insn "*umulsidi3_insn"
7154 [(set (match_operand:DI 0 "register_operand" "=A")
7155 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7156 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7157 (clobber (reg:CC FLAGS_REG))]
7158 "!TARGET_64BIT
7159 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7160 "mul{l}\t%2"
7161 [(set_attr "type" "imul")
7162 (set_attr "length_immediate" "0")
7163 (set (attr "athlon_decode")
7164 (if_then_else (eq_attr "cpu" "athlon")
7165 (const_string "vector")
7166 (const_string "double")))
7167 (set_attr "mode" "SI")])
7168
7169 (define_expand "mulditi3"
7170 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7171 (mult:TI (sign_extend:TI
7172 (match_operand:DI 1 "nonimmediate_operand" ""))
7173 (sign_extend:TI
7174 (match_operand:DI 2 "register_operand" ""))))
7175 (clobber (reg:CC FLAGS_REG))])]
7176 "TARGET_64BIT"
7177 "")
7178
7179 (define_insn "*mulditi3_insn"
7180 [(set (match_operand:TI 0 "register_operand" "=A")
7181 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7182 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7183 (clobber (reg:CC FLAGS_REG))]
7184 "TARGET_64BIT
7185 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7186 "imul{q}\t%2"
7187 [(set_attr "type" "imul")
7188 (set_attr "length_immediate" "0")
7189 (set (attr "athlon_decode")
7190 (if_then_else (eq_attr "cpu" "athlon")
7191 (const_string "vector")
7192 (const_string "double")))
7193 (set_attr "mode" "DI")])
7194
7195 (define_expand "mulsidi3"
7196 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7197 (mult:DI (sign_extend:DI
7198 (match_operand:SI 1 "nonimmediate_operand" ""))
7199 (sign_extend:DI
7200 (match_operand:SI 2 "register_operand" ""))))
7201 (clobber (reg:CC FLAGS_REG))])]
7202 "!TARGET_64BIT"
7203 "")
7204
7205 (define_insn "*mulsidi3_insn"
7206 [(set (match_operand:DI 0 "register_operand" "=A")
7207 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7208 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7209 (clobber (reg:CC FLAGS_REG))]
7210 "!TARGET_64BIT
7211 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7212 "imul{l}\t%2"
7213 [(set_attr "type" "imul")
7214 (set_attr "length_immediate" "0")
7215 (set (attr "athlon_decode")
7216 (if_then_else (eq_attr "cpu" "athlon")
7217 (const_string "vector")
7218 (const_string "double")))
7219 (set_attr "mode" "SI")])
7220
7221 (define_expand "umuldi3_highpart"
7222 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7223 (truncate:DI
7224 (lshiftrt:TI
7225 (mult:TI (zero_extend:TI
7226 (match_operand:DI 1 "nonimmediate_operand" ""))
7227 (zero_extend:TI
7228 (match_operand:DI 2 "register_operand" "")))
7229 (const_int 64))))
7230 (clobber (match_scratch:DI 3 ""))
7231 (clobber (reg:CC FLAGS_REG))])]
7232 "TARGET_64BIT"
7233 "")
7234
7235 (define_insn "*umuldi3_highpart_rex64"
7236 [(set (match_operand:DI 0 "register_operand" "=d")
7237 (truncate:DI
7238 (lshiftrt:TI
7239 (mult:TI (zero_extend:TI
7240 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7241 (zero_extend:TI
7242 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7243 (const_int 64))))
7244 (clobber (match_scratch:DI 3 "=1"))
7245 (clobber (reg:CC FLAGS_REG))]
7246 "TARGET_64BIT
7247 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7248 "mul{q}\t%2"
7249 [(set_attr "type" "imul")
7250 (set_attr "length_immediate" "0")
7251 (set (attr "athlon_decode")
7252 (if_then_else (eq_attr "cpu" "athlon")
7253 (const_string "vector")
7254 (const_string "double")))
7255 (set_attr "mode" "DI")])
7256
7257 (define_expand "umulsi3_highpart"
7258 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7259 (truncate:SI
7260 (lshiftrt:DI
7261 (mult:DI (zero_extend:DI
7262 (match_operand:SI 1 "nonimmediate_operand" ""))
7263 (zero_extend:DI
7264 (match_operand:SI 2 "register_operand" "")))
7265 (const_int 32))))
7266 (clobber (match_scratch:SI 3 ""))
7267 (clobber (reg:CC FLAGS_REG))])]
7268 ""
7269 "")
7270
7271 (define_insn "*umulsi3_highpart_insn"
7272 [(set (match_operand:SI 0 "register_operand" "=d")
7273 (truncate:SI
7274 (lshiftrt:DI
7275 (mult:DI (zero_extend:DI
7276 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7277 (zero_extend:DI
7278 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7279 (const_int 32))))
7280 (clobber (match_scratch:SI 3 "=1"))
7281 (clobber (reg:CC FLAGS_REG))]
7282 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7283 "mul{l}\t%2"
7284 [(set_attr "type" "imul")
7285 (set_attr "length_immediate" "0")
7286 (set (attr "athlon_decode")
7287 (if_then_else (eq_attr "cpu" "athlon")
7288 (const_string "vector")
7289 (const_string "double")))
7290 (set_attr "mode" "SI")])
7291
7292 (define_insn "*umulsi3_highpart_zext"
7293 [(set (match_operand:DI 0 "register_operand" "=d")
7294 (zero_extend:DI (truncate:SI
7295 (lshiftrt:DI
7296 (mult:DI (zero_extend:DI
7297 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7298 (zero_extend:DI
7299 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7300 (const_int 32)))))
7301 (clobber (match_scratch:SI 3 "=1"))
7302 (clobber (reg:CC FLAGS_REG))]
7303 "TARGET_64BIT
7304 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7305 "mul{l}\t%2"
7306 [(set_attr "type" "imul")
7307 (set_attr "length_immediate" "0")
7308 (set (attr "athlon_decode")
7309 (if_then_else (eq_attr "cpu" "athlon")
7310 (const_string "vector")
7311 (const_string "double")))
7312 (set_attr "mode" "SI")])
7313
7314 (define_expand "smuldi3_highpart"
7315 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7316 (truncate:DI
7317 (lshiftrt:TI
7318 (mult:TI (sign_extend:TI
7319 (match_operand:DI 1 "nonimmediate_operand" ""))
7320 (sign_extend:TI
7321 (match_operand:DI 2 "register_operand" "")))
7322 (const_int 64))))
7323 (clobber (match_scratch:DI 3 ""))
7324 (clobber (reg:CC FLAGS_REG))])]
7325 "TARGET_64BIT"
7326 "")
7327
7328 (define_insn "*smuldi3_highpart_rex64"
7329 [(set (match_operand:DI 0 "register_operand" "=d")
7330 (truncate:DI
7331 (lshiftrt:TI
7332 (mult:TI (sign_extend:TI
7333 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7334 (sign_extend:TI
7335 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7336 (const_int 64))))
7337 (clobber (match_scratch:DI 3 "=1"))
7338 (clobber (reg:CC FLAGS_REG))]
7339 "TARGET_64BIT
7340 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7341 "imul{q}\t%2"
7342 [(set_attr "type" "imul")
7343 (set (attr "athlon_decode")
7344 (if_then_else (eq_attr "cpu" "athlon")
7345 (const_string "vector")
7346 (const_string "double")))
7347 (set_attr "mode" "DI")])
7348
7349 (define_expand "smulsi3_highpart"
7350 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7351 (truncate:SI
7352 (lshiftrt:DI
7353 (mult:DI (sign_extend:DI
7354 (match_operand:SI 1 "nonimmediate_operand" ""))
7355 (sign_extend:DI
7356 (match_operand:SI 2 "register_operand" "")))
7357 (const_int 32))))
7358 (clobber (match_scratch:SI 3 ""))
7359 (clobber (reg:CC FLAGS_REG))])]
7360 ""
7361 "")
7362
7363 (define_insn "*smulsi3_highpart_insn"
7364 [(set (match_operand:SI 0 "register_operand" "=d")
7365 (truncate:SI
7366 (lshiftrt:DI
7367 (mult:DI (sign_extend:DI
7368 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7369 (sign_extend:DI
7370 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7371 (const_int 32))))
7372 (clobber (match_scratch:SI 3 "=1"))
7373 (clobber (reg:CC FLAGS_REG))]
7374 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7375 "imul{l}\t%2"
7376 [(set_attr "type" "imul")
7377 (set (attr "athlon_decode")
7378 (if_then_else (eq_attr "cpu" "athlon")
7379 (const_string "vector")
7380 (const_string "double")))
7381 (set_attr "mode" "SI")])
7382
7383 (define_insn "*smulsi3_highpart_zext"
7384 [(set (match_operand:DI 0 "register_operand" "=d")
7385 (zero_extend:DI (truncate:SI
7386 (lshiftrt:DI
7387 (mult:DI (sign_extend:DI
7388 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7389 (sign_extend:DI
7390 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7391 (const_int 32)))))
7392 (clobber (match_scratch:SI 3 "=1"))
7393 (clobber (reg:CC FLAGS_REG))]
7394 "TARGET_64BIT
7395 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7396 "imul{l}\t%2"
7397 [(set_attr "type" "imul")
7398 (set (attr "athlon_decode")
7399 (if_then_else (eq_attr "cpu" "athlon")
7400 (const_string "vector")
7401 (const_string "double")))
7402 (set_attr "mode" "SI")])
7403
7404 ;; The patterns that match these are at the end of this file.
7405
7406 (define_expand "mulxf3"
7407 [(set (match_operand:XF 0 "register_operand" "")
7408 (mult:XF (match_operand:XF 1 "register_operand" "")
7409 (match_operand:XF 2 "register_operand" "")))]
7410 "TARGET_80387"
7411 "")
7412
7413 (define_expand "muldf3"
7414 [(set (match_operand:DF 0 "register_operand" "")
7415 (mult:DF (match_operand:DF 1 "register_operand" "")
7416 (match_operand:DF 2 "nonimmediate_operand" "")))]
7417 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7418 "")
7419
7420 (define_expand "mulsf3"
7421 [(set (match_operand:SF 0 "register_operand" "")
7422 (mult:SF (match_operand:SF 1 "register_operand" "")
7423 (match_operand:SF 2 "nonimmediate_operand" "")))]
7424 "TARGET_80387 || TARGET_SSE_MATH"
7425 "")
7426 \f
7427 ;; Divide instructions
7428
7429 (define_insn "divqi3"
7430 [(set (match_operand:QI 0 "register_operand" "=a")
7431 (div:QI (match_operand:HI 1 "register_operand" "0")
7432 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7433 (clobber (reg:CC FLAGS_REG))]
7434 "TARGET_QIMODE_MATH"
7435 "idiv{b}\t%2"
7436 [(set_attr "type" "idiv")
7437 (set_attr "mode" "QI")])
7438
7439 (define_insn "udivqi3"
7440 [(set (match_operand:QI 0 "register_operand" "=a")
7441 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7442 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7443 (clobber (reg:CC FLAGS_REG))]
7444 "TARGET_QIMODE_MATH"
7445 "div{b}\t%2"
7446 [(set_attr "type" "idiv")
7447 (set_attr "mode" "QI")])
7448
7449 ;; The patterns that match these are at the end of this file.
7450
7451 (define_expand "divxf3"
7452 [(set (match_operand:XF 0 "register_operand" "")
7453 (div:XF (match_operand:XF 1 "register_operand" "")
7454 (match_operand:XF 2 "register_operand" "")))]
7455 "TARGET_80387"
7456 "")
7457
7458 (define_expand "divdf3"
7459 [(set (match_operand:DF 0 "register_operand" "")
7460 (div:DF (match_operand:DF 1 "register_operand" "")
7461 (match_operand:DF 2 "nonimmediate_operand" "")))]
7462 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7463 "")
7464
7465 (define_expand "divsf3"
7466 [(set (match_operand:SF 0 "register_operand" "")
7467 (div:SF (match_operand:SF 1 "register_operand" "")
7468 (match_operand:SF 2 "nonimmediate_operand" "")))]
7469 "TARGET_80387 || TARGET_SSE_MATH"
7470 "")
7471 \f
7472 ;; Remainder instructions.
7473
7474 (define_expand "divmoddi4"
7475 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7476 (div:DI (match_operand:DI 1 "register_operand" "")
7477 (match_operand:DI 2 "nonimmediate_operand" "")))
7478 (set (match_operand:DI 3 "register_operand" "")
7479 (mod:DI (match_dup 1) (match_dup 2)))
7480 (clobber (reg:CC FLAGS_REG))])]
7481 "TARGET_64BIT"
7482 "")
7483
7484 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7485 ;; Penalize eax case slightly because it results in worse scheduling
7486 ;; of code.
7487 (define_insn "*divmoddi4_nocltd_rex64"
7488 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7489 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7490 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7491 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7492 (mod:DI (match_dup 2) (match_dup 3)))
7493 (clobber (reg:CC FLAGS_REG))]
7494 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7495 "#"
7496 [(set_attr "type" "multi")])
7497
7498 (define_insn "*divmoddi4_cltd_rex64"
7499 [(set (match_operand:DI 0 "register_operand" "=a")
7500 (div:DI (match_operand:DI 2 "register_operand" "a")
7501 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7502 (set (match_operand:DI 1 "register_operand" "=&d")
7503 (mod:DI (match_dup 2) (match_dup 3)))
7504 (clobber (reg:CC FLAGS_REG))]
7505 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7506 "#"
7507 [(set_attr "type" "multi")])
7508
7509 (define_insn "*divmoddi_noext_rex64"
7510 [(set (match_operand:DI 0 "register_operand" "=a")
7511 (div:DI (match_operand:DI 1 "register_operand" "0")
7512 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7513 (set (match_operand:DI 3 "register_operand" "=d")
7514 (mod:DI (match_dup 1) (match_dup 2)))
7515 (use (match_operand:DI 4 "register_operand" "3"))
7516 (clobber (reg:CC FLAGS_REG))]
7517 "TARGET_64BIT"
7518 "idiv{q}\t%2"
7519 [(set_attr "type" "idiv")
7520 (set_attr "mode" "DI")])
7521
7522 (define_split
7523 [(set (match_operand:DI 0 "register_operand" "")
7524 (div:DI (match_operand:DI 1 "register_operand" "")
7525 (match_operand:DI 2 "nonimmediate_operand" "")))
7526 (set (match_operand:DI 3 "register_operand" "")
7527 (mod:DI (match_dup 1) (match_dup 2)))
7528 (clobber (reg:CC FLAGS_REG))]
7529 "TARGET_64BIT && reload_completed"
7530 [(parallel [(set (match_dup 3)
7531 (ashiftrt:DI (match_dup 4) (const_int 63)))
7532 (clobber (reg:CC FLAGS_REG))])
7533 (parallel [(set (match_dup 0)
7534 (div:DI (reg:DI 0) (match_dup 2)))
7535 (set (match_dup 3)
7536 (mod:DI (reg:DI 0) (match_dup 2)))
7537 (use (match_dup 3))
7538 (clobber (reg:CC FLAGS_REG))])]
7539 {
7540 /* Avoid use of cltd in favor of a mov+shift. */
7541 if (!TARGET_USE_CLTD && !optimize_size)
7542 {
7543 if (true_regnum (operands[1]))
7544 emit_move_insn (operands[0], operands[1]);
7545 else
7546 emit_move_insn (operands[3], operands[1]);
7547 operands[4] = operands[3];
7548 }
7549 else
7550 {
7551 if (true_regnum (operands[1]))
7552 abort();
7553 operands[4] = operands[1];
7554 }
7555 })
7556
7557
7558 (define_expand "divmodsi4"
7559 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7560 (div:SI (match_operand:SI 1 "register_operand" "")
7561 (match_operand:SI 2 "nonimmediate_operand" "")))
7562 (set (match_operand:SI 3 "register_operand" "")
7563 (mod:SI (match_dup 1) (match_dup 2)))
7564 (clobber (reg:CC FLAGS_REG))])]
7565 ""
7566 "")
7567
7568 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7569 ;; Penalize eax case slightly because it results in worse scheduling
7570 ;; of code.
7571 (define_insn "*divmodsi4_nocltd"
7572 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7573 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7574 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7575 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7576 (mod:SI (match_dup 2) (match_dup 3)))
7577 (clobber (reg:CC FLAGS_REG))]
7578 "!optimize_size && !TARGET_USE_CLTD"
7579 "#"
7580 [(set_attr "type" "multi")])
7581
7582 (define_insn "*divmodsi4_cltd"
7583 [(set (match_operand:SI 0 "register_operand" "=a")
7584 (div:SI (match_operand:SI 2 "register_operand" "a")
7585 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7586 (set (match_operand:SI 1 "register_operand" "=&d")
7587 (mod:SI (match_dup 2) (match_dup 3)))
7588 (clobber (reg:CC FLAGS_REG))]
7589 "optimize_size || TARGET_USE_CLTD"
7590 "#"
7591 [(set_attr "type" "multi")])
7592
7593 (define_insn "*divmodsi_noext"
7594 [(set (match_operand:SI 0 "register_operand" "=a")
7595 (div:SI (match_operand:SI 1 "register_operand" "0")
7596 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7597 (set (match_operand:SI 3 "register_operand" "=d")
7598 (mod:SI (match_dup 1) (match_dup 2)))
7599 (use (match_operand:SI 4 "register_operand" "3"))
7600 (clobber (reg:CC FLAGS_REG))]
7601 ""
7602 "idiv{l}\t%2"
7603 [(set_attr "type" "idiv")
7604 (set_attr "mode" "SI")])
7605
7606 (define_split
7607 [(set (match_operand:SI 0 "register_operand" "")
7608 (div:SI (match_operand:SI 1 "register_operand" "")
7609 (match_operand:SI 2 "nonimmediate_operand" "")))
7610 (set (match_operand:SI 3 "register_operand" "")
7611 (mod:SI (match_dup 1) (match_dup 2)))
7612 (clobber (reg:CC FLAGS_REG))]
7613 "reload_completed"
7614 [(parallel [(set (match_dup 3)
7615 (ashiftrt:SI (match_dup 4) (const_int 31)))
7616 (clobber (reg:CC FLAGS_REG))])
7617 (parallel [(set (match_dup 0)
7618 (div:SI (reg:SI 0) (match_dup 2)))
7619 (set (match_dup 3)
7620 (mod:SI (reg:SI 0) (match_dup 2)))
7621 (use (match_dup 3))
7622 (clobber (reg:CC FLAGS_REG))])]
7623 {
7624 /* Avoid use of cltd in favor of a mov+shift. */
7625 if (!TARGET_USE_CLTD && !optimize_size)
7626 {
7627 if (true_regnum (operands[1]))
7628 emit_move_insn (operands[0], operands[1]);
7629 else
7630 emit_move_insn (operands[3], operands[1]);
7631 operands[4] = operands[3];
7632 }
7633 else
7634 {
7635 if (true_regnum (operands[1]))
7636 abort();
7637 operands[4] = operands[1];
7638 }
7639 })
7640 ;; %%% Split me.
7641 (define_insn "divmodhi4"
7642 [(set (match_operand:HI 0 "register_operand" "=a")
7643 (div:HI (match_operand:HI 1 "register_operand" "0")
7644 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7645 (set (match_operand:HI 3 "register_operand" "=&d")
7646 (mod:HI (match_dup 1) (match_dup 2)))
7647 (clobber (reg:CC FLAGS_REG))]
7648 "TARGET_HIMODE_MATH"
7649 "cwtd\;idiv{w}\t%2"
7650 [(set_attr "type" "multi")
7651 (set_attr "length_immediate" "0")
7652 (set_attr "mode" "SI")])
7653
7654 (define_insn "udivmoddi4"
7655 [(set (match_operand:DI 0 "register_operand" "=a")
7656 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7657 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7658 (set (match_operand:DI 3 "register_operand" "=&d")
7659 (umod:DI (match_dup 1) (match_dup 2)))
7660 (clobber (reg:CC FLAGS_REG))]
7661 "TARGET_64BIT"
7662 "xor{q}\t%3, %3\;div{q}\t%2"
7663 [(set_attr "type" "multi")
7664 (set_attr "length_immediate" "0")
7665 (set_attr "mode" "DI")])
7666
7667 (define_insn "*udivmoddi4_noext"
7668 [(set (match_operand:DI 0 "register_operand" "=a")
7669 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7670 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7671 (set (match_operand:DI 3 "register_operand" "=d")
7672 (umod:DI (match_dup 1) (match_dup 2)))
7673 (use (match_dup 3))
7674 (clobber (reg:CC FLAGS_REG))]
7675 "TARGET_64BIT"
7676 "div{q}\t%2"
7677 [(set_attr "type" "idiv")
7678 (set_attr "mode" "DI")])
7679
7680 (define_split
7681 [(set (match_operand:DI 0 "register_operand" "")
7682 (udiv:DI (match_operand:DI 1 "register_operand" "")
7683 (match_operand:DI 2 "nonimmediate_operand" "")))
7684 (set (match_operand:DI 3 "register_operand" "")
7685 (umod:DI (match_dup 1) (match_dup 2)))
7686 (clobber (reg:CC FLAGS_REG))]
7687 "TARGET_64BIT && reload_completed"
7688 [(set (match_dup 3) (const_int 0))
7689 (parallel [(set (match_dup 0)
7690 (udiv:DI (match_dup 1) (match_dup 2)))
7691 (set (match_dup 3)
7692 (umod:DI (match_dup 1) (match_dup 2)))
7693 (use (match_dup 3))
7694 (clobber (reg:CC FLAGS_REG))])]
7695 "")
7696
7697 (define_insn "udivmodsi4"
7698 [(set (match_operand:SI 0 "register_operand" "=a")
7699 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7700 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7701 (set (match_operand:SI 3 "register_operand" "=&d")
7702 (umod:SI (match_dup 1) (match_dup 2)))
7703 (clobber (reg:CC FLAGS_REG))]
7704 ""
7705 "xor{l}\t%3, %3\;div{l}\t%2"
7706 [(set_attr "type" "multi")
7707 (set_attr "length_immediate" "0")
7708 (set_attr "mode" "SI")])
7709
7710 (define_insn "*udivmodsi4_noext"
7711 [(set (match_operand:SI 0 "register_operand" "=a")
7712 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7713 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7714 (set (match_operand:SI 3 "register_operand" "=d")
7715 (umod:SI (match_dup 1) (match_dup 2)))
7716 (use (match_dup 3))
7717 (clobber (reg:CC FLAGS_REG))]
7718 ""
7719 "div{l}\t%2"
7720 [(set_attr "type" "idiv")
7721 (set_attr "mode" "SI")])
7722
7723 (define_split
7724 [(set (match_operand:SI 0 "register_operand" "")
7725 (udiv:SI (match_operand:SI 1 "register_operand" "")
7726 (match_operand:SI 2 "nonimmediate_operand" "")))
7727 (set (match_operand:SI 3 "register_operand" "")
7728 (umod:SI (match_dup 1) (match_dup 2)))
7729 (clobber (reg:CC FLAGS_REG))]
7730 "reload_completed"
7731 [(set (match_dup 3) (const_int 0))
7732 (parallel [(set (match_dup 0)
7733 (udiv:SI (match_dup 1) (match_dup 2)))
7734 (set (match_dup 3)
7735 (umod:SI (match_dup 1) (match_dup 2)))
7736 (use (match_dup 3))
7737 (clobber (reg:CC FLAGS_REG))])]
7738 "")
7739
7740 (define_expand "udivmodhi4"
7741 [(set (match_dup 4) (const_int 0))
7742 (parallel [(set (match_operand:HI 0 "register_operand" "")
7743 (udiv:HI (match_operand:HI 1 "register_operand" "")
7744 (match_operand:HI 2 "nonimmediate_operand" "")))
7745 (set (match_operand:HI 3 "register_operand" "")
7746 (umod:HI (match_dup 1) (match_dup 2)))
7747 (use (match_dup 4))
7748 (clobber (reg:CC FLAGS_REG))])]
7749 "TARGET_HIMODE_MATH"
7750 "operands[4] = gen_reg_rtx (HImode);")
7751
7752 (define_insn "*udivmodhi_noext"
7753 [(set (match_operand:HI 0 "register_operand" "=a")
7754 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7755 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7756 (set (match_operand:HI 3 "register_operand" "=d")
7757 (umod:HI (match_dup 1) (match_dup 2)))
7758 (use (match_operand:HI 4 "register_operand" "3"))
7759 (clobber (reg:CC FLAGS_REG))]
7760 ""
7761 "div{w}\t%2"
7762 [(set_attr "type" "idiv")
7763 (set_attr "mode" "HI")])
7764
7765 ;; We cannot use div/idiv for double division, because it causes
7766 ;; "division by zero" on the overflow and that's not what we expect
7767 ;; from truncate. Because true (non truncating) double division is
7768 ;; never generated, we can't create this insn anyway.
7769 ;
7770 ;(define_insn ""
7771 ; [(set (match_operand:SI 0 "register_operand" "=a")
7772 ; (truncate:SI
7773 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7774 ; (zero_extend:DI
7775 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7776 ; (set (match_operand:SI 3 "register_operand" "=d")
7777 ; (truncate:SI
7778 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7779 ; (clobber (reg:CC FLAGS_REG))]
7780 ; ""
7781 ; "div{l}\t{%2, %0|%0, %2}"
7782 ; [(set_attr "type" "idiv")])
7783 \f
7784 ;;- Logical AND instructions
7785
7786 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7787 ;; Note that this excludes ah.
7788
7789 (define_insn "*testdi_1_rex64"
7790 [(set (reg FLAGS_REG)
7791 (compare
7792 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7793 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7794 (const_int 0)))]
7795 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7796 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7797 "@
7798 test{l}\t{%k1, %k0|%k0, %k1}
7799 test{l}\t{%k1, %k0|%k0, %k1}
7800 test{q}\t{%1, %0|%0, %1}
7801 test{q}\t{%1, %0|%0, %1}
7802 test{q}\t{%1, %0|%0, %1}"
7803 [(set_attr "type" "test")
7804 (set_attr "modrm" "0,1,0,1,1")
7805 (set_attr "mode" "SI,SI,DI,DI,DI")
7806 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7807
7808 (define_insn "testsi_1"
7809 [(set (reg FLAGS_REG)
7810 (compare
7811 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7812 (match_operand:SI 1 "general_operand" "in,in,rin"))
7813 (const_int 0)))]
7814 "ix86_match_ccmode (insn, CCNOmode)
7815 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7816 "test{l}\t{%1, %0|%0, %1}"
7817 [(set_attr "type" "test")
7818 (set_attr "modrm" "0,1,1")
7819 (set_attr "mode" "SI")
7820 (set_attr "pent_pair" "uv,np,uv")])
7821
7822 (define_expand "testsi_ccno_1"
7823 [(set (reg:CCNO FLAGS_REG)
7824 (compare:CCNO
7825 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7826 (match_operand:SI 1 "nonmemory_operand" ""))
7827 (const_int 0)))]
7828 ""
7829 "")
7830
7831 (define_insn "*testhi_1"
7832 [(set (reg FLAGS_REG)
7833 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7834 (match_operand:HI 1 "general_operand" "n,n,rn"))
7835 (const_int 0)))]
7836 "ix86_match_ccmode (insn, CCNOmode)
7837 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7838 "test{w}\t{%1, %0|%0, %1}"
7839 [(set_attr "type" "test")
7840 (set_attr "modrm" "0,1,1")
7841 (set_attr "mode" "HI")
7842 (set_attr "pent_pair" "uv,np,uv")])
7843
7844 (define_expand "testqi_ccz_1"
7845 [(set (reg:CCZ FLAGS_REG)
7846 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7847 (match_operand:QI 1 "nonmemory_operand" ""))
7848 (const_int 0)))]
7849 ""
7850 "")
7851
7852 (define_insn "*testqi_1_maybe_si"
7853 [(set (reg FLAGS_REG)
7854 (compare
7855 (and:QI
7856 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7857 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7858 (const_int 0)))]
7859 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7860 && ix86_match_ccmode (insn,
7861 GET_CODE (operands[1]) == CONST_INT
7862 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7863 {
7864 if (which_alternative == 3)
7865 {
7866 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7867 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7868 return "test{l}\t{%1, %k0|%k0, %1}";
7869 }
7870 return "test{b}\t{%1, %0|%0, %1}";
7871 }
7872 [(set_attr "type" "test")
7873 (set_attr "modrm" "0,1,1,1")
7874 (set_attr "mode" "QI,QI,QI,SI")
7875 (set_attr "pent_pair" "uv,np,uv,np")])
7876
7877 (define_insn "*testqi_1"
7878 [(set (reg FLAGS_REG)
7879 (compare
7880 (and:QI
7881 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7882 (match_operand:QI 1 "general_operand" "n,n,qn"))
7883 (const_int 0)))]
7884 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7885 && ix86_match_ccmode (insn, CCNOmode)"
7886 "test{b}\t{%1, %0|%0, %1}"
7887 [(set_attr "type" "test")
7888 (set_attr "modrm" "0,1,1")
7889 (set_attr "mode" "QI")
7890 (set_attr "pent_pair" "uv,np,uv")])
7891
7892 (define_expand "testqi_ext_ccno_0"
7893 [(set (reg:CCNO FLAGS_REG)
7894 (compare:CCNO
7895 (and:SI
7896 (zero_extract:SI
7897 (match_operand 0 "ext_register_operand" "")
7898 (const_int 8)
7899 (const_int 8))
7900 (match_operand 1 "const_int_operand" ""))
7901 (const_int 0)))]
7902 ""
7903 "")
7904
7905 (define_insn "*testqi_ext_0"
7906 [(set (reg FLAGS_REG)
7907 (compare
7908 (and:SI
7909 (zero_extract:SI
7910 (match_operand 0 "ext_register_operand" "Q")
7911 (const_int 8)
7912 (const_int 8))
7913 (match_operand 1 "const_int_operand" "n"))
7914 (const_int 0)))]
7915 "ix86_match_ccmode (insn, CCNOmode)"
7916 "test{b}\t{%1, %h0|%h0, %1}"
7917 [(set_attr "type" "test")
7918 (set_attr "mode" "QI")
7919 (set_attr "length_immediate" "1")
7920 (set_attr "pent_pair" "np")])
7921
7922 (define_insn "*testqi_ext_1"
7923 [(set (reg FLAGS_REG)
7924 (compare
7925 (and:SI
7926 (zero_extract:SI
7927 (match_operand 0 "ext_register_operand" "Q")
7928 (const_int 8)
7929 (const_int 8))
7930 (zero_extend:SI
7931 (match_operand:QI 1 "general_operand" "Qm")))
7932 (const_int 0)))]
7933 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7934 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7935 "test{b}\t{%1, %h0|%h0, %1}"
7936 [(set_attr "type" "test")
7937 (set_attr "mode" "QI")])
7938
7939 (define_insn "*testqi_ext_1_rex64"
7940 [(set (reg FLAGS_REG)
7941 (compare
7942 (and:SI
7943 (zero_extract:SI
7944 (match_operand 0 "ext_register_operand" "Q")
7945 (const_int 8)
7946 (const_int 8))
7947 (zero_extend:SI
7948 (match_operand:QI 1 "register_operand" "Q")))
7949 (const_int 0)))]
7950 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7951 "test{b}\t{%1, %h0|%h0, %1}"
7952 [(set_attr "type" "test")
7953 (set_attr "mode" "QI")])
7954
7955 (define_insn "*testqi_ext_2"
7956 [(set (reg FLAGS_REG)
7957 (compare
7958 (and:SI
7959 (zero_extract:SI
7960 (match_operand 0 "ext_register_operand" "Q")
7961 (const_int 8)
7962 (const_int 8))
7963 (zero_extract:SI
7964 (match_operand 1 "ext_register_operand" "Q")
7965 (const_int 8)
7966 (const_int 8)))
7967 (const_int 0)))]
7968 "ix86_match_ccmode (insn, CCNOmode)"
7969 "test{b}\t{%h1, %h0|%h0, %h1}"
7970 [(set_attr "type" "test")
7971 (set_attr "mode" "QI")])
7972
7973 ;; Combine likes to form bit extractions for some tests. Humor it.
7974 (define_insn "*testqi_ext_3"
7975 [(set (reg FLAGS_REG)
7976 (compare (zero_extract:SI
7977 (match_operand 0 "nonimmediate_operand" "rm")
7978 (match_operand:SI 1 "const_int_operand" "")
7979 (match_operand:SI 2 "const_int_operand" ""))
7980 (const_int 0)))]
7981 "ix86_match_ccmode (insn, CCNOmode)
7982 && (GET_MODE (operands[0]) == SImode
7983 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7984 || GET_MODE (operands[0]) == HImode
7985 || GET_MODE (operands[0]) == QImode)"
7986 "#")
7987
7988 (define_insn "*testqi_ext_3_rex64"
7989 [(set (reg FLAGS_REG)
7990 (compare (zero_extract:DI
7991 (match_operand 0 "nonimmediate_operand" "rm")
7992 (match_operand:DI 1 "const_int_operand" "")
7993 (match_operand:DI 2 "const_int_operand" ""))
7994 (const_int 0)))]
7995 "TARGET_64BIT
7996 && ix86_match_ccmode (insn, CCNOmode)
7997 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7998 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7999 /* Ensure that resulting mask is zero or sign extended operand. */
8000 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8001 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8002 && INTVAL (operands[1]) > 32))
8003 && (GET_MODE (operands[0]) == SImode
8004 || GET_MODE (operands[0]) == DImode
8005 || GET_MODE (operands[0]) == HImode
8006 || GET_MODE (operands[0]) == QImode)"
8007 "#")
8008
8009 (define_split
8010 [(set (match_operand 0 "flags_reg_operand" "")
8011 (match_operator 1 "compare_operator"
8012 [(zero_extract
8013 (match_operand 2 "nonimmediate_operand" "")
8014 (match_operand 3 "const_int_operand" "")
8015 (match_operand 4 "const_int_operand" ""))
8016 (const_int 0)]))]
8017 "ix86_match_ccmode (insn, CCNOmode)"
8018 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8019 {
8020 rtx val = operands[2];
8021 HOST_WIDE_INT len = INTVAL (operands[3]);
8022 HOST_WIDE_INT pos = INTVAL (operands[4]);
8023 HOST_WIDE_INT mask;
8024 enum machine_mode mode, submode;
8025
8026 mode = GET_MODE (val);
8027 if (GET_CODE (val) == MEM)
8028 {
8029 /* ??? Combine likes to put non-volatile mem extractions in QImode
8030 no matter the size of the test. So find a mode that works. */
8031 if (! MEM_VOLATILE_P (val))
8032 {
8033 mode = smallest_mode_for_size (pos + len, MODE_INT);
8034 val = adjust_address (val, mode, 0);
8035 }
8036 }
8037 else if (GET_CODE (val) == SUBREG
8038 && (submode = GET_MODE (SUBREG_REG (val)),
8039 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8040 && pos + len <= GET_MODE_BITSIZE (submode))
8041 {
8042 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8043 mode = submode;
8044 val = SUBREG_REG (val);
8045 }
8046 else if (mode == HImode && pos + len <= 8)
8047 {
8048 /* Small HImode tests can be converted to QImode. */
8049 mode = QImode;
8050 val = gen_lowpart (QImode, val);
8051 }
8052
8053 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8054 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8055
8056 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8057 })
8058
8059 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8060 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8061 ;; this is relatively important trick.
8062 ;; Do the conversion only post-reload to avoid limiting of the register class
8063 ;; to QI regs.
8064 (define_split
8065 [(set (match_operand 0 "flags_reg_operand" "")
8066 (match_operator 1 "compare_operator"
8067 [(and (match_operand 2 "register_operand" "")
8068 (match_operand 3 "const_int_operand" ""))
8069 (const_int 0)]))]
8070 "reload_completed
8071 && QI_REG_P (operands[2])
8072 && GET_MODE (operands[2]) != QImode
8073 && ((ix86_match_ccmode (insn, CCZmode)
8074 && !(INTVAL (operands[3]) & ~(255 << 8)))
8075 || (ix86_match_ccmode (insn, CCNOmode)
8076 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8077 [(set (match_dup 0)
8078 (match_op_dup 1
8079 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8080 (match_dup 3))
8081 (const_int 0)]))]
8082 "operands[2] = gen_lowpart (SImode, operands[2]);
8083 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8084
8085 (define_split
8086 [(set (match_operand 0 "flags_reg_operand" "")
8087 (match_operator 1 "compare_operator"
8088 [(and (match_operand 2 "nonimmediate_operand" "")
8089 (match_operand 3 "const_int_operand" ""))
8090 (const_int 0)]))]
8091 "reload_completed
8092 && GET_MODE (operands[2]) != QImode
8093 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8094 && ((ix86_match_ccmode (insn, CCZmode)
8095 && !(INTVAL (operands[3]) & ~255))
8096 || (ix86_match_ccmode (insn, CCNOmode)
8097 && !(INTVAL (operands[3]) & ~127)))"
8098 [(set (match_dup 0)
8099 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8100 (const_int 0)]))]
8101 "operands[2] = gen_lowpart (QImode, operands[2]);
8102 operands[3] = gen_lowpart (QImode, operands[3]);")
8103
8104
8105 ;; %%% This used to optimize known byte-wide and operations to memory,
8106 ;; and sometimes to QImode registers. If this is considered useful,
8107 ;; it should be done with splitters.
8108
8109 (define_expand "anddi3"
8110 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8111 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8112 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8113 (clobber (reg:CC FLAGS_REG))]
8114 "TARGET_64BIT"
8115 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8116
8117 (define_insn "*anddi_1_rex64"
8118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8119 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8120 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8121 (clobber (reg:CC FLAGS_REG))]
8122 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8123 {
8124 switch (get_attr_type (insn))
8125 {
8126 case TYPE_IMOVX:
8127 {
8128 enum machine_mode mode;
8129
8130 if (GET_CODE (operands[2]) != CONST_INT)
8131 abort ();
8132 if (INTVAL (operands[2]) == 0xff)
8133 mode = QImode;
8134 else if (INTVAL (operands[2]) == 0xffff)
8135 mode = HImode;
8136 else
8137 abort ();
8138
8139 operands[1] = gen_lowpart (mode, operands[1]);
8140 if (mode == QImode)
8141 return "movz{bq|x}\t{%1,%0|%0, %1}";
8142 else
8143 return "movz{wq|x}\t{%1,%0|%0, %1}";
8144 }
8145
8146 default:
8147 if (! rtx_equal_p (operands[0], operands[1]))
8148 abort ();
8149 if (get_attr_mode (insn) == MODE_SI)
8150 return "and{l}\t{%k2, %k0|%k0, %k2}";
8151 else
8152 return "and{q}\t{%2, %0|%0, %2}";
8153 }
8154 }
8155 [(set_attr "type" "alu,alu,alu,imovx")
8156 (set_attr "length_immediate" "*,*,*,0")
8157 (set_attr "mode" "SI,DI,DI,DI")])
8158
8159 (define_insn "*anddi_2"
8160 [(set (reg FLAGS_REG)
8161 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8162 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8163 (const_int 0)))
8164 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8165 (and:DI (match_dup 1) (match_dup 2)))]
8166 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8167 && ix86_binary_operator_ok (AND, DImode, operands)"
8168 "@
8169 and{l}\t{%k2, %k0|%k0, %k2}
8170 and{q}\t{%2, %0|%0, %2}
8171 and{q}\t{%2, %0|%0, %2}"
8172 [(set_attr "type" "alu")
8173 (set_attr "mode" "SI,DI,DI")])
8174
8175 (define_expand "andsi3"
8176 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8177 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8178 (match_operand:SI 2 "general_operand" "")))
8179 (clobber (reg:CC FLAGS_REG))]
8180 ""
8181 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8182
8183 (define_insn "*andsi_1"
8184 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8185 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8186 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8187 (clobber (reg:CC FLAGS_REG))]
8188 "ix86_binary_operator_ok (AND, SImode, operands)"
8189 {
8190 switch (get_attr_type (insn))
8191 {
8192 case TYPE_IMOVX:
8193 {
8194 enum machine_mode mode;
8195
8196 if (GET_CODE (operands[2]) != CONST_INT)
8197 abort ();
8198 if (INTVAL (operands[2]) == 0xff)
8199 mode = QImode;
8200 else if (INTVAL (operands[2]) == 0xffff)
8201 mode = HImode;
8202 else
8203 abort ();
8204
8205 operands[1] = gen_lowpart (mode, operands[1]);
8206 if (mode == QImode)
8207 return "movz{bl|x}\t{%1,%0|%0, %1}";
8208 else
8209 return "movz{wl|x}\t{%1,%0|%0, %1}";
8210 }
8211
8212 default:
8213 if (! rtx_equal_p (operands[0], operands[1]))
8214 abort ();
8215 return "and{l}\t{%2, %0|%0, %2}";
8216 }
8217 }
8218 [(set_attr "type" "alu,alu,imovx")
8219 (set_attr "length_immediate" "*,*,0")
8220 (set_attr "mode" "SI")])
8221
8222 (define_split
8223 [(set (match_operand 0 "register_operand" "")
8224 (and (match_dup 0)
8225 (const_int -65536)))
8226 (clobber (reg:CC FLAGS_REG))]
8227 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8228 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8229 "operands[1] = gen_lowpart (HImode, operands[0]);")
8230
8231 (define_split
8232 [(set (match_operand 0 "ext_register_operand" "")
8233 (and (match_dup 0)
8234 (const_int -256)))
8235 (clobber (reg:CC FLAGS_REG))]
8236 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8237 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8238 "operands[1] = gen_lowpart (QImode, operands[0]);")
8239
8240 (define_split
8241 [(set (match_operand 0 "ext_register_operand" "")
8242 (and (match_dup 0)
8243 (const_int -65281)))
8244 (clobber (reg:CC FLAGS_REG))]
8245 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8246 [(parallel [(set (zero_extract:SI (match_dup 0)
8247 (const_int 8)
8248 (const_int 8))
8249 (xor:SI
8250 (zero_extract:SI (match_dup 0)
8251 (const_int 8)
8252 (const_int 8))
8253 (zero_extract:SI (match_dup 0)
8254 (const_int 8)
8255 (const_int 8))))
8256 (clobber (reg:CC FLAGS_REG))])]
8257 "operands[0] = gen_lowpart (SImode, operands[0]);")
8258
8259 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8260 (define_insn "*andsi_1_zext"
8261 [(set (match_operand:DI 0 "register_operand" "=r")
8262 (zero_extend:DI
8263 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8264 (match_operand:SI 2 "general_operand" "rim"))))
8265 (clobber (reg:CC FLAGS_REG))]
8266 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8267 "and{l}\t{%2, %k0|%k0, %2}"
8268 [(set_attr "type" "alu")
8269 (set_attr "mode" "SI")])
8270
8271 (define_insn "*andsi_2"
8272 [(set (reg FLAGS_REG)
8273 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8274 (match_operand:SI 2 "general_operand" "rim,ri"))
8275 (const_int 0)))
8276 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8277 (and:SI (match_dup 1) (match_dup 2)))]
8278 "ix86_match_ccmode (insn, CCNOmode)
8279 && ix86_binary_operator_ok (AND, SImode, operands)"
8280 "and{l}\t{%2, %0|%0, %2}"
8281 [(set_attr "type" "alu")
8282 (set_attr "mode" "SI")])
8283
8284 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8285 (define_insn "*andsi_2_zext"
8286 [(set (reg FLAGS_REG)
8287 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8288 (match_operand:SI 2 "general_operand" "rim"))
8289 (const_int 0)))
8290 (set (match_operand:DI 0 "register_operand" "=r")
8291 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8292 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8293 && ix86_binary_operator_ok (AND, SImode, operands)"
8294 "and{l}\t{%2, %k0|%k0, %2}"
8295 [(set_attr "type" "alu")
8296 (set_attr "mode" "SI")])
8297
8298 (define_expand "andhi3"
8299 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8300 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8301 (match_operand:HI 2 "general_operand" "")))
8302 (clobber (reg:CC FLAGS_REG))]
8303 "TARGET_HIMODE_MATH"
8304 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8305
8306 (define_insn "*andhi_1"
8307 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8308 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8309 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8310 (clobber (reg:CC FLAGS_REG))]
8311 "ix86_binary_operator_ok (AND, HImode, operands)"
8312 {
8313 switch (get_attr_type (insn))
8314 {
8315 case TYPE_IMOVX:
8316 if (GET_CODE (operands[2]) != CONST_INT)
8317 abort ();
8318 if (INTVAL (operands[2]) == 0xff)
8319 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8320 abort ();
8321
8322 default:
8323 if (! rtx_equal_p (operands[0], operands[1]))
8324 abort ();
8325
8326 return "and{w}\t{%2, %0|%0, %2}";
8327 }
8328 }
8329 [(set_attr "type" "alu,alu,imovx")
8330 (set_attr "length_immediate" "*,*,0")
8331 (set_attr "mode" "HI,HI,SI")])
8332
8333 (define_insn "*andhi_2"
8334 [(set (reg FLAGS_REG)
8335 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8336 (match_operand:HI 2 "general_operand" "rim,ri"))
8337 (const_int 0)))
8338 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8339 (and:HI (match_dup 1) (match_dup 2)))]
8340 "ix86_match_ccmode (insn, CCNOmode)
8341 && ix86_binary_operator_ok (AND, HImode, operands)"
8342 "and{w}\t{%2, %0|%0, %2}"
8343 [(set_attr "type" "alu")
8344 (set_attr "mode" "HI")])
8345
8346 (define_expand "andqi3"
8347 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8348 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8349 (match_operand:QI 2 "general_operand" "")))
8350 (clobber (reg:CC FLAGS_REG))]
8351 "TARGET_QIMODE_MATH"
8352 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8353
8354 ;; %%% Potential partial reg stall on alternative 2. What to do?
8355 (define_insn "*andqi_1"
8356 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8357 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8358 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8359 (clobber (reg:CC FLAGS_REG))]
8360 "ix86_binary_operator_ok (AND, QImode, operands)"
8361 "@
8362 and{b}\t{%2, %0|%0, %2}
8363 and{b}\t{%2, %0|%0, %2}
8364 and{l}\t{%k2, %k0|%k0, %k2}"
8365 [(set_attr "type" "alu")
8366 (set_attr "mode" "QI,QI,SI")])
8367
8368 (define_insn "*andqi_1_slp"
8369 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8370 (and:QI (match_dup 0)
8371 (match_operand:QI 1 "general_operand" "qi,qmi")))
8372 (clobber (reg:CC FLAGS_REG))]
8373 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8374 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8375 "and{b}\t{%1, %0|%0, %1}"
8376 [(set_attr "type" "alu1")
8377 (set_attr "mode" "QI")])
8378
8379 (define_insn "*andqi_2_maybe_si"
8380 [(set (reg FLAGS_REG)
8381 (compare (and:QI
8382 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8383 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8384 (const_int 0)))
8385 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8386 (and:QI (match_dup 1) (match_dup 2)))]
8387 "ix86_binary_operator_ok (AND, QImode, operands)
8388 && ix86_match_ccmode (insn,
8389 GET_CODE (operands[2]) == CONST_INT
8390 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8391 {
8392 if (which_alternative == 2)
8393 {
8394 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8395 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8396 return "and{l}\t{%2, %k0|%k0, %2}";
8397 }
8398 return "and{b}\t{%2, %0|%0, %2}";
8399 }
8400 [(set_attr "type" "alu")
8401 (set_attr "mode" "QI,QI,SI")])
8402
8403 (define_insn "*andqi_2"
8404 [(set (reg FLAGS_REG)
8405 (compare (and:QI
8406 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8407 (match_operand:QI 2 "general_operand" "qim,qi"))
8408 (const_int 0)))
8409 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8410 (and:QI (match_dup 1) (match_dup 2)))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && ix86_binary_operator_ok (AND, QImode, operands)"
8413 "and{b}\t{%2, %0|%0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "QI")])
8416
8417 (define_insn "*andqi_2_slp"
8418 [(set (reg FLAGS_REG)
8419 (compare (and:QI
8420 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8421 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8422 (const_int 0)))
8423 (set (strict_low_part (match_dup 0))
8424 (and:QI (match_dup 0) (match_dup 1)))]
8425 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8426 && ix86_match_ccmode (insn, CCNOmode)
8427 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8428 "and{b}\t{%1, %0|%0, %1}"
8429 [(set_attr "type" "alu1")
8430 (set_attr "mode" "QI")])
8431
8432 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8433 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8434 ;; for a QImode operand, which of course failed.
8435
8436 (define_insn "andqi_ext_0"
8437 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8438 (const_int 8)
8439 (const_int 8))
8440 (and:SI
8441 (zero_extract:SI
8442 (match_operand 1 "ext_register_operand" "0")
8443 (const_int 8)
8444 (const_int 8))
8445 (match_operand 2 "const_int_operand" "n")))
8446 (clobber (reg:CC FLAGS_REG))]
8447 ""
8448 "and{b}\t{%2, %h0|%h0, %2}"
8449 [(set_attr "type" "alu")
8450 (set_attr "length_immediate" "1")
8451 (set_attr "mode" "QI")])
8452
8453 ;; Generated by peephole translating test to and. This shows up
8454 ;; often in fp comparisons.
8455
8456 (define_insn "*andqi_ext_0_cc"
8457 [(set (reg FLAGS_REG)
8458 (compare
8459 (and:SI
8460 (zero_extract:SI
8461 (match_operand 1 "ext_register_operand" "0")
8462 (const_int 8)
8463 (const_int 8))
8464 (match_operand 2 "const_int_operand" "n"))
8465 (const_int 0)))
8466 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8467 (const_int 8)
8468 (const_int 8))
8469 (and:SI
8470 (zero_extract:SI
8471 (match_dup 1)
8472 (const_int 8)
8473 (const_int 8))
8474 (match_dup 2)))]
8475 "ix86_match_ccmode (insn, CCNOmode)"
8476 "and{b}\t{%2, %h0|%h0, %2}"
8477 [(set_attr "type" "alu")
8478 (set_attr "length_immediate" "1")
8479 (set_attr "mode" "QI")])
8480
8481 (define_insn "*andqi_ext_1"
8482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8483 (const_int 8)
8484 (const_int 8))
8485 (and:SI
8486 (zero_extract:SI
8487 (match_operand 1 "ext_register_operand" "0")
8488 (const_int 8)
8489 (const_int 8))
8490 (zero_extend:SI
8491 (match_operand:QI 2 "general_operand" "Qm"))))
8492 (clobber (reg:CC FLAGS_REG))]
8493 "!TARGET_64BIT"
8494 "and{b}\t{%2, %h0|%h0, %2}"
8495 [(set_attr "type" "alu")
8496 (set_attr "length_immediate" "0")
8497 (set_attr "mode" "QI")])
8498
8499 (define_insn "*andqi_ext_1_rex64"
8500 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8501 (const_int 8)
8502 (const_int 8))
8503 (and:SI
8504 (zero_extract:SI
8505 (match_operand 1 "ext_register_operand" "0")
8506 (const_int 8)
8507 (const_int 8))
8508 (zero_extend:SI
8509 (match_operand 2 "ext_register_operand" "Q"))))
8510 (clobber (reg:CC FLAGS_REG))]
8511 "TARGET_64BIT"
8512 "and{b}\t{%2, %h0|%h0, %2}"
8513 [(set_attr "type" "alu")
8514 (set_attr "length_immediate" "0")
8515 (set_attr "mode" "QI")])
8516
8517 (define_insn "*andqi_ext_2"
8518 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8519 (const_int 8)
8520 (const_int 8))
8521 (and:SI
8522 (zero_extract:SI
8523 (match_operand 1 "ext_register_operand" "%0")
8524 (const_int 8)
8525 (const_int 8))
8526 (zero_extract:SI
8527 (match_operand 2 "ext_register_operand" "Q")
8528 (const_int 8)
8529 (const_int 8))))
8530 (clobber (reg:CC FLAGS_REG))]
8531 ""
8532 "and{b}\t{%h2, %h0|%h0, %h2}"
8533 [(set_attr "type" "alu")
8534 (set_attr "length_immediate" "0")
8535 (set_attr "mode" "QI")])
8536
8537 ;; Convert wide AND instructions with immediate operand to shorter QImode
8538 ;; equivalents when possible.
8539 ;; Don't do the splitting with memory operands, since it introduces risk
8540 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8541 ;; for size, but that can (should?) be handled by generic code instead.
8542 (define_split
8543 [(set (match_operand 0 "register_operand" "")
8544 (and (match_operand 1 "register_operand" "")
8545 (match_operand 2 "const_int_operand" "")))
8546 (clobber (reg:CC FLAGS_REG))]
8547 "reload_completed
8548 && QI_REG_P (operands[0])
8549 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8550 && !(~INTVAL (operands[2]) & ~(255 << 8))
8551 && GET_MODE (operands[0]) != QImode"
8552 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8553 (and:SI (zero_extract:SI (match_dup 1)
8554 (const_int 8) (const_int 8))
8555 (match_dup 2)))
8556 (clobber (reg:CC FLAGS_REG))])]
8557 "operands[0] = gen_lowpart (SImode, operands[0]);
8558 operands[1] = gen_lowpart (SImode, operands[1]);
8559 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8560
8561 ;; Since AND can be encoded with sign extended immediate, this is only
8562 ;; profitable when 7th bit is not set.
8563 (define_split
8564 [(set (match_operand 0 "register_operand" "")
8565 (and (match_operand 1 "general_operand" "")
8566 (match_operand 2 "const_int_operand" "")))
8567 (clobber (reg:CC FLAGS_REG))]
8568 "reload_completed
8569 && ANY_QI_REG_P (operands[0])
8570 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8571 && !(~INTVAL (operands[2]) & ~255)
8572 && !(INTVAL (operands[2]) & 128)
8573 && GET_MODE (operands[0]) != QImode"
8574 [(parallel [(set (strict_low_part (match_dup 0))
8575 (and:QI (match_dup 1)
8576 (match_dup 2)))
8577 (clobber (reg:CC FLAGS_REG))])]
8578 "operands[0] = gen_lowpart (QImode, operands[0]);
8579 operands[1] = gen_lowpart (QImode, operands[1]);
8580 operands[2] = gen_lowpart (QImode, operands[2]);")
8581 \f
8582 ;; Logical inclusive OR instructions
8583
8584 ;; %%% This used to optimize known byte-wide and operations to memory.
8585 ;; If this is considered useful, it should be done with splitters.
8586
8587 (define_expand "iordi3"
8588 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8589 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8590 (match_operand:DI 2 "x86_64_general_operand" "")))
8591 (clobber (reg:CC FLAGS_REG))]
8592 "TARGET_64BIT"
8593 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8594
8595 (define_insn "*iordi_1_rex64"
8596 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8597 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8598 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8599 (clobber (reg:CC FLAGS_REG))]
8600 "TARGET_64BIT
8601 && ix86_binary_operator_ok (IOR, DImode, operands)"
8602 "or{q}\t{%2, %0|%0, %2}"
8603 [(set_attr "type" "alu")
8604 (set_attr "mode" "DI")])
8605
8606 (define_insn "*iordi_2_rex64"
8607 [(set (reg FLAGS_REG)
8608 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8609 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8610 (const_int 0)))
8611 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8612 (ior:DI (match_dup 1) (match_dup 2)))]
8613 "TARGET_64BIT
8614 && ix86_match_ccmode (insn, CCNOmode)
8615 && ix86_binary_operator_ok (IOR, DImode, operands)"
8616 "or{q}\t{%2, %0|%0, %2}"
8617 [(set_attr "type" "alu")
8618 (set_attr "mode" "DI")])
8619
8620 (define_insn "*iordi_3_rex64"
8621 [(set (reg FLAGS_REG)
8622 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8623 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8624 (const_int 0)))
8625 (clobber (match_scratch:DI 0 "=r"))]
8626 "TARGET_64BIT
8627 && ix86_match_ccmode (insn, CCNOmode)
8628 && ix86_binary_operator_ok (IOR, DImode, operands)"
8629 "or{q}\t{%2, %0|%0, %2}"
8630 [(set_attr "type" "alu")
8631 (set_attr "mode" "DI")])
8632
8633
8634 (define_expand "iorsi3"
8635 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8636 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8637 (match_operand:SI 2 "general_operand" "")))
8638 (clobber (reg:CC FLAGS_REG))]
8639 ""
8640 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8641
8642 (define_insn "*iorsi_1"
8643 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8644 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8645 (match_operand:SI 2 "general_operand" "ri,rmi")))
8646 (clobber (reg:CC FLAGS_REG))]
8647 "ix86_binary_operator_ok (IOR, SImode, operands)"
8648 "or{l}\t{%2, %0|%0, %2}"
8649 [(set_attr "type" "alu")
8650 (set_attr "mode" "SI")])
8651
8652 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8653 (define_insn "*iorsi_1_zext"
8654 [(set (match_operand:DI 0 "register_operand" "=rm")
8655 (zero_extend:DI
8656 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8657 (match_operand:SI 2 "general_operand" "rim"))))
8658 (clobber (reg:CC FLAGS_REG))]
8659 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8660 "or{l}\t{%2, %k0|%k0, %2}"
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
8663
8664 (define_insn "*iorsi_1_zext_imm"
8665 [(set (match_operand:DI 0 "register_operand" "=rm")
8666 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8667 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8668 (clobber (reg:CC FLAGS_REG))]
8669 "TARGET_64BIT"
8670 "or{l}\t{%2, %k0|%k0, %2}"
8671 [(set_attr "type" "alu")
8672 (set_attr "mode" "SI")])
8673
8674 (define_insn "*iorsi_2"
8675 [(set (reg FLAGS_REG)
8676 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8677 (match_operand:SI 2 "general_operand" "rim,ri"))
8678 (const_int 0)))
8679 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8680 (ior:SI (match_dup 1) (match_dup 2)))]
8681 "ix86_match_ccmode (insn, CCNOmode)
8682 && ix86_binary_operator_ok (IOR, SImode, operands)"
8683 "or{l}\t{%2, %0|%0, %2}"
8684 [(set_attr "type" "alu")
8685 (set_attr "mode" "SI")])
8686
8687 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8688 ;; ??? Special case for immediate operand is missing - it is tricky.
8689 (define_insn "*iorsi_2_zext"
8690 [(set (reg FLAGS_REG)
8691 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8692 (match_operand:SI 2 "general_operand" "rim"))
8693 (const_int 0)))
8694 (set (match_operand:DI 0 "register_operand" "=r")
8695 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8696 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8697 && ix86_binary_operator_ok (IOR, SImode, operands)"
8698 "or{l}\t{%2, %k0|%k0, %2}"
8699 [(set_attr "type" "alu")
8700 (set_attr "mode" "SI")])
8701
8702 (define_insn "*iorsi_2_zext_imm"
8703 [(set (reg FLAGS_REG)
8704 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8705 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8706 (const_int 0)))
8707 (set (match_operand:DI 0 "register_operand" "=r")
8708 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8709 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8710 && ix86_binary_operator_ok (IOR, SImode, operands)"
8711 "or{l}\t{%2, %k0|%k0, %2}"
8712 [(set_attr "type" "alu")
8713 (set_attr "mode" "SI")])
8714
8715 (define_insn "*iorsi_3"
8716 [(set (reg FLAGS_REG)
8717 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8718 (match_operand:SI 2 "general_operand" "rim"))
8719 (const_int 0)))
8720 (clobber (match_scratch:SI 0 "=r"))]
8721 "ix86_match_ccmode (insn, CCNOmode)
8722 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8723 "or{l}\t{%2, %0|%0, %2}"
8724 [(set_attr "type" "alu")
8725 (set_attr "mode" "SI")])
8726
8727 (define_expand "iorhi3"
8728 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8729 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8730 (match_operand:HI 2 "general_operand" "")))
8731 (clobber (reg:CC FLAGS_REG))]
8732 "TARGET_HIMODE_MATH"
8733 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8734
8735 (define_insn "*iorhi_1"
8736 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8737 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8738 (match_operand:HI 2 "general_operand" "rmi,ri")))
8739 (clobber (reg:CC FLAGS_REG))]
8740 "ix86_binary_operator_ok (IOR, HImode, operands)"
8741 "or{w}\t{%2, %0|%0, %2}"
8742 [(set_attr "type" "alu")
8743 (set_attr "mode" "HI")])
8744
8745 (define_insn "*iorhi_2"
8746 [(set (reg FLAGS_REG)
8747 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8748 (match_operand:HI 2 "general_operand" "rim,ri"))
8749 (const_int 0)))
8750 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8751 (ior:HI (match_dup 1) (match_dup 2)))]
8752 "ix86_match_ccmode (insn, CCNOmode)
8753 && ix86_binary_operator_ok (IOR, HImode, operands)"
8754 "or{w}\t{%2, %0|%0, %2}"
8755 [(set_attr "type" "alu")
8756 (set_attr "mode" "HI")])
8757
8758 (define_insn "*iorhi_3"
8759 [(set (reg FLAGS_REG)
8760 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8761 (match_operand:HI 2 "general_operand" "rim"))
8762 (const_int 0)))
8763 (clobber (match_scratch:HI 0 "=r"))]
8764 "ix86_match_ccmode (insn, CCNOmode)
8765 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8766 "or{w}\t{%2, %0|%0, %2}"
8767 [(set_attr "type" "alu")
8768 (set_attr "mode" "HI")])
8769
8770 (define_expand "iorqi3"
8771 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8772 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8773 (match_operand:QI 2 "general_operand" "")))
8774 (clobber (reg:CC FLAGS_REG))]
8775 "TARGET_QIMODE_MATH"
8776 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8777
8778 ;; %%% Potential partial reg stall on alternative 2. What to do?
8779 (define_insn "*iorqi_1"
8780 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8781 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8782 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8783 (clobber (reg:CC FLAGS_REG))]
8784 "ix86_binary_operator_ok (IOR, QImode, operands)"
8785 "@
8786 or{b}\t{%2, %0|%0, %2}
8787 or{b}\t{%2, %0|%0, %2}
8788 or{l}\t{%k2, %k0|%k0, %k2}"
8789 [(set_attr "type" "alu")
8790 (set_attr "mode" "QI,QI,SI")])
8791
8792 (define_insn "*iorqi_1_slp"
8793 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8794 (ior:QI (match_dup 0)
8795 (match_operand:QI 1 "general_operand" "qmi,qi")))
8796 (clobber (reg:CC FLAGS_REG))]
8797 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8798 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8799 "or{b}\t{%1, %0|%0, %1}"
8800 [(set_attr "type" "alu1")
8801 (set_attr "mode" "QI")])
8802
8803 (define_insn "*iorqi_2"
8804 [(set (reg FLAGS_REG)
8805 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8806 (match_operand:QI 2 "general_operand" "qim,qi"))
8807 (const_int 0)))
8808 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8809 (ior:QI (match_dup 1) (match_dup 2)))]
8810 "ix86_match_ccmode (insn, CCNOmode)
8811 && ix86_binary_operator_ok (IOR, QImode, operands)"
8812 "or{b}\t{%2, %0|%0, %2}"
8813 [(set_attr "type" "alu")
8814 (set_attr "mode" "QI")])
8815
8816 (define_insn "*iorqi_2_slp"
8817 [(set (reg FLAGS_REG)
8818 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8819 (match_operand:QI 1 "general_operand" "qim,qi"))
8820 (const_int 0)))
8821 (set (strict_low_part (match_dup 0))
8822 (ior:QI (match_dup 0) (match_dup 1)))]
8823 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8824 && ix86_match_ccmode (insn, CCNOmode)
8825 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8826 "or{b}\t{%1, %0|%0, %1}"
8827 [(set_attr "type" "alu1")
8828 (set_attr "mode" "QI")])
8829
8830 (define_insn "*iorqi_3"
8831 [(set (reg FLAGS_REG)
8832 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8833 (match_operand:QI 2 "general_operand" "qim"))
8834 (const_int 0)))
8835 (clobber (match_scratch:QI 0 "=q"))]
8836 "ix86_match_ccmode (insn, CCNOmode)
8837 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8838 "or{b}\t{%2, %0|%0, %2}"
8839 [(set_attr "type" "alu")
8840 (set_attr "mode" "QI")])
8841
8842 (define_insn "iorqi_ext_0"
8843 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8844 (const_int 8)
8845 (const_int 8))
8846 (ior:SI
8847 (zero_extract:SI
8848 (match_operand 1 "ext_register_operand" "0")
8849 (const_int 8)
8850 (const_int 8))
8851 (match_operand 2 "const_int_operand" "n")))
8852 (clobber (reg:CC FLAGS_REG))]
8853 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8854 "or{b}\t{%2, %h0|%h0, %2}"
8855 [(set_attr "type" "alu")
8856 (set_attr "length_immediate" "1")
8857 (set_attr "mode" "QI")])
8858
8859 (define_insn "*iorqi_ext_1"
8860 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8861 (const_int 8)
8862 (const_int 8))
8863 (ior:SI
8864 (zero_extract:SI
8865 (match_operand 1 "ext_register_operand" "0")
8866 (const_int 8)
8867 (const_int 8))
8868 (zero_extend:SI
8869 (match_operand:QI 2 "general_operand" "Qm"))))
8870 (clobber (reg:CC FLAGS_REG))]
8871 "!TARGET_64BIT
8872 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8873 "or{b}\t{%2, %h0|%h0, %2}"
8874 [(set_attr "type" "alu")
8875 (set_attr "length_immediate" "0")
8876 (set_attr "mode" "QI")])
8877
8878 (define_insn "*iorqi_ext_1_rex64"
8879 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8880 (const_int 8)
8881 (const_int 8))
8882 (ior:SI
8883 (zero_extract:SI
8884 (match_operand 1 "ext_register_operand" "0")
8885 (const_int 8)
8886 (const_int 8))
8887 (zero_extend:SI
8888 (match_operand 2 "ext_register_operand" "Q"))))
8889 (clobber (reg:CC FLAGS_REG))]
8890 "TARGET_64BIT
8891 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8892 "or{b}\t{%2, %h0|%h0, %2}"
8893 [(set_attr "type" "alu")
8894 (set_attr "length_immediate" "0")
8895 (set_attr "mode" "QI")])
8896
8897 (define_insn "*iorqi_ext_2"
8898 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8899 (const_int 8)
8900 (const_int 8))
8901 (ior:SI
8902 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8903 (const_int 8)
8904 (const_int 8))
8905 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8906 (const_int 8)
8907 (const_int 8))))
8908 (clobber (reg:CC FLAGS_REG))]
8909 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8910 "ior{b}\t{%h2, %h0|%h0, %h2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "length_immediate" "0")
8913 (set_attr "mode" "QI")])
8914
8915 (define_split
8916 [(set (match_operand 0 "register_operand" "")
8917 (ior (match_operand 1 "register_operand" "")
8918 (match_operand 2 "const_int_operand" "")))
8919 (clobber (reg:CC FLAGS_REG))]
8920 "reload_completed
8921 && QI_REG_P (operands[0])
8922 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8923 && !(INTVAL (operands[2]) & ~(255 << 8))
8924 && GET_MODE (operands[0]) != QImode"
8925 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8926 (ior:SI (zero_extract:SI (match_dup 1)
8927 (const_int 8) (const_int 8))
8928 (match_dup 2)))
8929 (clobber (reg:CC FLAGS_REG))])]
8930 "operands[0] = gen_lowpart (SImode, operands[0]);
8931 operands[1] = gen_lowpart (SImode, operands[1]);
8932 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8933
8934 ;; Since OR can be encoded with sign extended immediate, this is only
8935 ;; profitable when 7th bit is set.
8936 (define_split
8937 [(set (match_operand 0 "register_operand" "")
8938 (ior (match_operand 1 "general_operand" "")
8939 (match_operand 2 "const_int_operand" "")))
8940 (clobber (reg:CC FLAGS_REG))]
8941 "reload_completed
8942 && ANY_QI_REG_P (operands[0])
8943 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8944 && !(INTVAL (operands[2]) & ~255)
8945 && (INTVAL (operands[2]) & 128)
8946 && GET_MODE (operands[0]) != QImode"
8947 [(parallel [(set (strict_low_part (match_dup 0))
8948 (ior:QI (match_dup 1)
8949 (match_dup 2)))
8950 (clobber (reg:CC FLAGS_REG))])]
8951 "operands[0] = gen_lowpart (QImode, operands[0]);
8952 operands[1] = gen_lowpart (QImode, operands[1]);
8953 operands[2] = gen_lowpart (QImode, operands[2]);")
8954 \f
8955 ;; Logical XOR instructions
8956
8957 ;; %%% This used to optimize known byte-wide and operations to memory.
8958 ;; If this is considered useful, it should be done with splitters.
8959
8960 (define_expand "xordi3"
8961 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8962 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8963 (match_operand:DI 2 "x86_64_general_operand" "")))
8964 (clobber (reg:CC FLAGS_REG))]
8965 "TARGET_64BIT"
8966 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8967
8968 (define_insn "*xordi_1_rex64"
8969 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8970 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8971 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8972 (clobber (reg:CC FLAGS_REG))]
8973 "TARGET_64BIT
8974 && ix86_binary_operator_ok (XOR, DImode, operands)"
8975 "@
8976 xor{q}\t{%2, %0|%0, %2}
8977 xor{q}\t{%2, %0|%0, %2}"
8978 [(set_attr "type" "alu")
8979 (set_attr "mode" "DI,DI")])
8980
8981 (define_insn "*xordi_2_rex64"
8982 [(set (reg FLAGS_REG)
8983 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8984 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8985 (const_int 0)))
8986 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8987 (xor:DI (match_dup 1) (match_dup 2)))]
8988 "TARGET_64BIT
8989 && ix86_match_ccmode (insn, CCNOmode)
8990 && ix86_binary_operator_ok (XOR, DImode, operands)"
8991 "@
8992 xor{q}\t{%2, %0|%0, %2}
8993 xor{q}\t{%2, %0|%0, %2}"
8994 [(set_attr "type" "alu")
8995 (set_attr "mode" "DI,DI")])
8996
8997 (define_insn "*xordi_3_rex64"
8998 [(set (reg FLAGS_REG)
8999 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9000 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9001 (const_int 0)))
9002 (clobber (match_scratch:DI 0 "=r"))]
9003 "TARGET_64BIT
9004 && ix86_match_ccmode (insn, CCNOmode)
9005 && ix86_binary_operator_ok (XOR, DImode, operands)"
9006 "xor{q}\t{%2, %0|%0, %2}"
9007 [(set_attr "type" "alu")
9008 (set_attr "mode" "DI")])
9009
9010 (define_expand "xorsi3"
9011 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9012 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9013 (match_operand:SI 2 "general_operand" "")))
9014 (clobber (reg:CC FLAGS_REG))]
9015 ""
9016 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9017
9018 (define_insn "*xorsi_1"
9019 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9020 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9021 (match_operand:SI 2 "general_operand" "ri,rm")))
9022 (clobber (reg:CC FLAGS_REG))]
9023 "ix86_binary_operator_ok (XOR, SImode, operands)"
9024 "xor{l}\t{%2, %0|%0, %2}"
9025 [(set_attr "type" "alu")
9026 (set_attr "mode" "SI")])
9027
9028 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9029 ;; Add speccase for immediates
9030 (define_insn "*xorsi_1_zext"
9031 [(set (match_operand:DI 0 "register_operand" "=r")
9032 (zero_extend:DI
9033 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9034 (match_operand:SI 2 "general_operand" "rim"))))
9035 (clobber (reg:CC FLAGS_REG))]
9036 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9037 "xor{l}\t{%2, %k0|%k0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "SI")])
9040
9041 (define_insn "*xorsi_1_zext_imm"
9042 [(set (match_operand:DI 0 "register_operand" "=r")
9043 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9044 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9045 (clobber (reg:CC FLAGS_REG))]
9046 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9047 "xor{l}\t{%2, %k0|%k0, %2}"
9048 [(set_attr "type" "alu")
9049 (set_attr "mode" "SI")])
9050
9051 (define_insn "*xorsi_2"
9052 [(set (reg FLAGS_REG)
9053 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9054 (match_operand:SI 2 "general_operand" "rim,ri"))
9055 (const_int 0)))
9056 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9057 (xor:SI (match_dup 1) (match_dup 2)))]
9058 "ix86_match_ccmode (insn, CCNOmode)
9059 && ix86_binary_operator_ok (XOR, SImode, operands)"
9060 "xor{l}\t{%2, %0|%0, %2}"
9061 [(set_attr "type" "alu")
9062 (set_attr "mode" "SI")])
9063
9064 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9065 ;; ??? Special case for immediate operand is missing - it is tricky.
9066 (define_insn "*xorsi_2_zext"
9067 [(set (reg FLAGS_REG)
9068 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9069 (match_operand:SI 2 "general_operand" "rim"))
9070 (const_int 0)))
9071 (set (match_operand:DI 0 "register_operand" "=r")
9072 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9073 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9074 && ix86_binary_operator_ok (XOR, SImode, operands)"
9075 "xor{l}\t{%2, %k0|%k0, %2}"
9076 [(set_attr "type" "alu")
9077 (set_attr "mode" "SI")])
9078
9079 (define_insn "*xorsi_2_zext_imm"
9080 [(set (reg FLAGS_REG)
9081 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9082 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9083 (const_int 0)))
9084 (set (match_operand:DI 0 "register_operand" "=r")
9085 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9086 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9087 && ix86_binary_operator_ok (XOR, SImode, operands)"
9088 "xor{l}\t{%2, %k0|%k0, %2}"
9089 [(set_attr "type" "alu")
9090 (set_attr "mode" "SI")])
9091
9092 (define_insn "*xorsi_3"
9093 [(set (reg FLAGS_REG)
9094 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9095 (match_operand:SI 2 "general_operand" "rim"))
9096 (const_int 0)))
9097 (clobber (match_scratch:SI 0 "=r"))]
9098 "ix86_match_ccmode (insn, CCNOmode)
9099 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9100 "xor{l}\t{%2, %0|%0, %2}"
9101 [(set_attr "type" "alu")
9102 (set_attr "mode" "SI")])
9103
9104 (define_expand "xorhi3"
9105 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9106 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9107 (match_operand:HI 2 "general_operand" "")))
9108 (clobber (reg:CC FLAGS_REG))]
9109 "TARGET_HIMODE_MATH"
9110 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9111
9112 (define_insn "*xorhi_1"
9113 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9114 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9115 (match_operand:HI 2 "general_operand" "rmi,ri")))
9116 (clobber (reg:CC FLAGS_REG))]
9117 "ix86_binary_operator_ok (XOR, HImode, operands)"
9118 "xor{w}\t{%2, %0|%0, %2}"
9119 [(set_attr "type" "alu")
9120 (set_attr "mode" "HI")])
9121
9122 (define_insn "*xorhi_2"
9123 [(set (reg FLAGS_REG)
9124 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9125 (match_operand:HI 2 "general_operand" "rim,ri"))
9126 (const_int 0)))
9127 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9128 (xor:HI (match_dup 1) (match_dup 2)))]
9129 "ix86_match_ccmode (insn, CCNOmode)
9130 && ix86_binary_operator_ok (XOR, HImode, operands)"
9131 "xor{w}\t{%2, %0|%0, %2}"
9132 [(set_attr "type" "alu")
9133 (set_attr "mode" "HI")])
9134
9135 (define_insn "*xorhi_3"
9136 [(set (reg FLAGS_REG)
9137 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9138 (match_operand:HI 2 "general_operand" "rim"))
9139 (const_int 0)))
9140 (clobber (match_scratch:HI 0 "=r"))]
9141 "ix86_match_ccmode (insn, CCNOmode)
9142 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9143 "xor{w}\t{%2, %0|%0, %2}"
9144 [(set_attr "type" "alu")
9145 (set_attr "mode" "HI")])
9146
9147 (define_expand "xorqi3"
9148 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9149 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9150 (match_operand:QI 2 "general_operand" "")))
9151 (clobber (reg:CC FLAGS_REG))]
9152 "TARGET_QIMODE_MATH"
9153 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9154
9155 ;; %%% Potential partial reg stall on alternative 2. What to do?
9156 (define_insn "*xorqi_1"
9157 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9158 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9159 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9160 (clobber (reg:CC FLAGS_REG))]
9161 "ix86_binary_operator_ok (XOR, QImode, operands)"
9162 "@
9163 xor{b}\t{%2, %0|%0, %2}
9164 xor{b}\t{%2, %0|%0, %2}
9165 xor{l}\t{%k2, %k0|%k0, %k2}"
9166 [(set_attr "type" "alu")
9167 (set_attr "mode" "QI,QI,SI")])
9168
9169 (define_insn "*xorqi_1_slp"
9170 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9171 (xor:QI (match_dup 0)
9172 (match_operand:QI 1 "general_operand" "qi,qmi")))
9173 (clobber (reg:CC FLAGS_REG))]
9174 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9175 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9176 "xor{b}\t{%1, %0|%0, %1}"
9177 [(set_attr "type" "alu1")
9178 (set_attr "mode" "QI")])
9179
9180 (define_insn "xorqi_ext_0"
9181 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9182 (const_int 8)
9183 (const_int 8))
9184 (xor:SI
9185 (zero_extract:SI
9186 (match_operand 1 "ext_register_operand" "0")
9187 (const_int 8)
9188 (const_int 8))
9189 (match_operand 2 "const_int_operand" "n")))
9190 (clobber (reg:CC FLAGS_REG))]
9191 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9192 "xor{b}\t{%2, %h0|%h0, %2}"
9193 [(set_attr "type" "alu")
9194 (set_attr "length_immediate" "1")
9195 (set_attr "mode" "QI")])
9196
9197 (define_insn "*xorqi_ext_1"
9198 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9199 (const_int 8)
9200 (const_int 8))
9201 (xor:SI
9202 (zero_extract:SI
9203 (match_operand 1 "ext_register_operand" "0")
9204 (const_int 8)
9205 (const_int 8))
9206 (zero_extend:SI
9207 (match_operand:QI 2 "general_operand" "Qm"))))
9208 (clobber (reg:CC FLAGS_REG))]
9209 "!TARGET_64BIT
9210 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9211 "xor{b}\t{%2, %h0|%h0, %2}"
9212 [(set_attr "type" "alu")
9213 (set_attr "length_immediate" "0")
9214 (set_attr "mode" "QI")])
9215
9216 (define_insn "*xorqi_ext_1_rex64"
9217 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9218 (const_int 8)
9219 (const_int 8))
9220 (xor:SI
9221 (zero_extract:SI
9222 (match_operand 1 "ext_register_operand" "0")
9223 (const_int 8)
9224 (const_int 8))
9225 (zero_extend:SI
9226 (match_operand 2 "ext_register_operand" "Q"))))
9227 (clobber (reg:CC FLAGS_REG))]
9228 "TARGET_64BIT
9229 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9230 "xor{b}\t{%2, %h0|%h0, %2}"
9231 [(set_attr "type" "alu")
9232 (set_attr "length_immediate" "0")
9233 (set_attr "mode" "QI")])
9234
9235 (define_insn "*xorqi_ext_2"
9236 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9237 (const_int 8)
9238 (const_int 8))
9239 (xor:SI
9240 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9241 (const_int 8)
9242 (const_int 8))
9243 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9244 (const_int 8)
9245 (const_int 8))))
9246 (clobber (reg:CC FLAGS_REG))]
9247 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9248 "xor{b}\t{%h2, %h0|%h0, %h2}"
9249 [(set_attr "type" "alu")
9250 (set_attr "length_immediate" "0")
9251 (set_attr "mode" "QI")])
9252
9253 (define_insn "*xorqi_cc_1"
9254 [(set (reg FLAGS_REG)
9255 (compare
9256 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9257 (match_operand:QI 2 "general_operand" "qim,qi"))
9258 (const_int 0)))
9259 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9260 (xor:QI (match_dup 1) (match_dup 2)))]
9261 "ix86_match_ccmode (insn, CCNOmode)
9262 && ix86_binary_operator_ok (XOR, QImode, operands)"
9263 "xor{b}\t{%2, %0|%0, %2}"
9264 [(set_attr "type" "alu")
9265 (set_attr "mode" "QI")])
9266
9267 (define_insn "*xorqi_2_slp"
9268 [(set (reg FLAGS_REG)
9269 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9270 (match_operand:QI 1 "general_operand" "qim,qi"))
9271 (const_int 0)))
9272 (set (strict_low_part (match_dup 0))
9273 (xor:QI (match_dup 0) (match_dup 1)))]
9274 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9275 && ix86_match_ccmode (insn, CCNOmode)
9276 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9277 "xor{b}\t{%1, %0|%0, %1}"
9278 [(set_attr "type" "alu1")
9279 (set_attr "mode" "QI")])
9280
9281 (define_insn "*xorqi_cc_2"
9282 [(set (reg FLAGS_REG)
9283 (compare
9284 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9285 (match_operand:QI 2 "general_operand" "qim"))
9286 (const_int 0)))
9287 (clobber (match_scratch:QI 0 "=q"))]
9288 "ix86_match_ccmode (insn, CCNOmode)
9289 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9290 "xor{b}\t{%2, %0|%0, %2}"
9291 [(set_attr "type" "alu")
9292 (set_attr "mode" "QI")])
9293
9294 (define_insn "*xorqi_cc_ext_1"
9295 [(set (reg FLAGS_REG)
9296 (compare
9297 (xor:SI
9298 (zero_extract:SI
9299 (match_operand 1 "ext_register_operand" "0")
9300 (const_int 8)
9301 (const_int 8))
9302 (match_operand:QI 2 "general_operand" "qmn"))
9303 (const_int 0)))
9304 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9305 (const_int 8)
9306 (const_int 8))
9307 (xor:SI
9308 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9309 (match_dup 2)))]
9310 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9311 "xor{b}\t{%2, %h0|%h0, %2}"
9312 [(set_attr "type" "alu")
9313 (set_attr "mode" "QI")])
9314
9315 (define_insn "*xorqi_cc_ext_1_rex64"
9316 [(set (reg FLAGS_REG)
9317 (compare
9318 (xor:SI
9319 (zero_extract:SI
9320 (match_operand 1 "ext_register_operand" "0")
9321 (const_int 8)
9322 (const_int 8))
9323 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9324 (const_int 0)))
9325 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9326 (const_int 8)
9327 (const_int 8))
9328 (xor:SI
9329 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9330 (match_dup 2)))]
9331 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9332 "xor{b}\t{%2, %h0|%h0, %2}"
9333 [(set_attr "type" "alu")
9334 (set_attr "mode" "QI")])
9335
9336 (define_expand "xorqi_cc_ext_1"
9337 [(parallel [
9338 (set (reg:CCNO FLAGS_REG)
9339 (compare:CCNO
9340 (xor:SI
9341 (zero_extract:SI
9342 (match_operand 1 "ext_register_operand" "")
9343 (const_int 8)
9344 (const_int 8))
9345 (match_operand:QI 2 "general_operand" ""))
9346 (const_int 0)))
9347 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9348 (const_int 8)
9349 (const_int 8))
9350 (xor:SI
9351 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9352 (match_dup 2)))])]
9353 ""
9354 "")
9355
9356 (define_split
9357 [(set (match_operand 0 "register_operand" "")
9358 (xor (match_operand 1 "register_operand" "")
9359 (match_operand 2 "const_int_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))]
9361 "reload_completed
9362 && QI_REG_P (operands[0])
9363 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9364 && !(INTVAL (operands[2]) & ~(255 << 8))
9365 && GET_MODE (operands[0]) != QImode"
9366 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9367 (xor:SI (zero_extract:SI (match_dup 1)
9368 (const_int 8) (const_int 8))
9369 (match_dup 2)))
9370 (clobber (reg:CC FLAGS_REG))])]
9371 "operands[0] = gen_lowpart (SImode, operands[0]);
9372 operands[1] = gen_lowpart (SImode, operands[1]);
9373 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9374
9375 ;; Since XOR can be encoded with sign extended immediate, this is only
9376 ;; profitable when 7th bit is set.
9377 (define_split
9378 [(set (match_operand 0 "register_operand" "")
9379 (xor (match_operand 1 "general_operand" "")
9380 (match_operand 2 "const_int_operand" "")))
9381 (clobber (reg:CC FLAGS_REG))]
9382 "reload_completed
9383 && ANY_QI_REG_P (operands[0])
9384 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9385 && !(INTVAL (operands[2]) & ~255)
9386 && (INTVAL (operands[2]) & 128)
9387 && GET_MODE (operands[0]) != QImode"
9388 [(parallel [(set (strict_low_part (match_dup 0))
9389 (xor:QI (match_dup 1)
9390 (match_dup 2)))
9391 (clobber (reg:CC FLAGS_REG))])]
9392 "operands[0] = gen_lowpart (QImode, operands[0]);
9393 operands[1] = gen_lowpart (QImode, operands[1]);
9394 operands[2] = gen_lowpart (QImode, operands[2]);")
9395 \f
9396 ;; Negation instructions
9397
9398 (define_expand "negdi2"
9399 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9400 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9401 (clobber (reg:CC FLAGS_REG))])]
9402 ""
9403 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9404
9405 (define_insn "*negdi2_1"
9406 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9407 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9408 (clobber (reg:CC FLAGS_REG))]
9409 "!TARGET_64BIT
9410 && ix86_unary_operator_ok (NEG, DImode, operands)"
9411 "#")
9412
9413 (define_split
9414 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9415 (neg:DI (match_operand:DI 1 "general_operand" "")))
9416 (clobber (reg:CC FLAGS_REG))]
9417 "!TARGET_64BIT && reload_completed"
9418 [(parallel
9419 [(set (reg:CCZ FLAGS_REG)
9420 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9421 (set (match_dup 0) (neg:SI (match_dup 2)))])
9422 (parallel
9423 [(set (match_dup 1)
9424 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9425 (match_dup 3))
9426 (const_int 0)))
9427 (clobber (reg:CC FLAGS_REG))])
9428 (parallel
9429 [(set (match_dup 1)
9430 (neg:SI (match_dup 1)))
9431 (clobber (reg:CC FLAGS_REG))])]
9432 "split_di (operands+1, 1, operands+2, operands+3);
9433 split_di (operands+0, 1, operands+0, operands+1);")
9434
9435 (define_insn "*negdi2_1_rex64"
9436 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9437 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9438 (clobber (reg:CC FLAGS_REG))]
9439 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9440 "neg{q}\t%0"
9441 [(set_attr "type" "negnot")
9442 (set_attr "mode" "DI")])
9443
9444 ;; The problem with neg is that it does not perform (compare x 0),
9445 ;; it really performs (compare 0 x), which leaves us with the zero
9446 ;; flag being the only useful item.
9447
9448 (define_insn "*negdi2_cmpz_rex64"
9449 [(set (reg:CCZ FLAGS_REG)
9450 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9451 (const_int 0)))
9452 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9453 (neg:DI (match_dup 1)))]
9454 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9455 "neg{q}\t%0"
9456 [(set_attr "type" "negnot")
9457 (set_attr "mode" "DI")])
9458
9459
9460 (define_expand "negsi2"
9461 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9462 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9463 (clobber (reg:CC FLAGS_REG))])]
9464 ""
9465 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9466
9467 (define_insn "*negsi2_1"
9468 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9469 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9470 (clobber (reg:CC FLAGS_REG))]
9471 "ix86_unary_operator_ok (NEG, SImode, operands)"
9472 "neg{l}\t%0"
9473 [(set_attr "type" "negnot")
9474 (set_attr "mode" "SI")])
9475
9476 ;; Combine is quite creative about this pattern.
9477 (define_insn "*negsi2_1_zext"
9478 [(set (match_operand:DI 0 "register_operand" "=r")
9479 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9480 (const_int 32)))
9481 (const_int 32)))
9482 (clobber (reg:CC FLAGS_REG))]
9483 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9484 "neg{l}\t%k0"
9485 [(set_attr "type" "negnot")
9486 (set_attr "mode" "SI")])
9487
9488 ;; The problem with neg is that it does not perform (compare x 0),
9489 ;; it really performs (compare 0 x), which leaves us with the zero
9490 ;; flag being the only useful item.
9491
9492 (define_insn "*negsi2_cmpz"
9493 [(set (reg:CCZ FLAGS_REG)
9494 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9495 (const_int 0)))
9496 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9497 (neg:SI (match_dup 1)))]
9498 "ix86_unary_operator_ok (NEG, SImode, operands)"
9499 "neg{l}\t%0"
9500 [(set_attr "type" "negnot")
9501 (set_attr "mode" "SI")])
9502
9503 (define_insn "*negsi2_cmpz_zext"
9504 [(set (reg:CCZ FLAGS_REG)
9505 (compare:CCZ (lshiftrt:DI
9506 (neg:DI (ashift:DI
9507 (match_operand:DI 1 "register_operand" "0")
9508 (const_int 32)))
9509 (const_int 32))
9510 (const_int 0)))
9511 (set (match_operand:DI 0 "register_operand" "=r")
9512 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9513 (const_int 32)))
9514 (const_int 32)))]
9515 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9516 "neg{l}\t%k0"
9517 [(set_attr "type" "negnot")
9518 (set_attr "mode" "SI")])
9519
9520 (define_expand "neghi2"
9521 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9522 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9523 (clobber (reg:CC FLAGS_REG))])]
9524 "TARGET_HIMODE_MATH"
9525 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9526
9527 (define_insn "*neghi2_1"
9528 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9529 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9530 (clobber (reg:CC FLAGS_REG))]
9531 "ix86_unary_operator_ok (NEG, HImode, operands)"
9532 "neg{w}\t%0"
9533 [(set_attr "type" "negnot")
9534 (set_attr "mode" "HI")])
9535
9536 (define_insn "*neghi2_cmpz"
9537 [(set (reg:CCZ FLAGS_REG)
9538 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9539 (const_int 0)))
9540 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9541 (neg:HI (match_dup 1)))]
9542 "ix86_unary_operator_ok (NEG, HImode, operands)"
9543 "neg{w}\t%0"
9544 [(set_attr "type" "negnot")
9545 (set_attr "mode" "HI")])
9546
9547 (define_expand "negqi2"
9548 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9549 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9550 (clobber (reg:CC FLAGS_REG))])]
9551 "TARGET_QIMODE_MATH"
9552 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9553
9554 (define_insn "*negqi2_1"
9555 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9556 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9557 (clobber (reg:CC FLAGS_REG))]
9558 "ix86_unary_operator_ok (NEG, QImode, operands)"
9559 "neg{b}\t%0"
9560 [(set_attr "type" "negnot")
9561 (set_attr "mode" "QI")])
9562
9563 (define_insn "*negqi2_cmpz"
9564 [(set (reg:CCZ FLAGS_REG)
9565 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9566 (const_int 0)))
9567 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9568 (neg:QI (match_dup 1)))]
9569 "ix86_unary_operator_ok (NEG, QImode, operands)"
9570 "neg{b}\t%0"
9571 [(set_attr "type" "negnot")
9572 (set_attr "mode" "QI")])
9573
9574 ;; Changing of sign for FP values is doable using integer unit too.
9575
9576 (define_expand "negsf2"
9577 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9578 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9579 "TARGET_80387 || TARGET_SSE_MATH"
9580 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9581
9582 (define_expand "abssf2"
9583 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9584 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9585 "TARGET_80387 || TARGET_SSE_MATH"
9586 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9587
9588 (define_insn "*absnegsf2_mixed"
9589 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9590 (match_operator:SF 3 "absneg_operator"
9591 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#fr,0 ,0")]))
9592 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9593 (clobber (reg:CC FLAGS_REG))]
9594 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9595 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9596 "#")
9597
9598 (define_insn "*absnegsf2_sse"
9599 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#r,x#r,rm#x")
9600 (match_operator:SF 3 "absneg_operator"
9601 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#r,0")]))
9602 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X"))
9603 (clobber (reg:CC FLAGS_REG))]
9604 "TARGET_SSE_MATH
9605 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9606 "#")
9607
9608 (define_insn "*absnegsf2_i387"
9609 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9610 (match_operator:SF 3 "absneg_operator"
9611 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9612 (use (match_operand 2 "" ""))
9613 (clobber (reg:CC FLAGS_REG))]
9614 "TARGET_80387 && !TARGET_SSE_MATH
9615 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9616 "#")
9617
9618 (define_expand "negdf2"
9619 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9620 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9621 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9622 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9623
9624 (define_expand "absdf2"
9625 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9626 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9627 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9628 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9629
9630 (define_insn "*absnegdf2_mixed"
9631 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9632 (match_operator:DF 3 "absneg_operator"
9633 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#fr,0 ,0")]))
9634 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9635 (clobber (reg:CC FLAGS_REG))]
9636 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9637 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9638 "#")
9639
9640 (define_insn "*absnegdf2_sse"
9641 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#r,Y#r,rm#Y")
9642 (match_operator:DF 3 "absneg_operator"
9643 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#r,0")]))
9644 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X"))
9645 (clobber (reg:CC FLAGS_REG))]
9646 "TARGET_SSE2 && TARGET_SSE_MATH
9647 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9648 "#")
9649
9650 (define_insn "*absnegdf2_i387"
9651 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9652 (match_operator:DF 3 "absneg_operator"
9653 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9654 (use (match_operand 2 "" ""))
9655 (clobber (reg:CC FLAGS_REG))]
9656 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9657 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9658 "#")
9659
9660 (define_expand "negxf2"
9661 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9662 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9663 "TARGET_80387"
9664 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9665
9666 (define_expand "absxf2"
9667 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9668 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9669 "TARGET_80387"
9670 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9671
9672 (define_insn "*absnegxf2_i387"
9673 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9674 (match_operator:XF 3 "absneg_operator"
9675 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9676 (use (match_operand 2 "" ""))
9677 (clobber (reg:CC FLAGS_REG))]
9678 "TARGET_80387
9679 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9680 "#")
9681
9682 ;; Splitters for fp abs and neg.
9683
9684 (define_split
9685 [(set (match_operand 0 "fp_register_operand" "")
9686 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9687 (use (match_operand 2 "" ""))
9688 (clobber (reg:CC FLAGS_REG))]
9689 "reload_completed"
9690 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9691
9692 (define_split
9693 [(set (match_operand 0 "register_operand" "")
9694 (match_operator 3 "absneg_operator"
9695 [(match_operand 1 "register_operand" "")]))
9696 (use (match_operand 2 "nonimmediate_operand" ""))
9697 (clobber (reg:CC FLAGS_REG))]
9698 "reload_completed && SSE_REG_P (operands[0])"
9699 [(set (match_dup 0) (match_dup 3))]
9700 {
9701 enum machine_mode mode = GET_MODE (operands[0]);
9702 enum machine_mode vmode = GET_MODE (operands[2]);
9703 rtx tmp;
9704
9705 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9706 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9707 if (operands_match_p (operands[0], operands[2]))
9708 {
9709 tmp = operands[1];
9710 operands[1] = operands[2];
9711 operands[2] = tmp;
9712 }
9713 if (GET_CODE (operands[3]) == ABS)
9714 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9715 else
9716 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9717 operands[3] = tmp;
9718 })
9719
9720 (define_split
9721 [(set (match_operand:SF 0 "register_operand" "")
9722 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9723 (use (match_operand:V4SF 2 "" ""))
9724 (clobber (reg:CC FLAGS_REG))]
9725 "reload_completed"
9726 [(parallel [(set (match_dup 0) (match_dup 1))
9727 (clobber (reg:CC FLAGS_REG))])]
9728 {
9729 rtx tmp;
9730 operands[0] = gen_lowpart (SImode, operands[0]);
9731 if (GET_CODE (operands[1]) == ABS)
9732 {
9733 tmp = gen_int_mode (0x7fffffff, SImode);
9734 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9735 }
9736 else
9737 {
9738 tmp = gen_int_mode (0x80000000, SImode);
9739 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9740 }
9741 operands[1] = tmp;
9742 })
9743
9744 (define_split
9745 [(set (match_operand:DF 0 "register_operand" "")
9746 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9747 (use (match_operand 2 "" ""))
9748 (clobber (reg:CC FLAGS_REG))]
9749 "reload_completed"
9750 [(parallel [(set (match_dup 0) (match_dup 1))
9751 (clobber (reg:CC FLAGS_REG))])]
9752 {
9753 rtx tmp;
9754 if (TARGET_64BIT)
9755 {
9756 tmp = gen_lowpart (DImode, operands[0]);
9757 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9758 operands[0] = tmp;
9759
9760 if (GET_CODE (operands[1]) == ABS)
9761 tmp = const0_rtx;
9762 else
9763 tmp = gen_rtx_NOT (DImode, tmp);
9764 }
9765 else
9766 {
9767 operands[0] = gen_highpart (SImode, operands[0]);
9768 if (GET_CODE (operands[1]) == ABS)
9769 {
9770 tmp = gen_int_mode (0x7fffffff, SImode);
9771 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9772 }
9773 else
9774 {
9775 tmp = gen_int_mode (0x80000000, SImode);
9776 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9777 }
9778 }
9779 operands[1] = tmp;
9780 })
9781
9782 (define_split
9783 [(set (match_operand:XF 0 "register_operand" "")
9784 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9785 (use (match_operand 2 "" ""))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "reload_completed"
9788 [(parallel [(set (match_dup 0) (match_dup 1))
9789 (clobber (reg:CC FLAGS_REG))])]
9790 {
9791 rtx tmp;
9792 operands[0] = gen_rtx_REG (SImode,
9793 true_regnum (operands[0])
9794 + (TARGET_64BIT ? 1 : 2));
9795 if (GET_CODE (operands[1]) == ABS)
9796 {
9797 tmp = GEN_INT (0x7fff);
9798 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9799 }
9800 else
9801 {
9802 tmp = GEN_INT (0x8000);
9803 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9804 }
9805 operands[1] = tmp;
9806 })
9807
9808 (define_split
9809 [(set (match_operand 0 "memory_operand" "")
9810 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9811 (use (match_operand 2 "" ""))
9812 (clobber (reg:CC FLAGS_REG))]
9813 "reload_completed"
9814 [(parallel [(set (match_dup 0) (match_dup 1))
9815 (clobber (reg:CC FLAGS_REG))])]
9816 {
9817 enum machine_mode mode = GET_MODE (operands[0]);
9818 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9819 rtx tmp;
9820
9821 operands[0] = adjust_address (operands[0], QImode, size - 1);
9822 if (GET_CODE (operands[1]) == ABS)
9823 {
9824 tmp = gen_int_mode (0x7f, QImode);
9825 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9826 }
9827 else
9828 {
9829 tmp = gen_int_mode (0x80, QImode);
9830 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9831 }
9832 operands[1] = tmp;
9833 })
9834
9835 ;; Conditionalize these after reload. If they match before reload, we
9836 ;; lose the clobber and ability to use integer instructions.
9837
9838 (define_insn "*negsf2_1"
9839 [(set (match_operand:SF 0 "register_operand" "=f")
9840 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9841 "TARGET_80387 && reload_completed"
9842 "fchs"
9843 [(set_attr "type" "fsgn")
9844 (set_attr "mode" "SF")])
9845
9846 (define_insn "*negdf2_1"
9847 [(set (match_operand:DF 0 "register_operand" "=f")
9848 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9849 "TARGET_80387 && reload_completed"
9850 "fchs"
9851 [(set_attr "type" "fsgn")
9852 (set_attr "mode" "DF")])
9853
9854 (define_insn "*negxf2_1"
9855 [(set (match_operand:XF 0 "register_operand" "=f")
9856 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9857 "TARGET_80387 && reload_completed"
9858 "fchs"
9859 [(set_attr "type" "fsgn")
9860 (set_attr "mode" "XF")])
9861
9862 (define_insn "*abssf2_1"
9863 [(set (match_operand:SF 0 "register_operand" "=f")
9864 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9865 "TARGET_80387 && reload_completed"
9866 "fabs"
9867 [(set_attr "type" "fsgn")
9868 (set_attr "mode" "SF")])
9869
9870 (define_insn "*absdf2_1"
9871 [(set (match_operand:DF 0 "register_operand" "=f")
9872 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9873 "TARGET_80387 && reload_completed"
9874 "fabs"
9875 [(set_attr "type" "fsgn")
9876 (set_attr "mode" "DF")])
9877
9878 (define_insn "*absxf2_1"
9879 [(set (match_operand:XF 0 "register_operand" "=f")
9880 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9881 "TARGET_80387 && reload_completed"
9882 "fabs"
9883 [(set_attr "type" "fsgn")
9884 (set_attr "mode" "DF")])
9885
9886 (define_insn "*negextendsfdf2"
9887 [(set (match_operand:DF 0 "register_operand" "=f")
9888 (neg:DF (float_extend:DF
9889 (match_operand:SF 1 "register_operand" "0"))))]
9890 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9891 "fchs"
9892 [(set_attr "type" "fsgn")
9893 (set_attr "mode" "DF")])
9894
9895 (define_insn "*negextenddfxf2"
9896 [(set (match_operand:XF 0 "register_operand" "=f")
9897 (neg:XF (float_extend:XF
9898 (match_operand:DF 1 "register_operand" "0"))))]
9899 "TARGET_80387"
9900 "fchs"
9901 [(set_attr "type" "fsgn")
9902 (set_attr "mode" "XF")])
9903
9904 (define_insn "*negextendsfxf2"
9905 [(set (match_operand:XF 0 "register_operand" "=f")
9906 (neg:XF (float_extend:XF
9907 (match_operand:SF 1 "register_operand" "0"))))]
9908 "TARGET_80387"
9909 "fchs"
9910 [(set_attr "type" "fsgn")
9911 (set_attr "mode" "XF")])
9912
9913 (define_insn "*absextendsfdf2"
9914 [(set (match_operand:DF 0 "register_operand" "=f")
9915 (abs:DF (float_extend:DF
9916 (match_operand:SF 1 "register_operand" "0"))))]
9917 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9918 "fabs"
9919 [(set_attr "type" "fsgn")
9920 (set_attr "mode" "DF")])
9921
9922 (define_insn "*absextenddfxf2"
9923 [(set (match_operand:XF 0 "register_operand" "=f")
9924 (abs:XF (float_extend:XF
9925 (match_operand:DF 1 "register_operand" "0"))))]
9926 "TARGET_80387"
9927 "fabs"
9928 [(set_attr "type" "fsgn")
9929 (set_attr "mode" "XF")])
9930
9931 (define_insn "*absextendsfxf2"
9932 [(set (match_operand:XF 0 "register_operand" "=f")
9933 (abs:XF (float_extend:XF
9934 (match_operand:SF 1 "register_operand" "0"))))]
9935 "TARGET_80387"
9936 "fabs"
9937 [(set_attr "type" "fsgn")
9938 (set_attr "mode" "XF")])
9939 \f
9940 ;; One complement instructions
9941
9942 (define_expand "one_cmpldi2"
9943 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9944 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9945 "TARGET_64BIT"
9946 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9947
9948 (define_insn "*one_cmpldi2_1_rex64"
9949 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9950 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9951 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9952 "not{q}\t%0"
9953 [(set_attr "type" "negnot")
9954 (set_attr "mode" "DI")])
9955
9956 (define_insn "*one_cmpldi2_2_rex64"
9957 [(set (reg FLAGS_REG)
9958 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9959 (const_int 0)))
9960 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9961 (not:DI (match_dup 1)))]
9962 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9963 && ix86_unary_operator_ok (NOT, DImode, operands)"
9964 "#"
9965 [(set_attr "type" "alu1")
9966 (set_attr "mode" "DI")])
9967
9968 (define_split
9969 [(set (match_operand 0 "flags_reg_operand" "")
9970 (match_operator 2 "compare_operator"
9971 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9972 (const_int 0)]))
9973 (set (match_operand:DI 1 "nonimmediate_operand" "")
9974 (not:DI (match_dup 3)))]
9975 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9976 [(parallel [(set (match_dup 0)
9977 (match_op_dup 2
9978 [(xor:DI (match_dup 3) (const_int -1))
9979 (const_int 0)]))
9980 (set (match_dup 1)
9981 (xor:DI (match_dup 3) (const_int -1)))])]
9982 "")
9983
9984 (define_expand "one_cmplsi2"
9985 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9986 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9987 ""
9988 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9989
9990 (define_insn "*one_cmplsi2_1"
9991 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9992 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9993 "ix86_unary_operator_ok (NOT, SImode, operands)"
9994 "not{l}\t%0"
9995 [(set_attr "type" "negnot")
9996 (set_attr "mode" "SI")])
9997
9998 ;; ??? Currently never generated - xor is used instead.
9999 (define_insn "*one_cmplsi2_1_zext"
10000 [(set (match_operand:DI 0 "register_operand" "=r")
10001 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10002 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10003 "not{l}\t%k0"
10004 [(set_attr "type" "negnot")
10005 (set_attr "mode" "SI")])
10006
10007 (define_insn "*one_cmplsi2_2"
10008 [(set (reg FLAGS_REG)
10009 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10010 (const_int 0)))
10011 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10012 (not:SI (match_dup 1)))]
10013 "ix86_match_ccmode (insn, CCNOmode)
10014 && ix86_unary_operator_ok (NOT, SImode, operands)"
10015 "#"
10016 [(set_attr "type" "alu1")
10017 (set_attr "mode" "SI")])
10018
10019 (define_split
10020 [(set (match_operand 0 "flags_reg_operand" "")
10021 (match_operator 2 "compare_operator"
10022 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10023 (const_int 0)]))
10024 (set (match_operand:SI 1 "nonimmediate_operand" "")
10025 (not:SI (match_dup 3)))]
10026 "ix86_match_ccmode (insn, CCNOmode)"
10027 [(parallel [(set (match_dup 0)
10028 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10029 (const_int 0)]))
10030 (set (match_dup 1)
10031 (xor:SI (match_dup 3) (const_int -1)))])]
10032 "")
10033
10034 ;; ??? Currently never generated - xor is used instead.
10035 (define_insn "*one_cmplsi2_2_zext"
10036 [(set (reg FLAGS_REG)
10037 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10038 (const_int 0)))
10039 (set (match_operand:DI 0 "register_operand" "=r")
10040 (zero_extend:DI (not:SI (match_dup 1))))]
10041 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10042 && ix86_unary_operator_ok (NOT, SImode, operands)"
10043 "#"
10044 [(set_attr "type" "alu1")
10045 (set_attr "mode" "SI")])
10046
10047 (define_split
10048 [(set (match_operand 0 "flags_reg_operand" "")
10049 (match_operator 2 "compare_operator"
10050 [(not:SI (match_operand:SI 3 "register_operand" ""))
10051 (const_int 0)]))
10052 (set (match_operand:DI 1 "register_operand" "")
10053 (zero_extend:DI (not:SI (match_dup 3))))]
10054 "ix86_match_ccmode (insn, CCNOmode)"
10055 [(parallel [(set (match_dup 0)
10056 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10057 (const_int 0)]))
10058 (set (match_dup 1)
10059 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10060 "")
10061
10062 (define_expand "one_cmplhi2"
10063 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10064 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10065 "TARGET_HIMODE_MATH"
10066 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10067
10068 (define_insn "*one_cmplhi2_1"
10069 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10070 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10071 "ix86_unary_operator_ok (NOT, HImode, operands)"
10072 "not{w}\t%0"
10073 [(set_attr "type" "negnot")
10074 (set_attr "mode" "HI")])
10075
10076 (define_insn "*one_cmplhi2_2"
10077 [(set (reg FLAGS_REG)
10078 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10079 (const_int 0)))
10080 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10081 (not:HI (match_dup 1)))]
10082 "ix86_match_ccmode (insn, CCNOmode)
10083 && ix86_unary_operator_ok (NEG, HImode, operands)"
10084 "#"
10085 [(set_attr "type" "alu1")
10086 (set_attr "mode" "HI")])
10087
10088 (define_split
10089 [(set (match_operand 0 "flags_reg_operand" "")
10090 (match_operator 2 "compare_operator"
10091 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10092 (const_int 0)]))
10093 (set (match_operand:HI 1 "nonimmediate_operand" "")
10094 (not:HI (match_dup 3)))]
10095 "ix86_match_ccmode (insn, CCNOmode)"
10096 [(parallel [(set (match_dup 0)
10097 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10098 (const_int 0)]))
10099 (set (match_dup 1)
10100 (xor:HI (match_dup 3) (const_int -1)))])]
10101 "")
10102
10103 ;; %%% Potential partial reg stall on alternative 1. What to do?
10104 (define_expand "one_cmplqi2"
10105 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10106 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10107 "TARGET_QIMODE_MATH"
10108 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10109
10110 (define_insn "*one_cmplqi2_1"
10111 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10112 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10113 "ix86_unary_operator_ok (NOT, QImode, operands)"
10114 "@
10115 not{b}\t%0
10116 not{l}\t%k0"
10117 [(set_attr "type" "negnot")
10118 (set_attr "mode" "QI,SI")])
10119
10120 (define_insn "*one_cmplqi2_2"
10121 [(set (reg FLAGS_REG)
10122 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10123 (const_int 0)))
10124 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10125 (not:QI (match_dup 1)))]
10126 "ix86_match_ccmode (insn, CCNOmode)
10127 && ix86_unary_operator_ok (NOT, QImode, operands)"
10128 "#"
10129 [(set_attr "type" "alu1")
10130 (set_attr "mode" "QI")])
10131
10132 (define_split
10133 [(set (match_operand 0 "flags_reg_operand" "")
10134 (match_operator 2 "compare_operator"
10135 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10136 (const_int 0)]))
10137 (set (match_operand:QI 1 "nonimmediate_operand" "")
10138 (not:QI (match_dup 3)))]
10139 "ix86_match_ccmode (insn, CCNOmode)"
10140 [(parallel [(set (match_dup 0)
10141 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10142 (const_int 0)]))
10143 (set (match_dup 1)
10144 (xor:QI (match_dup 3) (const_int -1)))])]
10145 "")
10146 \f
10147 ;; Arithmetic shift instructions
10148
10149 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10150 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10151 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10152 ;; from the assembler input.
10153 ;;
10154 ;; This instruction shifts the target reg/mem as usual, but instead of
10155 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10156 ;; is a left shift double, bits are taken from the high order bits of
10157 ;; reg, else if the insn is a shift right double, bits are taken from the
10158 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10159 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10160 ;;
10161 ;; Since sh[lr]d does not change the `reg' operand, that is done
10162 ;; separately, making all shifts emit pairs of shift double and normal
10163 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10164 ;; support a 63 bit shift, each shift where the count is in a reg expands
10165 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10166 ;;
10167 ;; If the shift count is a constant, we need never emit more than one
10168 ;; shift pair, instead using moves and sign extension for counts greater
10169 ;; than 31.
10170
10171 (define_expand "ashldi3"
10172 [(set (match_operand:DI 0 "shiftdi_operand" "")
10173 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10174 (match_operand:QI 2 "nonmemory_operand" "")))]
10175 ""
10176 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10177
10178 (define_insn "*ashldi3_1_rex64"
10179 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10180 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10181 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10182 (clobber (reg:CC FLAGS_REG))]
10183 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10184 {
10185 switch (get_attr_type (insn))
10186 {
10187 case TYPE_ALU:
10188 if (operands[2] != const1_rtx)
10189 abort ();
10190 if (!rtx_equal_p (operands[0], operands[1]))
10191 abort ();
10192 return "add{q}\t{%0, %0|%0, %0}";
10193
10194 case TYPE_LEA:
10195 if (GET_CODE (operands[2]) != CONST_INT
10196 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10197 abort ();
10198 operands[1] = gen_rtx_MULT (DImode, operands[1],
10199 GEN_INT (1 << INTVAL (operands[2])));
10200 return "lea{q}\t{%a1, %0|%0, %a1}";
10201
10202 default:
10203 if (REG_P (operands[2]))
10204 return "sal{q}\t{%b2, %0|%0, %b2}";
10205 else if (operands[2] == const1_rtx
10206 && (TARGET_SHIFT1 || optimize_size))
10207 return "sal{q}\t%0";
10208 else
10209 return "sal{q}\t{%2, %0|%0, %2}";
10210 }
10211 }
10212 [(set (attr "type")
10213 (cond [(eq_attr "alternative" "1")
10214 (const_string "lea")
10215 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10216 (const_int 0))
10217 (match_operand 0 "register_operand" ""))
10218 (match_operand 2 "const1_operand" ""))
10219 (const_string "alu")
10220 ]
10221 (const_string "ishift")))
10222 (set_attr "mode" "DI")])
10223
10224 ;; Convert lea to the lea pattern to avoid flags dependency.
10225 (define_split
10226 [(set (match_operand:DI 0 "register_operand" "")
10227 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10228 (match_operand:QI 2 "immediate_operand" "")))
10229 (clobber (reg:CC FLAGS_REG))]
10230 "TARGET_64BIT && reload_completed
10231 && true_regnum (operands[0]) != true_regnum (operands[1])"
10232 [(set (match_dup 0)
10233 (mult:DI (match_dup 1)
10234 (match_dup 2)))]
10235 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10236
10237 ;; This pattern can't accept a variable shift count, since shifts by
10238 ;; zero don't affect the flags. We assume that shifts by constant
10239 ;; zero are optimized away.
10240 (define_insn "*ashldi3_cmp_rex64"
10241 [(set (reg FLAGS_REG)
10242 (compare
10243 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10244 (match_operand:QI 2 "immediate_operand" "e"))
10245 (const_int 0)))
10246 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10247 (ashift:DI (match_dup 1) (match_dup 2)))]
10248 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10249 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10250 {
10251 switch (get_attr_type (insn))
10252 {
10253 case TYPE_ALU:
10254 if (operands[2] != const1_rtx)
10255 abort ();
10256 return "add{q}\t{%0, %0|%0, %0}";
10257
10258 default:
10259 if (REG_P (operands[2]))
10260 return "sal{q}\t{%b2, %0|%0, %b2}";
10261 else if (operands[2] == const1_rtx
10262 && (TARGET_SHIFT1 || optimize_size))
10263 return "sal{q}\t%0";
10264 else
10265 return "sal{q}\t{%2, %0|%0, %2}";
10266 }
10267 }
10268 [(set (attr "type")
10269 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10270 (const_int 0))
10271 (match_operand 0 "register_operand" ""))
10272 (match_operand 2 "const1_operand" ""))
10273 (const_string "alu")
10274 ]
10275 (const_string "ishift")))
10276 (set_attr "mode" "DI")])
10277
10278 (define_insn "*ashldi3_1"
10279 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10280 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10281 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10282 (clobber (reg:CC FLAGS_REG))]
10283 "!TARGET_64BIT"
10284 "#"
10285 [(set_attr "type" "multi")])
10286
10287 ;; By default we don't ask for a scratch register, because when DImode
10288 ;; values are manipulated, registers are already at a premium. But if
10289 ;; we have one handy, we won't turn it away.
10290 (define_peephole2
10291 [(match_scratch:SI 3 "r")
10292 (parallel [(set (match_operand:DI 0 "register_operand" "")
10293 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10294 (match_operand:QI 2 "nonmemory_operand" "")))
10295 (clobber (reg:CC FLAGS_REG))])
10296 (match_dup 3)]
10297 "!TARGET_64BIT && TARGET_CMOVE"
10298 [(const_int 0)]
10299 "ix86_split_ashldi (operands, operands[3]); DONE;")
10300
10301 (define_split
10302 [(set (match_operand:DI 0 "register_operand" "")
10303 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10304 (match_operand:QI 2 "nonmemory_operand" "")))
10305 (clobber (reg:CC FLAGS_REG))]
10306 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10307 [(const_int 0)]
10308 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10309
10310 (define_insn "x86_shld_1"
10311 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10312 (ior:SI (ashift:SI (match_dup 0)
10313 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10314 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10315 (minus:QI (const_int 32) (match_dup 2)))))
10316 (clobber (reg:CC FLAGS_REG))]
10317 ""
10318 "@
10319 shld{l}\t{%2, %1, %0|%0, %1, %2}
10320 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10321 [(set_attr "type" "ishift")
10322 (set_attr "prefix_0f" "1")
10323 (set_attr "mode" "SI")
10324 (set_attr "pent_pair" "np")
10325 (set_attr "athlon_decode" "vector")])
10326
10327 (define_expand "x86_shift_adj_1"
10328 [(set (reg:CCZ FLAGS_REG)
10329 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10330 (const_int 32))
10331 (const_int 0)))
10332 (set (match_operand:SI 0 "register_operand" "")
10333 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10334 (match_operand:SI 1 "register_operand" "")
10335 (match_dup 0)))
10336 (set (match_dup 1)
10337 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10338 (match_operand:SI 3 "register_operand" "r")
10339 (match_dup 1)))]
10340 "TARGET_CMOVE"
10341 "")
10342
10343 (define_expand "x86_shift_adj_2"
10344 [(use (match_operand:SI 0 "register_operand" ""))
10345 (use (match_operand:SI 1 "register_operand" ""))
10346 (use (match_operand:QI 2 "register_operand" ""))]
10347 ""
10348 {
10349 rtx label = gen_label_rtx ();
10350 rtx tmp;
10351
10352 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10353
10354 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10355 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10356 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10357 gen_rtx_LABEL_REF (VOIDmode, label),
10358 pc_rtx);
10359 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10360 JUMP_LABEL (tmp) = label;
10361
10362 emit_move_insn (operands[0], operands[1]);
10363 ix86_expand_clear (operands[1]);
10364
10365 emit_label (label);
10366 LABEL_NUSES (label) = 1;
10367
10368 DONE;
10369 })
10370
10371 (define_expand "ashlsi3"
10372 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10373 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10374 (match_operand:QI 2 "nonmemory_operand" "")))
10375 (clobber (reg:CC FLAGS_REG))]
10376 ""
10377 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10378
10379 (define_insn "*ashlsi3_1"
10380 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10381 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10382 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10383 (clobber (reg:CC FLAGS_REG))]
10384 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10385 {
10386 switch (get_attr_type (insn))
10387 {
10388 case TYPE_ALU:
10389 if (operands[2] != const1_rtx)
10390 abort ();
10391 if (!rtx_equal_p (operands[0], operands[1]))
10392 abort ();
10393 return "add{l}\t{%0, %0|%0, %0}";
10394
10395 case TYPE_LEA:
10396 return "#";
10397
10398 default:
10399 if (REG_P (operands[2]))
10400 return "sal{l}\t{%b2, %0|%0, %b2}";
10401 else if (operands[2] == const1_rtx
10402 && (TARGET_SHIFT1 || optimize_size))
10403 return "sal{l}\t%0";
10404 else
10405 return "sal{l}\t{%2, %0|%0, %2}";
10406 }
10407 }
10408 [(set (attr "type")
10409 (cond [(eq_attr "alternative" "1")
10410 (const_string "lea")
10411 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10412 (const_int 0))
10413 (match_operand 0 "register_operand" ""))
10414 (match_operand 2 "const1_operand" ""))
10415 (const_string "alu")
10416 ]
10417 (const_string "ishift")))
10418 (set_attr "mode" "SI")])
10419
10420 ;; Convert lea to the lea pattern to avoid flags dependency.
10421 (define_split
10422 [(set (match_operand 0 "register_operand" "")
10423 (ashift (match_operand 1 "index_register_operand" "")
10424 (match_operand:QI 2 "const_int_operand" "")))
10425 (clobber (reg:CC FLAGS_REG))]
10426 "reload_completed
10427 && true_regnum (operands[0]) != true_regnum (operands[1])
10428 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10429 [(const_int 0)]
10430 {
10431 rtx pat;
10432 enum machine_mode mode = GET_MODE (operands[0]);
10433
10434 if (GET_MODE_SIZE (mode) < 4)
10435 operands[0] = gen_lowpart (SImode, operands[0]);
10436 if (mode != Pmode)
10437 operands[1] = gen_lowpart (Pmode, operands[1]);
10438 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10439
10440 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10441 if (Pmode != SImode)
10442 pat = gen_rtx_SUBREG (SImode, pat, 0);
10443 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10444 DONE;
10445 })
10446
10447 ;; Rare case of shifting RSP is handled by generating move and shift
10448 (define_split
10449 [(set (match_operand 0 "register_operand" "")
10450 (ashift (match_operand 1 "register_operand" "")
10451 (match_operand:QI 2 "const_int_operand" "")))
10452 (clobber (reg:CC FLAGS_REG))]
10453 "reload_completed
10454 && true_regnum (operands[0]) != true_regnum (operands[1])"
10455 [(const_int 0)]
10456 {
10457 rtx pat, clob;
10458 emit_move_insn (operands[1], operands[0]);
10459 pat = gen_rtx_SET (VOIDmode, operands[0],
10460 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10461 operands[0], operands[2]));
10462 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10463 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10464 DONE;
10465 })
10466
10467 (define_insn "*ashlsi3_1_zext"
10468 [(set (match_operand:DI 0 "register_operand" "=r,r")
10469 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10470 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10471 (clobber (reg:CC FLAGS_REG))]
10472 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10473 {
10474 switch (get_attr_type (insn))
10475 {
10476 case TYPE_ALU:
10477 if (operands[2] != const1_rtx)
10478 abort ();
10479 return "add{l}\t{%k0, %k0|%k0, %k0}";
10480
10481 case TYPE_LEA:
10482 return "#";
10483
10484 default:
10485 if (REG_P (operands[2]))
10486 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10487 else if (operands[2] == const1_rtx
10488 && (TARGET_SHIFT1 || optimize_size))
10489 return "sal{l}\t%k0";
10490 else
10491 return "sal{l}\t{%2, %k0|%k0, %2}";
10492 }
10493 }
10494 [(set (attr "type")
10495 (cond [(eq_attr "alternative" "1")
10496 (const_string "lea")
10497 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10498 (const_int 0))
10499 (match_operand 2 "const1_operand" ""))
10500 (const_string "alu")
10501 ]
10502 (const_string "ishift")))
10503 (set_attr "mode" "SI")])
10504
10505 ;; Convert lea to the lea pattern to avoid flags dependency.
10506 (define_split
10507 [(set (match_operand:DI 0 "register_operand" "")
10508 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10509 (match_operand:QI 2 "const_int_operand" ""))))
10510 (clobber (reg:CC FLAGS_REG))]
10511 "TARGET_64BIT && reload_completed
10512 && true_regnum (operands[0]) != true_regnum (operands[1])"
10513 [(set (match_dup 0) (zero_extend:DI
10514 (subreg:SI (mult:SI (match_dup 1)
10515 (match_dup 2)) 0)))]
10516 {
10517 operands[1] = gen_lowpart (Pmode, operands[1]);
10518 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10519 })
10520
10521 ;; This pattern can't accept a variable shift count, since shifts by
10522 ;; zero don't affect the flags. We assume that shifts by constant
10523 ;; zero are optimized away.
10524 (define_insn "*ashlsi3_cmp"
10525 [(set (reg FLAGS_REG)
10526 (compare
10527 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10528 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10529 (const_int 0)))
10530 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10531 (ashift:SI (match_dup 1) (match_dup 2)))]
10532 "ix86_match_ccmode (insn, CCGOCmode)
10533 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10534 {
10535 switch (get_attr_type (insn))
10536 {
10537 case TYPE_ALU:
10538 if (operands[2] != const1_rtx)
10539 abort ();
10540 return "add{l}\t{%0, %0|%0, %0}";
10541
10542 default:
10543 if (REG_P (operands[2]))
10544 return "sal{l}\t{%b2, %0|%0, %b2}";
10545 else if (operands[2] == const1_rtx
10546 && (TARGET_SHIFT1 || optimize_size))
10547 return "sal{l}\t%0";
10548 else
10549 return "sal{l}\t{%2, %0|%0, %2}";
10550 }
10551 }
10552 [(set (attr "type")
10553 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10554 (const_int 0))
10555 (match_operand 0 "register_operand" ""))
10556 (match_operand 2 "const1_operand" ""))
10557 (const_string "alu")
10558 ]
10559 (const_string "ishift")))
10560 (set_attr "mode" "SI")])
10561
10562 (define_insn "*ashlsi3_cmp_zext"
10563 [(set (reg FLAGS_REG)
10564 (compare
10565 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10566 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10567 (const_int 0)))
10568 (set (match_operand:DI 0 "register_operand" "=r")
10569 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10570 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10571 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10572 {
10573 switch (get_attr_type (insn))
10574 {
10575 case TYPE_ALU:
10576 if (operands[2] != const1_rtx)
10577 abort ();
10578 return "add{l}\t{%k0, %k0|%k0, %k0}";
10579
10580 default:
10581 if (REG_P (operands[2]))
10582 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10583 else if (operands[2] == const1_rtx
10584 && (TARGET_SHIFT1 || optimize_size))
10585 return "sal{l}\t%k0";
10586 else
10587 return "sal{l}\t{%2, %k0|%k0, %2}";
10588 }
10589 }
10590 [(set (attr "type")
10591 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10592 (const_int 0))
10593 (match_operand 2 "const1_operand" ""))
10594 (const_string "alu")
10595 ]
10596 (const_string "ishift")))
10597 (set_attr "mode" "SI")])
10598
10599 (define_expand "ashlhi3"
10600 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10601 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10602 (match_operand:QI 2 "nonmemory_operand" "")))
10603 (clobber (reg:CC FLAGS_REG))]
10604 "TARGET_HIMODE_MATH"
10605 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10606
10607 (define_insn "*ashlhi3_1_lea"
10608 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10609 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10610 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10611 (clobber (reg:CC FLAGS_REG))]
10612 "!TARGET_PARTIAL_REG_STALL
10613 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10614 {
10615 switch (get_attr_type (insn))
10616 {
10617 case TYPE_LEA:
10618 return "#";
10619 case TYPE_ALU:
10620 if (operands[2] != const1_rtx)
10621 abort ();
10622 return "add{w}\t{%0, %0|%0, %0}";
10623
10624 default:
10625 if (REG_P (operands[2]))
10626 return "sal{w}\t{%b2, %0|%0, %b2}";
10627 else if (operands[2] == const1_rtx
10628 && (TARGET_SHIFT1 || optimize_size))
10629 return "sal{w}\t%0";
10630 else
10631 return "sal{w}\t{%2, %0|%0, %2}";
10632 }
10633 }
10634 [(set (attr "type")
10635 (cond [(eq_attr "alternative" "1")
10636 (const_string "lea")
10637 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10638 (const_int 0))
10639 (match_operand 0 "register_operand" ""))
10640 (match_operand 2 "const1_operand" ""))
10641 (const_string "alu")
10642 ]
10643 (const_string "ishift")))
10644 (set_attr "mode" "HI,SI")])
10645
10646 (define_insn "*ashlhi3_1"
10647 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10648 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10649 (match_operand:QI 2 "nonmemory_operand" "cI")))
10650 (clobber (reg:CC FLAGS_REG))]
10651 "TARGET_PARTIAL_REG_STALL
10652 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10653 {
10654 switch (get_attr_type (insn))
10655 {
10656 case TYPE_ALU:
10657 if (operands[2] != const1_rtx)
10658 abort ();
10659 return "add{w}\t{%0, %0|%0, %0}";
10660
10661 default:
10662 if (REG_P (operands[2]))
10663 return "sal{w}\t{%b2, %0|%0, %b2}";
10664 else if (operands[2] == const1_rtx
10665 && (TARGET_SHIFT1 || optimize_size))
10666 return "sal{w}\t%0";
10667 else
10668 return "sal{w}\t{%2, %0|%0, %2}";
10669 }
10670 }
10671 [(set (attr "type")
10672 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10673 (const_int 0))
10674 (match_operand 0 "register_operand" ""))
10675 (match_operand 2 "const1_operand" ""))
10676 (const_string "alu")
10677 ]
10678 (const_string "ishift")))
10679 (set_attr "mode" "HI")])
10680
10681 ;; This pattern can't accept a variable shift count, since shifts by
10682 ;; zero don't affect the flags. We assume that shifts by constant
10683 ;; zero are optimized away.
10684 (define_insn "*ashlhi3_cmp"
10685 [(set (reg FLAGS_REG)
10686 (compare
10687 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10688 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10689 (const_int 0)))
10690 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10691 (ashift:HI (match_dup 1) (match_dup 2)))]
10692 "ix86_match_ccmode (insn, CCGOCmode)
10693 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10694 {
10695 switch (get_attr_type (insn))
10696 {
10697 case TYPE_ALU:
10698 if (operands[2] != const1_rtx)
10699 abort ();
10700 return "add{w}\t{%0, %0|%0, %0}";
10701
10702 default:
10703 if (REG_P (operands[2]))
10704 return "sal{w}\t{%b2, %0|%0, %b2}";
10705 else if (operands[2] == const1_rtx
10706 && (TARGET_SHIFT1 || optimize_size))
10707 return "sal{w}\t%0";
10708 else
10709 return "sal{w}\t{%2, %0|%0, %2}";
10710 }
10711 }
10712 [(set (attr "type")
10713 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10714 (const_int 0))
10715 (match_operand 0 "register_operand" ""))
10716 (match_operand 2 "const1_operand" ""))
10717 (const_string "alu")
10718 ]
10719 (const_string "ishift")))
10720 (set_attr "mode" "HI")])
10721
10722 (define_expand "ashlqi3"
10723 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10724 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10725 (match_operand:QI 2 "nonmemory_operand" "")))
10726 (clobber (reg:CC FLAGS_REG))]
10727 "TARGET_QIMODE_MATH"
10728 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10729
10730 ;; %%% Potential partial reg stall on alternative 2. What to do?
10731
10732 (define_insn "*ashlqi3_1_lea"
10733 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10734 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10735 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10736 (clobber (reg:CC FLAGS_REG))]
10737 "!TARGET_PARTIAL_REG_STALL
10738 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10739 {
10740 switch (get_attr_type (insn))
10741 {
10742 case TYPE_LEA:
10743 return "#";
10744 case TYPE_ALU:
10745 if (operands[2] != const1_rtx)
10746 abort ();
10747 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10748 return "add{l}\t{%k0, %k0|%k0, %k0}";
10749 else
10750 return "add{b}\t{%0, %0|%0, %0}";
10751
10752 default:
10753 if (REG_P (operands[2]))
10754 {
10755 if (get_attr_mode (insn) == MODE_SI)
10756 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10757 else
10758 return "sal{b}\t{%b2, %0|%0, %b2}";
10759 }
10760 else if (operands[2] == const1_rtx
10761 && (TARGET_SHIFT1 || optimize_size))
10762 {
10763 if (get_attr_mode (insn) == MODE_SI)
10764 return "sal{l}\t%0";
10765 else
10766 return "sal{b}\t%0";
10767 }
10768 else
10769 {
10770 if (get_attr_mode (insn) == MODE_SI)
10771 return "sal{l}\t{%2, %k0|%k0, %2}";
10772 else
10773 return "sal{b}\t{%2, %0|%0, %2}";
10774 }
10775 }
10776 }
10777 [(set (attr "type")
10778 (cond [(eq_attr "alternative" "2")
10779 (const_string "lea")
10780 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10781 (const_int 0))
10782 (match_operand 0 "register_operand" ""))
10783 (match_operand 2 "const1_operand" ""))
10784 (const_string "alu")
10785 ]
10786 (const_string "ishift")))
10787 (set_attr "mode" "QI,SI,SI")])
10788
10789 (define_insn "*ashlqi3_1"
10790 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10791 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10792 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10793 (clobber (reg:CC FLAGS_REG))]
10794 "TARGET_PARTIAL_REG_STALL
10795 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10796 {
10797 switch (get_attr_type (insn))
10798 {
10799 case TYPE_ALU:
10800 if (operands[2] != const1_rtx)
10801 abort ();
10802 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10803 return "add{l}\t{%k0, %k0|%k0, %k0}";
10804 else
10805 return "add{b}\t{%0, %0|%0, %0}";
10806
10807 default:
10808 if (REG_P (operands[2]))
10809 {
10810 if (get_attr_mode (insn) == MODE_SI)
10811 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10812 else
10813 return "sal{b}\t{%b2, %0|%0, %b2}";
10814 }
10815 else if (operands[2] == const1_rtx
10816 && (TARGET_SHIFT1 || optimize_size))
10817 {
10818 if (get_attr_mode (insn) == MODE_SI)
10819 return "sal{l}\t%0";
10820 else
10821 return "sal{b}\t%0";
10822 }
10823 else
10824 {
10825 if (get_attr_mode (insn) == MODE_SI)
10826 return "sal{l}\t{%2, %k0|%k0, %2}";
10827 else
10828 return "sal{b}\t{%2, %0|%0, %2}";
10829 }
10830 }
10831 }
10832 [(set (attr "type")
10833 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10834 (const_int 0))
10835 (match_operand 0 "register_operand" ""))
10836 (match_operand 2 "const1_operand" ""))
10837 (const_string "alu")
10838 ]
10839 (const_string "ishift")))
10840 (set_attr "mode" "QI,SI")])
10841
10842 ;; This pattern can't accept a variable shift count, since shifts by
10843 ;; zero don't affect the flags. We assume that shifts by constant
10844 ;; zero are optimized away.
10845 (define_insn "*ashlqi3_cmp"
10846 [(set (reg FLAGS_REG)
10847 (compare
10848 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10849 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10850 (const_int 0)))
10851 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10852 (ashift:QI (match_dup 1) (match_dup 2)))]
10853 "ix86_match_ccmode (insn, CCGOCmode)
10854 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10855 {
10856 switch (get_attr_type (insn))
10857 {
10858 case TYPE_ALU:
10859 if (operands[2] != const1_rtx)
10860 abort ();
10861 return "add{b}\t{%0, %0|%0, %0}";
10862
10863 default:
10864 if (REG_P (operands[2]))
10865 return "sal{b}\t{%b2, %0|%0, %b2}";
10866 else if (operands[2] == const1_rtx
10867 && (TARGET_SHIFT1 || optimize_size))
10868 return "sal{b}\t%0";
10869 else
10870 return "sal{b}\t{%2, %0|%0, %2}";
10871 }
10872 }
10873 [(set (attr "type")
10874 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10875 (const_int 0))
10876 (match_operand 0 "register_operand" ""))
10877 (match_operand 2 "const1_operand" ""))
10878 (const_string "alu")
10879 ]
10880 (const_string "ishift")))
10881 (set_attr "mode" "QI")])
10882
10883 ;; See comment above `ashldi3' about how this works.
10884
10885 (define_expand "ashrdi3"
10886 [(set (match_operand:DI 0 "shiftdi_operand" "")
10887 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10888 (match_operand:QI 2 "nonmemory_operand" "")))]
10889 ""
10890 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10891
10892 (define_insn "*ashrdi3_63_rex64"
10893 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10894 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10895 (match_operand:DI 2 "const_int_operand" "i,i")))
10896 (clobber (reg:CC FLAGS_REG))]
10897 "TARGET_64BIT && INTVAL (operands[2]) == 63
10898 && (TARGET_USE_CLTD || optimize_size)
10899 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10900 "@
10901 {cqto|cqo}
10902 sar{q}\t{%2, %0|%0, %2}"
10903 [(set_attr "type" "imovx,ishift")
10904 (set_attr "prefix_0f" "0,*")
10905 (set_attr "length_immediate" "0,*")
10906 (set_attr "modrm" "0,1")
10907 (set_attr "mode" "DI")])
10908
10909 (define_insn "*ashrdi3_1_one_bit_rex64"
10910 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10911 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10912 (match_operand:QI 2 "const1_operand" "")))
10913 (clobber (reg:CC FLAGS_REG))]
10914 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10915 && (TARGET_SHIFT1 || optimize_size)"
10916 "sar{q}\t%0"
10917 [(set_attr "type" "ishift")
10918 (set (attr "length")
10919 (if_then_else (match_operand:DI 0 "register_operand" "")
10920 (const_string "2")
10921 (const_string "*")))])
10922
10923 (define_insn "*ashrdi3_1_rex64"
10924 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10925 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10926 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10927 (clobber (reg:CC FLAGS_REG))]
10928 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10929 "@
10930 sar{q}\t{%2, %0|%0, %2}
10931 sar{q}\t{%b2, %0|%0, %b2}"
10932 [(set_attr "type" "ishift")
10933 (set_attr "mode" "DI")])
10934
10935 ;; This pattern can't accept a variable shift count, since shifts by
10936 ;; zero don't affect the flags. We assume that shifts by constant
10937 ;; zero are optimized away.
10938 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10939 [(set (reg FLAGS_REG)
10940 (compare
10941 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10942 (match_operand:QI 2 "const1_operand" ""))
10943 (const_int 0)))
10944 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10945 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10946 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10947 && (TARGET_SHIFT1 || optimize_size)
10948 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10949 "sar{q}\t%0"
10950 [(set_attr "type" "ishift")
10951 (set (attr "length")
10952 (if_then_else (match_operand:DI 0 "register_operand" "")
10953 (const_string "2")
10954 (const_string "*")))])
10955
10956 ;; This pattern can't accept a variable shift count, since shifts by
10957 ;; zero don't affect the flags. We assume that shifts by constant
10958 ;; zero are optimized away.
10959 (define_insn "*ashrdi3_cmp_rex64"
10960 [(set (reg FLAGS_REG)
10961 (compare
10962 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10963 (match_operand:QI 2 "const_int_operand" "n"))
10964 (const_int 0)))
10965 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10966 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10967 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10968 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10969 "sar{q}\t{%2, %0|%0, %2}"
10970 [(set_attr "type" "ishift")
10971 (set_attr "mode" "DI")])
10972
10973 (define_insn "*ashrdi3_1"
10974 [(set (match_operand:DI 0 "register_operand" "=r")
10975 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10976 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10977 (clobber (reg:CC FLAGS_REG))]
10978 "!TARGET_64BIT"
10979 "#"
10980 [(set_attr "type" "multi")])
10981
10982 ;; By default we don't ask for a scratch register, because when DImode
10983 ;; values are manipulated, registers are already at a premium. But if
10984 ;; we have one handy, we won't turn it away.
10985 (define_peephole2
10986 [(match_scratch:SI 3 "r")
10987 (parallel [(set (match_operand:DI 0 "register_operand" "")
10988 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10989 (match_operand:QI 2 "nonmemory_operand" "")))
10990 (clobber (reg:CC FLAGS_REG))])
10991 (match_dup 3)]
10992 "!TARGET_64BIT && TARGET_CMOVE"
10993 [(const_int 0)]
10994 "ix86_split_ashrdi (operands, operands[3]); DONE;")
10995
10996 (define_split
10997 [(set (match_operand:DI 0 "register_operand" "")
10998 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10999 (match_operand:QI 2 "nonmemory_operand" "")))
11000 (clobber (reg:CC FLAGS_REG))]
11001 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11002 [(const_int 0)]
11003 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11004
11005 (define_insn "x86_shrd_1"
11006 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11007 (ior:SI (ashiftrt:SI (match_dup 0)
11008 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11009 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11010 (minus:QI (const_int 32) (match_dup 2)))))
11011 (clobber (reg:CC FLAGS_REG))]
11012 ""
11013 "@
11014 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11015 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11016 [(set_attr "type" "ishift")
11017 (set_attr "prefix_0f" "1")
11018 (set_attr "pent_pair" "np")
11019 (set_attr "mode" "SI")])
11020
11021 (define_expand "x86_shift_adj_3"
11022 [(use (match_operand:SI 0 "register_operand" ""))
11023 (use (match_operand:SI 1 "register_operand" ""))
11024 (use (match_operand:QI 2 "register_operand" ""))]
11025 ""
11026 {
11027 rtx label = gen_label_rtx ();
11028 rtx tmp;
11029
11030 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11031
11032 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11033 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11034 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11035 gen_rtx_LABEL_REF (VOIDmode, label),
11036 pc_rtx);
11037 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11038 JUMP_LABEL (tmp) = label;
11039
11040 emit_move_insn (operands[0], operands[1]);
11041 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11042
11043 emit_label (label);
11044 LABEL_NUSES (label) = 1;
11045
11046 DONE;
11047 })
11048
11049 (define_insn "ashrsi3_31"
11050 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11051 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11052 (match_operand:SI 2 "const_int_operand" "i,i")))
11053 (clobber (reg:CC FLAGS_REG))]
11054 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11055 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11056 "@
11057 {cltd|cdq}
11058 sar{l}\t{%2, %0|%0, %2}"
11059 [(set_attr "type" "imovx,ishift")
11060 (set_attr "prefix_0f" "0,*")
11061 (set_attr "length_immediate" "0,*")
11062 (set_attr "modrm" "0,1")
11063 (set_attr "mode" "SI")])
11064
11065 (define_insn "*ashrsi3_31_zext"
11066 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11067 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11068 (match_operand:SI 2 "const_int_operand" "i,i"))))
11069 (clobber (reg:CC FLAGS_REG))]
11070 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11071 && INTVAL (operands[2]) == 31
11072 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11073 "@
11074 {cltd|cdq}
11075 sar{l}\t{%2, %k0|%k0, %2}"
11076 [(set_attr "type" "imovx,ishift")
11077 (set_attr "prefix_0f" "0,*")
11078 (set_attr "length_immediate" "0,*")
11079 (set_attr "modrm" "0,1")
11080 (set_attr "mode" "SI")])
11081
11082 (define_expand "ashrsi3"
11083 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11084 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11085 (match_operand:QI 2 "nonmemory_operand" "")))
11086 (clobber (reg:CC FLAGS_REG))]
11087 ""
11088 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11089
11090 (define_insn "*ashrsi3_1_one_bit"
11091 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11092 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11093 (match_operand:QI 2 "const1_operand" "")))
11094 (clobber (reg:CC FLAGS_REG))]
11095 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11096 && (TARGET_SHIFT1 || optimize_size)"
11097 "sar{l}\t%0"
11098 [(set_attr "type" "ishift")
11099 (set (attr "length")
11100 (if_then_else (match_operand:SI 0 "register_operand" "")
11101 (const_string "2")
11102 (const_string "*")))])
11103
11104 (define_insn "*ashrsi3_1_one_bit_zext"
11105 [(set (match_operand:DI 0 "register_operand" "=r")
11106 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11107 (match_operand:QI 2 "const1_operand" ""))))
11108 (clobber (reg:CC FLAGS_REG))]
11109 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11110 && (TARGET_SHIFT1 || optimize_size)"
11111 "sar{l}\t%k0"
11112 [(set_attr "type" "ishift")
11113 (set_attr "length" "2")])
11114
11115 (define_insn "*ashrsi3_1"
11116 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11117 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11118 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11119 (clobber (reg:CC FLAGS_REG))]
11120 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11121 "@
11122 sar{l}\t{%2, %0|%0, %2}
11123 sar{l}\t{%b2, %0|%0, %b2}"
11124 [(set_attr "type" "ishift")
11125 (set_attr "mode" "SI")])
11126
11127 (define_insn "*ashrsi3_1_zext"
11128 [(set (match_operand:DI 0 "register_operand" "=r,r")
11129 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11130 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11131 (clobber (reg:CC FLAGS_REG))]
11132 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11133 "@
11134 sar{l}\t{%2, %k0|%k0, %2}
11135 sar{l}\t{%b2, %k0|%k0, %b2}"
11136 [(set_attr "type" "ishift")
11137 (set_attr "mode" "SI")])
11138
11139 ;; This pattern can't accept a variable shift count, since shifts by
11140 ;; zero don't affect the flags. We assume that shifts by constant
11141 ;; zero are optimized away.
11142 (define_insn "*ashrsi3_one_bit_cmp"
11143 [(set (reg FLAGS_REG)
11144 (compare
11145 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11146 (match_operand:QI 2 "const1_operand" ""))
11147 (const_int 0)))
11148 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11149 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11150 "ix86_match_ccmode (insn, CCGOCmode)
11151 && (TARGET_SHIFT1 || optimize_size)
11152 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11153 "sar{l}\t%0"
11154 [(set_attr "type" "ishift")
11155 (set (attr "length")
11156 (if_then_else (match_operand:SI 0 "register_operand" "")
11157 (const_string "2")
11158 (const_string "*")))])
11159
11160 (define_insn "*ashrsi3_one_bit_cmp_zext"
11161 [(set (reg FLAGS_REG)
11162 (compare
11163 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11164 (match_operand:QI 2 "const1_operand" ""))
11165 (const_int 0)))
11166 (set (match_operand:DI 0 "register_operand" "=r")
11167 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11168 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11169 && (TARGET_SHIFT1 || optimize_size)
11170 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11171 "sar{l}\t%k0"
11172 [(set_attr "type" "ishift")
11173 (set_attr "length" "2")])
11174
11175 ;; This pattern can't accept a variable shift count, since shifts by
11176 ;; zero don't affect the flags. We assume that shifts by constant
11177 ;; zero are optimized away.
11178 (define_insn "*ashrsi3_cmp"
11179 [(set (reg FLAGS_REG)
11180 (compare
11181 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11182 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11183 (const_int 0)))
11184 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11185 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11186 "ix86_match_ccmode (insn, CCGOCmode)
11187 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11188 "sar{l}\t{%2, %0|%0, %2}"
11189 [(set_attr "type" "ishift")
11190 (set_attr "mode" "SI")])
11191
11192 (define_insn "*ashrsi3_cmp_zext"
11193 [(set (reg FLAGS_REG)
11194 (compare
11195 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11196 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11197 (const_int 0)))
11198 (set (match_operand:DI 0 "register_operand" "=r")
11199 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11200 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11201 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11202 "sar{l}\t{%2, %k0|%k0, %2}"
11203 [(set_attr "type" "ishift")
11204 (set_attr "mode" "SI")])
11205
11206 (define_expand "ashrhi3"
11207 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11208 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11209 (match_operand:QI 2 "nonmemory_operand" "")))
11210 (clobber (reg:CC FLAGS_REG))]
11211 "TARGET_HIMODE_MATH"
11212 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11213
11214 (define_insn "*ashrhi3_1_one_bit"
11215 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11216 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11217 (match_operand:QI 2 "const1_operand" "")))
11218 (clobber (reg:CC FLAGS_REG))]
11219 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11220 && (TARGET_SHIFT1 || optimize_size)"
11221 "sar{w}\t%0"
11222 [(set_attr "type" "ishift")
11223 (set (attr "length")
11224 (if_then_else (match_operand 0 "register_operand" "")
11225 (const_string "2")
11226 (const_string "*")))])
11227
11228 (define_insn "*ashrhi3_1"
11229 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11230 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11231 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11232 (clobber (reg:CC FLAGS_REG))]
11233 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11234 "@
11235 sar{w}\t{%2, %0|%0, %2}
11236 sar{w}\t{%b2, %0|%0, %b2}"
11237 [(set_attr "type" "ishift")
11238 (set_attr "mode" "HI")])
11239
11240 ;; This pattern can't accept a variable shift count, since shifts by
11241 ;; zero don't affect the flags. We assume that shifts by constant
11242 ;; zero are optimized away.
11243 (define_insn "*ashrhi3_one_bit_cmp"
11244 [(set (reg FLAGS_REG)
11245 (compare
11246 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11247 (match_operand:QI 2 "const1_operand" ""))
11248 (const_int 0)))
11249 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11250 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11251 "ix86_match_ccmode (insn, CCGOCmode)
11252 && (TARGET_SHIFT1 || optimize_size)
11253 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11254 "sar{w}\t%0"
11255 [(set_attr "type" "ishift")
11256 (set (attr "length")
11257 (if_then_else (match_operand 0 "register_operand" "")
11258 (const_string "2")
11259 (const_string "*")))])
11260
11261 ;; This pattern can't accept a variable shift count, since shifts by
11262 ;; zero don't affect the flags. We assume that shifts by constant
11263 ;; zero are optimized away.
11264 (define_insn "*ashrhi3_cmp"
11265 [(set (reg FLAGS_REG)
11266 (compare
11267 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11268 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11269 (const_int 0)))
11270 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11271 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11272 "ix86_match_ccmode (insn, CCGOCmode)
11273 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11274 "sar{w}\t{%2, %0|%0, %2}"
11275 [(set_attr "type" "ishift")
11276 (set_attr "mode" "HI")])
11277
11278 (define_expand "ashrqi3"
11279 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11280 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11281 (match_operand:QI 2 "nonmemory_operand" "")))
11282 (clobber (reg:CC FLAGS_REG))]
11283 "TARGET_QIMODE_MATH"
11284 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11285
11286 (define_insn "*ashrqi3_1_one_bit"
11287 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11288 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11289 (match_operand:QI 2 "const1_operand" "")))
11290 (clobber (reg:CC FLAGS_REG))]
11291 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11292 && (TARGET_SHIFT1 || optimize_size)"
11293 "sar{b}\t%0"
11294 [(set_attr "type" "ishift")
11295 (set (attr "length")
11296 (if_then_else (match_operand 0 "register_operand" "")
11297 (const_string "2")
11298 (const_string "*")))])
11299
11300 (define_insn "*ashrqi3_1_one_bit_slp"
11301 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11302 (ashiftrt:QI (match_dup 0)
11303 (match_operand:QI 1 "const1_operand" "")))
11304 (clobber (reg:CC FLAGS_REG))]
11305 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11306 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11307 && (TARGET_SHIFT1 || optimize_size)"
11308 "sar{b}\t%0"
11309 [(set_attr "type" "ishift1")
11310 (set (attr "length")
11311 (if_then_else (match_operand 0 "register_operand" "")
11312 (const_string "2")
11313 (const_string "*")))])
11314
11315 (define_insn "*ashrqi3_1"
11316 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11317 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11318 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11319 (clobber (reg:CC FLAGS_REG))]
11320 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11321 "@
11322 sar{b}\t{%2, %0|%0, %2}
11323 sar{b}\t{%b2, %0|%0, %b2}"
11324 [(set_attr "type" "ishift")
11325 (set_attr "mode" "QI")])
11326
11327 (define_insn "*ashrqi3_1_slp"
11328 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11329 (ashiftrt:QI (match_dup 0)
11330 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11331 (clobber (reg:CC FLAGS_REG))]
11332 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11333 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11334 "@
11335 sar{b}\t{%1, %0|%0, %1}
11336 sar{b}\t{%b1, %0|%0, %b1}"
11337 [(set_attr "type" "ishift1")
11338 (set_attr "mode" "QI")])
11339
11340 ;; This pattern can't accept a variable shift count, since shifts by
11341 ;; zero don't affect the flags. We assume that shifts by constant
11342 ;; zero are optimized away.
11343 (define_insn "*ashrqi3_one_bit_cmp"
11344 [(set (reg FLAGS_REG)
11345 (compare
11346 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11347 (match_operand:QI 2 "const1_operand" "I"))
11348 (const_int 0)))
11349 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11350 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11351 "ix86_match_ccmode (insn, CCGOCmode)
11352 && (TARGET_SHIFT1 || optimize_size)
11353 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11354 "sar{b}\t%0"
11355 [(set_attr "type" "ishift")
11356 (set (attr "length")
11357 (if_then_else (match_operand 0 "register_operand" "")
11358 (const_string "2")
11359 (const_string "*")))])
11360
11361 ;; This pattern can't accept a variable shift count, since shifts by
11362 ;; zero don't affect the flags. We assume that shifts by constant
11363 ;; zero are optimized away.
11364 (define_insn "*ashrqi3_cmp"
11365 [(set (reg FLAGS_REG)
11366 (compare
11367 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11368 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11369 (const_int 0)))
11370 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11371 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11372 "ix86_match_ccmode (insn, CCGOCmode)
11373 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11374 "sar{b}\t{%2, %0|%0, %2}"
11375 [(set_attr "type" "ishift")
11376 (set_attr "mode" "QI")])
11377 \f
11378 ;; Logical shift instructions
11379
11380 ;; See comment above `ashldi3' about how this works.
11381
11382 (define_expand "lshrdi3"
11383 [(set (match_operand:DI 0 "shiftdi_operand" "")
11384 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11385 (match_operand:QI 2 "nonmemory_operand" "")))]
11386 ""
11387 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11388
11389 (define_insn "*lshrdi3_1_one_bit_rex64"
11390 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11391 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11392 (match_operand:QI 2 "const1_operand" "")))
11393 (clobber (reg:CC FLAGS_REG))]
11394 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11395 && (TARGET_SHIFT1 || optimize_size)"
11396 "shr{q}\t%0"
11397 [(set_attr "type" "ishift")
11398 (set (attr "length")
11399 (if_then_else (match_operand:DI 0 "register_operand" "")
11400 (const_string "2")
11401 (const_string "*")))])
11402
11403 (define_insn "*lshrdi3_1_rex64"
11404 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11405 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11406 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11407 (clobber (reg:CC FLAGS_REG))]
11408 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11409 "@
11410 shr{q}\t{%2, %0|%0, %2}
11411 shr{q}\t{%b2, %0|%0, %b2}"
11412 [(set_attr "type" "ishift")
11413 (set_attr "mode" "DI")])
11414
11415 ;; This pattern can't accept a variable shift count, since shifts by
11416 ;; zero don't affect the flags. We assume that shifts by constant
11417 ;; zero are optimized away.
11418 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11419 [(set (reg FLAGS_REG)
11420 (compare
11421 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11422 (match_operand:QI 2 "const1_operand" ""))
11423 (const_int 0)))
11424 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11425 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11426 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11427 && (TARGET_SHIFT1 || optimize_size)
11428 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11429 "shr{q}\t%0"
11430 [(set_attr "type" "ishift")
11431 (set (attr "length")
11432 (if_then_else (match_operand:DI 0 "register_operand" "")
11433 (const_string "2")
11434 (const_string "*")))])
11435
11436 ;; This pattern can't accept a variable shift count, since shifts by
11437 ;; zero don't affect the flags. We assume that shifts by constant
11438 ;; zero are optimized away.
11439 (define_insn "*lshrdi3_cmp_rex64"
11440 [(set (reg FLAGS_REG)
11441 (compare
11442 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11443 (match_operand:QI 2 "const_int_operand" "e"))
11444 (const_int 0)))
11445 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11446 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11447 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11448 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11449 "shr{q}\t{%2, %0|%0, %2}"
11450 [(set_attr "type" "ishift")
11451 (set_attr "mode" "DI")])
11452
11453 (define_insn "*lshrdi3_1"
11454 [(set (match_operand:DI 0 "register_operand" "=r")
11455 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11456 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11457 (clobber (reg:CC FLAGS_REG))]
11458 "!TARGET_64BIT"
11459 "#"
11460 [(set_attr "type" "multi")])
11461
11462 ;; By default we don't ask for a scratch register, because when DImode
11463 ;; values are manipulated, registers are already at a premium. But if
11464 ;; we have one handy, we won't turn it away.
11465 (define_peephole2
11466 [(match_scratch:SI 3 "r")
11467 (parallel [(set (match_operand:DI 0 "register_operand" "")
11468 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11469 (match_operand:QI 2 "nonmemory_operand" "")))
11470 (clobber (reg:CC FLAGS_REG))])
11471 (match_dup 3)]
11472 "!TARGET_64BIT && TARGET_CMOVE"
11473 [(const_int 0)]
11474 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11475
11476 (define_split
11477 [(set (match_operand:DI 0 "register_operand" "")
11478 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11479 (match_operand:QI 2 "nonmemory_operand" "")))
11480 (clobber (reg:CC FLAGS_REG))]
11481 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11482 [(const_int 0)]
11483 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11484
11485 (define_expand "lshrsi3"
11486 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11487 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11488 (match_operand:QI 2 "nonmemory_operand" "")))
11489 (clobber (reg:CC FLAGS_REG))]
11490 ""
11491 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11492
11493 (define_insn "*lshrsi3_1_one_bit"
11494 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11495 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11496 (match_operand:QI 2 "const1_operand" "")))
11497 (clobber (reg:CC FLAGS_REG))]
11498 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11499 && (TARGET_SHIFT1 || optimize_size)"
11500 "shr{l}\t%0"
11501 [(set_attr "type" "ishift")
11502 (set (attr "length")
11503 (if_then_else (match_operand:SI 0 "register_operand" "")
11504 (const_string "2")
11505 (const_string "*")))])
11506
11507 (define_insn "*lshrsi3_1_one_bit_zext"
11508 [(set (match_operand:DI 0 "register_operand" "=r")
11509 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11510 (match_operand:QI 2 "const1_operand" "")))
11511 (clobber (reg:CC FLAGS_REG))]
11512 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11513 && (TARGET_SHIFT1 || optimize_size)"
11514 "shr{l}\t%k0"
11515 [(set_attr "type" "ishift")
11516 (set_attr "length" "2")])
11517
11518 (define_insn "*lshrsi3_1"
11519 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11520 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11521 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11522 (clobber (reg:CC FLAGS_REG))]
11523 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11524 "@
11525 shr{l}\t{%2, %0|%0, %2}
11526 shr{l}\t{%b2, %0|%0, %b2}"
11527 [(set_attr "type" "ishift")
11528 (set_attr "mode" "SI")])
11529
11530 (define_insn "*lshrsi3_1_zext"
11531 [(set (match_operand:DI 0 "register_operand" "=r,r")
11532 (zero_extend:DI
11533 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11534 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11535 (clobber (reg:CC FLAGS_REG))]
11536 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11537 "@
11538 shr{l}\t{%2, %k0|%k0, %2}
11539 shr{l}\t{%b2, %k0|%k0, %b2}"
11540 [(set_attr "type" "ishift")
11541 (set_attr "mode" "SI")])
11542
11543 ;; This pattern can't accept a variable shift count, since shifts by
11544 ;; zero don't affect the flags. We assume that shifts by constant
11545 ;; zero are optimized away.
11546 (define_insn "*lshrsi3_one_bit_cmp"
11547 [(set (reg FLAGS_REG)
11548 (compare
11549 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11550 (match_operand:QI 2 "const1_operand" ""))
11551 (const_int 0)))
11552 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11553 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11554 "ix86_match_ccmode (insn, CCGOCmode)
11555 && (TARGET_SHIFT1 || optimize_size)
11556 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11557 "shr{l}\t%0"
11558 [(set_attr "type" "ishift")
11559 (set (attr "length")
11560 (if_then_else (match_operand:SI 0 "register_operand" "")
11561 (const_string "2")
11562 (const_string "*")))])
11563
11564 (define_insn "*lshrsi3_cmp_one_bit_zext"
11565 [(set (reg FLAGS_REG)
11566 (compare
11567 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11568 (match_operand:QI 2 "const1_operand" ""))
11569 (const_int 0)))
11570 (set (match_operand:DI 0 "register_operand" "=r")
11571 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11572 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11573 && (TARGET_SHIFT1 || optimize_size)
11574 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11575 "shr{l}\t%k0"
11576 [(set_attr "type" "ishift")
11577 (set_attr "length" "2")])
11578
11579 ;; This pattern can't accept a variable shift count, since shifts by
11580 ;; zero don't affect the flags. We assume that shifts by constant
11581 ;; zero are optimized away.
11582 (define_insn "*lshrsi3_cmp"
11583 [(set (reg FLAGS_REG)
11584 (compare
11585 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11586 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11587 (const_int 0)))
11588 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11589 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11590 "ix86_match_ccmode (insn, CCGOCmode)
11591 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11592 "shr{l}\t{%2, %0|%0, %2}"
11593 [(set_attr "type" "ishift")
11594 (set_attr "mode" "SI")])
11595
11596 (define_insn "*lshrsi3_cmp_zext"
11597 [(set (reg FLAGS_REG)
11598 (compare
11599 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11600 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11601 (const_int 0)))
11602 (set (match_operand:DI 0 "register_operand" "=r")
11603 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11604 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11605 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11606 "shr{l}\t{%2, %k0|%k0, %2}"
11607 [(set_attr "type" "ishift")
11608 (set_attr "mode" "SI")])
11609
11610 (define_expand "lshrhi3"
11611 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11612 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11613 (match_operand:QI 2 "nonmemory_operand" "")))
11614 (clobber (reg:CC FLAGS_REG))]
11615 "TARGET_HIMODE_MATH"
11616 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11617
11618 (define_insn "*lshrhi3_1_one_bit"
11619 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11620 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11621 (match_operand:QI 2 "const1_operand" "")))
11622 (clobber (reg:CC FLAGS_REG))]
11623 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11624 && (TARGET_SHIFT1 || optimize_size)"
11625 "shr{w}\t%0"
11626 [(set_attr "type" "ishift")
11627 (set (attr "length")
11628 (if_then_else (match_operand 0 "register_operand" "")
11629 (const_string "2")
11630 (const_string "*")))])
11631
11632 (define_insn "*lshrhi3_1"
11633 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11634 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11635 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11636 (clobber (reg:CC FLAGS_REG))]
11637 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11638 "@
11639 shr{w}\t{%2, %0|%0, %2}
11640 shr{w}\t{%b2, %0|%0, %b2}"
11641 [(set_attr "type" "ishift")
11642 (set_attr "mode" "HI")])
11643
11644 ;; This pattern can't accept a variable shift count, since shifts by
11645 ;; zero don't affect the flags. We assume that shifts by constant
11646 ;; zero are optimized away.
11647 (define_insn "*lshrhi3_one_bit_cmp"
11648 [(set (reg FLAGS_REG)
11649 (compare
11650 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11651 (match_operand:QI 2 "const1_operand" ""))
11652 (const_int 0)))
11653 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11654 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11655 "ix86_match_ccmode (insn, CCGOCmode)
11656 && (TARGET_SHIFT1 || optimize_size)
11657 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11658 "shr{w}\t%0"
11659 [(set_attr "type" "ishift")
11660 (set (attr "length")
11661 (if_then_else (match_operand:SI 0 "register_operand" "")
11662 (const_string "2")
11663 (const_string "*")))])
11664
11665 ;; This pattern can't accept a variable shift count, since shifts by
11666 ;; zero don't affect the flags. We assume that shifts by constant
11667 ;; zero are optimized away.
11668 (define_insn "*lshrhi3_cmp"
11669 [(set (reg FLAGS_REG)
11670 (compare
11671 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11672 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11673 (const_int 0)))
11674 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11675 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11676 "ix86_match_ccmode (insn, CCGOCmode)
11677 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11678 "shr{w}\t{%2, %0|%0, %2}"
11679 [(set_attr "type" "ishift")
11680 (set_attr "mode" "HI")])
11681
11682 (define_expand "lshrqi3"
11683 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11684 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11685 (match_operand:QI 2 "nonmemory_operand" "")))
11686 (clobber (reg:CC FLAGS_REG))]
11687 "TARGET_QIMODE_MATH"
11688 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11689
11690 (define_insn "*lshrqi3_1_one_bit"
11691 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11692 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11693 (match_operand:QI 2 "const1_operand" "")))
11694 (clobber (reg:CC FLAGS_REG))]
11695 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11696 && (TARGET_SHIFT1 || optimize_size)"
11697 "shr{b}\t%0"
11698 [(set_attr "type" "ishift")
11699 (set (attr "length")
11700 (if_then_else (match_operand 0 "register_operand" "")
11701 (const_string "2")
11702 (const_string "*")))])
11703
11704 (define_insn "*lshrqi3_1_one_bit_slp"
11705 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11706 (lshiftrt:QI (match_dup 0)
11707 (match_operand:QI 1 "const1_operand" "")))
11708 (clobber (reg:CC FLAGS_REG))]
11709 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11710 && (TARGET_SHIFT1 || optimize_size)"
11711 "shr{b}\t%0"
11712 [(set_attr "type" "ishift1")
11713 (set (attr "length")
11714 (if_then_else (match_operand 0 "register_operand" "")
11715 (const_string "2")
11716 (const_string "*")))])
11717
11718 (define_insn "*lshrqi3_1"
11719 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11720 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11721 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11722 (clobber (reg:CC FLAGS_REG))]
11723 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11724 "@
11725 shr{b}\t{%2, %0|%0, %2}
11726 shr{b}\t{%b2, %0|%0, %b2}"
11727 [(set_attr "type" "ishift")
11728 (set_attr "mode" "QI")])
11729
11730 (define_insn "*lshrqi3_1_slp"
11731 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11732 (lshiftrt:QI (match_dup 0)
11733 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11734 (clobber (reg:CC FLAGS_REG))]
11735 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11736 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11737 "@
11738 shr{b}\t{%1, %0|%0, %1}
11739 shr{b}\t{%b1, %0|%0, %b1}"
11740 [(set_attr "type" "ishift1")
11741 (set_attr "mode" "QI")])
11742
11743 ;; This pattern can't accept a variable shift count, since shifts by
11744 ;; zero don't affect the flags. We assume that shifts by constant
11745 ;; zero are optimized away.
11746 (define_insn "*lshrqi2_one_bit_cmp"
11747 [(set (reg FLAGS_REG)
11748 (compare
11749 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11750 (match_operand:QI 2 "const1_operand" ""))
11751 (const_int 0)))
11752 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11753 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11754 "ix86_match_ccmode (insn, CCGOCmode)
11755 && (TARGET_SHIFT1 || optimize_size)
11756 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11757 "shr{b}\t%0"
11758 [(set_attr "type" "ishift")
11759 (set (attr "length")
11760 (if_then_else (match_operand:SI 0 "register_operand" "")
11761 (const_string "2")
11762 (const_string "*")))])
11763
11764 ;; This pattern can't accept a variable shift count, since shifts by
11765 ;; zero don't affect the flags. We assume that shifts by constant
11766 ;; zero are optimized away.
11767 (define_insn "*lshrqi2_cmp"
11768 [(set (reg FLAGS_REG)
11769 (compare
11770 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11771 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11772 (const_int 0)))
11773 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11774 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11775 "ix86_match_ccmode (insn, CCGOCmode)
11776 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11777 "shr{b}\t{%2, %0|%0, %2}"
11778 [(set_attr "type" "ishift")
11779 (set_attr "mode" "QI")])
11780 \f
11781 ;; Rotate instructions
11782
11783 (define_expand "rotldi3"
11784 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11785 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11786 (match_operand:QI 2 "nonmemory_operand" "")))
11787 (clobber (reg:CC FLAGS_REG))]
11788 "TARGET_64BIT"
11789 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11790
11791 (define_insn "*rotlsi3_1_one_bit_rex64"
11792 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11793 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11794 (match_operand:QI 2 "const1_operand" "")))
11795 (clobber (reg:CC FLAGS_REG))]
11796 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11797 && (TARGET_SHIFT1 || optimize_size)"
11798 "rol{q}\t%0"
11799 [(set_attr "type" "rotate")
11800 (set (attr "length")
11801 (if_then_else (match_operand:DI 0 "register_operand" "")
11802 (const_string "2")
11803 (const_string "*")))])
11804
11805 (define_insn "*rotldi3_1_rex64"
11806 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11807 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11808 (match_operand:QI 2 "nonmemory_operand" "e,c")))
11809 (clobber (reg:CC FLAGS_REG))]
11810 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11811 "@
11812 rol{q}\t{%2, %0|%0, %2}
11813 rol{q}\t{%b2, %0|%0, %b2}"
11814 [(set_attr "type" "rotate")
11815 (set_attr "mode" "DI")])
11816
11817 (define_expand "rotlsi3"
11818 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11819 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11820 (match_operand:QI 2 "nonmemory_operand" "")))
11821 (clobber (reg:CC FLAGS_REG))]
11822 ""
11823 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11824
11825 (define_insn "*rotlsi3_1_one_bit"
11826 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11827 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11828 (match_operand:QI 2 "const1_operand" "")))
11829 (clobber (reg:CC FLAGS_REG))]
11830 "ix86_binary_operator_ok (ROTATE, SImode, operands)
11831 && (TARGET_SHIFT1 || optimize_size)"
11832 "rol{l}\t%0"
11833 [(set_attr "type" "rotate")
11834 (set (attr "length")
11835 (if_then_else (match_operand:SI 0 "register_operand" "")
11836 (const_string "2")
11837 (const_string "*")))])
11838
11839 (define_insn "*rotlsi3_1_one_bit_zext"
11840 [(set (match_operand:DI 0 "register_operand" "=r")
11841 (zero_extend:DI
11842 (rotate:SI (match_operand:SI 1 "register_operand" "0")
11843 (match_operand:QI 2 "const1_operand" ""))))
11844 (clobber (reg:CC FLAGS_REG))]
11845 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11846 && (TARGET_SHIFT1 || optimize_size)"
11847 "rol{l}\t%k0"
11848 [(set_attr "type" "rotate")
11849 (set_attr "length" "2")])
11850
11851 (define_insn "*rotlsi3_1"
11852 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11853 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11854 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11855 (clobber (reg:CC FLAGS_REG))]
11856 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11857 "@
11858 rol{l}\t{%2, %0|%0, %2}
11859 rol{l}\t{%b2, %0|%0, %b2}"
11860 [(set_attr "type" "rotate")
11861 (set_attr "mode" "SI")])
11862
11863 (define_insn "*rotlsi3_1_zext"
11864 [(set (match_operand:DI 0 "register_operand" "=r,r")
11865 (zero_extend:DI
11866 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11867 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11868 (clobber (reg:CC FLAGS_REG))]
11869 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11870 "@
11871 rol{l}\t{%2, %k0|%k0, %2}
11872 rol{l}\t{%b2, %k0|%k0, %b2}"
11873 [(set_attr "type" "rotate")
11874 (set_attr "mode" "SI")])
11875
11876 (define_expand "rotlhi3"
11877 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11878 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11879 (match_operand:QI 2 "nonmemory_operand" "")))
11880 (clobber (reg:CC FLAGS_REG))]
11881 "TARGET_HIMODE_MATH"
11882 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11883
11884 (define_insn "*rotlhi3_1_one_bit"
11885 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11886 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11887 (match_operand:QI 2 "const1_operand" "")))
11888 (clobber (reg:CC FLAGS_REG))]
11889 "ix86_binary_operator_ok (ROTATE, HImode, operands)
11890 && (TARGET_SHIFT1 || optimize_size)"
11891 "rol{w}\t%0"
11892 [(set_attr "type" "rotate")
11893 (set (attr "length")
11894 (if_then_else (match_operand 0 "register_operand" "")
11895 (const_string "2")
11896 (const_string "*")))])
11897
11898 (define_insn "*rotlhi3_1"
11899 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11900 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11901 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11902 (clobber (reg:CC FLAGS_REG))]
11903 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11904 "@
11905 rol{w}\t{%2, %0|%0, %2}
11906 rol{w}\t{%b2, %0|%0, %b2}"
11907 [(set_attr "type" "rotate")
11908 (set_attr "mode" "HI")])
11909
11910 (define_expand "rotlqi3"
11911 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11912 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11913 (match_operand:QI 2 "nonmemory_operand" "")))
11914 (clobber (reg:CC FLAGS_REG))]
11915 "TARGET_QIMODE_MATH"
11916 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11917
11918 (define_insn "*rotlqi3_1_one_bit_slp"
11919 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11920 (rotate:QI (match_dup 0)
11921 (match_operand:QI 1 "const1_operand" "")))
11922 (clobber (reg:CC FLAGS_REG))]
11923 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11924 && (TARGET_SHIFT1 || optimize_size)"
11925 "rol{b}\t%0"
11926 [(set_attr "type" "rotate1")
11927 (set (attr "length")
11928 (if_then_else (match_operand 0 "register_operand" "")
11929 (const_string "2")
11930 (const_string "*")))])
11931
11932 (define_insn "*rotlqi3_1_one_bit"
11933 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11934 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11935 (match_operand:QI 2 "const1_operand" "")))
11936 (clobber (reg:CC FLAGS_REG))]
11937 "ix86_binary_operator_ok (ROTATE, QImode, operands)
11938 && (TARGET_SHIFT1 || optimize_size)"
11939 "rol{b}\t%0"
11940 [(set_attr "type" "rotate")
11941 (set (attr "length")
11942 (if_then_else (match_operand 0 "register_operand" "")
11943 (const_string "2")
11944 (const_string "*")))])
11945
11946 (define_insn "*rotlqi3_1_slp"
11947 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11948 (rotate:QI (match_dup 0)
11949 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11950 (clobber (reg:CC FLAGS_REG))]
11951 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11952 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11953 "@
11954 rol{b}\t{%1, %0|%0, %1}
11955 rol{b}\t{%b1, %0|%0, %b1}"
11956 [(set_attr "type" "rotate1")
11957 (set_attr "mode" "QI")])
11958
11959 (define_insn "*rotlqi3_1"
11960 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11961 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11962 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11963 (clobber (reg:CC FLAGS_REG))]
11964 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11965 "@
11966 rol{b}\t{%2, %0|%0, %2}
11967 rol{b}\t{%b2, %0|%0, %b2}"
11968 [(set_attr "type" "rotate")
11969 (set_attr "mode" "QI")])
11970
11971 (define_expand "rotrdi3"
11972 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11973 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11974 (match_operand:QI 2 "nonmemory_operand" "")))
11975 (clobber (reg:CC FLAGS_REG))]
11976 "TARGET_64BIT"
11977 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11978
11979 (define_insn "*rotrdi3_1_one_bit_rex64"
11980 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11981 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11982 (match_operand:QI 2 "const1_operand" "")))
11983 (clobber (reg:CC FLAGS_REG))]
11984 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11985 && (TARGET_SHIFT1 || optimize_size)"
11986 "ror{q}\t%0"
11987 [(set_attr "type" "rotate")
11988 (set (attr "length")
11989 (if_then_else (match_operand:DI 0 "register_operand" "")
11990 (const_string "2")
11991 (const_string "*")))])
11992
11993 (define_insn "*rotrdi3_1_rex64"
11994 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11995 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11996 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11997 (clobber (reg:CC FLAGS_REG))]
11998 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11999 "@
12000 ror{q}\t{%2, %0|%0, %2}
12001 ror{q}\t{%b2, %0|%0, %b2}"
12002 [(set_attr "type" "rotate")
12003 (set_attr "mode" "DI")])
12004
12005 (define_expand "rotrsi3"
12006 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12007 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12008 (match_operand:QI 2 "nonmemory_operand" "")))
12009 (clobber (reg:CC FLAGS_REG))]
12010 ""
12011 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12012
12013 (define_insn "*rotrsi3_1_one_bit"
12014 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12015 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12016 (match_operand:QI 2 "const1_operand" "")))
12017 (clobber (reg:CC FLAGS_REG))]
12018 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12019 && (TARGET_SHIFT1 || optimize_size)"
12020 "ror{l}\t%0"
12021 [(set_attr "type" "rotate")
12022 (set (attr "length")
12023 (if_then_else (match_operand:SI 0 "register_operand" "")
12024 (const_string "2")
12025 (const_string "*")))])
12026
12027 (define_insn "*rotrsi3_1_one_bit_zext"
12028 [(set (match_operand:DI 0 "register_operand" "=r")
12029 (zero_extend:DI
12030 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12031 (match_operand:QI 2 "const1_operand" ""))))
12032 (clobber (reg:CC FLAGS_REG))]
12033 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12034 && (TARGET_SHIFT1 || optimize_size)"
12035 "ror{l}\t%k0"
12036 [(set_attr "type" "rotate")
12037 (set (attr "length")
12038 (if_then_else (match_operand:SI 0 "register_operand" "")
12039 (const_string "2")
12040 (const_string "*")))])
12041
12042 (define_insn "*rotrsi3_1"
12043 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12044 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12045 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12046 (clobber (reg:CC FLAGS_REG))]
12047 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12048 "@
12049 ror{l}\t{%2, %0|%0, %2}
12050 ror{l}\t{%b2, %0|%0, %b2}"
12051 [(set_attr "type" "rotate")
12052 (set_attr "mode" "SI")])
12053
12054 (define_insn "*rotrsi3_1_zext"
12055 [(set (match_operand:DI 0 "register_operand" "=r,r")
12056 (zero_extend:DI
12057 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12058 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12059 (clobber (reg:CC FLAGS_REG))]
12060 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12061 "@
12062 ror{l}\t{%2, %k0|%k0, %2}
12063 ror{l}\t{%b2, %k0|%k0, %b2}"
12064 [(set_attr "type" "rotate")
12065 (set_attr "mode" "SI")])
12066
12067 (define_expand "rotrhi3"
12068 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12069 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12070 (match_operand:QI 2 "nonmemory_operand" "")))
12071 (clobber (reg:CC FLAGS_REG))]
12072 "TARGET_HIMODE_MATH"
12073 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12074
12075 (define_insn "*rotrhi3_one_bit"
12076 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12077 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12078 (match_operand:QI 2 "const1_operand" "")))
12079 (clobber (reg:CC FLAGS_REG))]
12080 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12081 && (TARGET_SHIFT1 || optimize_size)"
12082 "ror{w}\t%0"
12083 [(set_attr "type" "rotate")
12084 (set (attr "length")
12085 (if_then_else (match_operand 0 "register_operand" "")
12086 (const_string "2")
12087 (const_string "*")))])
12088
12089 (define_insn "*rotrhi3"
12090 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12091 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12092 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12093 (clobber (reg:CC FLAGS_REG))]
12094 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12095 "@
12096 ror{w}\t{%2, %0|%0, %2}
12097 ror{w}\t{%b2, %0|%0, %b2}"
12098 [(set_attr "type" "rotate")
12099 (set_attr "mode" "HI")])
12100
12101 (define_expand "rotrqi3"
12102 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12103 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12104 (match_operand:QI 2 "nonmemory_operand" "")))
12105 (clobber (reg:CC FLAGS_REG))]
12106 "TARGET_QIMODE_MATH"
12107 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12108
12109 (define_insn "*rotrqi3_1_one_bit"
12110 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12111 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12112 (match_operand:QI 2 "const1_operand" "")))
12113 (clobber (reg:CC FLAGS_REG))]
12114 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12115 && (TARGET_SHIFT1 || optimize_size)"
12116 "ror{b}\t%0"
12117 [(set_attr "type" "rotate")
12118 (set (attr "length")
12119 (if_then_else (match_operand 0 "register_operand" "")
12120 (const_string "2")
12121 (const_string "*")))])
12122
12123 (define_insn "*rotrqi3_1_one_bit_slp"
12124 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12125 (rotatert:QI (match_dup 0)
12126 (match_operand:QI 1 "const1_operand" "")))
12127 (clobber (reg:CC FLAGS_REG))]
12128 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12129 && (TARGET_SHIFT1 || optimize_size)"
12130 "ror{b}\t%0"
12131 [(set_attr "type" "rotate1")
12132 (set (attr "length")
12133 (if_then_else (match_operand 0 "register_operand" "")
12134 (const_string "2")
12135 (const_string "*")))])
12136
12137 (define_insn "*rotrqi3_1"
12138 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12139 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12140 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12141 (clobber (reg:CC FLAGS_REG))]
12142 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12143 "@
12144 ror{b}\t{%2, %0|%0, %2}
12145 ror{b}\t{%b2, %0|%0, %b2}"
12146 [(set_attr "type" "rotate")
12147 (set_attr "mode" "QI")])
12148
12149 (define_insn "*rotrqi3_1_slp"
12150 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12151 (rotatert:QI (match_dup 0)
12152 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12153 (clobber (reg:CC FLAGS_REG))]
12154 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12155 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12156 "@
12157 ror{b}\t{%1, %0|%0, %1}
12158 ror{b}\t{%b1, %0|%0, %b1}"
12159 [(set_attr "type" "rotate1")
12160 (set_attr "mode" "QI")])
12161 \f
12162 ;; Bit set / bit test instructions
12163
12164 (define_expand "extv"
12165 [(set (match_operand:SI 0 "register_operand" "")
12166 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12167 (match_operand:SI 2 "immediate_operand" "")
12168 (match_operand:SI 3 "immediate_operand" "")))]
12169 ""
12170 {
12171 /* Handle extractions from %ah et al. */
12172 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12173 FAIL;
12174
12175 /* From mips.md: extract_bit_field doesn't verify that our source
12176 matches the predicate, so check it again here. */
12177 if (! ext_register_operand (operands[1], VOIDmode))
12178 FAIL;
12179 })
12180
12181 (define_expand "extzv"
12182 [(set (match_operand:SI 0 "register_operand" "")
12183 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12184 (match_operand:SI 2 "immediate_operand" "")
12185 (match_operand:SI 3 "immediate_operand" "")))]
12186 ""
12187 {
12188 /* Handle extractions from %ah et al. */
12189 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12190 FAIL;
12191
12192 /* From mips.md: extract_bit_field doesn't verify that our source
12193 matches the predicate, so check it again here. */
12194 if (! ext_register_operand (operands[1], VOIDmode))
12195 FAIL;
12196 })
12197
12198 (define_expand "insv"
12199 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12200 (match_operand 1 "immediate_operand" "")
12201 (match_operand 2 "immediate_operand" ""))
12202 (match_operand 3 "register_operand" ""))]
12203 ""
12204 {
12205 /* Handle extractions from %ah et al. */
12206 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12207 FAIL;
12208
12209 /* From mips.md: insert_bit_field doesn't verify that our source
12210 matches the predicate, so check it again here. */
12211 if (! ext_register_operand (operands[0], VOIDmode))
12212 FAIL;
12213
12214 if (TARGET_64BIT)
12215 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12216 else
12217 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12218
12219 DONE;
12220 })
12221
12222 ;; %%% bts, btr, btc, bt.
12223 ;; In general these instructions are *slow* when applied to memory,
12224 ;; since they enforce atomic operation. When applied to registers,
12225 ;; it depends on the cpu implementation. They're never faster than
12226 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12227 ;; no point. But in 64-bit, we can't hold the relevant immediates
12228 ;; within the instruction itself, so operating on bits in the high
12229 ;; 32-bits of a register becomes easier.
12230 ;;
12231 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12232 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12233 ;; negdf respectively, so they can never be disabled entirely.
12234
12235 (define_insn "*btsq"
12236 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12237 (const_int 1)
12238 (match_operand:DI 1 "const_0_to_63_operand" ""))
12239 (const_int 1))
12240 (clobber (reg:CC FLAGS_REG))]
12241 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12242 "bts{q} %1,%0"
12243 [(set_attr "type" "alu1")])
12244
12245 (define_insn "*btrq"
12246 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12247 (const_int 1)
12248 (match_operand:DI 1 "const_0_to_63_operand" ""))
12249 (const_int 0))
12250 (clobber (reg:CC FLAGS_REG))]
12251 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12252 "btr{q} %1,%0"
12253 [(set_attr "type" "alu1")])
12254
12255 (define_insn "*btcq"
12256 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12257 (const_int 1)
12258 (match_operand:DI 1 "const_0_to_63_operand" ""))
12259 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12260 (clobber (reg:CC FLAGS_REG))]
12261 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12262 "btc{q} %1,%0"
12263 [(set_attr "type" "alu1")])
12264
12265 ;; Allow Nocona to avoid these instructions if a register is available.
12266
12267 (define_peephole2
12268 [(match_scratch:DI 2 "r")
12269 (parallel [(set (zero_extract:DI
12270 (match_operand:DI 0 "register_operand" "")
12271 (const_int 1)
12272 (match_operand:DI 1 "const_0_to_63_operand" ""))
12273 (const_int 1))
12274 (clobber (reg:CC FLAGS_REG))])]
12275 "TARGET_64BIT && !TARGET_USE_BT"
12276 [(const_int 0)]
12277 {
12278 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12279 rtx op1;
12280
12281 if (HOST_BITS_PER_WIDE_INT >= 64)
12282 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12283 else if (i < HOST_BITS_PER_WIDE_INT)
12284 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12285 else
12286 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12287
12288 op1 = immed_double_const (lo, hi, DImode);
12289 if (i >= 31)
12290 {
12291 emit_move_insn (operands[2], op1);
12292 op1 = operands[2];
12293 }
12294
12295 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12296 DONE;
12297 })
12298
12299 (define_peephole2
12300 [(match_scratch:DI 2 "r")
12301 (parallel [(set (zero_extract:DI
12302 (match_operand:DI 0 "register_operand" "")
12303 (const_int 1)
12304 (match_operand:DI 1 "const_0_to_63_operand" ""))
12305 (const_int 0))
12306 (clobber (reg:CC FLAGS_REG))])]
12307 "TARGET_64BIT && !TARGET_USE_BT"
12308 [(const_int 0)]
12309 {
12310 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12311 rtx op1;
12312
12313 if (HOST_BITS_PER_WIDE_INT >= 64)
12314 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12315 else if (i < HOST_BITS_PER_WIDE_INT)
12316 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12317 else
12318 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12319
12320 op1 = immed_double_const (~lo, ~hi, DImode);
12321 if (i >= 32)
12322 {
12323 emit_move_insn (operands[2], op1);
12324 op1 = operands[2];
12325 }
12326
12327 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12328 DONE;
12329 })
12330
12331 (define_peephole2
12332 [(match_scratch:DI 2 "r")
12333 (parallel [(set (zero_extract:DI
12334 (match_operand:DI 0 "register_operand" "")
12335 (const_int 1)
12336 (match_operand:DI 1 "const_0_to_63_operand" ""))
12337 (not:DI (zero_extract:DI
12338 (match_dup 0) (const_int 1) (match_dup 1))))
12339 (clobber (reg:CC FLAGS_REG))])]
12340 "TARGET_64BIT && !TARGET_USE_BT"
12341 [(const_int 0)]
12342 {
12343 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12344 rtx op1;
12345
12346 if (HOST_BITS_PER_WIDE_INT >= 64)
12347 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12348 else if (i < HOST_BITS_PER_WIDE_INT)
12349 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12350 else
12351 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12352
12353 op1 = immed_double_const (lo, hi, DImode);
12354 if (i >= 31)
12355 {
12356 emit_move_insn (operands[2], op1);
12357 op1 = operands[2];
12358 }
12359
12360 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12361 DONE;
12362 })
12363 \f
12364 ;; Store-flag instructions.
12365
12366 ;; For all sCOND expanders, also expand the compare or test insn that
12367 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12368
12369 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12370 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12371 ;; way, which can later delete the movzx if only QImode is needed.
12372
12373 (define_expand "seq"
12374 [(set (match_operand:QI 0 "register_operand" "")
12375 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12376 ""
12377 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12378
12379 (define_expand "sne"
12380 [(set (match_operand:QI 0 "register_operand" "")
12381 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12382 ""
12383 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12384
12385 (define_expand "sgt"
12386 [(set (match_operand:QI 0 "register_operand" "")
12387 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12388 ""
12389 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12390
12391 (define_expand "sgtu"
12392 [(set (match_operand:QI 0 "register_operand" "")
12393 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12394 ""
12395 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12396
12397 (define_expand "slt"
12398 [(set (match_operand:QI 0 "register_operand" "")
12399 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12400 ""
12401 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12402
12403 (define_expand "sltu"
12404 [(set (match_operand:QI 0 "register_operand" "")
12405 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12406 ""
12407 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12408
12409 (define_expand "sge"
12410 [(set (match_operand:QI 0 "register_operand" "")
12411 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12412 ""
12413 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12414
12415 (define_expand "sgeu"
12416 [(set (match_operand:QI 0 "register_operand" "")
12417 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12418 ""
12419 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12420
12421 (define_expand "sle"
12422 [(set (match_operand:QI 0 "register_operand" "")
12423 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12424 ""
12425 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12426
12427 (define_expand "sleu"
12428 [(set (match_operand:QI 0 "register_operand" "")
12429 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12430 ""
12431 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12432
12433 (define_expand "sunordered"
12434 [(set (match_operand:QI 0 "register_operand" "")
12435 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12436 "TARGET_80387 || TARGET_SSE"
12437 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12438
12439 (define_expand "sordered"
12440 [(set (match_operand:QI 0 "register_operand" "")
12441 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12442 "TARGET_80387"
12443 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12444
12445 (define_expand "suneq"
12446 [(set (match_operand:QI 0 "register_operand" "")
12447 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12448 "TARGET_80387 || TARGET_SSE"
12449 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12450
12451 (define_expand "sunge"
12452 [(set (match_operand:QI 0 "register_operand" "")
12453 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12454 "TARGET_80387 || TARGET_SSE"
12455 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12456
12457 (define_expand "sungt"
12458 [(set (match_operand:QI 0 "register_operand" "")
12459 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12460 "TARGET_80387 || TARGET_SSE"
12461 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12462
12463 (define_expand "sunle"
12464 [(set (match_operand:QI 0 "register_operand" "")
12465 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12466 "TARGET_80387 || TARGET_SSE"
12467 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12468
12469 (define_expand "sunlt"
12470 [(set (match_operand:QI 0 "register_operand" "")
12471 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12472 "TARGET_80387 || TARGET_SSE"
12473 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12474
12475 (define_expand "sltgt"
12476 [(set (match_operand:QI 0 "register_operand" "")
12477 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12478 "TARGET_80387 || TARGET_SSE"
12479 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12480
12481 (define_insn "*setcc_1"
12482 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12483 (match_operator:QI 1 "ix86_comparison_operator"
12484 [(reg FLAGS_REG) (const_int 0)]))]
12485 ""
12486 "set%C1\t%0"
12487 [(set_attr "type" "setcc")
12488 (set_attr "mode" "QI")])
12489
12490 (define_insn "*setcc_2"
12491 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12492 (match_operator:QI 1 "ix86_comparison_operator"
12493 [(reg FLAGS_REG) (const_int 0)]))]
12494 ""
12495 "set%C1\t%0"
12496 [(set_attr "type" "setcc")
12497 (set_attr "mode" "QI")])
12498
12499 ;; In general it is not safe to assume too much about CCmode registers,
12500 ;; so simplify-rtx stops when it sees a second one. Under certain
12501 ;; conditions this is safe on x86, so help combine not create
12502 ;;
12503 ;; seta %al
12504 ;; testb %al, %al
12505 ;; sete %al
12506
12507 (define_split
12508 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12509 (ne:QI (match_operator 1 "ix86_comparison_operator"
12510 [(reg FLAGS_REG) (const_int 0)])
12511 (const_int 0)))]
12512 ""
12513 [(set (match_dup 0) (match_dup 1))]
12514 {
12515 PUT_MODE (operands[1], QImode);
12516 })
12517
12518 (define_split
12519 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12520 (ne:QI (match_operator 1 "ix86_comparison_operator"
12521 [(reg FLAGS_REG) (const_int 0)])
12522 (const_int 0)))]
12523 ""
12524 [(set (match_dup 0) (match_dup 1))]
12525 {
12526 PUT_MODE (operands[1], QImode);
12527 })
12528
12529 (define_split
12530 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12531 (eq:QI (match_operator 1 "ix86_comparison_operator"
12532 [(reg FLAGS_REG) (const_int 0)])
12533 (const_int 0)))]
12534 ""
12535 [(set (match_dup 0) (match_dup 1))]
12536 {
12537 rtx new_op1 = copy_rtx (operands[1]);
12538 operands[1] = new_op1;
12539 PUT_MODE (new_op1, QImode);
12540 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12541 GET_MODE (XEXP (new_op1, 0))));
12542
12543 /* Make sure that (a) the CCmode we have for the flags is strong
12544 enough for the reversed compare or (b) we have a valid FP compare. */
12545 if (! ix86_comparison_operator (new_op1, VOIDmode))
12546 FAIL;
12547 })
12548
12549 (define_split
12550 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12551 (eq:QI (match_operator 1 "ix86_comparison_operator"
12552 [(reg FLAGS_REG) (const_int 0)])
12553 (const_int 0)))]
12554 ""
12555 [(set (match_dup 0) (match_dup 1))]
12556 {
12557 rtx new_op1 = copy_rtx (operands[1]);
12558 operands[1] = new_op1;
12559 PUT_MODE (new_op1, QImode);
12560 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12561 GET_MODE (XEXP (new_op1, 0))));
12562
12563 /* Make sure that (a) the CCmode we have for the flags is strong
12564 enough for the reversed compare or (b) we have a valid FP compare. */
12565 if (! ix86_comparison_operator (new_op1, VOIDmode))
12566 FAIL;
12567 })
12568
12569 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12570 ;; subsequent logical operations are used to imitate conditional moves.
12571 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12572 ;; it directly. Further holding this value in pseudo register might bring
12573 ;; problem in implicit normalization in spill code.
12574 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12575 ;; instructions after reload by splitting the conditional move patterns.
12576
12577 (define_insn "*sse_setccsf"
12578 [(set (match_operand:SF 0 "register_operand" "=x")
12579 (match_operator:SF 1 "sse_comparison_operator"
12580 [(match_operand:SF 2 "register_operand" "0")
12581 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12582 "TARGET_SSE && reload_completed"
12583 "cmp%D1ss\t{%3, %0|%0, %3}"
12584 [(set_attr "type" "ssecmp")
12585 (set_attr "mode" "SF")])
12586
12587 (define_insn "*sse_setccdf"
12588 [(set (match_operand:DF 0 "register_operand" "=Y")
12589 (match_operator:DF 1 "sse_comparison_operator"
12590 [(match_operand:DF 2 "register_operand" "0")
12591 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12592 "TARGET_SSE2 && reload_completed"
12593 "cmp%D1sd\t{%3, %0|%0, %3}"
12594 [(set_attr "type" "ssecmp")
12595 (set_attr "mode" "DF")])
12596 \f
12597 ;; Basic conditional jump instructions.
12598 ;; We ignore the overflow flag for signed branch instructions.
12599
12600 ;; For all bCOND expanders, also expand the compare or test insn that
12601 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12602
12603 (define_expand "beq"
12604 [(set (pc)
12605 (if_then_else (match_dup 1)
12606 (label_ref (match_operand 0 "" ""))
12607 (pc)))]
12608 ""
12609 "ix86_expand_branch (EQ, operands[0]); DONE;")
12610
12611 (define_expand "bne"
12612 [(set (pc)
12613 (if_then_else (match_dup 1)
12614 (label_ref (match_operand 0 "" ""))
12615 (pc)))]
12616 ""
12617 "ix86_expand_branch (NE, operands[0]); DONE;")
12618
12619 (define_expand "bgt"
12620 [(set (pc)
12621 (if_then_else (match_dup 1)
12622 (label_ref (match_operand 0 "" ""))
12623 (pc)))]
12624 ""
12625 "ix86_expand_branch (GT, operands[0]); DONE;")
12626
12627 (define_expand "bgtu"
12628 [(set (pc)
12629 (if_then_else (match_dup 1)
12630 (label_ref (match_operand 0 "" ""))
12631 (pc)))]
12632 ""
12633 "ix86_expand_branch (GTU, operands[0]); DONE;")
12634
12635 (define_expand "blt"
12636 [(set (pc)
12637 (if_then_else (match_dup 1)
12638 (label_ref (match_operand 0 "" ""))
12639 (pc)))]
12640 ""
12641 "ix86_expand_branch (LT, operands[0]); DONE;")
12642
12643 (define_expand "bltu"
12644 [(set (pc)
12645 (if_then_else (match_dup 1)
12646 (label_ref (match_operand 0 "" ""))
12647 (pc)))]
12648 ""
12649 "ix86_expand_branch (LTU, operands[0]); DONE;")
12650
12651 (define_expand "bge"
12652 [(set (pc)
12653 (if_then_else (match_dup 1)
12654 (label_ref (match_operand 0 "" ""))
12655 (pc)))]
12656 ""
12657 "ix86_expand_branch (GE, operands[0]); DONE;")
12658
12659 (define_expand "bgeu"
12660 [(set (pc)
12661 (if_then_else (match_dup 1)
12662 (label_ref (match_operand 0 "" ""))
12663 (pc)))]
12664 ""
12665 "ix86_expand_branch (GEU, operands[0]); DONE;")
12666
12667 (define_expand "ble"
12668 [(set (pc)
12669 (if_then_else (match_dup 1)
12670 (label_ref (match_operand 0 "" ""))
12671 (pc)))]
12672 ""
12673 "ix86_expand_branch (LE, operands[0]); DONE;")
12674
12675 (define_expand "bleu"
12676 [(set (pc)
12677 (if_then_else (match_dup 1)
12678 (label_ref (match_operand 0 "" ""))
12679 (pc)))]
12680 ""
12681 "ix86_expand_branch (LEU, operands[0]); DONE;")
12682
12683 (define_expand "bunordered"
12684 [(set (pc)
12685 (if_then_else (match_dup 1)
12686 (label_ref (match_operand 0 "" ""))
12687 (pc)))]
12688 "TARGET_80387 || TARGET_SSE_MATH"
12689 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12690
12691 (define_expand "bordered"
12692 [(set (pc)
12693 (if_then_else (match_dup 1)
12694 (label_ref (match_operand 0 "" ""))
12695 (pc)))]
12696 "TARGET_80387 || TARGET_SSE_MATH"
12697 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12698
12699 (define_expand "buneq"
12700 [(set (pc)
12701 (if_then_else (match_dup 1)
12702 (label_ref (match_operand 0 "" ""))
12703 (pc)))]
12704 "TARGET_80387 || TARGET_SSE_MATH"
12705 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12706
12707 (define_expand "bunge"
12708 [(set (pc)
12709 (if_then_else (match_dup 1)
12710 (label_ref (match_operand 0 "" ""))
12711 (pc)))]
12712 "TARGET_80387 || TARGET_SSE_MATH"
12713 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12714
12715 (define_expand "bungt"
12716 [(set (pc)
12717 (if_then_else (match_dup 1)
12718 (label_ref (match_operand 0 "" ""))
12719 (pc)))]
12720 "TARGET_80387 || TARGET_SSE_MATH"
12721 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12722
12723 (define_expand "bunle"
12724 [(set (pc)
12725 (if_then_else (match_dup 1)
12726 (label_ref (match_operand 0 "" ""))
12727 (pc)))]
12728 "TARGET_80387 || TARGET_SSE_MATH"
12729 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12730
12731 (define_expand "bunlt"
12732 [(set (pc)
12733 (if_then_else (match_dup 1)
12734 (label_ref (match_operand 0 "" ""))
12735 (pc)))]
12736 "TARGET_80387 || TARGET_SSE_MATH"
12737 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12738
12739 (define_expand "bltgt"
12740 [(set (pc)
12741 (if_then_else (match_dup 1)
12742 (label_ref (match_operand 0 "" ""))
12743 (pc)))]
12744 "TARGET_80387 || TARGET_SSE_MATH"
12745 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12746
12747 (define_insn "*jcc_1"
12748 [(set (pc)
12749 (if_then_else (match_operator 1 "ix86_comparison_operator"
12750 [(reg FLAGS_REG) (const_int 0)])
12751 (label_ref (match_operand 0 "" ""))
12752 (pc)))]
12753 ""
12754 "%+j%C1\t%l0"
12755 [(set_attr "type" "ibr")
12756 (set_attr "modrm" "0")
12757 (set (attr "length")
12758 (if_then_else (and (ge (minus (match_dup 0) (pc))
12759 (const_int -126))
12760 (lt (minus (match_dup 0) (pc))
12761 (const_int 128)))
12762 (const_int 2)
12763 (const_int 6)))])
12764
12765 (define_insn "*jcc_2"
12766 [(set (pc)
12767 (if_then_else (match_operator 1 "ix86_comparison_operator"
12768 [(reg FLAGS_REG) (const_int 0)])
12769 (pc)
12770 (label_ref (match_operand 0 "" ""))))]
12771 ""
12772 "%+j%c1\t%l0"
12773 [(set_attr "type" "ibr")
12774 (set_attr "modrm" "0")
12775 (set (attr "length")
12776 (if_then_else (and (ge (minus (match_dup 0) (pc))
12777 (const_int -126))
12778 (lt (minus (match_dup 0) (pc))
12779 (const_int 128)))
12780 (const_int 2)
12781 (const_int 6)))])
12782
12783 ;; In general it is not safe to assume too much about CCmode registers,
12784 ;; so simplify-rtx stops when it sees a second one. Under certain
12785 ;; conditions this is safe on x86, so help combine not create
12786 ;;
12787 ;; seta %al
12788 ;; testb %al, %al
12789 ;; je Lfoo
12790
12791 (define_split
12792 [(set (pc)
12793 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12794 [(reg FLAGS_REG) (const_int 0)])
12795 (const_int 0))
12796 (label_ref (match_operand 1 "" ""))
12797 (pc)))]
12798 ""
12799 [(set (pc)
12800 (if_then_else (match_dup 0)
12801 (label_ref (match_dup 1))
12802 (pc)))]
12803 {
12804 PUT_MODE (operands[0], VOIDmode);
12805 })
12806
12807 (define_split
12808 [(set (pc)
12809 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12810 [(reg FLAGS_REG) (const_int 0)])
12811 (const_int 0))
12812 (label_ref (match_operand 1 "" ""))
12813 (pc)))]
12814 ""
12815 [(set (pc)
12816 (if_then_else (match_dup 0)
12817 (label_ref (match_dup 1))
12818 (pc)))]
12819 {
12820 rtx new_op0 = copy_rtx (operands[0]);
12821 operands[0] = new_op0;
12822 PUT_MODE (new_op0, VOIDmode);
12823 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12824 GET_MODE (XEXP (new_op0, 0))));
12825
12826 /* Make sure that (a) the CCmode we have for the flags is strong
12827 enough for the reversed compare or (b) we have a valid FP compare. */
12828 if (! ix86_comparison_operator (new_op0, VOIDmode))
12829 FAIL;
12830 })
12831
12832 ;; Define combination compare-and-branch fp compare instructions to use
12833 ;; during early optimization. Splitting the operation apart early makes
12834 ;; for bad code when we want to reverse the operation.
12835
12836 (define_insn "*fp_jcc_1_mixed"
12837 [(set (pc)
12838 (if_then_else (match_operator 0 "comparison_operator"
12839 [(match_operand 1 "register_operand" "f#x,x#f")
12840 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12841 (label_ref (match_operand 3 "" ""))
12842 (pc)))
12843 (clobber (reg:CCFP FPSR_REG))
12844 (clobber (reg:CCFP FLAGS_REG))]
12845 "TARGET_MIX_SSE_I387
12846 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12847 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12848 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12849 "#")
12850
12851 (define_insn "*fp_jcc_1_sse"
12852 [(set (pc)
12853 (if_then_else (match_operator 0 "comparison_operator"
12854 [(match_operand 1 "register_operand" "x")
12855 (match_operand 2 "nonimmediate_operand" "xm")])
12856 (label_ref (match_operand 3 "" ""))
12857 (pc)))
12858 (clobber (reg:CCFP FPSR_REG))
12859 (clobber (reg:CCFP FLAGS_REG))]
12860 "TARGET_SSE_MATH
12861 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12862 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12863 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12864 "#")
12865
12866 (define_insn "*fp_jcc_1_387"
12867 [(set (pc)
12868 (if_then_else (match_operator 0 "comparison_operator"
12869 [(match_operand 1 "register_operand" "f")
12870 (match_operand 2 "register_operand" "f")])
12871 (label_ref (match_operand 3 "" ""))
12872 (pc)))
12873 (clobber (reg:CCFP FPSR_REG))
12874 (clobber (reg:CCFP FLAGS_REG))]
12875 "TARGET_CMOVE && TARGET_80387
12876 && FLOAT_MODE_P (GET_MODE (operands[1]))
12877 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12878 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12879 "#")
12880
12881 (define_insn "*fp_jcc_2_mixed"
12882 [(set (pc)
12883 (if_then_else (match_operator 0 "comparison_operator"
12884 [(match_operand 1 "register_operand" "f#x,x#f")
12885 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12886 (pc)
12887 (label_ref (match_operand 3 "" ""))))
12888 (clobber (reg:CCFP FPSR_REG))
12889 (clobber (reg:CCFP FLAGS_REG))]
12890 "TARGET_MIX_SSE_I387
12891 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12892 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12893 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12894 "#")
12895
12896 (define_insn "*fp_jcc_2_sse"
12897 [(set (pc)
12898 (if_then_else (match_operator 0 "comparison_operator"
12899 [(match_operand 1 "register_operand" "x")
12900 (match_operand 2 "nonimmediate_operand" "xm")])
12901 (pc)
12902 (label_ref (match_operand 3 "" ""))))
12903 (clobber (reg:CCFP FPSR_REG))
12904 (clobber (reg:CCFP FLAGS_REG))]
12905 "TARGET_SSE_MATH
12906 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12907 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12908 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12909 "#")
12910
12911 (define_insn "*fp_jcc_2_387"
12912 [(set (pc)
12913 (if_then_else (match_operator 0 "comparison_operator"
12914 [(match_operand 1 "register_operand" "f")
12915 (match_operand 2 "register_operand" "f")])
12916 (pc)
12917 (label_ref (match_operand 3 "" ""))))
12918 (clobber (reg:CCFP FPSR_REG))
12919 (clobber (reg:CCFP FLAGS_REG))]
12920 "TARGET_CMOVE && TARGET_80387
12921 && FLOAT_MODE_P (GET_MODE (operands[1]))
12922 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12923 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12924 "#")
12925
12926 (define_insn "*fp_jcc_3_387"
12927 [(set (pc)
12928 (if_then_else (match_operator 0 "comparison_operator"
12929 [(match_operand 1 "register_operand" "f")
12930 (match_operand 2 "nonimmediate_operand" "fm")])
12931 (label_ref (match_operand 3 "" ""))
12932 (pc)))
12933 (clobber (reg:CCFP FPSR_REG))
12934 (clobber (reg:CCFP FLAGS_REG))
12935 (clobber (match_scratch:HI 4 "=a"))]
12936 "TARGET_80387
12937 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12938 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12939 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12940 && SELECT_CC_MODE (GET_CODE (operands[0]),
12941 operands[1], operands[2]) == CCFPmode
12942 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12943 "#")
12944
12945 (define_insn "*fp_jcc_4_387"
12946 [(set (pc)
12947 (if_then_else (match_operator 0 "comparison_operator"
12948 [(match_operand 1 "register_operand" "f")
12949 (match_operand 2 "nonimmediate_operand" "fm")])
12950 (pc)
12951 (label_ref (match_operand 3 "" ""))))
12952 (clobber (reg:CCFP FPSR_REG))
12953 (clobber (reg:CCFP FLAGS_REG))
12954 (clobber (match_scratch:HI 4 "=a"))]
12955 "TARGET_80387
12956 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12957 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12958 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12959 && SELECT_CC_MODE (GET_CODE (operands[0]),
12960 operands[1], operands[2]) == CCFPmode
12961 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12962 "#")
12963
12964 (define_insn "*fp_jcc_5_387"
12965 [(set (pc)
12966 (if_then_else (match_operator 0 "comparison_operator"
12967 [(match_operand 1 "register_operand" "f")
12968 (match_operand 2 "register_operand" "f")])
12969 (label_ref (match_operand 3 "" ""))
12970 (pc)))
12971 (clobber (reg:CCFP FPSR_REG))
12972 (clobber (reg:CCFP FLAGS_REG))
12973 (clobber (match_scratch:HI 4 "=a"))]
12974 "TARGET_80387
12975 && FLOAT_MODE_P (GET_MODE (operands[1]))
12976 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12977 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12978 "#")
12979
12980 (define_insn "*fp_jcc_6_387"
12981 [(set (pc)
12982 (if_then_else (match_operator 0 "comparison_operator"
12983 [(match_operand 1 "register_operand" "f")
12984 (match_operand 2 "register_operand" "f")])
12985 (pc)
12986 (label_ref (match_operand 3 "" ""))))
12987 (clobber (reg:CCFP FPSR_REG))
12988 (clobber (reg:CCFP FLAGS_REG))
12989 (clobber (match_scratch:HI 4 "=a"))]
12990 "TARGET_80387
12991 && FLOAT_MODE_P (GET_MODE (operands[1]))
12992 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12993 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12994 "#")
12995
12996 (define_insn "*fp_jcc_7_387"
12997 [(set (pc)
12998 (if_then_else (match_operator 0 "comparison_operator"
12999 [(match_operand 1 "register_operand" "f")
13000 (match_operand 2 "const_double_operand" "C")])
13001 (label_ref (match_operand 3 "" ""))
13002 (pc)))
13003 (clobber (reg:CCFP FPSR_REG))
13004 (clobber (reg:CCFP FLAGS_REG))
13005 (clobber (match_scratch:HI 4 "=a"))]
13006 "TARGET_80387
13007 && FLOAT_MODE_P (GET_MODE (operands[1]))
13008 && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13009 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13010 && SELECT_CC_MODE (GET_CODE (operands[0]),
13011 operands[1], operands[2]) == CCFPmode
13012 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13013 "#")
13014
13015 ;; The order of operands in *fp_jcc_8 is forced by combine in
13016 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13017 ;; with a precedence over other operators and is always put in the first
13018 ;; place. Swap condition and operands to match ficom instruction.
13019
13020 (define_insn "*fp_jcc_8_387"
13021 [(set (pc)
13022 (if_then_else (match_operator 0 "comparison_operator"
13023 [(match_operator 1 "float_operator"
13024 [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13025 (match_operand 3 "register_operand" "f,f")])
13026 (label_ref (match_operand 4 "" ""))
13027 (pc)))
13028 (clobber (reg:CCFP FPSR_REG))
13029 (clobber (reg:CCFP FLAGS_REG))
13030 (clobber (match_scratch:HI 5 "=a,a"))]
13031 "TARGET_80387 && TARGET_USE_FIOP
13032 && FLOAT_MODE_P (GET_MODE (operands[3]))
13033 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13034 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13035 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13036 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13037 "#")
13038
13039 (define_split
13040 [(set (pc)
13041 (if_then_else (match_operator 0 "comparison_operator"
13042 [(match_operand 1 "register_operand" "")
13043 (match_operand 2 "nonimmediate_operand" "")])
13044 (match_operand 3 "" "")
13045 (match_operand 4 "" "")))
13046 (clobber (reg:CCFP FPSR_REG))
13047 (clobber (reg:CCFP FLAGS_REG))]
13048 "reload_completed"
13049 [(const_int 0)]
13050 {
13051 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13052 operands[3], operands[4], NULL_RTX, NULL_RTX);
13053 DONE;
13054 })
13055
13056 (define_split
13057 [(set (pc)
13058 (if_then_else (match_operator 0 "comparison_operator"
13059 [(match_operand 1 "register_operand" "")
13060 (match_operand 2 "general_operand" "")])
13061 (match_operand 3 "" "")
13062 (match_operand 4 "" "")))
13063 (clobber (reg:CCFP FPSR_REG))
13064 (clobber (reg:CCFP FLAGS_REG))
13065 (clobber (match_scratch:HI 5 "=a"))]
13066 "reload_completed"
13067 [(const_int 0)]
13068 {
13069 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13070 operands[3], operands[4], operands[5], NULL_RTX);
13071 DONE;
13072 })
13073
13074 (define_split
13075 [(set (pc)
13076 (if_then_else (match_operator 0 "comparison_operator"
13077 [(match_operator 1 "float_operator"
13078 [(match_operand:SI 2 "memory_operand" "")])
13079 (match_operand 3 "register_operand" "")])
13080 (match_operand 4 "" "")
13081 (match_operand 5 "" "")))
13082 (clobber (reg:CCFP FPSR_REG))
13083 (clobber (reg:CCFP FLAGS_REG))
13084 (clobber (match_scratch:HI 6 "=a"))]
13085 "reload_completed"
13086 [(const_int 0)]
13087 {
13088 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13089 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13090 operands[3], operands[7],
13091 operands[4], operands[5], operands[6], NULL_RTX);
13092 DONE;
13093 })
13094
13095 ;; %%% Kill this when reload knows how to do it.
13096 (define_split
13097 [(set (pc)
13098 (if_then_else (match_operator 0 "comparison_operator"
13099 [(match_operator 1 "float_operator"
13100 [(match_operand:SI 2 "register_operand" "")])
13101 (match_operand 3 "register_operand" "")])
13102 (match_operand 4 "" "")
13103 (match_operand 5 "" "")))
13104 (clobber (reg:CCFP FPSR_REG))
13105 (clobber (reg:CCFP FLAGS_REG))
13106 (clobber (match_scratch:HI 6 "=a"))]
13107 "reload_completed"
13108 [(const_int 0)]
13109 {
13110 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13111 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13112 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13113 operands[3], operands[7],
13114 operands[4], operands[5], operands[6], operands[2]);
13115 DONE;
13116 })
13117 \f
13118 ;; Unconditional and other jump instructions
13119
13120 (define_insn "jump"
13121 [(set (pc)
13122 (label_ref (match_operand 0 "" "")))]
13123 ""
13124 "jmp\t%l0"
13125 [(set_attr "type" "ibr")
13126 (set (attr "length")
13127 (if_then_else (and (ge (minus (match_dup 0) (pc))
13128 (const_int -126))
13129 (lt (minus (match_dup 0) (pc))
13130 (const_int 128)))
13131 (const_int 2)
13132 (const_int 5)))
13133 (set_attr "modrm" "0")])
13134
13135 (define_expand "indirect_jump"
13136 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13137 ""
13138 "")
13139
13140 (define_insn "*indirect_jump"
13141 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13142 "!TARGET_64BIT"
13143 "jmp\t%A0"
13144 [(set_attr "type" "ibr")
13145 (set_attr "length_immediate" "0")])
13146
13147 (define_insn "*indirect_jump_rtx64"
13148 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13149 "TARGET_64BIT"
13150 "jmp\t%A0"
13151 [(set_attr "type" "ibr")
13152 (set_attr "length_immediate" "0")])
13153
13154 (define_expand "tablejump"
13155 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13156 (use (label_ref (match_operand 1 "" "")))])]
13157 ""
13158 {
13159 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13160 relative. Convert the relative address to an absolute address. */
13161 if (flag_pic)
13162 {
13163 rtx op0, op1;
13164 enum rtx_code code;
13165
13166 if (TARGET_64BIT)
13167 {
13168 code = PLUS;
13169 op0 = operands[0];
13170 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13171 }
13172 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13173 {
13174 code = PLUS;
13175 op0 = operands[0];
13176 op1 = pic_offset_table_rtx;
13177 }
13178 else
13179 {
13180 code = MINUS;
13181 op0 = pic_offset_table_rtx;
13182 op1 = operands[0];
13183 }
13184
13185 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13186 OPTAB_DIRECT);
13187 }
13188 })
13189
13190 (define_insn "*tablejump_1"
13191 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13192 (use (label_ref (match_operand 1 "" "")))]
13193 "!TARGET_64BIT"
13194 "jmp\t%A0"
13195 [(set_attr "type" "ibr")
13196 (set_attr "length_immediate" "0")])
13197
13198 (define_insn "*tablejump_1_rtx64"
13199 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13200 (use (label_ref (match_operand 1 "" "")))]
13201 "TARGET_64BIT"
13202 "jmp\t%A0"
13203 [(set_attr "type" "ibr")
13204 (set_attr "length_immediate" "0")])
13205 \f
13206 ;; Loop instruction
13207 ;;
13208 ;; This is all complicated by the fact that since this is a jump insn
13209 ;; we must handle our own reloads.
13210
13211 (define_expand "doloop_end"
13212 [(use (match_operand 0 "" "")) ; loop pseudo
13213 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13214 (use (match_operand 2 "" "")) ; max iterations
13215 (use (match_operand 3 "" "")) ; loop level
13216 (use (match_operand 4 "" ""))] ; label
13217 "!TARGET_64BIT && TARGET_USE_LOOP"
13218 "
13219 {
13220 /* Only use cloop on innermost loops. */
13221 if (INTVAL (operands[3]) > 1)
13222 FAIL;
13223 if (GET_MODE (operands[0]) != SImode)
13224 FAIL;
13225 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13226 operands[0]));
13227 DONE;
13228 }")
13229
13230 (define_insn "doloop_end_internal"
13231 [(set (pc)
13232 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13233 (const_int 1))
13234 (label_ref (match_operand 0 "" ""))
13235 (pc)))
13236 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13237 (plus:SI (match_dup 1)
13238 (const_int -1)))
13239 (clobber (match_scratch:SI 3 "=X,X,r"))
13240 (clobber (reg:CC FLAGS_REG))]
13241 "!TARGET_64BIT && TARGET_USE_LOOP
13242 && (reload_in_progress || reload_completed
13243 || register_operand (operands[2], VOIDmode))"
13244 {
13245 if (which_alternative != 0)
13246 return "#";
13247 if (get_attr_length (insn) == 2)
13248 return "%+loop\t%l0";
13249 else
13250 return "dec{l}\t%1\;%+jne\t%l0";
13251 }
13252 [(set (attr "length")
13253 (if_then_else (and (eq_attr "alternative" "0")
13254 (and (ge (minus (match_dup 0) (pc))
13255 (const_int -126))
13256 (lt (minus (match_dup 0) (pc))
13257 (const_int 128))))
13258 (const_int 2)
13259 (const_int 16)))
13260 ;; We don't know the type before shorten branches. Optimistically expect
13261 ;; the loop instruction to match.
13262 (set (attr "type") (const_string "ibr"))])
13263
13264 (define_split
13265 [(set (pc)
13266 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13267 (const_int 1))
13268 (match_operand 0 "" "")
13269 (pc)))
13270 (set (match_dup 1)
13271 (plus:SI (match_dup 1)
13272 (const_int -1)))
13273 (clobber (match_scratch:SI 2 ""))
13274 (clobber (reg:CC FLAGS_REG))]
13275 "!TARGET_64BIT && TARGET_USE_LOOP
13276 && reload_completed
13277 && REGNO (operands[1]) != 2"
13278 [(parallel [(set (reg:CCZ FLAGS_REG)
13279 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13280 (const_int 0)))
13281 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13282 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13283 (match_dup 0)
13284 (pc)))]
13285 "")
13286
13287 (define_split
13288 [(set (pc)
13289 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13290 (const_int 1))
13291 (match_operand 0 "" "")
13292 (pc)))
13293 (set (match_operand:SI 2 "nonimmediate_operand" "")
13294 (plus:SI (match_dup 1)
13295 (const_int -1)))
13296 (clobber (match_scratch:SI 3 ""))
13297 (clobber (reg:CC FLAGS_REG))]
13298 "!TARGET_64BIT && TARGET_USE_LOOP
13299 && reload_completed
13300 && (! REG_P (operands[2])
13301 || ! rtx_equal_p (operands[1], operands[2]))"
13302 [(set (match_dup 3) (match_dup 1))
13303 (parallel [(set (reg:CCZ FLAGS_REG)
13304 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13305 (const_int 0)))
13306 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13307 (set (match_dup 2) (match_dup 3))
13308 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13309 (match_dup 0)
13310 (pc)))]
13311 "")
13312
13313 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13314
13315 (define_peephole2
13316 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13317 (set (match_operand:QI 1 "register_operand" "")
13318 (match_operator:QI 2 "ix86_comparison_operator"
13319 [(reg FLAGS_REG) (const_int 0)]))
13320 (set (match_operand 3 "q_regs_operand" "")
13321 (zero_extend (match_dup 1)))]
13322 "(peep2_reg_dead_p (3, operands[1])
13323 || operands_match_p (operands[1], operands[3]))
13324 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13325 [(set (match_dup 4) (match_dup 0))
13326 (set (strict_low_part (match_dup 5))
13327 (match_dup 2))]
13328 {
13329 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13330 operands[5] = gen_lowpart (QImode, operands[3]);
13331 ix86_expand_clear (operands[3]);
13332 })
13333
13334 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13335
13336 (define_peephole2
13337 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13338 (set (match_operand:QI 1 "register_operand" "")
13339 (match_operator:QI 2 "ix86_comparison_operator"
13340 [(reg FLAGS_REG) (const_int 0)]))
13341 (parallel [(set (match_operand 3 "q_regs_operand" "")
13342 (zero_extend (match_dup 1)))
13343 (clobber (reg:CC FLAGS_REG))])]
13344 "(peep2_reg_dead_p (3, operands[1])
13345 || operands_match_p (operands[1], operands[3]))
13346 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13347 [(set (match_dup 4) (match_dup 0))
13348 (set (strict_low_part (match_dup 5))
13349 (match_dup 2))]
13350 {
13351 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13352 operands[5] = gen_lowpart (QImode, operands[3]);
13353 ix86_expand_clear (operands[3]);
13354 })
13355 \f
13356 ;; Call instructions.
13357
13358 ;; The predicates normally associated with named expanders are not properly
13359 ;; checked for calls. This is a bug in the generic code, but it isn't that
13360 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13361
13362 ;; Call subroutine returning no value.
13363
13364 (define_expand "call_pop"
13365 [(parallel [(call (match_operand:QI 0 "" "")
13366 (match_operand:SI 1 "" ""))
13367 (set (reg:SI SP_REG)
13368 (plus:SI (reg:SI SP_REG)
13369 (match_operand:SI 3 "" "")))])]
13370 "!TARGET_64BIT"
13371 {
13372 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13373 DONE;
13374 })
13375
13376 (define_insn "*call_pop_0"
13377 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13378 (match_operand:SI 1 "" ""))
13379 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13380 (match_operand:SI 2 "immediate_operand" "")))]
13381 "!TARGET_64BIT"
13382 {
13383 if (SIBLING_CALL_P (insn))
13384 return "jmp\t%P0";
13385 else
13386 return "call\t%P0";
13387 }
13388 [(set_attr "type" "call")])
13389
13390 (define_insn "*call_pop_1"
13391 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13392 (match_operand:SI 1 "" ""))
13393 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13394 (match_operand:SI 2 "immediate_operand" "i")))]
13395 "!TARGET_64BIT"
13396 {
13397 if (constant_call_address_operand (operands[0], Pmode))
13398 {
13399 if (SIBLING_CALL_P (insn))
13400 return "jmp\t%P0";
13401 else
13402 return "call\t%P0";
13403 }
13404 if (SIBLING_CALL_P (insn))
13405 return "jmp\t%A0";
13406 else
13407 return "call\t%A0";
13408 }
13409 [(set_attr "type" "call")])
13410
13411 (define_expand "call"
13412 [(call (match_operand:QI 0 "" "")
13413 (match_operand 1 "" ""))
13414 (use (match_operand 2 "" ""))]
13415 ""
13416 {
13417 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13418 DONE;
13419 })
13420
13421 (define_expand "sibcall"
13422 [(call (match_operand:QI 0 "" "")
13423 (match_operand 1 "" ""))
13424 (use (match_operand 2 "" ""))]
13425 ""
13426 {
13427 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13428 DONE;
13429 })
13430
13431 (define_insn "*call_0"
13432 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13433 (match_operand 1 "" ""))]
13434 ""
13435 {
13436 if (SIBLING_CALL_P (insn))
13437 return "jmp\t%P0";
13438 else
13439 return "call\t%P0";
13440 }
13441 [(set_attr "type" "call")])
13442
13443 (define_insn "*call_1"
13444 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13445 (match_operand 1 "" ""))]
13446 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13447 {
13448 if (constant_call_address_operand (operands[0], Pmode))
13449 return "call\t%P0";
13450 return "call\t%A0";
13451 }
13452 [(set_attr "type" "call")])
13453
13454 (define_insn "*sibcall_1"
13455 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13456 (match_operand 1 "" ""))]
13457 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13458 {
13459 if (constant_call_address_operand (operands[0], Pmode))
13460 return "jmp\t%P0";
13461 return "jmp\t%A0";
13462 }
13463 [(set_attr "type" "call")])
13464
13465 (define_insn "*call_1_rex64"
13466 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13467 (match_operand 1 "" ""))]
13468 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13469 {
13470 if (constant_call_address_operand (operands[0], Pmode))
13471 return "call\t%P0";
13472 return "call\t%A0";
13473 }
13474 [(set_attr "type" "call")])
13475
13476 (define_insn "*sibcall_1_rex64"
13477 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13478 (match_operand 1 "" ""))]
13479 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13480 "jmp\t%P0"
13481 [(set_attr "type" "call")])
13482
13483 (define_insn "*sibcall_1_rex64_v"
13484 [(call (mem:QI (reg:DI 40))
13485 (match_operand 0 "" ""))]
13486 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13487 "jmp\t*%%r11"
13488 [(set_attr "type" "call")])
13489
13490
13491 ;; Call subroutine, returning value in operand 0
13492
13493 (define_expand "call_value_pop"
13494 [(parallel [(set (match_operand 0 "" "")
13495 (call (match_operand:QI 1 "" "")
13496 (match_operand:SI 2 "" "")))
13497 (set (reg:SI SP_REG)
13498 (plus:SI (reg:SI SP_REG)
13499 (match_operand:SI 4 "" "")))])]
13500 "!TARGET_64BIT"
13501 {
13502 ix86_expand_call (operands[0], operands[1], operands[2],
13503 operands[3], operands[4], 0);
13504 DONE;
13505 })
13506
13507 (define_expand "call_value"
13508 [(set (match_operand 0 "" "")
13509 (call (match_operand:QI 1 "" "")
13510 (match_operand:SI 2 "" "")))
13511 (use (match_operand:SI 3 "" ""))]
13512 ;; Operand 2 not used on the i386.
13513 ""
13514 {
13515 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13516 DONE;
13517 })
13518
13519 (define_expand "sibcall_value"
13520 [(set (match_operand 0 "" "")
13521 (call (match_operand:QI 1 "" "")
13522 (match_operand:SI 2 "" "")))
13523 (use (match_operand:SI 3 "" ""))]
13524 ;; Operand 2 not used on the i386.
13525 ""
13526 {
13527 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13528 DONE;
13529 })
13530
13531 ;; Call subroutine returning any type.
13532
13533 (define_expand "untyped_call"
13534 [(parallel [(call (match_operand 0 "" "")
13535 (const_int 0))
13536 (match_operand 1 "" "")
13537 (match_operand 2 "" "")])]
13538 ""
13539 {
13540 int i;
13541
13542 /* In order to give reg-stack an easier job in validating two
13543 coprocessor registers as containing a possible return value,
13544 simply pretend the untyped call returns a complex long double
13545 value. */
13546
13547 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13548 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13549 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13550 NULL, 0);
13551
13552 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13553 {
13554 rtx set = XVECEXP (operands[2], 0, i);
13555 emit_move_insn (SET_DEST (set), SET_SRC (set));
13556 }
13557
13558 /* The optimizer does not know that the call sets the function value
13559 registers we stored in the result block. We avoid problems by
13560 claiming that all hard registers are used and clobbered at this
13561 point. */
13562 emit_insn (gen_blockage (const0_rtx));
13563
13564 DONE;
13565 })
13566 \f
13567 ;; Prologue and epilogue instructions
13568
13569 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13570 ;; all of memory. This blocks insns from being moved across this point.
13571
13572 (define_insn "blockage"
13573 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13574 ""
13575 ""
13576 [(set_attr "length" "0")])
13577
13578 ;; Insn emitted into the body of a function to return from a function.
13579 ;; This is only done if the function's epilogue is known to be simple.
13580 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13581
13582 (define_expand "return"
13583 [(return)]
13584 "ix86_can_use_return_insn_p ()"
13585 {
13586 if (current_function_pops_args)
13587 {
13588 rtx popc = GEN_INT (current_function_pops_args);
13589 emit_jump_insn (gen_return_pop_internal (popc));
13590 DONE;
13591 }
13592 })
13593
13594 (define_insn "return_internal"
13595 [(return)]
13596 "reload_completed"
13597 "ret"
13598 [(set_attr "length" "1")
13599 (set_attr "length_immediate" "0")
13600 (set_attr "modrm" "0")])
13601
13602 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13603 ;; instruction Athlon and K8 have.
13604
13605 (define_insn "return_internal_long"
13606 [(return)
13607 (unspec [(const_int 0)] UNSPEC_REP)]
13608 "reload_completed"
13609 "rep {;} ret"
13610 [(set_attr "length" "1")
13611 (set_attr "length_immediate" "0")
13612 (set_attr "prefix_rep" "1")
13613 (set_attr "modrm" "0")])
13614
13615 (define_insn "return_pop_internal"
13616 [(return)
13617 (use (match_operand:SI 0 "const_int_operand" ""))]
13618 "reload_completed"
13619 "ret\t%0"
13620 [(set_attr "length" "3")
13621 (set_attr "length_immediate" "2")
13622 (set_attr "modrm" "0")])
13623
13624 (define_insn "return_indirect_internal"
13625 [(return)
13626 (use (match_operand:SI 0 "register_operand" "r"))]
13627 "reload_completed"
13628 "jmp\t%A0"
13629 [(set_attr "type" "ibr")
13630 (set_attr "length_immediate" "0")])
13631
13632 (define_insn "nop"
13633 [(const_int 0)]
13634 ""
13635 "nop"
13636 [(set_attr "length" "1")
13637 (set_attr "length_immediate" "0")
13638 (set_attr "modrm" "0")])
13639
13640 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13641 ;; branch prediction penalty for the third jump in a 16-byte
13642 ;; block on K8.
13643
13644 (define_insn "align"
13645 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13646 ""
13647 {
13648 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13649 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13650 #else
13651 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13652 The align insn is used to avoid 3 jump instructions in the row to improve
13653 branch prediction and the benefits hardly outweight the cost of extra 8
13654 nops on the average inserted by full alignment pseudo operation. */
13655 #endif
13656 return "";
13657 }
13658 [(set_attr "length" "16")])
13659
13660 (define_expand "prologue"
13661 [(const_int 1)]
13662 ""
13663 "ix86_expand_prologue (); DONE;")
13664
13665 (define_insn "set_got"
13666 [(set (match_operand:SI 0 "register_operand" "=r")
13667 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13668 (clobber (reg:CC FLAGS_REG))]
13669 "!TARGET_64BIT"
13670 { return output_set_got (operands[0]); }
13671 [(set_attr "type" "multi")
13672 (set_attr "length" "12")])
13673
13674 (define_expand "epilogue"
13675 [(const_int 1)]
13676 ""
13677 "ix86_expand_epilogue (1); DONE;")
13678
13679 (define_expand "sibcall_epilogue"
13680 [(const_int 1)]
13681 ""
13682 "ix86_expand_epilogue (0); DONE;")
13683
13684 (define_expand "eh_return"
13685 [(use (match_operand 0 "register_operand" ""))]
13686 ""
13687 {
13688 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13689
13690 /* Tricky bit: we write the address of the handler to which we will
13691 be returning into someone else's stack frame, one word below the
13692 stack address we wish to restore. */
13693 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13694 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13695 tmp = gen_rtx_MEM (Pmode, tmp);
13696 emit_move_insn (tmp, ra);
13697
13698 if (Pmode == SImode)
13699 emit_jump_insn (gen_eh_return_si (sa));
13700 else
13701 emit_jump_insn (gen_eh_return_di (sa));
13702 emit_barrier ();
13703 DONE;
13704 })
13705
13706 (define_insn_and_split "eh_return_si"
13707 [(set (pc)
13708 (unspec [(match_operand:SI 0 "register_operand" "c")]
13709 UNSPEC_EH_RETURN))]
13710 "!TARGET_64BIT"
13711 "#"
13712 "reload_completed"
13713 [(const_int 1)]
13714 "ix86_expand_epilogue (2); DONE;")
13715
13716 (define_insn_and_split "eh_return_di"
13717 [(set (pc)
13718 (unspec [(match_operand:DI 0 "register_operand" "c")]
13719 UNSPEC_EH_RETURN))]
13720 "TARGET_64BIT"
13721 "#"
13722 "reload_completed"
13723 [(const_int 1)]
13724 "ix86_expand_epilogue (2); DONE;")
13725
13726 (define_insn "leave"
13727 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13728 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13729 (clobber (mem:BLK (scratch)))]
13730 "!TARGET_64BIT"
13731 "leave"
13732 [(set_attr "type" "leave")])
13733
13734 (define_insn "leave_rex64"
13735 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13736 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13737 (clobber (mem:BLK (scratch)))]
13738 "TARGET_64BIT"
13739 "leave"
13740 [(set_attr "type" "leave")])
13741 \f
13742 (define_expand "ffssi2"
13743 [(parallel
13744 [(set (match_operand:SI 0 "register_operand" "")
13745 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13746 (clobber (match_scratch:SI 2 ""))
13747 (clobber (reg:CC FLAGS_REG))])]
13748 ""
13749 "")
13750
13751 (define_insn_and_split "*ffs_cmove"
13752 [(set (match_operand:SI 0 "register_operand" "=r")
13753 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13754 (clobber (match_scratch:SI 2 "=&r"))
13755 (clobber (reg:CC FLAGS_REG))]
13756 "TARGET_CMOVE"
13757 "#"
13758 "&& reload_completed"
13759 [(set (match_dup 2) (const_int -1))
13760 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13761 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13762 (set (match_dup 0) (if_then_else:SI
13763 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13764 (match_dup 2)
13765 (match_dup 0)))
13766 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13767 (clobber (reg:CC FLAGS_REG))])]
13768 "")
13769
13770 (define_insn_and_split "*ffs_no_cmove"
13771 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13772 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13773 (clobber (match_scratch:SI 2 "=&q"))
13774 (clobber (reg:CC FLAGS_REG))]
13775 ""
13776 "#"
13777 "reload_completed"
13778 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13779 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13780 (set (strict_low_part (match_dup 3))
13781 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13782 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13783 (clobber (reg:CC FLAGS_REG))])
13784 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13785 (clobber (reg:CC FLAGS_REG))])
13786 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13787 (clobber (reg:CC FLAGS_REG))])]
13788 {
13789 operands[3] = gen_lowpart (QImode, operands[2]);
13790 ix86_expand_clear (operands[2]);
13791 })
13792
13793 (define_insn "*ffssi_1"
13794 [(set (reg:CCZ FLAGS_REG)
13795 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13796 (const_int 0)))
13797 (set (match_operand:SI 0 "register_operand" "=r")
13798 (ctz:SI (match_dup 1)))]
13799 ""
13800 "bsf{l}\t{%1, %0|%0, %1}"
13801 [(set_attr "prefix_0f" "1")])
13802
13803 (define_expand "ffsdi2"
13804 [(parallel
13805 [(set (match_operand:DI 0 "register_operand" "")
13806 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13807 (clobber (match_scratch:DI 2 ""))
13808 (clobber (reg:CC FLAGS_REG))])]
13809 "TARGET_64BIT && TARGET_CMOVE"
13810 "")
13811
13812 (define_insn_and_split "*ffs_rex64"
13813 [(set (match_operand:DI 0 "register_operand" "=r")
13814 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13815 (clobber (match_scratch:DI 2 "=&r"))
13816 (clobber (reg:CC FLAGS_REG))]
13817 "TARGET_64BIT && TARGET_CMOVE"
13818 "#"
13819 "&& reload_completed"
13820 [(set (match_dup 2) (const_int -1))
13821 (parallel [(set (reg:CCZ FLAGS_REG)
13822 (compare:CCZ (match_dup 1) (const_int 0)))
13823 (set (match_dup 0) (ctz:DI (match_dup 1)))])
13824 (set (match_dup 0) (if_then_else:DI
13825 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13826 (match_dup 2)
13827 (match_dup 0)))
13828 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13829 (clobber (reg:CC FLAGS_REG))])]
13830 "")
13831
13832 (define_insn "*ffsdi_1"
13833 [(set (reg:CCZ FLAGS_REG)
13834 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13835 (const_int 0)))
13836 (set (match_operand:DI 0 "register_operand" "=r")
13837 (ctz:DI (match_dup 1)))]
13838 "TARGET_64BIT"
13839 "bsf{q}\t{%1, %0|%0, %1}"
13840 [(set_attr "prefix_0f" "1")])
13841
13842 (define_insn "ctzsi2"
13843 [(set (match_operand:SI 0 "register_operand" "=r")
13844 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13845 (clobber (reg:CC FLAGS_REG))]
13846 ""
13847 "bsf{l}\t{%1, %0|%0, %1}"
13848 [(set_attr "prefix_0f" "1")])
13849
13850 (define_insn "ctzdi2"
13851 [(set (match_operand:DI 0 "register_operand" "=r")
13852 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13853 (clobber (reg:CC FLAGS_REG))]
13854 "TARGET_64BIT"
13855 "bsf{q}\t{%1, %0|%0, %1}"
13856 [(set_attr "prefix_0f" "1")])
13857
13858 (define_expand "clzsi2"
13859 [(parallel
13860 [(set (match_operand:SI 0 "register_operand" "")
13861 (minus:SI (const_int 31)
13862 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13863 (clobber (reg:CC FLAGS_REG))])
13864 (parallel
13865 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13866 (clobber (reg:CC FLAGS_REG))])]
13867 ""
13868 "")
13869
13870 (define_insn "*bsr"
13871 [(set (match_operand:SI 0 "register_operand" "=r")
13872 (minus:SI (const_int 31)
13873 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13874 (clobber (reg:CC FLAGS_REG))]
13875 ""
13876 "bsr{l}\t{%1, %0|%0, %1}"
13877 [(set_attr "prefix_0f" "1")])
13878
13879 (define_expand "clzdi2"
13880 [(parallel
13881 [(set (match_operand:DI 0 "register_operand" "")
13882 (minus:DI (const_int 63)
13883 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13884 (clobber (reg:CC FLAGS_REG))])
13885 (parallel
13886 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13887 (clobber (reg:CC FLAGS_REG))])]
13888 "TARGET_64BIT"
13889 "")
13890
13891 (define_insn "*bsr_rex64"
13892 [(set (match_operand:DI 0 "register_operand" "=r")
13893 (minus:DI (const_int 63)
13894 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13895 (clobber (reg:CC FLAGS_REG))]
13896 "TARGET_64BIT"
13897 "bsr{q}\t{%1, %0|%0, %1}"
13898 [(set_attr "prefix_0f" "1")])
13899 \f
13900 ;; Thread-local storage patterns for ELF.
13901 ;;
13902 ;; Note that these code sequences must appear exactly as shown
13903 ;; in order to allow linker relaxation.
13904
13905 (define_insn "*tls_global_dynamic_32_gnu"
13906 [(set (match_operand:SI 0 "register_operand" "=a")
13907 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13908 (match_operand:SI 2 "tls_symbolic_operand" "")
13909 (match_operand:SI 3 "call_insn_operand" "")]
13910 UNSPEC_TLS_GD))
13911 (clobber (match_scratch:SI 4 "=d"))
13912 (clobber (match_scratch:SI 5 "=c"))
13913 (clobber (reg:CC FLAGS_REG))]
13914 "!TARGET_64BIT && TARGET_GNU_TLS"
13915 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13916 [(set_attr "type" "multi")
13917 (set_attr "length" "12")])
13918
13919 (define_insn "*tls_global_dynamic_32_sun"
13920 [(set (match_operand:SI 0 "register_operand" "=a")
13921 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13922 (match_operand:SI 2 "tls_symbolic_operand" "")
13923 (match_operand:SI 3 "call_insn_operand" "")]
13924 UNSPEC_TLS_GD))
13925 (clobber (match_scratch:SI 4 "=d"))
13926 (clobber (match_scratch:SI 5 "=c"))
13927 (clobber (reg:CC FLAGS_REG))]
13928 "!TARGET_64BIT && TARGET_SUN_TLS"
13929 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13930 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13931 [(set_attr "type" "multi")
13932 (set_attr "length" "14")])
13933
13934 (define_expand "tls_global_dynamic_32"
13935 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13936 (unspec:SI
13937 [(match_dup 2)
13938 (match_operand:SI 1 "tls_symbolic_operand" "")
13939 (match_dup 3)]
13940 UNSPEC_TLS_GD))
13941 (clobber (match_scratch:SI 4 ""))
13942 (clobber (match_scratch:SI 5 ""))
13943 (clobber (reg:CC FLAGS_REG))])]
13944 ""
13945 {
13946 if (flag_pic)
13947 operands[2] = pic_offset_table_rtx;
13948 else
13949 {
13950 operands[2] = gen_reg_rtx (Pmode);
13951 emit_insn (gen_set_got (operands[2]));
13952 }
13953 operands[3] = ix86_tls_get_addr ();
13954 })
13955
13956 (define_insn "*tls_global_dynamic_64"
13957 [(set (match_operand:DI 0 "register_operand" "=a")
13958 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13959 (match_operand:DI 3 "" "")))
13960 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13961 UNSPEC_TLS_GD)]
13962 "TARGET_64BIT"
13963 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13964 [(set_attr "type" "multi")
13965 (set_attr "length" "16")])
13966
13967 (define_expand "tls_global_dynamic_64"
13968 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13969 (call (mem:QI (match_dup 2)) (const_int 0)))
13970 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13971 UNSPEC_TLS_GD)])]
13972 ""
13973 {
13974 operands[2] = ix86_tls_get_addr ();
13975 })
13976
13977 (define_insn "*tls_local_dynamic_base_32_gnu"
13978 [(set (match_operand:SI 0 "register_operand" "=a")
13979 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13980 (match_operand:SI 2 "call_insn_operand" "")]
13981 UNSPEC_TLS_LD_BASE))
13982 (clobber (match_scratch:SI 3 "=d"))
13983 (clobber (match_scratch:SI 4 "=c"))
13984 (clobber (reg:CC FLAGS_REG))]
13985 "!TARGET_64BIT && TARGET_GNU_TLS"
13986 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13987 [(set_attr "type" "multi")
13988 (set_attr "length" "11")])
13989
13990 (define_insn "*tls_local_dynamic_base_32_sun"
13991 [(set (match_operand:SI 0 "register_operand" "=a")
13992 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13993 (match_operand:SI 2 "call_insn_operand" "")]
13994 UNSPEC_TLS_LD_BASE))
13995 (clobber (match_scratch:SI 3 "=d"))
13996 (clobber (match_scratch:SI 4 "=c"))
13997 (clobber (reg:CC FLAGS_REG))]
13998 "!TARGET_64BIT && TARGET_SUN_TLS"
13999 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14000 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14001 [(set_attr "type" "multi")
14002 (set_attr "length" "13")])
14003
14004 (define_expand "tls_local_dynamic_base_32"
14005 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14006 (unspec:SI [(match_dup 1) (match_dup 2)]
14007 UNSPEC_TLS_LD_BASE))
14008 (clobber (match_scratch:SI 3 ""))
14009 (clobber (match_scratch:SI 4 ""))
14010 (clobber (reg:CC FLAGS_REG))])]
14011 ""
14012 {
14013 if (flag_pic)
14014 operands[1] = pic_offset_table_rtx;
14015 else
14016 {
14017 operands[1] = gen_reg_rtx (Pmode);
14018 emit_insn (gen_set_got (operands[1]));
14019 }
14020 operands[2] = ix86_tls_get_addr ();
14021 })
14022
14023 (define_insn "*tls_local_dynamic_base_64"
14024 [(set (match_operand:DI 0 "register_operand" "=a")
14025 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14026 (match_operand:DI 2 "" "")))
14027 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14028 "TARGET_64BIT"
14029 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14030 [(set_attr "type" "multi")
14031 (set_attr "length" "12")])
14032
14033 (define_expand "tls_local_dynamic_base_64"
14034 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14035 (call (mem:QI (match_dup 1)) (const_int 0)))
14036 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14037 ""
14038 {
14039 operands[1] = ix86_tls_get_addr ();
14040 })
14041
14042 ;; Local dynamic of a single variable is a lose. Show combine how
14043 ;; to convert that back to global dynamic.
14044
14045 (define_insn_and_split "*tls_local_dynamic_32_once"
14046 [(set (match_operand:SI 0 "register_operand" "=a")
14047 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14048 (match_operand:SI 2 "call_insn_operand" "")]
14049 UNSPEC_TLS_LD_BASE)
14050 (const:SI (unspec:SI
14051 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14052 UNSPEC_DTPOFF))))
14053 (clobber (match_scratch:SI 4 "=d"))
14054 (clobber (match_scratch:SI 5 "=c"))
14055 (clobber (reg:CC FLAGS_REG))]
14056 ""
14057 "#"
14058 ""
14059 [(parallel [(set (match_dup 0)
14060 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14061 UNSPEC_TLS_GD))
14062 (clobber (match_dup 4))
14063 (clobber (match_dup 5))
14064 (clobber (reg:CC FLAGS_REG))])]
14065 "")
14066
14067 ;; Load and add the thread base pointer from %gs:0.
14068
14069 (define_insn "*load_tp_si"
14070 [(set (match_operand:SI 0 "register_operand" "=r")
14071 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14072 "!TARGET_64BIT"
14073 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14074 [(set_attr "type" "imov")
14075 (set_attr "modrm" "0")
14076 (set_attr "length" "7")
14077 (set_attr "memory" "load")
14078 (set_attr "imm_disp" "false")])
14079
14080 (define_insn "*add_tp_si"
14081 [(set (match_operand:SI 0 "register_operand" "=r")
14082 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14083 (match_operand:SI 1 "register_operand" "0")))
14084 (clobber (reg:CC FLAGS_REG))]
14085 "!TARGET_64BIT"
14086 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14087 [(set_attr "type" "alu")
14088 (set_attr "modrm" "0")
14089 (set_attr "length" "7")
14090 (set_attr "memory" "load")
14091 (set_attr "imm_disp" "false")])
14092
14093 (define_insn "*load_tp_di"
14094 [(set (match_operand:DI 0 "register_operand" "=r")
14095 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14096 "TARGET_64BIT"
14097 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14098 [(set_attr "type" "imov")
14099 (set_attr "modrm" "0")
14100 (set_attr "length" "7")
14101 (set_attr "memory" "load")
14102 (set_attr "imm_disp" "false")])
14103
14104 (define_insn "*add_tp_di"
14105 [(set (match_operand:DI 0 "register_operand" "=r")
14106 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14107 (match_operand:DI 1 "register_operand" "0")))
14108 (clobber (reg:CC FLAGS_REG))]
14109 "TARGET_64BIT"
14110 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14111 [(set_attr "type" "alu")
14112 (set_attr "modrm" "0")
14113 (set_attr "length" "7")
14114 (set_attr "memory" "load")
14115 (set_attr "imm_disp" "false")])
14116 \f
14117 ;; These patterns match the binary 387 instructions for addM3, subM3,
14118 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14119 ;; SFmode. The first is the normal insn, the second the same insn but
14120 ;; with one operand a conversion, and the third the same insn but with
14121 ;; the other operand a conversion. The conversion may be SFmode or
14122 ;; SImode if the target mode DFmode, but only SImode if the target mode
14123 ;; is SFmode.
14124
14125 ;; Gcc is slightly more smart about handling normal two address instructions
14126 ;; so use special patterns for add and mull.
14127
14128 (define_insn "*fop_sf_comm_mixed"
14129 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14130 (match_operator:SF 3 "binary_fp_operator"
14131 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14132 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14133 "TARGET_MIX_SSE_I387
14134 && COMMUTATIVE_ARITH_P (operands[3])
14135 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14136 "* return output_387_binary_op (insn, operands);"
14137 [(set (attr "type")
14138 (if_then_else (eq_attr "alternative" "1")
14139 (if_then_else (match_operand:SF 3 "mult_operator" "")
14140 (const_string "ssemul")
14141 (const_string "sseadd"))
14142 (if_then_else (match_operand:SF 3 "mult_operator" "")
14143 (const_string "fmul")
14144 (const_string "fop"))))
14145 (set_attr "mode" "SF")])
14146
14147 (define_insn "*fop_sf_comm_sse"
14148 [(set (match_operand:SF 0 "register_operand" "=x")
14149 (match_operator:SF 3 "binary_fp_operator"
14150 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14151 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14152 "TARGET_SSE_MATH
14153 && COMMUTATIVE_ARITH_P (operands[3])
14154 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14155 "* return output_387_binary_op (insn, operands);"
14156 [(set (attr "type")
14157 (if_then_else (match_operand:SF 3 "mult_operator" "")
14158 (const_string "ssemul")
14159 (const_string "sseadd")))
14160 (set_attr "mode" "SF")])
14161
14162 (define_insn "*fop_sf_comm_i387"
14163 [(set (match_operand:SF 0 "register_operand" "=f")
14164 (match_operator:SF 3 "binary_fp_operator"
14165 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14166 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14167 "TARGET_80387
14168 && COMMUTATIVE_ARITH_P (operands[3])
14169 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14170 "* return output_387_binary_op (insn, operands);"
14171 [(set (attr "type")
14172 (if_then_else (match_operand:SF 3 "mult_operator" "")
14173 (const_string "fmul")
14174 (const_string "fop")))
14175 (set_attr "mode" "SF")])
14176
14177 (define_insn "*fop_sf_1_mixed"
14178 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14179 (match_operator:SF 3 "binary_fp_operator"
14180 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14181 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14182 "TARGET_MIX_SSE_I387
14183 && !COMMUTATIVE_ARITH_P (operands[3])
14184 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14185 "* return output_387_binary_op (insn, operands);"
14186 [(set (attr "type")
14187 (cond [(and (eq_attr "alternative" "2")
14188 (match_operand:SF 3 "mult_operator" ""))
14189 (const_string "ssemul")
14190 (and (eq_attr "alternative" "2")
14191 (match_operand:SF 3 "div_operator" ""))
14192 (const_string "ssediv")
14193 (eq_attr "alternative" "2")
14194 (const_string "sseadd")
14195 (match_operand:SF 3 "mult_operator" "")
14196 (const_string "fmul")
14197 (match_operand:SF 3 "div_operator" "")
14198 (const_string "fdiv")
14199 ]
14200 (const_string "fop")))
14201 (set_attr "mode" "SF")])
14202
14203 (define_insn "*fop_sf_1_sse"
14204 [(set (match_operand:SF 0 "register_operand" "=x")
14205 (match_operator:SF 3 "binary_fp_operator"
14206 [(match_operand:SF 1 "register_operand" "0")
14207 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14208 "TARGET_SSE_MATH
14209 && !COMMUTATIVE_ARITH_P (operands[3])"
14210 "* return output_387_binary_op (insn, operands);"
14211 [(set (attr "type")
14212 (cond [(match_operand:SF 3 "mult_operator" "")
14213 (const_string "ssemul")
14214 (match_operand:SF 3 "div_operator" "")
14215 (const_string "ssediv")
14216 ]
14217 (const_string "sseadd")))
14218 (set_attr "mode" "SF")])
14219
14220 ;; This pattern is not fully shadowed by the pattern above.
14221 (define_insn "*fop_sf_1_i387"
14222 [(set (match_operand:SF 0 "register_operand" "=f,f")
14223 (match_operator:SF 3 "binary_fp_operator"
14224 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14225 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14226 "TARGET_80387 && !TARGET_SSE_MATH
14227 && !COMMUTATIVE_ARITH_P (operands[3])
14228 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14229 "* return output_387_binary_op (insn, operands);"
14230 [(set (attr "type")
14231 (cond [(match_operand:SF 3 "mult_operator" "")
14232 (const_string "fmul")
14233 (match_operand:SF 3 "div_operator" "")
14234 (const_string "fdiv")
14235 ]
14236 (const_string "fop")))
14237 (set_attr "mode" "SF")])
14238
14239
14240 ;; ??? Add SSE splitters for these!
14241 (define_insn "*fop_sf_2_i387"
14242 [(set (match_operand:SF 0 "register_operand" "=f,f")
14243 (match_operator:SF 3 "binary_fp_operator"
14244 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14245 (match_operand:SF 2 "register_operand" "0,0")]))]
14246 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14247 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14248 [(set (attr "type")
14249 (cond [(match_operand:SF 3 "mult_operator" "")
14250 (const_string "fmul")
14251 (match_operand:SF 3 "div_operator" "")
14252 (const_string "fdiv")
14253 ]
14254 (const_string "fop")))
14255 (set_attr "fp_int_src" "true")
14256 (set_attr "mode" "SI")])
14257
14258 (define_insn "*fop_sf_3_i387"
14259 [(set (match_operand:SF 0 "register_operand" "=f,f")
14260 (match_operator:SF 3 "binary_fp_operator"
14261 [(match_operand:SF 1 "register_operand" "0,0")
14262 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14263 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14264 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14265 [(set (attr "type")
14266 (cond [(match_operand:SF 3 "mult_operator" "")
14267 (const_string "fmul")
14268 (match_operand:SF 3 "div_operator" "")
14269 (const_string "fdiv")
14270 ]
14271 (const_string "fop")))
14272 (set_attr "fp_int_src" "true")
14273 (set_attr "mode" "SI")])
14274
14275 (define_insn "*fop_df_comm_mixed"
14276 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14277 (match_operator:DF 3 "binary_fp_operator"
14278 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14279 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14280 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14281 && COMMUTATIVE_ARITH_P (operands[3])
14282 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14283 "* return output_387_binary_op (insn, operands);"
14284 [(set (attr "type")
14285 (if_then_else (eq_attr "alternative" "1")
14286 (if_then_else (match_operand:SF 3 "mult_operator" "")
14287 (const_string "ssemul")
14288 (const_string "sseadd"))
14289 (if_then_else (match_operand:SF 3 "mult_operator" "")
14290 (const_string "fmul")
14291 (const_string "fop"))))
14292 (set_attr "mode" "DF")])
14293
14294 (define_insn "*fop_df_comm_sse"
14295 [(set (match_operand:DF 0 "register_operand" "=Y")
14296 (match_operator:DF 3 "binary_fp_operator"
14297 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14298 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14299 "TARGET_SSE2 && TARGET_SSE_MATH
14300 && COMMUTATIVE_ARITH_P (operands[3])
14301 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14302 "* return output_387_binary_op (insn, operands);"
14303 [(set (attr "type")
14304 (if_then_else (match_operand:SF 3 "mult_operator" "")
14305 (const_string "ssemul")
14306 (const_string "sseadd")))
14307 (set_attr "mode" "DF")])
14308
14309 (define_insn "*fop_df_comm_i387"
14310 [(set (match_operand:DF 0 "register_operand" "=f")
14311 (match_operator:DF 3 "binary_fp_operator"
14312 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14313 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14314 "TARGET_80387
14315 && COMMUTATIVE_ARITH_P (operands[3])
14316 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14317 "* return output_387_binary_op (insn, operands);"
14318 [(set (attr "type")
14319 (if_then_else (match_operand:SF 3 "mult_operator" "")
14320 (const_string "fmul")
14321 (const_string "fop")))
14322 (set_attr "mode" "DF")])
14323
14324 (define_insn "*fop_df_1_mixed"
14325 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14326 (match_operator:DF 3 "binary_fp_operator"
14327 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14328 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14329 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14330 && !COMMUTATIVE_ARITH_P (operands[3])
14331 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14332 "* return output_387_binary_op (insn, operands);"
14333 [(set (attr "type")
14334 (cond [(and (eq_attr "alternative" "2")
14335 (match_operand:SF 3 "mult_operator" ""))
14336 (const_string "ssemul")
14337 (and (eq_attr "alternative" "2")
14338 (match_operand:SF 3 "div_operator" ""))
14339 (const_string "ssediv")
14340 (eq_attr "alternative" "2")
14341 (const_string "sseadd")
14342 (match_operand:DF 3 "mult_operator" "")
14343 (const_string "fmul")
14344 (match_operand:DF 3 "div_operator" "")
14345 (const_string "fdiv")
14346 ]
14347 (const_string "fop")))
14348 (set_attr "mode" "DF")])
14349
14350 (define_insn "*fop_df_1_sse"
14351 [(set (match_operand:DF 0 "register_operand" "=Y")
14352 (match_operator:DF 3 "binary_fp_operator"
14353 [(match_operand:DF 1 "register_operand" "0")
14354 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14355 "TARGET_SSE2 && TARGET_SSE_MATH
14356 && !COMMUTATIVE_ARITH_P (operands[3])"
14357 "* return output_387_binary_op (insn, operands);"
14358 [(set_attr "mode" "DF")
14359 (set (attr "type")
14360 (cond [(match_operand:SF 3 "mult_operator" "")
14361 (const_string "ssemul")
14362 (match_operand:SF 3 "div_operator" "")
14363 (const_string "ssediv")
14364 ]
14365 (const_string "sseadd")))])
14366
14367 ;; This pattern is not fully shadowed by the pattern above.
14368 (define_insn "*fop_df_1_i387"
14369 [(set (match_operand:DF 0 "register_operand" "=f,f")
14370 (match_operator:DF 3 "binary_fp_operator"
14371 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14372 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14373 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14374 && !COMMUTATIVE_ARITH_P (operands[3])
14375 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14376 "* return output_387_binary_op (insn, operands);"
14377 [(set (attr "type")
14378 (cond [(match_operand:DF 3 "mult_operator" "")
14379 (const_string "fmul")
14380 (match_operand:DF 3 "div_operator" "")
14381 (const_string "fdiv")
14382 ]
14383 (const_string "fop")))
14384 (set_attr "mode" "DF")])
14385
14386 ;; ??? Add SSE splitters for these!
14387 (define_insn "*fop_df_2_i387"
14388 [(set (match_operand:DF 0 "register_operand" "=f,f")
14389 (match_operator:DF 3 "binary_fp_operator"
14390 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14391 (match_operand:DF 2 "register_operand" "0,0")]))]
14392 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14393 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14394 [(set (attr "type")
14395 (cond [(match_operand:DF 3 "mult_operator" "")
14396 (const_string "fmul")
14397 (match_operand:DF 3 "div_operator" "")
14398 (const_string "fdiv")
14399 ]
14400 (const_string "fop")))
14401 (set_attr "fp_int_src" "true")
14402 (set_attr "mode" "SI")])
14403
14404 (define_insn "*fop_df_3_i387"
14405 [(set (match_operand:DF 0 "register_operand" "=f,f")
14406 (match_operator:DF 3 "binary_fp_operator"
14407 [(match_operand:DF 1 "register_operand" "0,0")
14408 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14409 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14410 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14411 [(set (attr "type")
14412 (cond [(match_operand:DF 3 "mult_operator" "")
14413 (const_string "fmul")
14414 (match_operand:DF 3 "div_operator" "")
14415 (const_string "fdiv")
14416 ]
14417 (const_string "fop")))
14418 (set_attr "fp_int_src" "true")
14419 (set_attr "mode" "SI")])
14420
14421 (define_insn "*fop_df_4_i387"
14422 [(set (match_operand:DF 0 "register_operand" "=f,f")
14423 (match_operator:DF 3 "binary_fp_operator"
14424 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14425 (match_operand:DF 2 "register_operand" "0,f")]))]
14426 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14427 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14428 "* return output_387_binary_op (insn, operands);"
14429 [(set (attr "type")
14430 (cond [(match_operand:DF 3 "mult_operator" "")
14431 (const_string "fmul")
14432 (match_operand:DF 3 "div_operator" "")
14433 (const_string "fdiv")
14434 ]
14435 (const_string "fop")))
14436 (set_attr "mode" "SF")])
14437
14438 (define_insn "*fop_df_5_i387"
14439 [(set (match_operand:DF 0 "register_operand" "=f,f")
14440 (match_operator:DF 3 "binary_fp_operator"
14441 [(match_operand:DF 1 "register_operand" "0,f")
14442 (float_extend:DF
14443 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14444 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14445 "* return output_387_binary_op (insn, operands);"
14446 [(set (attr "type")
14447 (cond [(match_operand:DF 3 "mult_operator" "")
14448 (const_string "fmul")
14449 (match_operand:DF 3 "div_operator" "")
14450 (const_string "fdiv")
14451 ]
14452 (const_string "fop")))
14453 (set_attr "mode" "SF")])
14454
14455 (define_insn "*fop_df_6_i387"
14456 [(set (match_operand:DF 0 "register_operand" "=f,f")
14457 (match_operator:DF 3 "binary_fp_operator"
14458 [(float_extend:DF
14459 (match_operand:SF 1 "register_operand" "0,f"))
14460 (float_extend:DF
14461 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14462 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14463 "* return output_387_binary_op (insn, operands);"
14464 [(set (attr "type")
14465 (cond [(match_operand:DF 3 "mult_operator" "")
14466 (const_string "fmul")
14467 (match_operand:DF 3 "div_operator" "")
14468 (const_string "fdiv")
14469 ]
14470 (const_string "fop")))
14471 (set_attr "mode" "SF")])
14472
14473 (define_insn "*fop_xf_comm_i387"
14474 [(set (match_operand:XF 0 "register_operand" "=f")
14475 (match_operator:XF 3 "binary_fp_operator"
14476 [(match_operand:XF 1 "register_operand" "%0")
14477 (match_operand:XF 2 "register_operand" "f")]))]
14478 "TARGET_80387
14479 && COMMUTATIVE_ARITH_P (operands[3])"
14480 "* return output_387_binary_op (insn, operands);"
14481 [(set (attr "type")
14482 (if_then_else (match_operand:XF 3 "mult_operator" "")
14483 (const_string "fmul")
14484 (const_string "fop")))
14485 (set_attr "mode" "XF")])
14486
14487 (define_insn "*fop_xf_1_i387"
14488 [(set (match_operand:XF 0 "register_operand" "=f,f")
14489 (match_operator:XF 3 "binary_fp_operator"
14490 [(match_operand:XF 1 "register_operand" "0,f")
14491 (match_operand:XF 2 "register_operand" "f,0")]))]
14492 "TARGET_80387
14493 && !COMMUTATIVE_ARITH_P (operands[3])"
14494 "* return output_387_binary_op (insn, operands);"
14495 [(set (attr "type")
14496 (cond [(match_operand:XF 3 "mult_operator" "")
14497 (const_string "fmul")
14498 (match_operand:XF 3 "div_operator" "")
14499 (const_string "fdiv")
14500 ]
14501 (const_string "fop")))
14502 (set_attr "mode" "XF")])
14503
14504 (define_insn "*fop_xf_2_i387"
14505 [(set (match_operand:XF 0 "register_operand" "=f,f")
14506 (match_operator:XF 3 "binary_fp_operator"
14507 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14508 (match_operand:XF 2 "register_operand" "0,0")]))]
14509 "TARGET_80387 && TARGET_USE_FIOP"
14510 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14511 [(set (attr "type")
14512 (cond [(match_operand:XF 3 "mult_operator" "")
14513 (const_string "fmul")
14514 (match_operand:XF 3 "div_operator" "")
14515 (const_string "fdiv")
14516 ]
14517 (const_string "fop")))
14518 (set_attr "fp_int_src" "true")
14519 (set_attr "mode" "SI")])
14520
14521 (define_insn "*fop_xf_3_i387"
14522 [(set (match_operand:XF 0 "register_operand" "=f,f")
14523 (match_operator:XF 3 "binary_fp_operator"
14524 [(match_operand:XF 1 "register_operand" "0,0")
14525 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14526 "TARGET_80387 && TARGET_USE_FIOP"
14527 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14528 [(set (attr "type")
14529 (cond [(match_operand:XF 3 "mult_operator" "")
14530 (const_string "fmul")
14531 (match_operand:XF 3 "div_operator" "")
14532 (const_string "fdiv")
14533 ]
14534 (const_string "fop")))
14535 (set_attr "fp_int_src" "true")
14536 (set_attr "mode" "SI")])
14537
14538 (define_insn "*fop_xf_4_i387"
14539 [(set (match_operand:XF 0 "register_operand" "=f,f")
14540 (match_operator:XF 3 "binary_fp_operator"
14541 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14542 (match_operand:XF 2 "register_operand" "0,f")]))]
14543 "TARGET_80387"
14544 "* return output_387_binary_op (insn, operands);"
14545 [(set (attr "type")
14546 (cond [(match_operand:XF 3 "mult_operator" "")
14547 (const_string "fmul")
14548 (match_operand:XF 3 "div_operator" "")
14549 (const_string "fdiv")
14550 ]
14551 (const_string "fop")))
14552 (set_attr "mode" "SF")])
14553
14554 (define_insn "*fop_xf_5_i387"
14555 [(set (match_operand:XF 0 "register_operand" "=f,f")
14556 (match_operator:XF 3 "binary_fp_operator"
14557 [(match_operand:XF 1 "register_operand" "0,f")
14558 (float_extend:XF
14559 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14560 "TARGET_80387"
14561 "* return output_387_binary_op (insn, operands);"
14562 [(set (attr "type")
14563 (cond [(match_operand:XF 3 "mult_operator" "")
14564 (const_string "fmul")
14565 (match_operand:XF 3 "div_operator" "")
14566 (const_string "fdiv")
14567 ]
14568 (const_string "fop")))
14569 (set_attr "mode" "SF")])
14570
14571 (define_insn "*fop_xf_6_i387"
14572 [(set (match_operand:XF 0 "register_operand" "=f,f")
14573 (match_operator:XF 3 "binary_fp_operator"
14574 [(float_extend:XF
14575 (match_operand 1 "register_operand" "0,f"))
14576 (float_extend:XF
14577 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14578 "TARGET_80387"
14579 "* return output_387_binary_op (insn, operands);"
14580 [(set (attr "type")
14581 (cond [(match_operand:XF 3 "mult_operator" "")
14582 (const_string "fmul")
14583 (match_operand:XF 3 "div_operator" "")
14584 (const_string "fdiv")
14585 ]
14586 (const_string "fop")))
14587 (set_attr "mode" "SF")])
14588
14589 (define_split
14590 [(set (match_operand 0 "register_operand" "")
14591 (match_operator 3 "binary_fp_operator"
14592 [(float (match_operand:SI 1 "register_operand" ""))
14593 (match_operand 2 "register_operand" "")]))]
14594 "TARGET_80387 && reload_completed
14595 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14596 [(const_int 0)]
14597 {
14598 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14599 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14600 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14601 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14602 GET_MODE (operands[3]),
14603 operands[4],
14604 operands[2])));
14605 ix86_free_from_memory (GET_MODE (operands[1]));
14606 DONE;
14607 })
14608
14609 (define_split
14610 [(set (match_operand 0 "register_operand" "")
14611 (match_operator 3 "binary_fp_operator"
14612 [(match_operand 1 "register_operand" "")
14613 (float (match_operand:SI 2 "register_operand" ""))]))]
14614 "TARGET_80387 && reload_completed
14615 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14616 [(const_int 0)]
14617 {
14618 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14619 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14620 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14621 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14622 GET_MODE (operands[3]),
14623 operands[1],
14624 operands[4])));
14625 ix86_free_from_memory (GET_MODE (operands[2]));
14626 DONE;
14627 })
14628 \f
14629 ;; FPU special functions.
14630
14631 (define_expand "sqrtsf2"
14632 [(set (match_operand:SF 0 "register_operand" "")
14633 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14634 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14635 {
14636 if (!TARGET_SSE_MATH)
14637 operands[1] = force_reg (SFmode, operands[1]);
14638 })
14639
14640 (define_insn "*sqrtsf2_mixed"
14641 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14642 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14643 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14644 "@
14645 fsqrt
14646 sqrtss\t{%1, %0|%0, %1}"
14647 [(set_attr "type" "fpspc,sse")
14648 (set_attr "mode" "SF,SF")
14649 (set_attr "athlon_decode" "direct,*")])
14650
14651 (define_insn "*sqrtsf2_sse"
14652 [(set (match_operand:SF 0 "register_operand" "=x")
14653 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14654 "TARGET_SSE_MATH"
14655 "sqrtss\t{%1, %0|%0, %1}"
14656 [(set_attr "type" "sse")
14657 (set_attr "mode" "SF")
14658 (set_attr "athlon_decode" "*")])
14659
14660 (define_insn "*sqrtsf2_i387"
14661 [(set (match_operand:SF 0 "register_operand" "=f")
14662 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14663 "TARGET_USE_FANCY_MATH_387"
14664 "fsqrt"
14665 [(set_attr "type" "fpspc")
14666 (set_attr "mode" "SF")
14667 (set_attr "athlon_decode" "direct")])
14668
14669 (define_expand "sqrtdf2"
14670 [(set (match_operand:DF 0 "register_operand" "")
14671 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14672 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14673 {
14674 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14675 operands[1] = force_reg (DFmode, operands[1]);
14676 })
14677
14678 (define_insn "*sqrtdf2_mixed"
14679 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14680 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14681 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14682 "@
14683 fsqrt
14684 sqrtsd\t{%1, %0|%0, %1}"
14685 [(set_attr "type" "fpspc,sse")
14686 (set_attr "mode" "DF,DF")
14687 (set_attr "athlon_decode" "direct,*")])
14688
14689 (define_insn "*sqrtdf2_sse"
14690 [(set (match_operand:DF 0 "register_operand" "=Y")
14691 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14692 "TARGET_SSE2 && TARGET_SSE_MATH"
14693 "sqrtsd\t{%1, %0|%0, %1}"
14694 [(set_attr "type" "sse")
14695 (set_attr "mode" "DF")
14696 (set_attr "athlon_decode" "*")])
14697
14698 (define_insn "*sqrtdf2_i387"
14699 [(set (match_operand:DF 0 "register_operand" "=f")
14700 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14701 "TARGET_USE_FANCY_MATH_387"
14702 "fsqrt"
14703 [(set_attr "type" "fpspc")
14704 (set_attr "mode" "DF")
14705 (set_attr "athlon_decode" "direct")])
14706
14707 (define_insn "*sqrtextendsfdf2_i387"
14708 [(set (match_operand:DF 0 "register_operand" "=f")
14709 (sqrt:DF (float_extend:DF
14710 (match_operand:SF 1 "register_operand" "0"))))]
14711 "TARGET_USE_FANCY_MATH_387
14712 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14713 "fsqrt"
14714 [(set_attr "type" "fpspc")
14715 (set_attr "mode" "DF")
14716 (set_attr "athlon_decode" "direct")])
14717
14718 (define_insn "sqrtxf2"
14719 [(set (match_operand:XF 0 "register_operand" "=f")
14720 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14721 "TARGET_USE_FANCY_MATH_387
14722 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14723 "fsqrt"
14724 [(set_attr "type" "fpspc")
14725 (set_attr "mode" "XF")
14726 (set_attr "athlon_decode" "direct")])
14727
14728 (define_insn "*sqrtextendsfxf2_i387"
14729 [(set (match_operand:XF 0 "register_operand" "=f")
14730 (sqrt:XF (float_extend:XF
14731 (match_operand:SF 1 "register_operand" "0"))))]
14732 "TARGET_USE_FANCY_MATH_387"
14733 "fsqrt"
14734 [(set_attr "type" "fpspc")
14735 (set_attr "mode" "XF")
14736 (set_attr "athlon_decode" "direct")])
14737
14738 (define_insn "*sqrtextenddfxf2_i387"
14739 [(set (match_operand:XF 0 "register_operand" "=f")
14740 (sqrt:XF (float_extend:XF
14741 (match_operand:DF 1 "register_operand" "0"))))]
14742 "TARGET_USE_FANCY_MATH_387"
14743 "fsqrt"
14744 [(set_attr "type" "fpspc")
14745 (set_attr "mode" "XF")
14746 (set_attr "athlon_decode" "direct")])
14747
14748 (define_insn "fpremxf4"
14749 [(set (match_operand:XF 0 "register_operand" "=f")
14750 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14751 (match_operand:XF 3 "register_operand" "1")]
14752 UNSPEC_FPREM_F))
14753 (set (match_operand:XF 1 "register_operand" "=u")
14754 (unspec:XF [(match_dup 2) (match_dup 3)]
14755 UNSPEC_FPREM_U))
14756 (set (reg:CCFP FPSR_REG)
14757 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14758 "TARGET_USE_FANCY_MATH_387
14759 && flag_unsafe_math_optimizations"
14760 "fprem"
14761 [(set_attr "type" "fpspc")
14762 (set_attr "mode" "XF")])
14763
14764 (define_expand "fmodsf3"
14765 [(use (match_operand:SF 0 "register_operand" ""))
14766 (use (match_operand:SF 1 "register_operand" ""))
14767 (use (match_operand:SF 2 "register_operand" ""))]
14768 "TARGET_USE_FANCY_MATH_387
14769 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14770 && flag_unsafe_math_optimizations"
14771 {
14772 rtx label = gen_label_rtx ();
14773
14774 rtx op1 = gen_reg_rtx (XFmode);
14775 rtx op2 = gen_reg_rtx (XFmode);
14776
14777 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14778 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14779
14780 emit_label (label);
14781
14782 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14783 ix86_emit_fp_unordered_jump (label);
14784
14785 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14786 DONE;
14787 })
14788
14789 (define_expand "fmoddf3"
14790 [(use (match_operand:DF 0 "register_operand" ""))
14791 (use (match_operand:DF 1 "register_operand" ""))
14792 (use (match_operand:DF 2 "register_operand" ""))]
14793 "TARGET_USE_FANCY_MATH_387
14794 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14795 && flag_unsafe_math_optimizations"
14796 {
14797 rtx label = gen_label_rtx ();
14798
14799 rtx op1 = gen_reg_rtx (XFmode);
14800 rtx op2 = gen_reg_rtx (XFmode);
14801
14802 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14803 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14804
14805 emit_label (label);
14806
14807 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14808 ix86_emit_fp_unordered_jump (label);
14809
14810 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14811 DONE;
14812 })
14813
14814 (define_expand "fmodxf3"
14815 [(use (match_operand:XF 0 "register_operand" ""))
14816 (use (match_operand:XF 1 "register_operand" ""))
14817 (use (match_operand:XF 2 "register_operand" ""))]
14818 "TARGET_USE_FANCY_MATH_387
14819 && flag_unsafe_math_optimizations"
14820 {
14821 rtx label = gen_label_rtx ();
14822
14823 emit_label (label);
14824
14825 emit_insn (gen_fpremxf4 (operands[1], operands[2],
14826 operands[1], operands[2]));
14827 ix86_emit_fp_unordered_jump (label);
14828
14829 emit_move_insn (operands[0], operands[1]);
14830 DONE;
14831 })
14832
14833 (define_insn "fprem1xf4"
14834 [(set (match_operand:XF 0 "register_operand" "=f")
14835 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14836 (match_operand:XF 3 "register_operand" "1")]
14837 UNSPEC_FPREM1_F))
14838 (set (match_operand:XF 1 "register_operand" "=u")
14839 (unspec:XF [(match_dup 2) (match_dup 3)]
14840 UNSPEC_FPREM1_U))
14841 (set (reg:CCFP FPSR_REG)
14842 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14843 "TARGET_USE_FANCY_MATH_387
14844 && flag_unsafe_math_optimizations"
14845 "fprem1"
14846 [(set_attr "type" "fpspc")
14847 (set_attr "mode" "XF")])
14848
14849 (define_expand "dremsf3"
14850 [(use (match_operand:SF 0 "register_operand" ""))
14851 (use (match_operand:SF 1 "register_operand" ""))
14852 (use (match_operand:SF 2 "register_operand" ""))]
14853 "TARGET_USE_FANCY_MATH_387
14854 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14855 && flag_unsafe_math_optimizations"
14856 {
14857 rtx label = gen_label_rtx ();
14858
14859 rtx op1 = gen_reg_rtx (XFmode);
14860 rtx op2 = gen_reg_rtx (XFmode);
14861
14862 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14863 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14864
14865 emit_label (label);
14866
14867 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14868 ix86_emit_fp_unordered_jump (label);
14869
14870 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14871 DONE;
14872 })
14873
14874 (define_expand "dremdf3"
14875 [(use (match_operand:DF 0 "register_operand" ""))
14876 (use (match_operand:DF 1 "register_operand" ""))
14877 (use (match_operand:DF 2 "register_operand" ""))]
14878 "TARGET_USE_FANCY_MATH_387
14879 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14880 && flag_unsafe_math_optimizations"
14881 {
14882 rtx label = gen_label_rtx ();
14883
14884 rtx op1 = gen_reg_rtx (XFmode);
14885 rtx op2 = gen_reg_rtx (XFmode);
14886
14887 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14888 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14889
14890 emit_label (label);
14891
14892 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14893 ix86_emit_fp_unordered_jump (label);
14894
14895 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14896 DONE;
14897 })
14898
14899 (define_expand "dremxf3"
14900 [(use (match_operand:XF 0 "register_operand" ""))
14901 (use (match_operand:XF 1 "register_operand" ""))
14902 (use (match_operand:XF 2 "register_operand" ""))]
14903 "TARGET_USE_FANCY_MATH_387
14904 && flag_unsafe_math_optimizations"
14905 {
14906 rtx label = gen_label_rtx ();
14907
14908 emit_label (label);
14909
14910 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14911 operands[1], operands[2]));
14912 ix86_emit_fp_unordered_jump (label);
14913
14914 emit_move_insn (operands[0], operands[1]);
14915 DONE;
14916 })
14917
14918 (define_insn "*sindf2"
14919 [(set (match_operand:DF 0 "register_operand" "=f")
14920 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14921 "TARGET_USE_FANCY_MATH_387
14922 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14923 && flag_unsafe_math_optimizations"
14924 "fsin"
14925 [(set_attr "type" "fpspc")
14926 (set_attr "mode" "DF")])
14927
14928 (define_insn "*sinsf2"
14929 [(set (match_operand:SF 0 "register_operand" "=f")
14930 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14931 "TARGET_USE_FANCY_MATH_387
14932 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14933 && flag_unsafe_math_optimizations"
14934 "fsin"
14935 [(set_attr "type" "fpspc")
14936 (set_attr "mode" "SF")])
14937
14938 (define_insn "*sinextendsfdf2"
14939 [(set (match_operand:DF 0 "register_operand" "=f")
14940 (unspec:DF [(float_extend:DF
14941 (match_operand:SF 1 "register_operand" "0"))]
14942 UNSPEC_SIN))]
14943 "TARGET_USE_FANCY_MATH_387
14944 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14945 && flag_unsafe_math_optimizations"
14946 "fsin"
14947 [(set_attr "type" "fpspc")
14948 (set_attr "mode" "DF")])
14949
14950 (define_insn "*sinxf2"
14951 [(set (match_operand:XF 0 "register_operand" "=f")
14952 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14953 "TARGET_USE_FANCY_MATH_387
14954 && flag_unsafe_math_optimizations"
14955 "fsin"
14956 [(set_attr "type" "fpspc")
14957 (set_attr "mode" "XF")])
14958
14959 (define_insn "*cosdf2"
14960 [(set (match_operand:DF 0 "register_operand" "=f")
14961 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14962 "TARGET_USE_FANCY_MATH_387
14963 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14964 && flag_unsafe_math_optimizations"
14965 "fcos"
14966 [(set_attr "type" "fpspc")
14967 (set_attr "mode" "DF")])
14968
14969 (define_insn "*cossf2"
14970 [(set (match_operand:SF 0 "register_operand" "=f")
14971 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14972 "TARGET_USE_FANCY_MATH_387
14973 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14974 && flag_unsafe_math_optimizations"
14975 "fcos"
14976 [(set_attr "type" "fpspc")
14977 (set_attr "mode" "SF")])
14978
14979 (define_insn "*cosextendsfdf2"
14980 [(set (match_operand:DF 0 "register_operand" "=f")
14981 (unspec:DF [(float_extend:DF
14982 (match_operand:SF 1 "register_operand" "0"))]
14983 UNSPEC_COS))]
14984 "TARGET_USE_FANCY_MATH_387
14985 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14986 && flag_unsafe_math_optimizations"
14987 "fcos"
14988 [(set_attr "type" "fpspc")
14989 (set_attr "mode" "DF")])
14990
14991 (define_insn "*cosxf2"
14992 [(set (match_operand:XF 0 "register_operand" "=f")
14993 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14994 "TARGET_USE_FANCY_MATH_387
14995 && flag_unsafe_math_optimizations"
14996 "fcos"
14997 [(set_attr "type" "fpspc")
14998 (set_attr "mode" "XF")])
14999
15000 ;; With sincos pattern defined, sin and cos builtin function will be
15001 ;; expanded to sincos pattern with one of its outputs left unused.
15002 ;; Cse pass will detected, if two sincos patterns can be combined,
15003 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15004 ;; depending on the unused output.
15005
15006 (define_insn "sincosdf3"
15007 [(set (match_operand:DF 0 "register_operand" "=f")
15008 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15009 UNSPEC_SINCOS_COS))
15010 (set (match_operand:DF 1 "register_operand" "=u")
15011 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15012 "TARGET_USE_FANCY_MATH_387
15013 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15014 && flag_unsafe_math_optimizations"
15015 "fsincos"
15016 [(set_attr "type" "fpspc")
15017 (set_attr "mode" "DF")])
15018
15019 (define_split
15020 [(set (match_operand:DF 0 "register_operand" "")
15021 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15022 UNSPEC_SINCOS_COS))
15023 (set (match_operand:DF 1 "register_operand" "")
15024 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15025 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15026 && !reload_completed && !reload_in_progress"
15027 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15028 "")
15029
15030 (define_split
15031 [(set (match_operand:DF 0 "register_operand" "")
15032 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15033 UNSPEC_SINCOS_COS))
15034 (set (match_operand:DF 1 "register_operand" "")
15035 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15036 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15037 && !reload_completed && !reload_in_progress"
15038 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15039 "")
15040
15041 (define_insn "sincossf3"
15042 [(set (match_operand:SF 0 "register_operand" "=f")
15043 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15044 UNSPEC_SINCOS_COS))
15045 (set (match_operand:SF 1 "register_operand" "=u")
15046 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15047 "TARGET_USE_FANCY_MATH_387
15048 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15049 && flag_unsafe_math_optimizations"
15050 "fsincos"
15051 [(set_attr "type" "fpspc")
15052 (set_attr "mode" "SF")])
15053
15054 (define_split
15055 [(set (match_operand:SF 0 "register_operand" "")
15056 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15057 UNSPEC_SINCOS_COS))
15058 (set (match_operand:SF 1 "register_operand" "")
15059 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15060 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15061 && !reload_completed && !reload_in_progress"
15062 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15063 "")
15064
15065 (define_split
15066 [(set (match_operand:SF 0 "register_operand" "")
15067 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15068 UNSPEC_SINCOS_COS))
15069 (set (match_operand:SF 1 "register_operand" "")
15070 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15071 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15072 && !reload_completed && !reload_in_progress"
15073 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15074 "")
15075
15076 (define_insn "*sincosextendsfdf3"
15077 [(set (match_operand:DF 0 "register_operand" "=f")
15078 (unspec:DF [(float_extend:DF
15079 (match_operand:SF 2 "register_operand" "0"))]
15080 UNSPEC_SINCOS_COS))
15081 (set (match_operand:DF 1 "register_operand" "=u")
15082 (unspec:DF [(float_extend:DF
15083 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15084 "TARGET_USE_FANCY_MATH_387
15085 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15086 && flag_unsafe_math_optimizations"
15087 "fsincos"
15088 [(set_attr "type" "fpspc")
15089 (set_attr "mode" "DF")])
15090
15091 (define_split
15092 [(set (match_operand:DF 0 "register_operand" "")
15093 (unspec:DF [(float_extend:DF
15094 (match_operand:SF 2 "register_operand" ""))]
15095 UNSPEC_SINCOS_COS))
15096 (set (match_operand:DF 1 "register_operand" "")
15097 (unspec:DF [(float_extend:DF
15098 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15099 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15100 && !reload_completed && !reload_in_progress"
15101 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15102 (match_dup 2))] UNSPEC_SIN))]
15103 "")
15104
15105 (define_split
15106 [(set (match_operand:DF 0 "register_operand" "")
15107 (unspec:DF [(float_extend:DF
15108 (match_operand:SF 2 "register_operand" ""))]
15109 UNSPEC_SINCOS_COS))
15110 (set (match_operand:DF 1 "register_operand" "")
15111 (unspec:DF [(float_extend:DF
15112 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15113 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15114 && !reload_completed && !reload_in_progress"
15115 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15116 (match_dup 2))] UNSPEC_COS))]
15117 "")
15118
15119 (define_insn "sincosxf3"
15120 [(set (match_operand:XF 0 "register_operand" "=f")
15121 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15122 UNSPEC_SINCOS_COS))
15123 (set (match_operand:XF 1 "register_operand" "=u")
15124 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15125 "TARGET_USE_FANCY_MATH_387
15126 && flag_unsafe_math_optimizations"
15127 "fsincos"
15128 [(set_attr "type" "fpspc")
15129 (set_attr "mode" "XF")])
15130
15131 (define_split
15132 [(set (match_operand:XF 0 "register_operand" "")
15133 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15134 UNSPEC_SINCOS_COS))
15135 (set (match_operand:XF 1 "register_operand" "")
15136 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15137 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15138 && !reload_completed && !reload_in_progress"
15139 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15140 "")
15141
15142 (define_split
15143 [(set (match_operand:XF 0 "register_operand" "")
15144 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15145 UNSPEC_SINCOS_COS))
15146 (set (match_operand:XF 1 "register_operand" "")
15147 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15148 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15149 && !reload_completed && !reload_in_progress"
15150 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15151 "")
15152
15153 (define_insn "*tandf3_1"
15154 [(set (match_operand:DF 0 "register_operand" "=f")
15155 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15156 UNSPEC_TAN_ONE))
15157 (set (match_operand:DF 1 "register_operand" "=u")
15158 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15159 "TARGET_USE_FANCY_MATH_387
15160 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15161 && flag_unsafe_math_optimizations"
15162 "fptan"
15163 [(set_attr "type" "fpspc")
15164 (set_attr "mode" "DF")])
15165
15166 ;; optimize sequence: fptan
15167 ;; fstp %st(0)
15168 ;; fld1
15169 ;; into fptan insn.
15170
15171 (define_peephole2
15172 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15173 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15174 UNSPEC_TAN_ONE))
15175 (set (match_operand:DF 1 "register_operand" "")
15176 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15177 (set (match_dup 0)
15178 (match_operand:DF 3 "immediate_operand" ""))]
15179 "standard_80387_constant_p (operands[3]) == 2"
15180 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15181 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15182 "")
15183
15184 (define_expand "tandf2"
15185 [(parallel [(set (match_dup 2)
15186 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15187 UNSPEC_TAN_ONE))
15188 (set (match_operand:DF 0 "register_operand" "")
15189 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15190 "TARGET_USE_FANCY_MATH_387
15191 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15192 && flag_unsafe_math_optimizations"
15193 {
15194 operands[2] = gen_reg_rtx (DFmode);
15195 })
15196
15197 (define_insn "*tansf3_1"
15198 [(set (match_operand:SF 0 "register_operand" "=f")
15199 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15200 UNSPEC_TAN_ONE))
15201 (set (match_operand:SF 1 "register_operand" "=u")
15202 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15203 "TARGET_USE_FANCY_MATH_387
15204 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15205 && flag_unsafe_math_optimizations"
15206 "fptan"
15207 [(set_attr "type" "fpspc")
15208 (set_attr "mode" "SF")])
15209
15210 ;; optimize sequence: fptan
15211 ;; fstp %st(0)
15212 ;; fld1
15213 ;; into fptan insn.
15214
15215 (define_peephole2
15216 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15217 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15218 UNSPEC_TAN_ONE))
15219 (set (match_operand:SF 1 "register_operand" "")
15220 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15221 (set (match_dup 0)
15222 (match_operand:SF 3 "immediate_operand" ""))]
15223 "standard_80387_constant_p (operands[3]) == 2"
15224 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15225 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15226 "")
15227
15228 (define_expand "tansf2"
15229 [(parallel [(set (match_dup 2)
15230 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15231 UNSPEC_TAN_ONE))
15232 (set (match_operand:SF 0 "register_operand" "")
15233 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15234 "TARGET_USE_FANCY_MATH_387
15235 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15236 && flag_unsafe_math_optimizations"
15237 {
15238 operands[2] = gen_reg_rtx (SFmode);
15239 })
15240
15241 (define_insn "*tanxf3_1"
15242 [(set (match_operand:XF 0 "register_operand" "=f")
15243 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15244 UNSPEC_TAN_ONE))
15245 (set (match_operand:XF 1 "register_operand" "=u")
15246 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15247 "TARGET_USE_FANCY_MATH_387
15248 && flag_unsafe_math_optimizations"
15249 "fptan"
15250 [(set_attr "type" "fpspc")
15251 (set_attr "mode" "XF")])
15252
15253 ;; optimize sequence: fptan
15254 ;; fstp %st(0)
15255 ;; fld1
15256 ;; into fptan insn.
15257
15258 (define_peephole2
15259 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15260 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15261 UNSPEC_TAN_ONE))
15262 (set (match_operand:XF 1 "register_operand" "")
15263 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15264 (set (match_dup 0)
15265 (match_operand:XF 3 "immediate_operand" ""))]
15266 "standard_80387_constant_p (operands[3]) == 2"
15267 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15268 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15269 "")
15270
15271 (define_expand "tanxf2"
15272 [(parallel [(set (match_dup 2)
15273 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15274 UNSPEC_TAN_ONE))
15275 (set (match_operand:XF 0 "register_operand" "")
15276 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15277 "TARGET_USE_FANCY_MATH_387
15278 && flag_unsafe_math_optimizations"
15279 {
15280 operands[2] = gen_reg_rtx (XFmode);
15281 })
15282
15283 (define_insn "atan2df3_1"
15284 [(set (match_operand:DF 0 "register_operand" "=f")
15285 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15286 (match_operand:DF 1 "register_operand" "u")]
15287 UNSPEC_FPATAN))
15288 (clobber (match_scratch:DF 3 "=1"))]
15289 "TARGET_USE_FANCY_MATH_387
15290 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15291 && flag_unsafe_math_optimizations"
15292 "fpatan"
15293 [(set_attr "type" "fpspc")
15294 (set_attr "mode" "DF")])
15295
15296 (define_expand "atan2df3"
15297 [(use (match_operand:DF 0 "register_operand" ""))
15298 (use (match_operand:DF 2 "register_operand" ""))
15299 (use (match_operand:DF 1 "register_operand" ""))]
15300 "TARGET_USE_FANCY_MATH_387
15301 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15302 && flag_unsafe_math_optimizations"
15303 {
15304 rtx copy = gen_reg_rtx (DFmode);
15305 emit_move_insn (copy, operands[1]);
15306 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15307 DONE;
15308 })
15309
15310 (define_expand "atandf2"
15311 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15312 (unspec:DF [(match_dup 2)
15313 (match_operand:DF 1 "register_operand" "")]
15314 UNSPEC_FPATAN))
15315 (clobber (match_scratch:DF 3 ""))])]
15316 "TARGET_USE_FANCY_MATH_387
15317 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15318 && flag_unsafe_math_optimizations"
15319 {
15320 operands[2] = gen_reg_rtx (DFmode);
15321 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15322 })
15323
15324 (define_insn "atan2sf3_1"
15325 [(set (match_operand:SF 0 "register_operand" "=f")
15326 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15327 (match_operand:SF 1 "register_operand" "u")]
15328 UNSPEC_FPATAN))
15329 (clobber (match_scratch:SF 3 "=1"))]
15330 "TARGET_USE_FANCY_MATH_387
15331 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15332 && flag_unsafe_math_optimizations"
15333 "fpatan"
15334 [(set_attr "type" "fpspc")
15335 (set_attr "mode" "SF")])
15336
15337 (define_expand "atan2sf3"
15338 [(use (match_operand:SF 0 "register_operand" ""))
15339 (use (match_operand:SF 2 "register_operand" ""))
15340 (use (match_operand:SF 1 "register_operand" ""))]
15341 "TARGET_USE_FANCY_MATH_387
15342 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15343 && flag_unsafe_math_optimizations"
15344 {
15345 rtx copy = gen_reg_rtx (SFmode);
15346 emit_move_insn (copy, operands[1]);
15347 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15348 DONE;
15349 })
15350
15351 (define_expand "atansf2"
15352 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15353 (unspec:SF [(match_dup 2)
15354 (match_operand:SF 1 "register_operand" "")]
15355 UNSPEC_FPATAN))
15356 (clobber (match_scratch:SF 3 ""))])]
15357 "TARGET_USE_FANCY_MATH_387
15358 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15359 && flag_unsafe_math_optimizations"
15360 {
15361 operands[2] = gen_reg_rtx (SFmode);
15362 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15363 })
15364
15365 (define_insn "atan2xf3_1"
15366 [(set (match_operand:XF 0 "register_operand" "=f")
15367 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15368 (match_operand:XF 1 "register_operand" "u")]
15369 UNSPEC_FPATAN))
15370 (clobber (match_scratch:XF 3 "=1"))]
15371 "TARGET_USE_FANCY_MATH_387
15372 && flag_unsafe_math_optimizations"
15373 "fpatan"
15374 [(set_attr "type" "fpspc")
15375 (set_attr "mode" "XF")])
15376
15377 (define_expand "atan2xf3"
15378 [(use (match_operand:XF 0 "register_operand" ""))
15379 (use (match_operand:XF 2 "register_operand" ""))
15380 (use (match_operand:XF 1 "register_operand" ""))]
15381 "TARGET_USE_FANCY_MATH_387
15382 && flag_unsafe_math_optimizations"
15383 {
15384 rtx copy = gen_reg_rtx (XFmode);
15385 emit_move_insn (copy, operands[1]);
15386 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15387 DONE;
15388 })
15389
15390 (define_expand "atanxf2"
15391 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15392 (unspec:XF [(match_dup 2)
15393 (match_operand:XF 1 "register_operand" "")]
15394 UNSPEC_FPATAN))
15395 (clobber (match_scratch:XF 3 ""))])]
15396 "TARGET_USE_FANCY_MATH_387
15397 && flag_unsafe_math_optimizations"
15398 {
15399 operands[2] = gen_reg_rtx (XFmode);
15400 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15401 })
15402
15403 (define_expand "asindf2"
15404 [(set (match_dup 2)
15405 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15406 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15407 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15408 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15409 (parallel [(set (match_dup 7)
15410 (unspec:XF [(match_dup 6) (match_dup 2)]
15411 UNSPEC_FPATAN))
15412 (clobber (match_scratch:XF 8 ""))])
15413 (set (match_operand:DF 0 "register_operand" "")
15414 (float_truncate:DF (match_dup 7)))]
15415 "TARGET_USE_FANCY_MATH_387
15416 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15417 && flag_unsafe_math_optimizations"
15418 {
15419 int i;
15420
15421 for (i=2; i<8; i++)
15422 operands[i] = gen_reg_rtx (XFmode);
15423
15424 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15425 })
15426
15427 (define_expand "asinsf2"
15428 [(set (match_dup 2)
15429 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15430 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15431 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15432 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15433 (parallel [(set (match_dup 7)
15434 (unspec:XF [(match_dup 6) (match_dup 2)]
15435 UNSPEC_FPATAN))
15436 (clobber (match_scratch:XF 8 ""))])
15437 (set (match_operand:SF 0 "register_operand" "")
15438 (float_truncate:SF (match_dup 7)))]
15439 "TARGET_USE_FANCY_MATH_387
15440 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15441 && flag_unsafe_math_optimizations"
15442 {
15443 int i;
15444
15445 for (i=2; i<8; i++)
15446 operands[i] = gen_reg_rtx (XFmode);
15447
15448 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15449 })
15450
15451 (define_expand "asinxf2"
15452 [(set (match_dup 2)
15453 (mult:XF (match_operand:XF 1 "register_operand" "")
15454 (match_dup 1)))
15455 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15456 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15457 (parallel [(set (match_operand:XF 0 "register_operand" "")
15458 (unspec:XF [(match_dup 5) (match_dup 1)]
15459 UNSPEC_FPATAN))
15460 (clobber (match_scratch:XF 6 ""))])]
15461 "TARGET_USE_FANCY_MATH_387
15462 && flag_unsafe_math_optimizations"
15463 {
15464 int i;
15465
15466 for (i=2; i<6; i++)
15467 operands[i] = gen_reg_rtx (XFmode);
15468
15469 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15470 })
15471
15472 (define_expand "acosdf2"
15473 [(set (match_dup 2)
15474 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15475 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15476 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15477 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15478 (parallel [(set (match_dup 7)
15479 (unspec:XF [(match_dup 2) (match_dup 6)]
15480 UNSPEC_FPATAN))
15481 (clobber (match_scratch:XF 8 ""))])
15482 (set (match_operand:DF 0 "register_operand" "")
15483 (float_truncate:DF (match_dup 7)))]
15484 "TARGET_USE_FANCY_MATH_387
15485 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15486 && flag_unsafe_math_optimizations"
15487 {
15488 int i;
15489
15490 for (i=2; i<8; i++)
15491 operands[i] = gen_reg_rtx (XFmode);
15492
15493 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15494 })
15495
15496 (define_expand "acossf2"
15497 [(set (match_dup 2)
15498 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15499 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15500 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15501 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15502 (parallel [(set (match_dup 7)
15503 (unspec:XF [(match_dup 2) (match_dup 6)]
15504 UNSPEC_FPATAN))
15505 (clobber (match_scratch:XF 8 ""))])
15506 (set (match_operand:SF 0 "register_operand" "")
15507 (float_truncate:SF (match_dup 7)))]
15508 "TARGET_USE_FANCY_MATH_387
15509 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15510 && flag_unsafe_math_optimizations"
15511 {
15512 int i;
15513
15514 for (i=2; i<8; i++)
15515 operands[i] = gen_reg_rtx (XFmode);
15516
15517 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15518 })
15519
15520 (define_expand "acosxf2"
15521 [(set (match_dup 2)
15522 (mult:XF (match_operand:XF 1 "register_operand" "")
15523 (match_dup 1)))
15524 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15525 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15526 (parallel [(set (match_operand:XF 0 "register_operand" "")
15527 (unspec:XF [(match_dup 1) (match_dup 5)]
15528 UNSPEC_FPATAN))
15529 (clobber (match_scratch:XF 6 ""))])]
15530 "TARGET_USE_FANCY_MATH_387
15531 && flag_unsafe_math_optimizations"
15532 {
15533 int i;
15534
15535 for (i=2; i<6; i++)
15536 operands[i] = gen_reg_rtx (XFmode);
15537
15538 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15539 })
15540
15541 (define_insn "fyl2x_xf3"
15542 [(set (match_operand:XF 0 "register_operand" "=f")
15543 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15544 (match_operand:XF 1 "register_operand" "u")]
15545 UNSPEC_FYL2X))
15546 (clobber (match_scratch:XF 3 "=1"))]
15547 "TARGET_USE_FANCY_MATH_387
15548 && flag_unsafe_math_optimizations"
15549 "fyl2x"
15550 [(set_attr "type" "fpspc")
15551 (set_attr "mode" "XF")])
15552
15553 (define_expand "logsf2"
15554 [(set (match_dup 2)
15555 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15556 (parallel [(set (match_dup 4)
15557 (unspec:XF [(match_dup 2)
15558 (match_dup 3)] UNSPEC_FYL2X))
15559 (clobber (match_scratch:XF 5 ""))])
15560 (set (match_operand:SF 0 "register_operand" "")
15561 (float_truncate:SF (match_dup 4)))]
15562 "TARGET_USE_FANCY_MATH_387
15563 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15564 && flag_unsafe_math_optimizations"
15565 {
15566 rtx temp;
15567
15568 operands[2] = gen_reg_rtx (XFmode);
15569 operands[3] = gen_reg_rtx (XFmode);
15570 operands[4] = gen_reg_rtx (XFmode);
15571
15572 temp = standard_80387_constant_rtx (4); /* fldln2 */
15573 emit_move_insn (operands[3], temp);
15574 })
15575
15576 (define_expand "logdf2"
15577 [(set (match_dup 2)
15578 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15579 (parallel [(set (match_dup 4)
15580 (unspec:XF [(match_dup 2)
15581 (match_dup 3)] UNSPEC_FYL2X))
15582 (clobber (match_scratch:XF 5 ""))])
15583 (set (match_operand:DF 0 "register_operand" "")
15584 (float_truncate:DF (match_dup 4)))]
15585 "TARGET_USE_FANCY_MATH_387
15586 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15587 && flag_unsafe_math_optimizations"
15588 {
15589 rtx temp;
15590
15591 operands[2] = gen_reg_rtx (XFmode);
15592 operands[3] = gen_reg_rtx (XFmode);
15593 operands[4] = gen_reg_rtx (XFmode);
15594
15595 temp = standard_80387_constant_rtx (4); /* fldln2 */
15596 emit_move_insn (operands[3], temp);
15597 })
15598
15599 (define_expand "logxf2"
15600 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15601 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15602 (match_dup 2)] UNSPEC_FYL2X))
15603 (clobber (match_scratch:XF 3 ""))])]
15604 "TARGET_USE_FANCY_MATH_387
15605 && flag_unsafe_math_optimizations"
15606 {
15607 rtx temp;
15608
15609 operands[2] = gen_reg_rtx (XFmode);
15610 temp = standard_80387_constant_rtx (4); /* fldln2 */
15611 emit_move_insn (operands[2], temp);
15612 })
15613
15614 (define_expand "log10sf2"
15615 [(set (match_dup 2)
15616 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15617 (parallel [(set (match_dup 4)
15618 (unspec:XF [(match_dup 2)
15619 (match_dup 3)] UNSPEC_FYL2X))
15620 (clobber (match_scratch:XF 5 ""))])
15621 (set (match_operand:SF 0 "register_operand" "")
15622 (float_truncate:SF (match_dup 4)))]
15623 "TARGET_USE_FANCY_MATH_387
15624 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15625 && flag_unsafe_math_optimizations"
15626 {
15627 rtx temp;
15628
15629 operands[2] = gen_reg_rtx (XFmode);
15630 operands[3] = gen_reg_rtx (XFmode);
15631 operands[4] = gen_reg_rtx (XFmode);
15632
15633 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15634 emit_move_insn (operands[3], temp);
15635 })
15636
15637 (define_expand "log10df2"
15638 [(set (match_dup 2)
15639 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15640 (parallel [(set (match_dup 4)
15641 (unspec:XF [(match_dup 2)
15642 (match_dup 3)] UNSPEC_FYL2X))
15643 (clobber (match_scratch:XF 5 ""))])
15644 (set (match_operand:DF 0 "register_operand" "")
15645 (float_truncate:DF (match_dup 4)))]
15646 "TARGET_USE_FANCY_MATH_387
15647 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15648 && flag_unsafe_math_optimizations"
15649 {
15650 rtx temp;
15651
15652 operands[2] = gen_reg_rtx (XFmode);
15653 operands[3] = gen_reg_rtx (XFmode);
15654 operands[4] = gen_reg_rtx (XFmode);
15655
15656 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15657 emit_move_insn (operands[3], temp);
15658 })
15659
15660 (define_expand "log10xf2"
15661 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15662 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15663 (match_dup 2)] UNSPEC_FYL2X))
15664 (clobber (match_scratch:XF 3 ""))])]
15665 "TARGET_USE_FANCY_MATH_387
15666 && flag_unsafe_math_optimizations"
15667 {
15668 rtx temp;
15669
15670 operands[2] = gen_reg_rtx (XFmode);
15671 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15672 emit_move_insn (operands[2], temp);
15673 })
15674
15675 (define_expand "log2sf2"
15676 [(set (match_dup 2)
15677 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15678 (parallel [(set (match_dup 4)
15679 (unspec:XF [(match_dup 2)
15680 (match_dup 3)] UNSPEC_FYL2X))
15681 (clobber (match_scratch:XF 5 ""))])
15682 (set (match_operand:SF 0 "register_operand" "")
15683 (float_truncate:SF (match_dup 4)))]
15684 "TARGET_USE_FANCY_MATH_387
15685 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15686 && flag_unsafe_math_optimizations"
15687 {
15688 operands[2] = gen_reg_rtx (XFmode);
15689 operands[3] = gen_reg_rtx (XFmode);
15690 operands[4] = gen_reg_rtx (XFmode);
15691
15692 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15693 })
15694
15695 (define_expand "log2df2"
15696 [(set (match_dup 2)
15697 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15698 (parallel [(set (match_dup 4)
15699 (unspec:XF [(match_dup 2)
15700 (match_dup 3)] UNSPEC_FYL2X))
15701 (clobber (match_scratch:XF 5 ""))])
15702 (set (match_operand:DF 0 "register_operand" "")
15703 (float_truncate:DF (match_dup 4)))]
15704 "TARGET_USE_FANCY_MATH_387
15705 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15706 && flag_unsafe_math_optimizations"
15707 {
15708 operands[2] = gen_reg_rtx (XFmode);
15709 operands[3] = gen_reg_rtx (XFmode);
15710 operands[4] = gen_reg_rtx (XFmode);
15711
15712 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15713 })
15714
15715 (define_expand "log2xf2"
15716 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15717 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15718 (match_dup 2)] UNSPEC_FYL2X))
15719 (clobber (match_scratch:XF 3 ""))])]
15720 "TARGET_USE_FANCY_MATH_387
15721 && flag_unsafe_math_optimizations"
15722 {
15723 operands[2] = gen_reg_rtx (XFmode);
15724 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15725 })
15726
15727 (define_insn "fyl2xp1_xf3"
15728 [(set (match_operand:XF 0 "register_operand" "=f")
15729 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15730 (match_operand:XF 1 "register_operand" "u")]
15731 UNSPEC_FYL2XP1))
15732 (clobber (match_scratch:XF 3 "=1"))]
15733 "TARGET_USE_FANCY_MATH_387
15734 && flag_unsafe_math_optimizations"
15735 "fyl2xp1"
15736 [(set_attr "type" "fpspc")
15737 (set_attr "mode" "XF")])
15738
15739 (define_expand "log1psf2"
15740 [(use (match_operand:SF 0 "register_operand" ""))
15741 (use (match_operand:SF 1 "register_operand" ""))]
15742 "TARGET_USE_FANCY_MATH_387
15743 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15744 && flag_unsafe_math_optimizations"
15745 {
15746 rtx op0 = gen_reg_rtx (XFmode);
15747 rtx op1 = gen_reg_rtx (XFmode);
15748
15749 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15750 ix86_emit_i387_log1p (op0, op1);
15751 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15752 DONE;
15753 })
15754
15755 (define_expand "log1pdf2"
15756 [(use (match_operand:DF 0 "register_operand" ""))
15757 (use (match_operand:DF 1 "register_operand" ""))]
15758 "TARGET_USE_FANCY_MATH_387
15759 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15760 && flag_unsafe_math_optimizations"
15761 {
15762 rtx op0 = gen_reg_rtx (XFmode);
15763 rtx op1 = gen_reg_rtx (XFmode);
15764
15765 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15766 ix86_emit_i387_log1p (op0, op1);
15767 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15768 DONE;
15769 })
15770
15771 (define_expand "log1pxf2"
15772 [(use (match_operand:XF 0 "register_operand" ""))
15773 (use (match_operand:XF 1 "register_operand" ""))]
15774 "TARGET_USE_FANCY_MATH_387
15775 && flag_unsafe_math_optimizations"
15776 {
15777 ix86_emit_i387_log1p (operands[0], operands[1]);
15778 DONE;
15779 })
15780
15781 (define_insn "*fxtractxf3"
15782 [(set (match_operand:XF 0 "register_operand" "=f")
15783 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15784 UNSPEC_XTRACT_FRACT))
15785 (set (match_operand:XF 1 "register_operand" "=u")
15786 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15787 "TARGET_USE_FANCY_MATH_387
15788 && flag_unsafe_math_optimizations"
15789 "fxtract"
15790 [(set_attr "type" "fpspc")
15791 (set_attr "mode" "XF")])
15792
15793 (define_expand "logbsf2"
15794 [(set (match_dup 2)
15795 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15796 (parallel [(set (match_dup 3)
15797 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15798 (set (match_dup 4)
15799 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15800 (set (match_operand:SF 0 "register_operand" "")
15801 (float_truncate:SF (match_dup 4)))]
15802 "TARGET_USE_FANCY_MATH_387
15803 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15804 && flag_unsafe_math_optimizations"
15805 {
15806 operands[2] = gen_reg_rtx (XFmode);
15807 operands[3] = gen_reg_rtx (XFmode);
15808 operands[4] = gen_reg_rtx (XFmode);
15809 })
15810
15811 (define_expand "logbdf2"
15812 [(set (match_dup 2)
15813 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15814 (parallel [(set (match_dup 3)
15815 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15816 (set (match_dup 4)
15817 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15818 (set (match_operand:DF 0 "register_operand" "")
15819 (float_truncate:DF (match_dup 4)))]
15820 "TARGET_USE_FANCY_MATH_387
15821 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15822 && flag_unsafe_math_optimizations"
15823 {
15824 operands[2] = gen_reg_rtx (XFmode);
15825 operands[3] = gen_reg_rtx (XFmode);
15826 operands[4] = gen_reg_rtx (XFmode);
15827 })
15828
15829 (define_expand "logbxf2"
15830 [(parallel [(set (match_dup 2)
15831 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15832 UNSPEC_XTRACT_FRACT))
15833 (set (match_operand:XF 0 "register_operand" "")
15834 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15835 "TARGET_USE_FANCY_MATH_387
15836 && flag_unsafe_math_optimizations"
15837 {
15838 operands[2] = gen_reg_rtx (XFmode);
15839 })
15840
15841 (define_expand "ilogbsi2"
15842 [(parallel [(set (match_dup 2)
15843 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15844 UNSPEC_XTRACT_FRACT))
15845 (set (match_operand:XF 3 "register_operand" "")
15846 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15847 (parallel [(set (match_operand:SI 0 "register_operand" "")
15848 (fix:SI (match_dup 3)))
15849 (clobber (reg:CC FLAGS_REG))])]
15850 "TARGET_USE_FANCY_MATH_387
15851 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15852 && flag_unsafe_math_optimizations"
15853 {
15854 operands[2] = gen_reg_rtx (XFmode);
15855 operands[3] = gen_reg_rtx (XFmode);
15856 })
15857
15858 (define_insn "*f2xm1xf2"
15859 [(set (match_operand:XF 0 "register_operand" "=f")
15860 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15861 UNSPEC_F2XM1))]
15862 "TARGET_USE_FANCY_MATH_387
15863 && flag_unsafe_math_optimizations"
15864 "f2xm1"
15865 [(set_attr "type" "fpspc")
15866 (set_attr "mode" "XF")])
15867
15868 (define_insn "*fscalexf4"
15869 [(set (match_operand:XF 0 "register_operand" "=f")
15870 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15871 (match_operand:XF 3 "register_operand" "1")]
15872 UNSPEC_FSCALE_FRACT))
15873 (set (match_operand:XF 1 "register_operand" "=u")
15874 (unspec:XF [(match_dup 2) (match_dup 3)]
15875 UNSPEC_FSCALE_EXP))]
15876 "TARGET_USE_FANCY_MATH_387
15877 && flag_unsafe_math_optimizations"
15878 "fscale"
15879 [(set_attr "type" "fpspc")
15880 (set_attr "mode" "XF")])
15881
15882 (define_expand "expsf2"
15883 [(set (match_dup 2)
15884 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15885 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15886 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15887 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15888 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15889 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15890 (parallel [(set (match_dup 10)
15891 (unspec:XF [(match_dup 9) (match_dup 5)]
15892 UNSPEC_FSCALE_FRACT))
15893 (set (match_dup 11)
15894 (unspec:XF [(match_dup 9) (match_dup 5)]
15895 UNSPEC_FSCALE_EXP))])
15896 (set (match_operand:SF 0 "register_operand" "")
15897 (float_truncate:SF (match_dup 10)))]
15898 "TARGET_USE_FANCY_MATH_387
15899 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15900 && flag_unsafe_math_optimizations"
15901 {
15902 rtx temp;
15903 int i;
15904
15905 for (i=2; i<12; i++)
15906 operands[i] = gen_reg_rtx (XFmode);
15907 temp = standard_80387_constant_rtx (5); /* fldl2e */
15908 emit_move_insn (operands[3], temp);
15909 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15910 })
15911
15912 (define_expand "expdf2"
15913 [(set (match_dup 2)
15914 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15915 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15916 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15917 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15918 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15919 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15920 (parallel [(set (match_dup 10)
15921 (unspec:XF [(match_dup 9) (match_dup 5)]
15922 UNSPEC_FSCALE_FRACT))
15923 (set (match_dup 11)
15924 (unspec:XF [(match_dup 9) (match_dup 5)]
15925 UNSPEC_FSCALE_EXP))])
15926 (set (match_operand:DF 0 "register_operand" "")
15927 (float_truncate:DF (match_dup 10)))]
15928 "TARGET_USE_FANCY_MATH_387
15929 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15930 && flag_unsafe_math_optimizations"
15931 {
15932 rtx temp;
15933 int i;
15934
15935 for (i=2; i<12; i++)
15936 operands[i] = gen_reg_rtx (XFmode);
15937 temp = standard_80387_constant_rtx (5); /* fldl2e */
15938 emit_move_insn (operands[3], temp);
15939 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15940 })
15941
15942 (define_expand "expxf2"
15943 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15944 (match_dup 2)))
15945 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15946 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15947 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15948 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15949 (parallel [(set (match_operand:XF 0 "register_operand" "")
15950 (unspec:XF [(match_dup 8) (match_dup 4)]
15951 UNSPEC_FSCALE_FRACT))
15952 (set (match_dup 9)
15953 (unspec:XF [(match_dup 8) (match_dup 4)]
15954 UNSPEC_FSCALE_EXP))])]
15955 "TARGET_USE_FANCY_MATH_387
15956 && flag_unsafe_math_optimizations"
15957 {
15958 rtx temp;
15959 int i;
15960
15961 for (i=2; i<10; i++)
15962 operands[i] = gen_reg_rtx (XFmode);
15963 temp = standard_80387_constant_rtx (5); /* fldl2e */
15964 emit_move_insn (operands[2], temp);
15965 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15966 })
15967
15968 (define_expand "exp10sf2"
15969 [(set (match_dup 2)
15970 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15971 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15972 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15973 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15974 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15975 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15976 (parallel [(set (match_dup 10)
15977 (unspec:XF [(match_dup 9) (match_dup 5)]
15978 UNSPEC_FSCALE_FRACT))
15979 (set (match_dup 11)
15980 (unspec:XF [(match_dup 9) (match_dup 5)]
15981 UNSPEC_FSCALE_EXP))])
15982 (set (match_operand:SF 0 "register_operand" "")
15983 (float_truncate:SF (match_dup 10)))]
15984 "TARGET_USE_FANCY_MATH_387
15985 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15986 && flag_unsafe_math_optimizations"
15987 {
15988 rtx temp;
15989 int i;
15990
15991 for (i=2; i<12; i++)
15992 operands[i] = gen_reg_rtx (XFmode);
15993 temp = standard_80387_constant_rtx (6); /* fldl2t */
15994 emit_move_insn (operands[3], temp);
15995 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15996 })
15997
15998 (define_expand "exp10df2"
15999 [(set (match_dup 2)
16000 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16001 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16002 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16003 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16004 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16005 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16006 (parallel [(set (match_dup 10)
16007 (unspec:XF [(match_dup 9) (match_dup 5)]
16008 UNSPEC_FSCALE_FRACT))
16009 (set (match_dup 11)
16010 (unspec:XF [(match_dup 9) (match_dup 5)]
16011 UNSPEC_FSCALE_EXP))])
16012 (set (match_operand:DF 0 "register_operand" "")
16013 (float_truncate:DF (match_dup 10)))]
16014 "TARGET_USE_FANCY_MATH_387
16015 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16016 && flag_unsafe_math_optimizations"
16017 {
16018 rtx temp;
16019 int i;
16020
16021 for (i=2; i<12; i++)
16022 operands[i] = gen_reg_rtx (XFmode);
16023 temp = standard_80387_constant_rtx (6); /* fldl2t */
16024 emit_move_insn (operands[3], temp);
16025 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16026 })
16027
16028 (define_expand "exp10xf2"
16029 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16030 (match_dup 2)))
16031 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16032 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16033 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16034 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16035 (parallel [(set (match_operand:XF 0 "register_operand" "")
16036 (unspec:XF [(match_dup 8) (match_dup 4)]
16037 UNSPEC_FSCALE_FRACT))
16038 (set (match_dup 9)
16039 (unspec:XF [(match_dup 8) (match_dup 4)]
16040 UNSPEC_FSCALE_EXP))])]
16041 "TARGET_USE_FANCY_MATH_387
16042 && flag_unsafe_math_optimizations"
16043 {
16044 rtx temp;
16045 int i;
16046
16047 for (i=2; i<10; i++)
16048 operands[i] = gen_reg_rtx (XFmode);
16049 temp = standard_80387_constant_rtx (6); /* fldl2t */
16050 emit_move_insn (operands[2], temp);
16051 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16052 })
16053
16054 (define_expand "exp2sf2"
16055 [(set (match_dup 2)
16056 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16057 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16058 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16059 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16060 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16061 (parallel [(set (match_dup 8)
16062 (unspec:XF [(match_dup 7) (match_dup 3)]
16063 UNSPEC_FSCALE_FRACT))
16064 (set (match_dup 9)
16065 (unspec:XF [(match_dup 7) (match_dup 3)]
16066 UNSPEC_FSCALE_EXP))])
16067 (set (match_operand:SF 0 "register_operand" "")
16068 (float_truncate:SF (match_dup 8)))]
16069 "TARGET_USE_FANCY_MATH_387
16070 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16071 && flag_unsafe_math_optimizations"
16072 {
16073 int i;
16074
16075 for (i=2; i<10; i++)
16076 operands[i] = gen_reg_rtx (XFmode);
16077 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16078 })
16079
16080 (define_expand "exp2df2"
16081 [(set (match_dup 2)
16082 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16083 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16084 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16085 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16086 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16087 (parallel [(set (match_dup 8)
16088 (unspec:XF [(match_dup 7) (match_dup 3)]
16089 UNSPEC_FSCALE_FRACT))
16090 (set (match_dup 9)
16091 (unspec:XF [(match_dup 7) (match_dup 3)]
16092 UNSPEC_FSCALE_EXP))])
16093 (set (match_operand:DF 0 "register_operand" "")
16094 (float_truncate:DF (match_dup 8)))]
16095 "TARGET_USE_FANCY_MATH_387
16096 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16097 && flag_unsafe_math_optimizations"
16098 {
16099 int i;
16100
16101 for (i=2; i<10; i++)
16102 operands[i] = gen_reg_rtx (XFmode);
16103 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16104 })
16105
16106 (define_expand "exp2xf2"
16107 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16108 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16109 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16110 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16111 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16112 (parallel [(set (match_operand:XF 0 "register_operand" "")
16113 (unspec:XF [(match_dup 7) (match_dup 3)]
16114 UNSPEC_FSCALE_FRACT))
16115 (set (match_dup 8)
16116 (unspec:XF [(match_dup 7) (match_dup 3)]
16117 UNSPEC_FSCALE_EXP))])]
16118 "TARGET_USE_FANCY_MATH_387
16119 && flag_unsafe_math_optimizations"
16120 {
16121 int i;
16122
16123 for (i=2; i<9; i++)
16124 operands[i] = gen_reg_rtx (XFmode);
16125 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16126 })
16127
16128 (define_expand "expm1df2"
16129 [(set (match_dup 2)
16130 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16131 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16132 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16133 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16134 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16135 (parallel [(set (match_dup 8)
16136 (unspec:XF [(match_dup 7) (match_dup 5)]
16137 UNSPEC_FSCALE_FRACT))
16138 (set (match_dup 9)
16139 (unspec:XF [(match_dup 7) (match_dup 5)]
16140 UNSPEC_FSCALE_EXP))])
16141 (parallel [(set (match_dup 11)
16142 (unspec:XF [(match_dup 10) (match_dup 9)]
16143 UNSPEC_FSCALE_FRACT))
16144 (set (match_dup 12)
16145 (unspec:XF [(match_dup 10) (match_dup 9)]
16146 UNSPEC_FSCALE_EXP))])
16147 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16148 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16149 (set (match_operand:DF 0 "register_operand" "")
16150 (float_truncate:DF (match_dup 14)))]
16151 "TARGET_USE_FANCY_MATH_387
16152 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16153 && flag_unsafe_math_optimizations"
16154 {
16155 rtx temp;
16156 int i;
16157
16158 for (i=2; i<15; i++)
16159 operands[i] = gen_reg_rtx (XFmode);
16160 temp = standard_80387_constant_rtx (5); /* fldl2e */
16161 emit_move_insn (operands[3], temp);
16162 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16163 })
16164
16165 (define_expand "expm1sf2"
16166 [(set (match_dup 2)
16167 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16168 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16169 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16170 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16171 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16172 (parallel [(set (match_dup 8)
16173 (unspec:XF [(match_dup 7) (match_dup 5)]
16174 UNSPEC_FSCALE_FRACT))
16175 (set (match_dup 9)
16176 (unspec:XF [(match_dup 7) (match_dup 5)]
16177 UNSPEC_FSCALE_EXP))])
16178 (parallel [(set (match_dup 11)
16179 (unspec:XF [(match_dup 10) (match_dup 9)]
16180 UNSPEC_FSCALE_FRACT))
16181 (set (match_dup 12)
16182 (unspec:XF [(match_dup 10) (match_dup 9)]
16183 UNSPEC_FSCALE_EXP))])
16184 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16185 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16186 (set (match_operand:SF 0 "register_operand" "")
16187 (float_truncate:SF (match_dup 14)))]
16188 "TARGET_USE_FANCY_MATH_387
16189 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16190 && flag_unsafe_math_optimizations"
16191 {
16192 rtx temp;
16193 int i;
16194
16195 for (i=2; i<15; i++)
16196 operands[i] = gen_reg_rtx (XFmode);
16197 temp = standard_80387_constant_rtx (5); /* fldl2e */
16198 emit_move_insn (operands[3], temp);
16199 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16200 })
16201
16202 (define_expand "expm1xf2"
16203 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16204 (match_dup 2)))
16205 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16206 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16207 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16208 (parallel [(set (match_dup 7)
16209 (unspec:XF [(match_dup 6) (match_dup 4)]
16210 UNSPEC_FSCALE_FRACT))
16211 (set (match_dup 8)
16212 (unspec:XF [(match_dup 6) (match_dup 4)]
16213 UNSPEC_FSCALE_EXP))])
16214 (parallel [(set (match_dup 10)
16215 (unspec:XF [(match_dup 9) (match_dup 8)]
16216 UNSPEC_FSCALE_FRACT))
16217 (set (match_dup 11)
16218 (unspec:XF [(match_dup 9) (match_dup 8)]
16219 UNSPEC_FSCALE_EXP))])
16220 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16221 (set (match_operand:XF 0 "register_operand" "")
16222 (plus:XF (match_dup 12) (match_dup 7)))]
16223 "TARGET_USE_FANCY_MATH_387
16224 && flag_unsafe_math_optimizations"
16225 {
16226 rtx temp;
16227 int i;
16228
16229 for (i=2; i<13; i++)
16230 operands[i] = gen_reg_rtx (XFmode);
16231 temp = standard_80387_constant_rtx (5); /* fldl2e */
16232 emit_move_insn (operands[2], temp);
16233 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16234 })
16235 \f
16236
16237 (define_insn "frndintxf2"
16238 [(set (match_operand:XF 0 "register_operand" "=f")
16239 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16240 UNSPEC_FRNDINT))]
16241 "TARGET_USE_FANCY_MATH_387
16242 && flag_unsafe_math_optimizations"
16243 "frndint"
16244 [(set_attr "type" "fpspc")
16245 (set_attr "mode" "XF")])
16246
16247 (define_expand "rintdf2"
16248 [(use (match_operand:DF 0 "register_operand" ""))
16249 (use (match_operand:DF 1 "register_operand" ""))]
16250 "TARGET_USE_FANCY_MATH_387
16251 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16252 && flag_unsafe_math_optimizations"
16253 {
16254 rtx op0 = gen_reg_rtx (XFmode);
16255 rtx op1 = gen_reg_rtx (XFmode);
16256
16257 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16258 emit_insn (gen_frndintxf2 (op0, op1));
16259
16260 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16261 DONE;
16262 })
16263
16264 (define_expand "rintsf2"
16265 [(use (match_operand:SF 0 "register_operand" ""))
16266 (use (match_operand:SF 1 "register_operand" ""))]
16267 "TARGET_USE_FANCY_MATH_387
16268 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16269 && flag_unsafe_math_optimizations"
16270 {
16271 rtx op0 = gen_reg_rtx (XFmode);
16272 rtx op1 = gen_reg_rtx (XFmode);
16273
16274 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16275 emit_insn (gen_frndintxf2 (op0, op1));
16276
16277 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16278 DONE;
16279 })
16280
16281 (define_expand "rintxf2"
16282 [(use (match_operand:XF 0 "register_operand" ""))
16283 (use (match_operand:XF 1 "register_operand" ""))]
16284 "TARGET_USE_FANCY_MATH_387
16285 && flag_unsafe_math_optimizations"
16286 {
16287 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16288 DONE;
16289 })
16290
16291 (define_insn "frndintxf2_floor"
16292 [(set (match_operand:XF 0 "register_operand" "=f")
16293 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16294 UNSPEC_FRNDINT_FLOOR))
16295 (use (match_operand:HI 2 "memory_operand" "m"))
16296 (use (match_operand:HI 3 "memory_operand" "m"))]
16297 "TARGET_USE_FANCY_MATH_387
16298 && flag_unsafe_math_optimizations"
16299 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16300 [(set_attr "type" "frndint")
16301 (set_attr "i387_cw" "floor")
16302 (set_attr "mode" "XF")])
16303
16304 (define_expand "floordf2"
16305 [(use (match_operand:DF 0 "register_operand" ""))
16306 (use (match_operand:DF 1 "register_operand" ""))]
16307 "TARGET_USE_FANCY_MATH_387
16308 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16309 && flag_unsafe_math_optimizations"
16310 {
16311 rtx op0 = gen_reg_rtx (XFmode);
16312 rtx op1 = gen_reg_rtx (XFmode);
16313 rtx op2 = assign_386_stack_local (HImode, 1);
16314 rtx op3 = assign_386_stack_local (HImode, 2);
16315
16316 ix86_optimize_mode_switching = 1;
16317
16318 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16319 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16320
16321 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16322 DONE;
16323 })
16324
16325 (define_expand "floorsf2"
16326 [(use (match_operand:SF 0 "register_operand" ""))
16327 (use (match_operand:SF 1 "register_operand" ""))]
16328 "TARGET_USE_FANCY_MATH_387
16329 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16330 && flag_unsafe_math_optimizations"
16331 {
16332 rtx op0 = gen_reg_rtx (XFmode);
16333 rtx op1 = gen_reg_rtx (XFmode);
16334 rtx op2 = assign_386_stack_local (HImode, 1);
16335 rtx op3 = assign_386_stack_local (HImode, 2);
16336
16337 ix86_optimize_mode_switching = 1;
16338
16339 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16340 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16341
16342 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16343 DONE;
16344 })
16345
16346 (define_expand "floorxf2"
16347 [(use (match_operand:XF 0 "register_operand" ""))
16348 (use (match_operand:XF 1 "register_operand" ""))]
16349 "TARGET_USE_FANCY_MATH_387
16350 && flag_unsafe_math_optimizations"
16351 {
16352 rtx op2 = assign_386_stack_local (HImode, 1);
16353 rtx op3 = assign_386_stack_local (HImode, 2);
16354
16355 ix86_optimize_mode_switching = 1;
16356
16357 emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16358 DONE;
16359 })
16360
16361 (define_insn "frndintxf2_ceil"
16362 [(set (match_operand:XF 0 "register_operand" "=f")
16363 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16364 UNSPEC_FRNDINT_CEIL))
16365 (use (match_operand:HI 2 "memory_operand" "m"))
16366 (use (match_operand:HI 3 "memory_operand" "m"))]
16367 "TARGET_USE_FANCY_MATH_387
16368 && flag_unsafe_math_optimizations"
16369 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16370 [(set_attr "type" "frndint")
16371 (set_attr "i387_cw" "ceil")
16372 (set_attr "mode" "XF")])
16373
16374 (define_expand "ceildf2"
16375 [(use (match_operand:DF 0 "register_operand" ""))
16376 (use (match_operand:DF 1 "register_operand" ""))]
16377 "TARGET_USE_FANCY_MATH_387
16378 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16379 && flag_unsafe_math_optimizations"
16380 {
16381 rtx op0 = gen_reg_rtx (XFmode);
16382 rtx op1 = gen_reg_rtx (XFmode);
16383 rtx op2 = assign_386_stack_local (HImode, 1);
16384 rtx op3 = assign_386_stack_local (HImode, 2);
16385
16386 ix86_optimize_mode_switching = 1;
16387
16388 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16389 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16390
16391 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16392 DONE;
16393 })
16394
16395 (define_expand "ceilsf2"
16396 [(use (match_operand:SF 0 "register_operand" ""))
16397 (use (match_operand:SF 1 "register_operand" ""))]
16398 "TARGET_USE_FANCY_MATH_387
16399 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16400 && flag_unsafe_math_optimizations"
16401 {
16402 rtx op0 = gen_reg_rtx (XFmode);
16403 rtx op1 = gen_reg_rtx (XFmode);
16404 rtx op2 = assign_386_stack_local (HImode, 1);
16405 rtx op3 = assign_386_stack_local (HImode, 2);
16406
16407 ix86_optimize_mode_switching = 1;
16408
16409 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16410 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16411
16412 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16413 DONE;
16414 })
16415
16416 (define_expand "ceilxf2"
16417 [(use (match_operand:XF 0 "register_operand" ""))
16418 (use (match_operand:XF 1 "register_operand" ""))]
16419 "TARGET_USE_FANCY_MATH_387
16420 && flag_unsafe_math_optimizations"
16421 {
16422 rtx op2 = assign_386_stack_local (HImode, 1);
16423 rtx op3 = assign_386_stack_local (HImode, 2);
16424
16425 ix86_optimize_mode_switching = 1;
16426
16427 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16428 DONE;
16429 })
16430
16431 (define_insn "frndintxf2_trunc"
16432 [(set (match_operand:XF 0 "register_operand" "=f")
16433 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16434 UNSPEC_FRNDINT_TRUNC))
16435 (use (match_operand:HI 2 "memory_operand" "m"))
16436 (use (match_operand:HI 3 "memory_operand" "m"))]
16437 "TARGET_USE_FANCY_MATH_387
16438 && flag_unsafe_math_optimizations"
16439 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16440 [(set_attr "type" "frndint")
16441 (set_attr "i387_cw" "trunc")
16442 (set_attr "mode" "XF")])
16443
16444 (define_expand "btruncdf2"
16445 [(use (match_operand:DF 0 "register_operand" ""))
16446 (use (match_operand:DF 1 "register_operand" ""))]
16447 "TARGET_USE_FANCY_MATH_387
16448 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16449 && flag_unsafe_math_optimizations"
16450 {
16451 rtx op0 = gen_reg_rtx (XFmode);
16452 rtx op1 = gen_reg_rtx (XFmode);
16453 rtx op2 = assign_386_stack_local (HImode, 1);
16454 rtx op3 = assign_386_stack_local (HImode, 2);
16455
16456 ix86_optimize_mode_switching = 1;
16457
16458 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16459 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16460
16461 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16462 DONE;
16463 })
16464
16465 (define_expand "btruncsf2"
16466 [(use (match_operand:SF 0 "register_operand" ""))
16467 (use (match_operand:SF 1 "register_operand" ""))]
16468 "TARGET_USE_FANCY_MATH_387
16469 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16470 && flag_unsafe_math_optimizations"
16471 {
16472 rtx op0 = gen_reg_rtx (XFmode);
16473 rtx op1 = gen_reg_rtx (XFmode);
16474 rtx op2 = assign_386_stack_local (HImode, 1);
16475 rtx op3 = assign_386_stack_local (HImode, 2);
16476
16477 ix86_optimize_mode_switching = 1;
16478
16479 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16480 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16481
16482 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16483 DONE;
16484 })
16485
16486 (define_expand "btruncxf2"
16487 [(use (match_operand:XF 0 "register_operand" ""))
16488 (use (match_operand:XF 1 "register_operand" ""))]
16489 "TARGET_USE_FANCY_MATH_387
16490 && flag_unsafe_math_optimizations"
16491 {
16492 rtx op2 = assign_386_stack_local (HImode, 1);
16493 rtx op3 = assign_386_stack_local (HImode, 2);
16494
16495 ix86_optimize_mode_switching = 1;
16496
16497 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16498 DONE;
16499 })
16500
16501 (define_insn "frndintxf2_mask_pm"
16502 [(set (match_operand:XF 0 "register_operand" "=f")
16503 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16504 UNSPEC_FRNDINT_MASK_PM))
16505 (use (match_operand:HI 2 "memory_operand" "m"))
16506 (use (match_operand:HI 3 "memory_operand" "m"))]
16507 "TARGET_USE_FANCY_MATH_387
16508 && flag_unsafe_math_optimizations"
16509 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16510 [(set_attr "type" "frndint")
16511 (set_attr "i387_cw" "mask_pm")
16512 (set_attr "mode" "XF")])
16513
16514 (define_expand "nearbyintdf2"
16515 [(use (match_operand:DF 0 "register_operand" ""))
16516 (use (match_operand:DF 1 "register_operand" ""))]
16517 "TARGET_USE_FANCY_MATH_387
16518 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16519 && flag_unsafe_math_optimizations"
16520 {
16521 rtx op0 = gen_reg_rtx (XFmode);
16522 rtx op1 = gen_reg_rtx (XFmode);
16523 rtx op2 = assign_386_stack_local (HImode, 1);
16524 rtx op3 = assign_386_stack_local (HImode, 2);
16525
16526 ix86_optimize_mode_switching = 1;
16527
16528 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16529 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16530
16531 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16532 DONE;
16533 })
16534
16535 (define_expand "nearbyintsf2"
16536 [(use (match_operand:SF 0 "register_operand" ""))
16537 (use (match_operand:SF 1 "register_operand" ""))]
16538 "TARGET_USE_FANCY_MATH_387
16539 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16540 && flag_unsafe_math_optimizations"
16541 {
16542 rtx op0 = gen_reg_rtx (XFmode);
16543 rtx op1 = gen_reg_rtx (XFmode);
16544 rtx op2 = assign_386_stack_local (HImode, 1);
16545 rtx op3 = assign_386_stack_local (HImode, 2);
16546
16547 ix86_optimize_mode_switching = 1;
16548
16549 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16550 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16551
16552 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16553 DONE;
16554 })
16555
16556 (define_expand "nearbyintxf2"
16557 [(use (match_operand:XF 0 "register_operand" ""))
16558 (use (match_operand:XF 1 "register_operand" ""))]
16559 "TARGET_USE_FANCY_MATH_387
16560 && flag_unsafe_math_optimizations"
16561 {
16562 rtx op2 = assign_386_stack_local (HImode, 1);
16563 rtx op3 = assign_386_stack_local (HImode, 2);
16564
16565 ix86_optimize_mode_switching = 1;
16566
16567 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16568 op2, op3));
16569 DONE;
16570 })
16571
16572 \f
16573 ;; Block operation instructions
16574
16575 (define_insn "cld"
16576 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16577 ""
16578 "cld"
16579 [(set_attr "type" "cld")])
16580
16581 (define_expand "movmemsi"
16582 [(use (match_operand:BLK 0 "memory_operand" ""))
16583 (use (match_operand:BLK 1 "memory_operand" ""))
16584 (use (match_operand:SI 2 "nonmemory_operand" ""))
16585 (use (match_operand:SI 3 "const_int_operand" ""))]
16586 "! optimize_size"
16587 {
16588 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16589 DONE;
16590 else
16591 FAIL;
16592 })
16593
16594 (define_expand "movmemdi"
16595 [(use (match_operand:BLK 0 "memory_operand" ""))
16596 (use (match_operand:BLK 1 "memory_operand" ""))
16597 (use (match_operand:DI 2 "nonmemory_operand" ""))
16598 (use (match_operand:DI 3 "const_int_operand" ""))]
16599 "TARGET_64BIT"
16600 {
16601 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16602 DONE;
16603 else
16604 FAIL;
16605 })
16606
16607 ;; Most CPUs don't like single string operations
16608 ;; Handle this case here to simplify previous expander.
16609
16610 (define_expand "strmov"
16611 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16612 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16613 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16614 (clobber (reg:CC FLAGS_REG))])
16615 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16616 (clobber (reg:CC FLAGS_REG))])]
16617 ""
16618 {
16619 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16620
16621 /* If .md ever supports :P for Pmode, these can be directly
16622 in the pattern above. */
16623 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16624 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16625
16626 if (TARGET_SINGLE_STRINGOP || optimize_size)
16627 {
16628 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16629 operands[2], operands[3],
16630 operands[5], operands[6]));
16631 DONE;
16632 }
16633
16634 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16635 })
16636
16637 (define_expand "strmov_singleop"
16638 [(parallel [(set (match_operand 1 "memory_operand" "")
16639 (match_operand 3 "memory_operand" ""))
16640 (set (match_operand 0 "register_operand" "")
16641 (match_operand 4 "" ""))
16642 (set (match_operand 2 "register_operand" "")
16643 (match_operand 5 "" ""))
16644 (use (reg:SI DIRFLAG_REG))])]
16645 "TARGET_SINGLE_STRINGOP || optimize_size"
16646 "")
16647
16648 (define_insn "*strmovdi_rex_1"
16649 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16650 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16651 (set (match_operand:DI 0 "register_operand" "=D")
16652 (plus:DI (match_dup 2)
16653 (const_int 8)))
16654 (set (match_operand:DI 1 "register_operand" "=S")
16655 (plus:DI (match_dup 3)
16656 (const_int 8)))
16657 (use (reg:SI DIRFLAG_REG))]
16658 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16659 "movsq"
16660 [(set_attr "type" "str")
16661 (set_attr "mode" "DI")
16662 (set_attr "memory" "both")])
16663
16664 (define_insn "*strmovsi_1"
16665 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16666 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16667 (set (match_operand:SI 0 "register_operand" "=D")
16668 (plus:SI (match_dup 2)
16669 (const_int 4)))
16670 (set (match_operand:SI 1 "register_operand" "=S")
16671 (plus:SI (match_dup 3)
16672 (const_int 4)))
16673 (use (reg:SI DIRFLAG_REG))]
16674 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16675 "{movsl|movsd}"
16676 [(set_attr "type" "str")
16677 (set_attr "mode" "SI")
16678 (set_attr "memory" "both")])
16679
16680 (define_insn "*strmovsi_rex_1"
16681 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16682 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16683 (set (match_operand:DI 0 "register_operand" "=D")
16684 (plus:DI (match_dup 2)
16685 (const_int 4)))
16686 (set (match_operand:DI 1 "register_operand" "=S")
16687 (plus:DI (match_dup 3)
16688 (const_int 4)))
16689 (use (reg:SI DIRFLAG_REG))]
16690 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16691 "{movsl|movsd}"
16692 [(set_attr "type" "str")
16693 (set_attr "mode" "SI")
16694 (set_attr "memory" "both")])
16695
16696 (define_insn "*strmovhi_1"
16697 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16698 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16699 (set (match_operand:SI 0 "register_operand" "=D")
16700 (plus:SI (match_dup 2)
16701 (const_int 2)))
16702 (set (match_operand:SI 1 "register_operand" "=S")
16703 (plus:SI (match_dup 3)
16704 (const_int 2)))
16705 (use (reg:SI DIRFLAG_REG))]
16706 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16707 "movsw"
16708 [(set_attr "type" "str")
16709 (set_attr "memory" "both")
16710 (set_attr "mode" "HI")])
16711
16712 (define_insn "*strmovhi_rex_1"
16713 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16714 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16715 (set (match_operand:DI 0 "register_operand" "=D")
16716 (plus:DI (match_dup 2)
16717 (const_int 2)))
16718 (set (match_operand:DI 1 "register_operand" "=S")
16719 (plus:DI (match_dup 3)
16720 (const_int 2)))
16721 (use (reg:SI DIRFLAG_REG))]
16722 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16723 "movsw"
16724 [(set_attr "type" "str")
16725 (set_attr "memory" "both")
16726 (set_attr "mode" "HI")])
16727
16728 (define_insn "*strmovqi_1"
16729 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16730 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16731 (set (match_operand:SI 0 "register_operand" "=D")
16732 (plus:SI (match_dup 2)
16733 (const_int 1)))
16734 (set (match_operand:SI 1 "register_operand" "=S")
16735 (plus:SI (match_dup 3)
16736 (const_int 1)))
16737 (use (reg:SI DIRFLAG_REG))]
16738 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16739 "movsb"
16740 [(set_attr "type" "str")
16741 (set_attr "memory" "both")
16742 (set_attr "mode" "QI")])
16743
16744 (define_insn "*strmovqi_rex_1"
16745 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16746 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16747 (set (match_operand:DI 0 "register_operand" "=D")
16748 (plus:DI (match_dup 2)
16749 (const_int 1)))
16750 (set (match_operand:DI 1 "register_operand" "=S")
16751 (plus:DI (match_dup 3)
16752 (const_int 1)))
16753 (use (reg:SI DIRFLAG_REG))]
16754 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16755 "movsb"
16756 [(set_attr "type" "str")
16757 (set_attr "memory" "both")
16758 (set_attr "mode" "QI")])
16759
16760 (define_expand "rep_mov"
16761 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16762 (set (match_operand 0 "register_operand" "")
16763 (match_operand 5 "" ""))
16764 (set (match_operand 2 "register_operand" "")
16765 (match_operand 6 "" ""))
16766 (set (match_operand 1 "memory_operand" "")
16767 (match_operand 3 "memory_operand" ""))
16768 (use (match_dup 4))
16769 (use (reg:SI DIRFLAG_REG))])]
16770 ""
16771 "")
16772
16773 (define_insn "*rep_movdi_rex64"
16774 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16775 (set (match_operand:DI 0 "register_operand" "=D")
16776 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16777 (const_int 3))
16778 (match_operand:DI 3 "register_operand" "0")))
16779 (set (match_operand:DI 1 "register_operand" "=S")
16780 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16781 (match_operand:DI 4 "register_operand" "1")))
16782 (set (mem:BLK (match_dup 3))
16783 (mem:BLK (match_dup 4)))
16784 (use (match_dup 5))
16785 (use (reg:SI DIRFLAG_REG))]
16786 "TARGET_64BIT"
16787 "{rep\;movsq|rep movsq}"
16788 [(set_attr "type" "str")
16789 (set_attr "prefix_rep" "1")
16790 (set_attr "memory" "both")
16791 (set_attr "mode" "DI")])
16792
16793 (define_insn "*rep_movsi"
16794 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16795 (set (match_operand:SI 0 "register_operand" "=D")
16796 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16797 (const_int 2))
16798 (match_operand:SI 3 "register_operand" "0")))
16799 (set (match_operand:SI 1 "register_operand" "=S")
16800 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16801 (match_operand:SI 4 "register_operand" "1")))
16802 (set (mem:BLK (match_dup 3))
16803 (mem:BLK (match_dup 4)))
16804 (use (match_dup 5))
16805 (use (reg:SI DIRFLAG_REG))]
16806 "!TARGET_64BIT"
16807 "{rep\;movsl|rep movsd}"
16808 [(set_attr "type" "str")
16809 (set_attr "prefix_rep" "1")
16810 (set_attr "memory" "both")
16811 (set_attr "mode" "SI")])
16812
16813 (define_insn "*rep_movsi_rex64"
16814 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16815 (set (match_operand:DI 0 "register_operand" "=D")
16816 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16817 (const_int 2))
16818 (match_operand:DI 3 "register_operand" "0")))
16819 (set (match_operand:DI 1 "register_operand" "=S")
16820 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16821 (match_operand:DI 4 "register_operand" "1")))
16822 (set (mem:BLK (match_dup 3))
16823 (mem:BLK (match_dup 4)))
16824 (use (match_dup 5))
16825 (use (reg:SI DIRFLAG_REG))]
16826 "TARGET_64BIT"
16827 "{rep\;movsl|rep movsd}"
16828 [(set_attr "type" "str")
16829 (set_attr "prefix_rep" "1")
16830 (set_attr "memory" "both")
16831 (set_attr "mode" "SI")])
16832
16833 (define_insn "*rep_movqi"
16834 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16835 (set (match_operand:SI 0 "register_operand" "=D")
16836 (plus:SI (match_operand:SI 3 "register_operand" "0")
16837 (match_operand:SI 5 "register_operand" "2")))
16838 (set (match_operand:SI 1 "register_operand" "=S")
16839 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16840 (set (mem:BLK (match_dup 3))
16841 (mem:BLK (match_dup 4)))
16842 (use (match_dup 5))
16843 (use (reg:SI DIRFLAG_REG))]
16844 "!TARGET_64BIT"
16845 "{rep\;movsb|rep movsb}"
16846 [(set_attr "type" "str")
16847 (set_attr "prefix_rep" "1")
16848 (set_attr "memory" "both")
16849 (set_attr "mode" "SI")])
16850
16851 (define_insn "*rep_movqi_rex64"
16852 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16853 (set (match_operand:DI 0 "register_operand" "=D")
16854 (plus:DI (match_operand:DI 3 "register_operand" "0")
16855 (match_operand:DI 5 "register_operand" "2")))
16856 (set (match_operand:DI 1 "register_operand" "=S")
16857 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16858 (set (mem:BLK (match_dup 3))
16859 (mem:BLK (match_dup 4)))
16860 (use (match_dup 5))
16861 (use (reg:SI DIRFLAG_REG))]
16862 "TARGET_64BIT"
16863 "{rep\;movsb|rep movsb}"
16864 [(set_attr "type" "str")
16865 (set_attr "prefix_rep" "1")
16866 (set_attr "memory" "both")
16867 (set_attr "mode" "SI")])
16868
16869 (define_expand "clrmemsi"
16870 [(use (match_operand:BLK 0 "memory_operand" ""))
16871 (use (match_operand:SI 1 "nonmemory_operand" ""))
16872 (use (match_operand 2 "const_int_operand" ""))]
16873 ""
16874 {
16875 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16876 DONE;
16877 else
16878 FAIL;
16879 })
16880
16881 (define_expand "clrmemdi"
16882 [(use (match_operand:BLK 0 "memory_operand" ""))
16883 (use (match_operand:DI 1 "nonmemory_operand" ""))
16884 (use (match_operand 2 "const_int_operand" ""))]
16885 "TARGET_64BIT"
16886 {
16887 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16888 DONE;
16889 else
16890 FAIL;
16891 })
16892
16893 ;; Most CPUs don't like single string operations
16894 ;; Handle this case here to simplify previous expander.
16895
16896 (define_expand "strset"
16897 [(set (match_operand 1 "memory_operand" "")
16898 (match_operand 2 "register_operand" ""))
16899 (parallel [(set (match_operand 0 "register_operand" "")
16900 (match_dup 3))
16901 (clobber (reg:CC FLAGS_REG))])]
16902 ""
16903 {
16904 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16905 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16906
16907 /* If .md ever supports :P for Pmode, this can be directly
16908 in the pattern above. */
16909 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16910 GEN_INT (GET_MODE_SIZE (GET_MODE
16911 (operands[2]))));
16912 if (TARGET_SINGLE_STRINGOP || optimize_size)
16913 {
16914 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16915 operands[3]));
16916 DONE;
16917 }
16918 })
16919
16920 (define_expand "strset_singleop"
16921 [(parallel [(set (match_operand 1 "memory_operand" "")
16922 (match_operand 2 "register_operand" ""))
16923 (set (match_operand 0 "register_operand" "")
16924 (match_operand 3 "" ""))
16925 (use (reg:SI DIRFLAG_REG))])]
16926 "TARGET_SINGLE_STRINGOP || optimize_size"
16927 "")
16928
16929 (define_insn "*strsetdi_rex_1"
16930 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16931 (match_operand:DI 2 "register_operand" "a"))
16932 (set (match_operand:DI 0 "register_operand" "=D")
16933 (plus:DI (match_dup 1)
16934 (const_int 8)))
16935 (use (reg:SI DIRFLAG_REG))]
16936 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16937 "stosq"
16938 [(set_attr "type" "str")
16939 (set_attr "memory" "store")
16940 (set_attr "mode" "DI")])
16941
16942 (define_insn "*strsetsi_1"
16943 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16944 (match_operand:SI 2 "register_operand" "a"))
16945 (set (match_operand:SI 0 "register_operand" "=D")
16946 (plus:SI (match_dup 1)
16947 (const_int 4)))
16948 (use (reg:SI DIRFLAG_REG))]
16949 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16950 "{stosl|stosd}"
16951 [(set_attr "type" "str")
16952 (set_attr "memory" "store")
16953 (set_attr "mode" "SI")])
16954
16955 (define_insn "*strsetsi_rex_1"
16956 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16957 (match_operand:SI 2 "register_operand" "a"))
16958 (set (match_operand:DI 0 "register_operand" "=D")
16959 (plus:DI (match_dup 1)
16960 (const_int 4)))
16961 (use (reg:SI DIRFLAG_REG))]
16962 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16963 "{stosl|stosd}"
16964 [(set_attr "type" "str")
16965 (set_attr "memory" "store")
16966 (set_attr "mode" "SI")])
16967
16968 (define_insn "*strsethi_1"
16969 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16970 (match_operand:HI 2 "register_operand" "a"))
16971 (set (match_operand:SI 0 "register_operand" "=D")
16972 (plus:SI (match_dup 1)
16973 (const_int 2)))
16974 (use (reg:SI DIRFLAG_REG))]
16975 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16976 "stosw"
16977 [(set_attr "type" "str")
16978 (set_attr "memory" "store")
16979 (set_attr "mode" "HI")])
16980
16981 (define_insn "*strsethi_rex_1"
16982 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16983 (match_operand:HI 2 "register_operand" "a"))
16984 (set (match_operand:DI 0 "register_operand" "=D")
16985 (plus:DI (match_dup 1)
16986 (const_int 2)))
16987 (use (reg:SI DIRFLAG_REG))]
16988 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16989 "stosw"
16990 [(set_attr "type" "str")
16991 (set_attr "memory" "store")
16992 (set_attr "mode" "HI")])
16993
16994 (define_insn "*strsetqi_1"
16995 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16996 (match_operand:QI 2 "register_operand" "a"))
16997 (set (match_operand:SI 0 "register_operand" "=D")
16998 (plus:SI (match_dup 1)
16999 (const_int 1)))
17000 (use (reg:SI DIRFLAG_REG))]
17001 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17002 "stosb"
17003 [(set_attr "type" "str")
17004 (set_attr "memory" "store")
17005 (set_attr "mode" "QI")])
17006
17007 (define_insn "*strsetqi_rex_1"
17008 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17009 (match_operand:QI 2 "register_operand" "a"))
17010 (set (match_operand:DI 0 "register_operand" "=D")
17011 (plus:DI (match_dup 1)
17012 (const_int 1)))
17013 (use (reg:SI DIRFLAG_REG))]
17014 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17015 "stosb"
17016 [(set_attr "type" "str")
17017 (set_attr "memory" "store")
17018 (set_attr "mode" "QI")])
17019
17020 (define_expand "rep_stos"
17021 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17022 (set (match_operand 0 "register_operand" "")
17023 (match_operand 4 "" ""))
17024 (set (match_operand 2 "memory_operand" "") (const_int 0))
17025 (use (match_operand 3 "register_operand" ""))
17026 (use (match_dup 1))
17027 (use (reg:SI DIRFLAG_REG))])]
17028 ""
17029 "")
17030
17031 (define_insn "*rep_stosdi_rex64"
17032 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17033 (set (match_operand:DI 0 "register_operand" "=D")
17034 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17035 (const_int 3))
17036 (match_operand:DI 3 "register_operand" "0")))
17037 (set (mem:BLK (match_dup 3))
17038 (const_int 0))
17039 (use (match_operand:DI 2 "register_operand" "a"))
17040 (use (match_dup 4))
17041 (use (reg:SI DIRFLAG_REG))]
17042 "TARGET_64BIT"
17043 "{rep\;stosq|rep stosq}"
17044 [(set_attr "type" "str")
17045 (set_attr "prefix_rep" "1")
17046 (set_attr "memory" "store")
17047 (set_attr "mode" "DI")])
17048
17049 (define_insn "*rep_stossi"
17050 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17051 (set (match_operand:SI 0 "register_operand" "=D")
17052 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17053 (const_int 2))
17054 (match_operand:SI 3 "register_operand" "0")))
17055 (set (mem:BLK (match_dup 3))
17056 (const_int 0))
17057 (use (match_operand:SI 2 "register_operand" "a"))
17058 (use (match_dup 4))
17059 (use (reg:SI DIRFLAG_REG))]
17060 "!TARGET_64BIT"
17061 "{rep\;stosl|rep stosd}"
17062 [(set_attr "type" "str")
17063 (set_attr "prefix_rep" "1")
17064 (set_attr "memory" "store")
17065 (set_attr "mode" "SI")])
17066
17067 (define_insn "*rep_stossi_rex64"
17068 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17069 (set (match_operand:DI 0 "register_operand" "=D")
17070 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17071 (const_int 2))
17072 (match_operand:DI 3 "register_operand" "0")))
17073 (set (mem:BLK (match_dup 3))
17074 (const_int 0))
17075 (use (match_operand:SI 2 "register_operand" "a"))
17076 (use (match_dup 4))
17077 (use (reg:SI DIRFLAG_REG))]
17078 "TARGET_64BIT"
17079 "{rep\;stosl|rep stosd}"
17080 [(set_attr "type" "str")
17081 (set_attr "prefix_rep" "1")
17082 (set_attr "memory" "store")
17083 (set_attr "mode" "SI")])
17084
17085 (define_insn "*rep_stosqi"
17086 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17087 (set (match_operand:SI 0 "register_operand" "=D")
17088 (plus:SI (match_operand:SI 3 "register_operand" "0")
17089 (match_operand:SI 4 "register_operand" "1")))
17090 (set (mem:BLK (match_dup 3))
17091 (const_int 0))
17092 (use (match_operand:QI 2 "register_operand" "a"))
17093 (use (match_dup 4))
17094 (use (reg:SI DIRFLAG_REG))]
17095 "!TARGET_64BIT"
17096 "{rep\;stosb|rep stosb}"
17097 [(set_attr "type" "str")
17098 (set_attr "prefix_rep" "1")
17099 (set_attr "memory" "store")
17100 (set_attr "mode" "QI")])
17101
17102 (define_insn "*rep_stosqi_rex64"
17103 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17104 (set (match_operand:DI 0 "register_operand" "=D")
17105 (plus:DI (match_operand:DI 3 "register_operand" "0")
17106 (match_operand:DI 4 "register_operand" "1")))
17107 (set (mem:BLK (match_dup 3))
17108 (const_int 0))
17109 (use (match_operand:QI 2 "register_operand" "a"))
17110 (use (match_dup 4))
17111 (use (reg:SI DIRFLAG_REG))]
17112 "TARGET_64BIT"
17113 "{rep\;stosb|rep stosb}"
17114 [(set_attr "type" "str")
17115 (set_attr "prefix_rep" "1")
17116 (set_attr "memory" "store")
17117 (set_attr "mode" "QI")])
17118
17119 (define_expand "cmpstrsi"
17120 [(set (match_operand:SI 0 "register_operand" "")
17121 (compare:SI (match_operand:BLK 1 "general_operand" "")
17122 (match_operand:BLK 2 "general_operand" "")))
17123 (use (match_operand 3 "general_operand" ""))
17124 (use (match_operand 4 "immediate_operand" ""))]
17125 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17126 {
17127 rtx addr1, addr2, out, outlow, count, countreg, align;
17128
17129 /* Can't use this if the user has appropriated esi or edi. */
17130 if (global_regs[4] || global_regs[5])
17131 FAIL;
17132
17133 out = operands[0];
17134 if (GET_CODE (out) != REG)
17135 out = gen_reg_rtx (SImode);
17136
17137 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17138 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17139 if (addr1 != XEXP (operands[1], 0))
17140 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17141 if (addr2 != XEXP (operands[2], 0))
17142 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17143
17144 count = operands[3];
17145 countreg = ix86_zero_extend_to_Pmode (count);
17146
17147 /* %%% Iff we are testing strict equality, we can use known alignment
17148 to good advantage. This may be possible with combine, particularly
17149 once cc0 is dead. */
17150 align = operands[4];
17151
17152 emit_insn (gen_cld ());
17153 if (GET_CODE (count) == CONST_INT)
17154 {
17155 if (INTVAL (count) == 0)
17156 {
17157 emit_move_insn (operands[0], const0_rtx);
17158 DONE;
17159 }
17160 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17161 operands[1], operands[2]));
17162 }
17163 else
17164 {
17165 if (TARGET_64BIT)
17166 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17167 else
17168 emit_insn (gen_cmpsi_1 (countreg, countreg));
17169 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17170 operands[1], operands[2]));
17171 }
17172
17173 outlow = gen_lowpart (QImode, out);
17174 emit_insn (gen_cmpintqi (outlow));
17175 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17176
17177 if (operands[0] != out)
17178 emit_move_insn (operands[0], out);
17179
17180 DONE;
17181 })
17182
17183 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17184
17185 (define_expand "cmpintqi"
17186 [(set (match_dup 1)
17187 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17188 (set (match_dup 2)
17189 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17190 (parallel [(set (match_operand:QI 0 "register_operand" "")
17191 (minus:QI (match_dup 1)
17192 (match_dup 2)))
17193 (clobber (reg:CC FLAGS_REG))])]
17194 ""
17195 "operands[1] = gen_reg_rtx (QImode);
17196 operands[2] = gen_reg_rtx (QImode);")
17197
17198 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17199 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17200
17201 (define_expand "cmpstrqi_nz_1"
17202 [(parallel [(set (reg:CC FLAGS_REG)
17203 (compare:CC (match_operand 4 "memory_operand" "")
17204 (match_operand 5 "memory_operand" "")))
17205 (use (match_operand 2 "register_operand" ""))
17206 (use (match_operand:SI 3 "immediate_operand" ""))
17207 (use (reg:SI DIRFLAG_REG))
17208 (clobber (match_operand 0 "register_operand" ""))
17209 (clobber (match_operand 1 "register_operand" ""))
17210 (clobber (match_dup 2))])]
17211 ""
17212 "")
17213
17214 (define_insn "*cmpstrqi_nz_1"
17215 [(set (reg:CC FLAGS_REG)
17216 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17217 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17218 (use (match_operand:SI 6 "register_operand" "2"))
17219 (use (match_operand:SI 3 "immediate_operand" "i"))
17220 (use (reg:SI DIRFLAG_REG))
17221 (clobber (match_operand:SI 0 "register_operand" "=S"))
17222 (clobber (match_operand:SI 1 "register_operand" "=D"))
17223 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17224 "!TARGET_64BIT"
17225 "repz{\;| }cmpsb"
17226 [(set_attr "type" "str")
17227 (set_attr "mode" "QI")
17228 (set_attr "prefix_rep" "1")])
17229
17230 (define_insn "*cmpstrqi_nz_rex_1"
17231 [(set (reg:CC FLAGS_REG)
17232 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17233 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17234 (use (match_operand:DI 6 "register_operand" "2"))
17235 (use (match_operand:SI 3 "immediate_operand" "i"))
17236 (use (reg:SI DIRFLAG_REG))
17237 (clobber (match_operand:DI 0 "register_operand" "=S"))
17238 (clobber (match_operand:DI 1 "register_operand" "=D"))
17239 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17240 "TARGET_64BIT"
17241 "repz{\;| }cmpsb"
17242 [(set_attr "type" "str")
17243 (set_attr "mode" "QI")
17244 (set_attr "prefix_rep" "1")])
17245
17246 ;; The same, but the count is not known to not be zero.
17247
17248 (define_expand "cmpstrqi_1"
17249 [(parallel [(set (reg:CC FLAGS_REG)
17250 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17251 (const_int 0))
17252 (compare:CC (match_operand 4 "memory_operand" "")
17253 (match_operand 5 "memory_operand" ""))
17254 (const_int 0)))
17255 (use (match_operand:SI 3 "immediate_operand" ""))
17256 (use (reg:CC FLAGS_REG))
17257 (use (reg:SI DIRFLAG_REG))
17258 (clobber (match_operand 0 "register_operand" ""))
17259 (clobber (match_operand 1 "register_operand" ""))
17260 (clobber (match_dup 2))])]
17261 ""
17262 "")
17263
17264 (define_insn "*cmpstrqi_1"
17265 [(set (reg:CC FLAGS_REG)
17266 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17267 (const_int 0))
17268 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17269 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17270 (const_int 0)))
17271 (use (match_operand:SI 3 "immediate_operand" "i"))
17272 (use (reg:CC FLAGS_REG))
17273 (use (reg:SI DIRFLAG_REG))
17274 (clobber (match_operand:SI 0 "register_operand" "=S"))
17275 (clobber (match_operand:SI 1 "register_operand" "=D"))
17276 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17277 "!TARGET_64BIT"
17278 "repz{\;| }cmpsb"
17279 [(set_attr "type" "str")
17280 (set_attr "mode" "QI")
17281 (set_attr "prefix_rep" "1")])
17282
17283 (define_insn "*cmpstrqi_rex_1"
17284 [(set (reg:CC FLAGS_REG)
17285 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17286 (const_int 0))
17287 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17288 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17289 (const_int 0)))
17290 (use (match_operand:SI 3 "immediate_operand" "i"))
17291 (use (reg:CC FLAGS_REG))
17292 (use (reg:SI DIRFLAG_REG))
17293 (clobber (match_operand:DI 0 "register_operand" "=S"))
17294 (clobber (match_operand:DI 1 "register_operand" "=D"))
17295 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17296 "TARGET_64BIT"
17297 "repz{\;| }cmpsb"
17298 [(set_attr "type" "str")
17299 (set_attr "mode" "QI")
17300 (set_attr "prefix_rep" "1")])
17301
17302 (define_expand "strlensi"
17303 [(set (match_operand:SI 0 "register_operand" "")
17304 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17305 (match_operand:QI 2 "immediate_operand" "")
17306 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17307 ""
17308 {
17309 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17310 DONE;
17311 else
17312 FAIL;
17313 })
17314
17315 (define_expand "strlendi"
17316 [(set (match_operand:DI 0 "register_operand" "")
17317 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17318 (match_operand:QI 2 "immediate_operand" "")
17319 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17320 ""
17321 {
17322 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17323 DONE;
17324 else
17325 FAIL;
17326 })
17327
17328 (define_expand "strlenqi_1"
17329 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17330 (use (reg:SI DIRFLAG_REG))
17331 (clobber (match_operand 1 "register_operand" ""))
17332 (clobber (reg:CC FLAGS_REG))])]
17333 ""
17334 "")
17335
17336 (define_insn "*strlenqi_1"
17337 [(set (match_operand:SI 0 "register_operand" "=&c")
17338 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17339 (match_operand:QI 2 "register_operand" "a")
17340 (match_operand:SI 3 "immediate_operand" "i")
17341 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17342 (use (reg:SI DIRFLAG_REG))
17343 (clobber (match_operand:SI 1 "register_operand" "=D"))
17344 (clobber (reg:CC FLAGS_REG))]
17345 "!TARGET_64BIT"
17346 "repnz{\;| }scasb"
17347 [(set_attr "type" "str")
17348 (set_attr "mode" "QI")
17349 (set_attr "prefix_rep" "1")])
17350
17351 (define_insn "*strlenqi_rex_1"
17352 [(set (match_operand:DI 0 "register_operand" "=&c")
17353 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17354 (match_operand:QI 2 "register_operand" "a")
17355 (match_operand:DI 3 "immediate_operand" "i")
17356 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17357 (use (reg:SI DIRFLAG_REG))
17358 (clobber (match_operand:DI 1 "register_operand" "=D"))
17359 (clobber (reg:CC FLAGS_REG))]
17360 "TARGET_64BIT"
17361 "repnz{\;| }scasb"
17362 [(set_attr "type" "str")
17363 (set_attr "mode" "QI")
17364 (set_attr "prefix_rep" "1")])
17365
17366 ;; Peephole optimizations to clean up after cmpstr*. This should be
17367 ;; handled in combine, but it is not currently up to the task.
17368 ;; When used for their truth value, the cmpstr* expanders generate
17369 ;; code like this:
17370 ;;
17371 ;; repz cmpsb
17372 ;; seta %al
17373 ;; setb %dl
17374 ;; cmpb %al, %dl
17375 ;; jcc label
17376 ;;
17377 ;; The intermediate three instructions are unnecessary.
17378
17379 ;; This one handles cmpstr*_nz_1...
17380 (define_peephole2
17381 [(parallel[
17382 (set (reg:CC FLAGS_REG)
17383 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17384 (mem:BLK (match_operand 5 "register_operand" ""))))
17385 (use (match_operand 6 "register_operand" ""))
17386 (use (match_operand:SI 3 "immediate_operand" ""))
17387 (use (reg:SI DIRFLAG_REG))
17388 (clobber (match_operand 0 "register_operand" ""))
17389 (clobber (match_operand 1 "register_operand" ""))
17390 (clobber (match_operand 2 "register_operand" ""))])
17391 (set (match_operand:QI 7 "register_operand" "")
17392 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17393 (set (match_operand:QI 8 "register_operand" "")
17394 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17395 (set (reg FLAGS_REG)
17396 (compare (match_dup 7) (match_dup 8)))
17397 ]
17398 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17399 [(parallel[
17400 (set (reg:CC FLAGS_REG)
17401 (compare:CC (mem:BLK (match_dup 4))
17402 (mem:BLK (match_dup 5))))
17403 (use (match_dup 6))
17404 (use (match_dup 3))
17405 (use (reg:SI DIRFLAG_REG))
17406 (clobber (match_dup 0))
17407 (clobber (match_dup 1))
17408 (clobber (match_dup 2))])]
17409 "")
17410
17411 ;; ...and this one handles cmpstr*_1.
17412 (define_peephole2
17413 [(parallel[
17414 (set (reg:CC FLAGS_REG)
17415 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17416 (const_int 0))
17417 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17418 (mem:BLK (match_operand 5 "register_operand" "")))
17419 (const_int 0)))
17420 (use (match_operand:SI 3 "immediate_operand" ""))
17421 (use (reg:CC FLAGS_REG))
17422 (use (reg:SI DIRFLAG_REG))
17423 (clobber (match_operand 0 "register_operand" ""))
17424 (clobber (match_operand 1 "register_operand" ""))
17425 (clobber (match_operand 2 "register_operand" ""))])
17426 (set (match_operand:QI 7 "register_operand" "")
17427 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17428 (set (match_operand:QI 8 "register_operand" "")
17429 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17430 (set (reg FLAGS_REG)
17431 (compare (match_dup 7) (match_dup 8)))
17432 ]
17433 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17434 [(parallel[
17435 (set (reg:CC FLAGS_REG)
17436 (if_then_else:CC (ne (match_dup 6)
17437 (const_int 0))
17438 (compare:CC (mem:BLK (match_dup 4))
17439 (mem:BLK (match_dup 5)))
17440 (const_int 0)))
17441 (use (match_dup 3))
17442 (use (reg:CC FLAGS_REG))
17443 (use (reg:SI DIRFLAG_REG))
17444 (clobber (match_dup 0))
17445 (clobber (match_dup 1))
17446 (clobber (match_dup 2))])]
17447 "")
17448
17449
17450 \f
17451 ;; Conditional move instructions.
17452
17453 (define_expand "movdicc"
17454 [(set (match_operand:DI 0 "register_operand" "")
17455 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17456 (match_operand:DI 2 "general_operand" "")
17457 (match_operand:DI 3 "general_operand" "")))]
17458 "TARGET_64BIT"
17459 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17460
17461 (define_insn "x86_movdicc_0_m1_rex64"
17462 [(set (match_operand:DI 0 "register_operand" "=r")
17463 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17464 (const_int -1)
17465 (const_int 0)))
17466 (clobber (reg:CC FLAGS_REG))]
17467 "TARGET_64BIT"
17468 "sbb{q}\t%0, %0"
17469 ; Since we don't have the proper number of operands for an alu insn,
17470 ; fill in all the blanks.
17471 [(set_attr "type" "alu")
17472 (set_attr "pent_pair" "pu")
17473 (set_attr "memory" "none")
17474 (set_attr "imm_disp" "false")
17475 (set_attr "mode" "DI")
17476 (set_attr "length_immediate" "0")])
17477
17478 (define_insn "*movdicc_c_rex64"
17479 [(set (match_operand:DI 0 "register_operand" "=r,r")
17480 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17481 [(reg FLAGS_REG) (const_int 0)])
17482 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17483 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17484 "TARGET_64BIT && TARGET_CMOVE
17485 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17486 "@
17487 cmov%O2%C1\t{%2, %0|%0, %2}
17488 cmov%O2%c1\t{%3, %0|%0, %3}"
17489 [(set_attr "type" "icmov")
17490 (set_attr "mode" "DI")])
17491
17492 (define_expand "movsicc"
17493 [(set (match_operand:SI 0 "register_operand" "")
17494 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17495 (match_operand:SI 2 "general_operand" "")
17496 (match_operand:SI 3 "general_operand" "")))]
17497 ""
17498 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17499
17500 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17501 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17502 ;; So just document what we're doing explicitly.
17503
17504 (define_insn "x86_movsicc_0_m1"
17505 [(set (match_operand:SI 0 "register_operand" "=r")
17506 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17507 (const_int -1)
17508 (const_int 0)))
17509 (clobber (reg:CC FLAGS_REG))]
17510 ""
17511 "sbb{l}\t%0, %0"
17512 ; Since we don't have the proper number of operands for an alu insn,
17513 ; fill in all the blanks.
17514 [(set_attr "type" "alu")
17515 (set_attr "pent_pair" "pu")
17516 (set_attr "memory" "none")
17517 (set_attr "imm_disp" "false")
17518 (set_attr "mode" "SI")
17519 (set_attr "length_immediate" "0")])
17520
17521 (define_insn "*movsicc_noc"
17522 [(set (match_operand:SI 0 "register_operand" "=r,r")
17523 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17524 [(reg FLAGS_REG) (const_int 0)])
17525 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17526 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17527 "TARGET_CMOVE
17528 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17529 "@
17530 cmov%O2%C1\t{%2, %0|%0, %2}
17531 cmov%O2%c1\t{%3, %0|%0, %3}"
17532 [(set_attr "type" "icmov")
17533 (set_attr "mode" "SI")])
17534
17535 (define_expand "movhicc"
17536 [(set (match_operand:HI 0 "register_operand" "")
17537 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17538 (match_operand:HI 2 "general_operand" "")
17539 (match_operand:HI 3 "general_operand" "")))]
17540 "TARGET_HIMODE_MATH"
17541 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17542
17543 (define_insn "*movhicc_noc"
17544 [(set (match_operand:HI 0 "register_operand" "=r,r")
17545 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17546 [(reg FLAGS_REG) (const_int 0)])
17547 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17548 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17549 "TARGET_CMOVE
17550 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17551 "@
17552 cmov%O2%C1\t{%2, %0|%0, %2}
17553 cmov%O2%c1\t{%3, %0|%0, %3}"
17554 [(set_attr "type" "icmov")
17555 (set_attr "mode" "HI")])
17556
17557 (define_expand "movqicc"
17558 [(set (match_operand:QI 0 "register_operand" "")
17559 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17560 (match_operand:QI 2 "general_operand" "")
17561 (match_operand:QI 3 "general_operand" "")))]
17562 "TARGET_QIMODE_MATH"
17563 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17564
17565 (define_insn_and_split "*movqicc_noc"
17566 [(set (match_operand:QI 0 "register_operand" "=r,r")
17567 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17568 [(match_operand 4 "flags_reg_operand" "")
17569 (const_int 0)])
17570 (match_operand:QI 2 "register_operand" "r,0")
17571 (match_operand:QI 3 "register_operand" "0,r")))]
17572 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17573 "#"
17574 "&& reload_completed"
17575 [(set (match_dup 0)
17576 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17577 (match_dup 2)
17578 (match_dup 3)))]
17579 "operands[0] = gen_lowpart (SImode, operands[0]);
17580 operands[2] = gen_lowpart (SImode, operands[2]);
17581 operands[3] = gen_lowpart (SImode, operands[3]);"
17582 [(set_attr "type" "icmov")
17583 (set_attr "mode" "SI")])
17584
17585 (define_expand "movsfcc"
17586 [(set (match_operand:SF 0 "register_operand" "")
17587 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17588 (match_operand:SF 2 "register_operand" "")
17589 (match_operand:SF 3 "register_operand" "")))]
17590 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17591 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17592
17593 ;; These versions of min/max are aware of the instruction's behaviour
17594 ;; wrt -0.0 and NaN inputs. If we don't care about either, then we
17595 ;; should have used the smin/smax expanders in the first place.
17596 (define_insn "*movsfcc_1_sse_min"
17597 [(set (match_operand:SF 0 "register_operand" "=x")
17598 (if_then_else:SF
17599 (lt:SF (match_operand:SF 1 "register_operand" "0")
17600 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17601 (match_dup 1)
17602 (match_dup 2)))]
17603 "TARGET_SSE_MATH"
17604 "minss\t{%2, %0|%0, %2}"
17605 [(set_attr "type" "sseadd")
17606 (set_attr "mode" "SF")])
17607
17608 (define_insn "*movsfcc_1_sse_max"
17609 [(set (match_operand:SF 0 "register_operand" "=x")
17610 (if_then_else:SF
17611 (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
17612 (match_operand:SF 1 "register_operand" "0"))
17613 (match_dup 1)
17614 (match_dup 2)))]
17615 "TARGET_SSE_MATH"
17616 "maxss\t{%2, %0|%0, %2}"
17617 [(set_attr "type" "sseadd")
17618 (set_attr "mode" "SF")])
17619
17620 (define_insn_and_split "*movsfcc_1_sse"
17621 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
17622 (if_then_else:SF
17623 (match_operator:SF 4 "sse_comparison_operator"
17624 [(match_operand:SF 5 "register_operand" "0,0,0")
17625 (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
17626 (match_operand:SF 2 "reg_or_0_operand" "C,x,1")
17627 (match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
17628 (clobber (match_scratch:V4SF 1 "=X,X,x"))]
17629 "TARGET_SSE_MATH"
17630 "#"
17631 "&& reload_completed"
17632 [(const_int 0)]
17633 {
17634 ix86_split_sse_movcc (operands);
17635 DONE;
17636 })
17637
17638 (define_insn "*movsfcc_1_387"
17639 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17640 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17641 [(reg FLAGS_REG) (const_int 0)])
17642 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17643 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17644 "TARGET_80387 && TARGET_CMOVE
17645 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17646 "@
17647 fcmov%F1\t{%2, %0|%0, %2}
17648 fcmov%f1\t{%3, %0|%0, %3}
17649 cmov%O2%C1\t{%2, %0|%0, %2}
17650 cmov%O2%c1\t{%3, %0|%0, %3}"
17651 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17652 (set_attr "mode" "SF,SF,SI,SI")])
17653
17654 (define_expand "movdfcc"
17655 [(set (match_operand:DF 0 "register_operand" "")
17656 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17657 (match_operand:DF 2 "register_operand" "")
17658 (match_operand:DF 3 "register_operand" "")))]
17659 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17660 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17661
17662 ;; These versions of min/max are aware of the instruction's behaviour
17663 ;; wrt -0.0 and NaN inputs. If we don't care about either, then we
17664 ;; should have used the smin/smax expanders in the first place.
17665 (define_insn "*movdfcc_1_sse_min"
17666 [(set (match_operand:DF 0 "register_operand" "=x")
17667 (if_then_else:DF
17668 (lt:DF (match_operand:DF 1 "register_operand" "0")
17669 (match_operand:DF 2 "nonimmediate_operand" "xm"))
17670 (match_dup 1)
17671 (match_dup 2)))]
17672 "TARGET_SSE2 && TARGET_SSE_MATH"
17673 "minsd\t{%2, %0|%0, %2}"
17674 [(set_attr "type" "sseadd")
17675 (set_attr "mode" "DF")])
17676
17677 (define_insn "*movdfcc_1_sse_max"
17678 [(set (match_operand:DF 0 "register_operand" "=x")
17679 (if_then_else:DF
17680 (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
17681 (match_operand:DF 1 "register_operand" "0"))
17682 (match_dup 1)
17683 (match_dup 2)))]
17684 "TARGET_SSE2 && TARGET_SSE_MATH"
17685 "maxsd\t{%2, %0|%0, %2}"
17686 [(set_attr "type" "sseadd")
17687 (set_attr "mode" "DF")])
17688
17689 (define_insn_and_split "*movdfcc_1_sse"
17690 [(set (match_operand:DF 0 "register_operand" "=x,x,x")
17691 (if_then_else:DF
17692 (match_operator:DF 4 "sse_comparison_operator"
17693 [(match_operand:DF 5 "register_operand" "0,0,0")
17694 (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
17695 (match_operand:DF 2 "reg_or_0_operand" "C,x,1")
17696 (match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
17697 (clobber (match_scratch:V2DF 1 "=X,X,x"))]
17698 "TARGET_SSE2 && TARGET_SSE_MATH"
17699 "#"
17700 "&& reload_completed"
17701 [(const_int 0)]
17702 {
17703 ix86_split_sse_movcc (operands);
17704 DONE;
17705 })
17706
17707 (define_insn "*movdfcc_1"
17708 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17709 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17710 [(reg FLAGS_REG) (const_int 0)])
17711 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17712 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17713 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17714 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17715 "@
17716 fcmov%F1\t{%2, %0|%0, %2}
17717 fcmov%f1\t{%3, %0|%0, %3}
17718 #
17719 #"
17720 [(set_attr "type" "fcmov,fcmov,multi,multi")
17721 (set_attr "mode" "DF")])
17722
17723 (define_insn "*movdfcc_1_rex64"
17724 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17725 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17726 [(reg FLAGS_REG) (const_int 0)])
17727 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17728 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17729 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17730 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17731 "@
17732 fcmov%F1\t{%2, %0|%0, %2}
17733 fcmov%f1\t{%3, %0|%0, %3}
17734 cmov%O2%C1\t{%2, %0|%0, %2}
17735 cmov%O2%c1\t{%3, %0|%0, %3}"
17736 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17737 (set_attr "mode" "DF")])
17738
17739 (define_split
17740 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17741 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17742 [(match_operand 4 "flags_reg_operand" "")
17743 (const_int 0)])
17744 (match_operand:DF 2 "nonimmediate_operand" "")
17745 (match_operand:DF 3 "nonimmediate_operand" "")))]
17746 "!TARGET_64BIT && reload_completed"
17747 [(set (match_dup 2)
17748 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17749 (match_dup 5)
17750 (match_dup 7)))
17751 (set (match_dup 3)
17752 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17753 (match_dup 6)
17754 (match_dup 8)))]
17755 "split_di (operands+2, 1, operands+5, operands+6);
17756 split_di (operands+3, 1, operands+7, operands+8);
17757 split_di (operands, 1, operands+2, operands+3);")
17758
17759 (define_expand "movxfcc"
17760 [(set (match_operand:XF 0 "register_operand" "")
17761 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17762 (match_operand:XF 2 "register_operand" "")
17763 (match_operand:XF 3 "register_operand" "")))]
17764 "TARGET_80387 && TARGET_CMOVE"
17765 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17766
17767 (define_insn "*movxfcc_1"
17768 [(set (match_operand:XF 0 "register_operand" "=f,f")
17769 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17770 [(reg FLAGS_REG) (const_int 0)])
17771 (match_operand:XF 2 "register_operand" "f,0")
17772 (match_operand:XF 3 "register_operand" "0,f")))]
17773 "TARGET_80387 && TARGET_CMOVE"
17774 "@
17775 fcmov%F1\t{%2, %0|%0, %2}
17776 fcmov%f1\t{%3, %0|%0, %3}"
17777 [(set_attr "type" "fcmov")
17778 (set_attr "mode" "XF")])
17779
17780 ;; These versions of the min/max patterns are intentionally ignorant of
17781 ;; their behaviour wrt -0.0 and NaN (via the commutative operand mark).
17782 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17783 ;; are undefined in this condition, we're certain this is correct.
17784
17785 (define_insn "sminsf3"
17786 [(set (match_operand:SF 0 "register_operand" "=x")
17787 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17788 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17789 "TARGET_SSE_MATH"
17790 "minss\t{%2, %0|%0, %2}"
17791 [(set_attr "type" "sseadd")
17792 (set_attr "mode" "SF")])
17793
17794 (define_insn "smaxsf3"
17795 [(set (match_operand:SF 0 "register_operand" "=x")
17796 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17797 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17798 "TARGET_SSE_MATH"
17799 "minss\t{%2, %0|%0, %2}"
17800 [(set_attr "type" "sseadd")
17801 (set_attr "mode" "SF")])
17802
17803 (define_insn "smindf3"
17804 [(set (match_operand:DF 0 "register_operand" "=x")
17805 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17806 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17807 "TARGET_SSE2 && TARGET_SSE_MATH"
17808 "minsd\t{%2, %0|%0, %2}"
17809 [(set_attr "type" "sseadd")
17810 (set_attr "mode" "DF")])
17811
17812 (define_insn "smaxdf3"
17813 [(set (match_operand:DF 0 "register_operand" "=x")
17814 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17815 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17816 "TARGET_SSE2 && TARGET_SSE_MATH"
17817 "maxsd\t{%2, %0|%0, %2}"
17818 [(set_attr "type" "sseadd")
17819 (set_attr "mode" "DF")])
17820
17821 ;; Conditional addition patterns
17822 (define_expand "addqicc"
17823 [(match_operand:QI 0 "register_operand" "")
17824 (match_operand 1 "comparison_operator" "")
17825 (match_operand:QI 2 "register_operand" "")
17826 (match_operand:QI 3 "const_int_operand" "")]
17827 ""
17828 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17829
17830 (define_expand "addhicc"
17831 [(match_operand:HI 0 "register_operand" "")
17832 (match_operand 1 "comparison_operator" "")
17833 (match_operand:HI 2 "register_operand" "")
17834 (match_operand:HI 3 "const_int_operand" "")]
17835 ""
17836 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17837
17838 (define_expand "addsicc"
17839 [(match_operand:SI 0 "register_operand" "")
17840 (match_operand 1 "comparison_operator" "")
17841 (match_operand:SI 2 "register_operand" "")
17842 (match_operand:SI 3 "const_int_operand" "")]
17843 ""
17844 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17845
17846 (define_expand "adddicc"
17847 [(match_operand:DI 0 "register_operand" "")
17848 (match_operand 1 "comparison_operator" "")
17849 (match_operand:DI 2 "register_operand" "")
17850 (match_operand:DI 3 "const_int_operand" "")]
17851 "TARGET_64BIT"
17852 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17853
17854 \f
17855 ;; Misc patterns (?)
17856
17857 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17858 ;; Otherwise there will be nothing to keep
17859 ;;
17860 ;; [(set (reg ebp) (reg esp))]
17861 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17862 ;; (clobber (eflags)]
17863 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17864 ;;
17865 ;; in proper program order.
17866 (define_insn "pro_epilogue_adjust_stack_1"
17867 [(set (match_operand:SI 0 "register_operand" "=r,r")
17868 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17869 (match_operand:SI 2 "immediate_operand" "i,i")))
17870 (clobber (reg:CC FLAGS_REG))
17871 (clobber (mem:BLK (scratch)))]
17872 "!TARGET_64BIT"
17873 {
17874 switch (get_attr_type (insn))
17875 {
17876 case TYPE_IMOV:
17877 return "mov{l}\t{%1, %0|%0, %1}";
17878
17879 case TYPE_ALU:
17880 if (GET_CODE (operands[2]) == CONST_INT
17881 && (INTVAL (operands[2]) == 128
17882 || (INTVAL (operands[2]) < 0
17883 && INTVAL (operands[2]) != -128)))
17884 {
17885 operands[2] = GEN_INT (-INTVAL (operands[2]));
17886 return "sub{l}\t{%2, %0|%0, %2}";
17887 }
17888 return "add{l}\t{%2, %0|%0, %2}";
17889
17890 case TYPE_LEA:
17891 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17892 return "lea{l}\t{%a2, %0|%0, %a2}";
17893
17894 default:
17895 abort ();
17896 }
17897 }
17898 [(set (attr "type")
17899 (cond [(eq_attr "alternative" "0")
17900 (const_string "alu")
17901 (match_operand:SI 2 "const0_operand" "")
17902 (const_string "imov")
17903 ]
17904 (const_string "lea")))
17905 (set_attr "mode" "SI")])
17906
17907 (define_insn "pro_epilogue_adjust_stack_rex64"
17908 [(set (match_operand:DI 0 "register_operand" "=r,r")
17909 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17910 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17911 (clobber (reg:CC FLAGS_REG))
17912 (clobber (mem:BLK (scratch)))]
17913 "TARGET_64BIT"
17914 {
17915 switch (get_attr_type (insn))
17916 {
17917 case TYPE_IMOV:
17918 return "mov{q}\t{%1, %0|%0, %1}";
17919
17920 case TYPE_ALU:
17921 if (GET_CODE (operands[2]) == CONST_INT
17922 /* Avoid overflows. */
17923 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17924 && (INTVAL (operands[2]) == 128
17925 || (INTVAL (operands[2]) < 0
17926 && INTVAL (operands[2]) != -128)))
17927 {
17928 operands[2] = GEN_INT (-INTVAL (operands[2]));
17929 return "sub{q}\t{%2, %0|%0, %2}";
17930 }
17931 return "add{q}\t{%2, %0|%0, %2}";
17932
17933 case TYPE_LEA:
17934 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17935 return "lea{q}\t{%a2, %0|%0, %a2}";
17936
17937 default:
17938 abort ();
17939 }
17940 }
17941 [(set (attr "type")
17942 (cond [(eq_attr "alternative" "0")
17943 (const_string "alu")
17944 (match_operand:DI 2 "const0_operand" "")
17945 (const_string "imov")
17946 ]
17947 (const_string "lea")))
17948 (set_attr "mode" "DI")])
17949
17950 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17951 [(set (match_operand:DI 0 "register_operand" "=r,r")
17952 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17953 (match_operand:DI 3 "immediate_operand" "i,i")))
17954 (use (match_operand:DI 2 "register_operand" "r,r"))
17955 (clobber (reg:CC FLAGS_REG))
17956 (clobber (mem:BLK (scratch)))]
17957 "TARGET_64BIT"
17958 {
17959 switch (get_attr_type (insn))
17960 {
17961 case TYPE_ALU:
17962 return "add{q}\t{%2, %0|%0, %2}";
17963
17964 case TYPE_LEA:
17965 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17966 return "lea{q}\t{%a2, %0|%0, %a2}";
17967
17968 default:
17969 abort ();
17970 }
17971 }
17972 [(set_attr "type" "alu,lea")
17973 (set_attr "mode" "DI")])
17974
17975 (define_expand "allocate_stack_worker"
17976 [(match_operand:SI 0 "register_operand" "")]
17977 "TARGET_STACK_PROBE"
17978 {
17979 if (reload_completed)
17980 {
17981 if (TARGET_64BIT)
17982 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17983 else
17984 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17985 }
17986 else
17987 {
17988 if (TARGET_64BIT)
17989 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17990 else
17991 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17992 }
17993 DONE;
17994 })
17995
17996 (define_insn "allocate_stack_worker_1"
17997 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17998 UNSPECV_STACK_PROBE)
17999 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18000 (clobber (match_scratch:SI 1 "=0"))
18001 (clobber (reg:CC FLAGS_REG))]
18002 "!TARGET_64BIT && TARGET_STACK_PROBE"
18003 "call\t__alloca"
18004 [(set_attr "type" "multi")
18005 (set_attr "length" "5")])
18006
18007 (define_expand "allocate_stack_worker_postreload"
18008 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18009 UNSPECV_STACK_PROBE)
18010 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18011 (clobber (match_dup 0))
18012 (clobber (reg:CC FLAGS_REG))])]
18013 ""
18014 "")
18015
18016 (define_insn "allocate_stack_worker_rex64"
18017 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18018 UNSPECV_STACK_PROBE)
18019 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18020 (clobber (match_scratch:DI 1 "=0"))
18021 (clobber (reg:CC FLAGS_REG))]
18022 "TARGET_64BIT && TARGET_STACK_PROBE"
18023 "call\t__alloca"
18024 [(set_attr "type" "multi")
18025 (set_attr "length" "5")])
18026
18027 (define_expand "allocate_stack_worker_rex64_postreload"
18028 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18029 UNSPECV_STACK_PROBE)
18030 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18031 (clobber (match_dup 0))
18032 (clobber (reg:CC FLAGS_REG))])]
18033 ""
18034 "")
18035
18036 (define_expand "allocate_stack"
18037 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18038 (minus:SI (reg:SI SP_REG)
18039 (match_operand:SI 1 "general_operand" "")))
18040 (clobber (reg:CC FLAGS_REG))])
18041 (parallel [(set (reg:SI SP_REG)
18042 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18043 (clobber (reg:CC FLAGS_REG))])]
18044 "TARGET_STACK_PROBE"
18045 {
18046 #ifdef CHECK_STACK_LIMIT
18047 if (GET_CODE (operands[1]) == CONST_INT
18048 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18049 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18050 operands[1]));
18051 else
18052 #endif
18053 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18054 operands[1])));
18055
18056 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18057 DONE;
18058 })
18059
18060 (define_expand "builtin_setjmp_receiver"
18061 [(label_ref (match_operand 0 "" ""))]
18062 "!TARGET_64BIT && flag_pic"
18063 {
18064 emit_insn (gen_set_got (pic_offset_table_rtx));
18065 DONE;
18066 })
18067 \f
18068 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18069
18070 (define_split
18071 [(set (match_operand 0 "register_operand" "")
18072 (match_operator 3 "promotable_binary_operator"
18073 [(match_operand 1 "register_operand" "")
18074 (match_operand 2 "aligned_operand" "")]))
18075 (clobber (reg:CC FLAGS_REG))]
18076 "! TARGET_PARTIAL_REG_STALL && reload_completed
18077 && ((GET_MODE (operands[0]) == HImode
18078 && ((!optimize_size && !TARGET_FAST_PREFIX)
18079 || GET_CODE (operands[2]) != CONST_INT
18080 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18081 || (GET_MODE (operands[0]) == QImode
18082 && (TARGET_PROMOTE_QImode || optimize_size)))"
18083 [(parallel [(set (match_dup 0)
18084 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18085 (clobber (reg:CC FLAGS_REG))])]
18086 "operands[0] = gen_lowpart (SImode, operands[0]);
18087 operands[1] = gen_lowpart (SImode, operands[1]);
18088 if (GET_CODE (operands[3]) != ASHIFT)
18089 operands[2] = gen_lowpart (SImode, operands[2]);
18090 PUT_MODE (operands[3], SImode);")
18091
18092 ; Promote the QImode tests, as i386 has encoding of the AND
18093 ; instruction with 32-bit sign-extended immediate and thus the
18094 ; instruction size is unchanged, except in the %eax case for
18095 ; which it is increased by one byte, hence the ! optimize_size.
18096 (define_split
18097 [(set (match_operand 0 "flags_reg_operand" "")
18098 (match_operator 2 "compare_operator"
18099 [(and (match_operand 3 "aligned_operand" "")
18100 (match_operand 4 "const_int_operand" ""))
18101 (const_int 0)]))
18102 (set (match_operand 1 "register_operand" "")
18103 (and (match_dup 3) (match_dup 4)))]
18104 "! TARGET_PARTIAL_REG_STALL && reload_completed
18105 /* Ensure that the operand will remain sign-extended immediate. */
18106 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18107 && ! optimize_size
18108 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18109 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18110 [(parallel [(set (match_dup 0)
18111 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18112 (const_int 0)]))
18113 (set (match_dup 1)
18114 (and:SI (match_dup 3) (match_dup 4)))])]
18115 {
18116 operands[4]
18117 = gen_int_mode (INTVAL (operands[4])
18118 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18119 operands[1] = gen_lowpart (SImode, operands[1]);
18120 operands[3] = gen_lowpart (SImode, operands[3]);
18121 })
18122
18123 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18124 ; the TEST instruction with 32-bit sign-extended immediate and thus
18125 ; the instruction size would at least double, which is not what we
18126 ; want even with ! optimize_size.
18127 (define_split
18128 [(set (match_operand 0 "flags_reg_operand" "")
18129 (match_operator 1 "compare_operator"
18130 [(and (match_operand:HI 2 "aligned_operand" "")
18131 (match_operand:HI 3 "const_int_operand" ""))
18132 (const_int 0)]))]
18133 "! TARGET_PARTIAL_REG_STALL && reload_completed
18134 /* Ensure that the operand will remain sign-extended immediate. */
18135 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18136 && ! TARGET_FAST_PREFIX
18137 && ! optimize_size"
18138 [(set (match_dup 0)
18139 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18140 (const_int 0)]))]
18141 {
18142 operands[3]
18143 = gen_int_mode (INTVAL (operands[3])
18144 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18145 operands[2] = gen_lowpart (SImode, operands[2]);
18146 })
18147
18148 (define_split
18149 [(set (match_operand 0 "register_operand" "")
18150 (neg (match_operand 1 "register_operand" "")))
18151 (clobber (reg:CC FLAGS_REG))]
18152 "! TARGET_PARTIAL_REG_STALL && reload_completed
18153 && (GET_MODE (operands[0]) == HImode
18154 || (GET_MODE (operands[0]) == QImode
18155 && (TARGET_PROMOTE_QImode || optimize_size)))"
18156 [(parallel [(set (match_dup 0)
18157 (neg:SI (match_dup 1)))
18158 (clobber (reg:CC FLAGS_REG))])]
18159 "operands[0] = gen_lowpart (SImode, operands[0]);
18160 operands[1] = gen_lowpart (SImode, operands[1]);")
18161
18162 (define_split
18163 [(set (match_operand 0 "register_operand" "")
18164 (not (match_operand 1 "register_operand" "")))]
18165 "! TARGET_PARTIAL_REG_STALL && reload_completed
18166 && (GET_MODE (operands[0]) == HImode
18167 || (GET_MODE (operands[0]) == QImode
18168 && (TARGET_PROMOTE_QImode || optimize_size)))"
18169 [(set (match_dup 0)
18170 (not:SI (match_dup 1)))]
18171 "operands[0] = gen_lowpart (SImode, operands[0]);
18172 operands[1] = gen_lowpart (SImode, operands[1]);")
18173
18174 (define_split
18175 [(set (match_operand 0 "register_operand" "")
18176 (if_then_else (match_operator 1 "comparison_operator"
18177 [(reg FLAGS_REG) (const_int 0)])
18178 (match_operand 2 "register_operand" "")
18179 (match_operand 3 "register_operand" "")))]
18180 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18181 && (GET_MODE (operands[0]) == HImode
18182 || (GET_MODE (operands[0]) == QImode
18183 && (TARGET_PROMOTE_QImode || optimize_size)))"
18184 [(set (match_dup 0)
18185 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18186 "operands[0] = gen_lowpart (SImode, operands[0]);
18187 operands[2] = gen_lowpart (SImode, operands[2]);
18188 operands[3] = gen_lowpart (SImode, operands[3]);")
18189
18190 \f
18191 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18192 ;; transform a complex memory operation into two memory to register operations.
18193
18194 ;; Don't push memory operands
18195 (define_peephole2
18196 [(set (match_operand:SI 0 "push_operand" "")
18197 (match_operand:SI 1 "memory_operand" ""))
18198 (match_scratch:SI 2 "r")]
18199 "! optimize_size && ! TARGET_PUSH_MEMORY"
18200 [(set (match_dup 2) (match_dup 1))
18201 (set (match_dup 0) (match_dup 2))]
18202 "")
18203
18204 (define_peephole2
18205 [(set (match_operand:DI 0 "push_operand" "")
18206 (match_operand:DI 1 "memory_operand" ""))
18207 (match_scratch:DI 2 "r")]
18208 "! optimize_size && ! TARGET_PUSH_MEMORY"
18209 [(set (match_dup 2) (match_dup 1))
18210 (set (match_dup 0) (match_dup 2))]
18211 "")
18212
18213 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18214 ;; SImode pushes.
18215 (define_peephole2
18216 [(set (match_operand:SF 0 "push_operand" "")
18217 (match_operand:SF 1 "memory_operand" ""))
18218 (match_scratch:SF 2 "r")]
18219 "! optimize_size && ! TARGET_PUSH_MEMORY"
18220 [(set (match_dup 2) (match_dup 1))
18221 (set (match_dup 0) (match_dup 2))]
18222 "")
18223
18224 (define_peephole2
18225 [(set (match_operand:HI 0 "push_operand" "")
18226 (match_operand:HI 1 "memory_operand" ""))
18227 (match_scratch:HI 2 "r")]
18228 "! optimize_size && ! TARGET_PUSH_MEMORY"
18229 [(set (match_dup 2) (match_dup 1))
18230 (set (match_dup 0) (match_dup 2))]
18231 "")
18232
18233 (define_peephole2
18234 [(set (match_operand:QI 0 "push_operand" "")
18235 (match_operand:QI 1 "memory_operand" ""))
18236 (match_scratch:QI 2 "q")]
18237 "! optimize_size && ! TARGET_PUSH_MEMORY"
18238 [(set (match_dup 2) (match_dup 1))
18239 (set (match_dup 0) (match_dup 2))]
18240 "")
18241
18242 ;; Don't move an immediate directly to memory when the instruction
18243 ;; gets too big.
18244 (define_peephole2
18245 [(match_scratch:SI 1 "r")
18246 (set (match_operand:SI 0 "memory_operand" "")
18247 (const_int 0))]
18248 "! optimize_size
18249 && ! TARGET_USE_MOV0
18250 && TARGET_SPLIT_LONG_MOVES
18251 && get_attr_length (insn) >= ix86_cost->large_insn
18252 && peep2_regno_dead_p (0, FLAGS_REG)"
18253 [(parallel [(set (match_dup 1) (const_int 0))
18254 (clobber (reg:CC FLAGS_REG))])
18255 (set (match_dup 0) (match_dup 1))]
18256 "")
18257
18258 (define_peephole2
18259 [(match_scratch:HI 1 "r")
18260 (set (match_operand:HI 0 "memory_operand" "")
18261 (const_int 0))]
18262 "! optimize_size
18263 && ! TARGET_USE_MOV0
18264 && TARGET_SPLIT_LONG_MOVES
18265 && get_attr_length (insn) >= ix86_cost->large_insn
18266 && peep2_regno_dead_p (0, FLAGS_REG)"
18267 [(parallel [(set (match_dup 2) (const_int 0))
18268 (clobber (reg:CC FLAGS_REG))])
18269 (set (match_dup 0) (match_dup 1))]
18270 "operands[2] = gen_lowpart (SImode, operands[1]);")
18271
18272 (define_peephole2
18273 [(match_scratch:QI 1 "q")
18274 (set (match_operand:QI 0 "memory_operand" "")
18275 (const_int 0))]
18276 "! optimize_size
18277 && ! TARGET_USE_MOV0
18278 && TARGET_SPLIT_LONG_MOVES
18279 && get_attr_length (insn) >= ix86_cost->large_insn
18280 && peep2_regno_dead_p (0, FLAGS_REG)"
18281 [(parallel [(set (match_dup 2) (const_int 0))
18282 (clobber (reg:CC FLAGS_REG))])
18283 (set (match_dup 0) (match_dup 1))]
18284 "operands[2] = gen_lowpart (SImode, operands[1]);")
18285
18286 (define_peephole2
18287 [(match_scratch:SI 2 "r")
18288 (set (match_operand:SI 0 "memory_operand" "")
18289 (match_operand:SI 1 "immediate_operand" ""))]
18290 "! optimize_size
18291 && get_attr_length (insn) >= ix86_cost->large_insn
18292 && TARGET_SPLIT_LONG_MOVES"
18293 [(set (match_dup 2) (match_dup 1))
18294 (set (match_dup 0) (match_dup 2))]
18295 "")
18296
18297 (define_peephole2
18298 [(match_scratch:HI 2 "r")
18299 (set (match_operand:HI 0 "memory_operand" "")
18300 (match_operand:HI 1 "immediate_operand" ""))]
18301 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18302 && TARGET_SPLIT_LONG_MOVES"
18303 [(set (match_dup 2) (match_dup 1))
18304 (set (match_dup 0) (match_dup 2))]
18305 "")
18306
18307 (define_peephole2
18308 [(match_scratch:QI 2 "q")
18309 (set (match_operand:QI 0 "memory_operand" "")
18310 (match_operand:QI 1 "immediate_operand" ""))]
18311 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18312 && TARGET_SPLIT_LONG_MOVES"
18313 [(set (match_dup 2) (match_dup 1))
18314 (set (match_dup 0) (match_dup 2))]
18315 "")
18316
18317 ;; Don't compare memory with zero, load and use a test instead.
18318 (define_peephole2
18319 [(set (match_operand 0 "flags_reg_operand" "")
18320 (match_operator 1 "compare_operator"
18321 [(match_operand:SI 2 "memory_operand" "")
18322 (const_int 0)]))
18323 (match_scratch:SI 3 "r")]
18324 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18325 [(set (match_dup 3) (match_dup 2))
18326 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18327 "")
18328
18329 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18330 ;; Don't split NOTs with a displacement operand, because resulting XOR
18331 ;; will not be pairable anyway.
18332 ;;
18333 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18334 ;; represented using a modRM byte. The XOR replacement is long decoded,
18335 ;; so this split helps here as well.
18336 ;;
18337 ;; Note: Can't do this as a regular split because we can't get proper
18338 ;; lifetime information then.
18339
18340 (define_peephole2
18341 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18342 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18343 "!optimize_size
18344 && peep2_regno_dead_p (0, FLAGS_REG)
18345 && ((TARGET_PENTIUM
18346 && (GET_CODE (operands[0]) != MEM
18347 || !memory_displacement_operand (operands[0], SImode)))
18348 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18349 [(parallel [(set (match_dup 0)
18350 (xor:SI (match_dup 1) (const_int -1)))
18351 (clobber (reg:CC FLAGS_REG))])]
18352 "")
18353
18354 (define_peephole2
18355 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18356 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18357 "!optimize_size
18358 && peep2_regno_dead_p (0, FLAGS_REG)
18359 && ((TARGET_PENTIUM
18360 && (GET_CODE (operands[0]) != MEM
18361 || !memory_displacement_operand (operands[0], HImode)))
18362 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18363 [(parallel [(set (match_dup 0)
18364 (xor:HI (match_dup 1) (const_int -1)))
18365 (clobber (reg:CC FLAGS_REG))])]
18366 "")
18367
18368 (define_peephole2
18369 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18370 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18371 "!optimize_size
18372 && peep2_regno_dead_p (0, FLAGS_REG)
18373 && ((TARGET_PENTIUM
18374 && (GET_CODE (operands[0]) != MEM
18375 || !memory_displacement_operand (operands[0], QImode)))
18376 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18377 [(parallel [(set (match_dup 0)
18378 (xor:QI (match_dup 1) (const_int -1)))
18379 (clobber (reg:CC FLAGS_REG))])]
18380 "")
18381
18382 ;; Non pairable "test imm, reg" instructions can be translated to
18383 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18384 ;; byte opcode instead of two, have a short form for byte operands),
18385 ;; so do it for other CPUs as well. Given that the value was dead,
18386 ;; this should not create any new dependencies. Pass on the sub-word
18387 ;; versions if we're concerned about partial register stalls.
18388
18389 (define_peephole2
18390 [(set (match_operand 0 "flags_reg_operand" "")
18391 (match_operator 1 "compare_operator"
18392 [(and:SI (match_operand:SI 2 "register_operand" "")
18393 (match_operand:SI 3 "immediate_operand" ""))
18394 (const_int 0)]))]
18395 "ix86_match_ccmode (insn, CCNOmode)
18396 && (true_regnum (operands[2]) != 0
18397 || (GET_CODE (operands[3]) == CONST_INT
18398 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18399 && peep2_reg_dead_p (1, operands[2])"
18400 [(parallel
18401 [(set (match_dup 0)
18402 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18403 (const_int 0)]))
18404 (set (match_dup 2)
18405 (and:SI (match_dup 2) (match_dup 3)))])]
18406 "")
18407
18408 ;; We don't need to handle HImode case, because it will be promoted to SImode
18409 ;; on ! TARGET_PARTIAL_REG_STALL
18410
18411 (define_peephole2
18412 [(set (match_operand 0 "flags_reg_operand" "")
18413 (match_operator 1 "compare_operator"
18414 [(and:QI (match_operand:QI 2 "register_operand" "")
18415 (match_operand:QI 3 "immediate_operand" ""))
18416 (const_int 0)]))]
18417 "! TARGET_PARTIAL_REG_STALL
18418 && ix86_match_ccmode (insn, CCNOmode)
18419 && true_regnum (operands[2]) != 0
18420 && peep2_reg_dead_p (1, operands[2])"
18421 [(parallel
18422 [(set (match_dup 0)
18423 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18424 (const_int 0)]))
18425 (set (match_dup 2)
18426 (and:QI (match_dup 2) (match_dup 3)))])]
18427 "")
18428
18429 (define_peephole2
18430 [(set (match_operand 0 "flags_reg_operand" "")
18431 (match_operator 1 "compare_operator"
18432 [(and:SI
18433 (zero_extract:SI
18434 (match_operand 2 "ext_register_operand" "")
18435 (const_int 8)
18436 (const_int 8))
18437 (match_operand 3 "const_int_operand" ""))
18438 (const_int 0)]))]
18439 "! TARGET_PARTIAL_REG_STALL
18440 && ix86_match_ccmode (insn, CCNOmode)
18441 && true_regnum (operands[2]) != 0
18442 && peep2_reg_dead_p (1, operands[2])"
18443 [(parallel [(set (match_dup 0)
18444 (match_op_dup 1
18445 [(and:SI
18446 (zero_extract:SI
18447 (match_dup 2)
18448 (const_int 8)
18449 (const_int 8))
18450 (match_dup 3))
18451 (const_int 0)]))
18452 (set (zero_extract:SI (match_dup 2)
18453 (const_int 8)
18454 (const_int 8))
18455 (and:SI
18456 (zero_extract:SI
18457 (match_dup 2)
18458 (const_int 8)
18459 (const_int 8))
18460 (match_dup 3)))])]
18461 "")
18462
18463 ;; Don't do logical operations with memory inputs.
18464 (define_peephole2
18465 [(match_scratch:SI 2 "r")
18466 (parallel [(set (match_operand:SI 0 "register_operand" "")
18467 (match_operator:SI 3 "arith_or_logical_operator"
18468 [(match_dup 0)
18469 (match_operand:SI 1 "memory_operand" "")]))
18470 (clobber (reg:CC FLAGS_REG))])]
18471 "! optimize_size && ! TARGET_READ_MODIFY"
18472 [(set (match_dup 2) (match_dup 1))
18473 (parallel [(set (match_dup 0)
18474 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18475 (clobber (reg:CC FLAGS_REG))])]
18476 "")
18477
18478 (define_peephole2
18479 [(match_scratch:SI 2 "r")
18480 (parallel [(set (match_operand:SI 0 "register_operand" "")
18481 (match_operator:SI 3 "arith_or_logical_operator"
18482 [(match_operand:SI 1 "memory_operand" "")
18483 (match_dup 0)]))
18484 (clobber (reg:CC FLAGS_REG))])]
18485 "! optimize_size && ! TARGET_READ_MODIFY"
18486 [(set (match_dup 2) (match_dup 1))
18487 (parallel [(set (match_dup 0)
18488 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18489 (clobber (reg:CC FLAGS_REG))])]
18490 "")
18491
18492 ; Don't do logical operations with memory outputs
18493 ;
18494 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18495 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18496 ; the same decoder scheduling characteristics as the original.
18497
18498 (define_peephole2
18499 [(match_scratch:SI 2 "r")
18500 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18501 (match_operator:SI 3 "arith_or_logical_operator"
18502 [(match_dup 0)
18503 (match_operand:SI 1 "nonmemory_operand" "")]))
18504 (clobber (reg:CC FLAGS_REG))])]
18505 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18506 [(set (match_dup 2) (match_dup 0))
18507 (parallel [(set (match_dup 2)
18508 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18509 (clobber (reg:CC FLAGS_REG))])
18510 (set (match_dup 0) (match_dup 2))]
18511 "")
18512
18513 (define_peephole2
18514 [(match_scratch:SI 2 "r")
18515 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18516 (match_operator:SI 3 "arith_or_logical_operator"
18517 [(match_operand:SI 1 "nonmemory_operand" "")
18518 (match_dup 0)]))
18519 (clobber (reg:CC FLAGS_REG))])]
18520 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18521 [(set (match_dup 2) (match_dup 0))
18522 (parallel [(set (match_dup 2)
18523 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18524 (clobber (reg:CC FLAGS_REG))])
18525 (set (match_dup 0) (match_dup 2))]
18526 "")
18527
18528 ;; Attempt to always use XOR for zeroing registers.
18529 (define_peephole2
18530 [(set (match_operand 0 "register_operand" "")
18531 (const_int 0))]
18532 "(GET_MODE (operands[0]) == QImode
18533 || GET_MODE (operands[0]) == HImode
18534 || GET_MODE (operands[0]) == SImode
18535 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18536 && (! TARGET_USE_MOV0 || optimize_size)
18537 && peep2_regno_dead_p (0, FLAGS_REG)"
18538 [(parallel [(set (match_dup 0) (const_int 0))
18539 (clobber (reg:CC FLAGS_REG))])]
18540 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18541 operands[0]);")
18542
18543 (define_peephole2
18544 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18545 (const_int 0))]
18546 "(GET_MODE (operands[0]) == QImode
18547 || GET_MODE (operands[0]) == HImode)
18548 && (! TARGET_USE_MOV0 || optimize_size)
18549 && peep2_regno_dead_p (0, FLAGS_REG)"
18550 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18551 (clobber (reg:CC FLAGS_REG))])])
18552
18553 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18554 (define_peephole2
18555 [(set (match_operand 0 "register_operand" "")
18556 (const_int -1))]
18557 "(GET_MODE (operands[0]) == HImode
18558 || GET_MODE (operands[0]) == SImode
18559 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18560 && (optimize_size || TARGET_PENTIUM)
18561 && peep2_regno_dead_p (0, FLAGS_REG)"
18562 [(parallel [(set (match_dup 0) (const_int -1))
18563 (clobber (reg:CC FLAGS_REG))])]
18564 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18565 operands[0]);")
18566
18567 ;; Attempt to convert simple leas to adds. These can be created by
18568 ;; move expanders.
18569 (define_peephole2
18570 [(set (match_operand:SI 0 "register_operand" "")
18571 (plus:SI (match_dup 0)
18572 (match_operand:SI 1 "nonmemory_operand" "")))]
18573 "peep2_regno_dead_p (0, FLAGS_REG)"
18574 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18575 (clobber (reg:CC FLAGS_REG))])]
18576 "")
18577
18578 (define_peephole2
18579 [(set (match_operand:SI 0 "register_operand" "")
18580 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18581 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18582 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18583 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18584 (clobber (reg:CC FLAGS_REG))])]
18585 "operands[2] = gen_lowpart (SImode, operands[2]);")
18586
18587 (define_peephole2
18588 [(set (match_operand:DI 0 "register_operand" "")
18589 (plus:DI (match_dup 0)
18590 (match_operand:DI 1 "x86_64_general_operand" "")))]
18591 "peep2_regno_dead_p (0, FLAGS_REG)"
18592 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18593 (clobber (reg:CC FLAGS_REG))])]
18594 "")
18595
18596 (define_peephole2
18597 [(set (match_operand:SI 0 "register_operand" "")
18598 (mult:SI (match_dup 0)
18599 (match_operand:SI 1 "const_int_operand" "")))]
18600 "exact_log2 (INTVAL (operands[1])) >= 0
18601 && peep2_regno_dead_p (0, FLAGS_REG)"
18602 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18603 (clobber (reg:CC FLAGS_REG))])]
18604 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18605
18606 (define_peephole2
18607 [(set (match_operand:DI 0 "register_operand" "")
18608 (mult:DI (match_dup 0)
18609 (match_operand:DI 1 "const_int_operand" "")))]
18610 "exact_log2 (INTVAL (operands[1])) >= 0
18611 && peep2_regno_dead_p (0, FLAGS_REG)"
18612 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18613 (clobber (reg:CC FLAGS_REG))])]
18614 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18615
18616 (define_peephole2
18617 [(set (match_operand:SI 0 "register_operand" "")
18618 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18619 (match_operand:DI 2 "const_int_operand" "")) 0))]
18620 "exact_log2 (INTVAL (operands[2])) >= 0
18621 && REGNO (operands[0]) == REGNO (operands[1])
18622 && peep2_regno_dead_p (0, FLAGS_REG)"
18623 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18624 (clobber (reg:CC FLAGS_REG))])]
18625 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18626
18627 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18628 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18629 ;; many CPUs it is also faster, since special hardware to avoid esp
18630 ;; dependencies is present.
18631
18632 ;; While some of these conversions may be done using splitters, we use peepholes
18633 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18634
18635 ;; Convert prologue esp subtractions to push.
18636 ;; We need register to push. In order to keep verify_flow_info happy we have
18637 ;; two choices
18638 ;; - use scratch and clobber it in order to avoid dependencies
18639 ;; - use already live register
18640 ;; We can't use the second way right now, since there is no reliable way how to
18641 ;; verify that given register is live. First choice will also most likely in
18642 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18643 ;; call clobbered registers are dead. We may want to use base pointer as an
18644 ;; alternative when no register is available later.
18645
18646 (define_peephole2
18647 [(match_scratch:SI 0 "r")
18648 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18649 (clobber (reg:CC FLAGS_REG))
18650 (clobber (mem:BLK (scratch)))])]
18651 "optimize_size || !TARGET_SUB_ESP_4"
18652 [(clobber (match_dup 0))
18653 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18654 (clobber (mem:BLK (scratch)))])])
18655
18656 (define_peephole2
18657 [(match_scratch:SI 0 "r")
18658 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18659 (clobber (reg:CC FLAGS_REG))
18660 (clobber (mem:BLK (scratch)))])]
18661 "optimize_size || !TARGET_SUB_ESP_8"
18662 [(clobber (match_dup 0))
18663 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18664 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18665 (clobber (mem:BLK (scratch)))])])
18666
18667 ;; Convert esp subtractions to push.
18668 (define_peephole2
18669 [(match_scratch:SI 0 "r")
18670 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18671 (clobber (reg:CC FLAGS_REG))])]
18672 "optimize_size || !TARGET_SUB_ESP_4"
18673 [(clobber (match_dup 0))
18674 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18675
18676 (define_peephole2
18677 [(match_scratch:SI 0 "r")
18678 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18679 (clobber (reg:CC FLAGS_REG))])]
18680 "optimize_size || !TARGET_SUB_ESP_8"
18681 [(clobber (match_dup 0))
18682 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18683 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18684
18685 ;; Convert epilogue deallocator to pop.
18686 (define_peephole2
18687 [(match_scratch:SI 0 "r")
18688 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18689 (clobber (reg:CC FLAGS_REG))
18690 (clobber (mem:BLK (scratch)))])]
18691 "optimize_size || !TARGET_ADD_ESP_4"
18692 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18693 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18694 (clobber (mem:BLK (scratch)))])]
18695 "")
18696
18697 ;; Two pops case is tricky, since pop causes dependency on destination register.
18698 ;; We use two registers if available.
18699 (define_peephole2
18700 [(match_scratch:SI 0 "r")
18701 (match_scratch:SI 1 "r")
18702 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18703 (clobber (reg:CC FLAGS_REG))
18704 (clobber (mem:BLK (scratch)))])]
18705 "optimize_size || !TARGET_ADD_ESP_8"
18706 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18707 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18708 (clobber (mem:BLK (scratch)))])
18709 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18710 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18711 "")
18712
18713 (define_peephole2
18714 [(match_scratch:SI 0 "r")
18715 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18716 (clobber (reg:CC FLAGS_REG))
18717 (clobber (mem:BLK (scratch)))])]
18718 "optimize_size"
18719 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18720 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18721 (clobber (mem:BLK (scratch)))])
18722 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18723 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18724 "")
18725
18726 ;; Convert esp additions to pop.
18727 (define_peephole2
18728 [(match_scratch:SI 0 "r")
18729 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18730 (clobber (reg:CC FLAGS_REG))])]
18731 ""
18732 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18733 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18734 "")
18735
18736 ;; Two pops case is tricky, since pop causes dependency on destination register.
18737 ;; We use two registers if available.
18738 (define_peephole2
18739 [(match_scratch:SI 0 "r")
18740 (match_scratch:SI 1 "r")
18741 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18742 (clobber (reg:CC FLAGS_REG))])]
18743 ""
18744 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18745 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18746 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18747 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18748 "")
18749
18750 (define_peephole2
18751 [(match_scratch:SI 0 "r")
18752 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18753 (clobber (reg:CC FLAGS_REG))])]
18754 "optimize_size"
18755 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18756 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18757 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18758 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18759 "")
18760 \f
18761 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18762 ;; required and register dies. Similarly for 128 to plus -128.
18763 (define_peephole2
18764 [(set (match_operand 0 "flags_reg_operand" "")
18765 (match_operator 1 "compare_operator"
18766 [(match_operand 2 "register_operand" "")
18767 (match_operand 3 "const_int_operand" "")]))]
18768 "(INTVAL (operands[3]) == -1
18769 || INTVAL (operands[3]) == 1
18770 || INTVAL (operands[3]) == 128)
18771 && ix86_match_ccmode (insn, CCGCmode)
18772 && peep2_reg_dead_p (1, operands[2])"
18773 [(parallel [(set (match_dup 0)
18774 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18775 (clobber (match_dup 2))])]
18776 "")
18777 \f
18778 (define_peephole2
18779 [(match_scratch:DI 0 "r")
18780 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18781 (clobber (reg:CC FLAGS_REG))
18782 (clobber (mem:BLK (scratch)))])]
18783 "optimize_size || !TARGET_SUB_ESP_4"
18784 [(clobber (match_dup 0))
18785 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18786 (clobber (mem:BLK (scratch)))])])
18787
18788 (define_peephole2
18789 [(match_scratch:DI 0 "r")
18790 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18791 (clobber (reg:CC FLAGS_REG))
18792 (clobber (mem:BLK (scratch)))])]
18793 "optimize_size || !TARGET_SUB_ESP_8"
18794 [(clobber (match_dup 0))
18795 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18796 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18797 (clobber (mem:BLK (scratch)))])])
18798
18799 ;; Convert esp subtractions to push.
18800 (define_peephole2
18801 [(match_scratch:DI 0 "r")
18802 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18803 (clobber (reg:CC FLAGS_REG))])]
18804 "optimize_size || !TARGET_SUB_ESP_4"
18805 [(clobber (match_dup 0))
18806 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18807
18808 (define_peephole2
18809 [(match_scratch:DI 0 "r")
18810 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18811 (clobber (reg:CC FLAGS_REG))])]
18812 "optimize_size || !TARGET_SUB_ESP_8"
18813 [(clobber (match_dup 0))
18814 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18815 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18816
18817 ;; Convert epilogue deallocator to pop.
18818 (define_peephole2
18819 [(match_scratch:DI 0 "r")
18820 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18821 (clobber (reg:CC FLAGS_REG))
18822 (clobber (mem:BLK (scratch)))])]
18823 "optimize_size || !TARGET_ADD_ESP_4"
18824 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18825 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18826 (clobber (mem:BLK (scratch)))])]
18827 "")
18828
18829 ;; Two pops case is tricky, since pop causes dependency on destination register.
18830 ;; We use two registers if available.
18831 (define_peephole2
18832 [(match_scratch:DI 0 "r")
18833 (match_scratch:DI 1 "r")
18834 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18835 (clobber (reg:CC FLAGS_REG))
18836 (clobber (mem:BLK (scratch)))])]
18837 "optimize_size || !TARGET_ADD_ESP_8"
18838 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18839 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18840 (clobber (mem:BLK (scratch)))])
18841 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18842 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18843 "")
18844
18845 (define_peephole2
18846 [(match_scratch:DI 0 "r")
18847 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18848 (clobber (reg:CC FLAGS_REG))
18849 (clobber (mem:BLK (scratch)))])]
18850 "optimize_size"
18851 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18852 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18853 (clobber (mem:BLK (scratch)))])
18854 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18855 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18856 "")
18857
18858 ;; Convert esp additions to pop.
18859 (define_peephole2
18860 [(match_scratch:DI 0 "r")
18861 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18862 (clobber (reg:CC FLAGS_REG))])]
18863 ""
18864 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18865 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18866 "")
18867
18868 ;; Two pops case is tricky, since pop causes dependency on destination register.
18869 ;; We use two registers if available.
18870 (define_peephole2
18871 [(match_scratch:DI 0 "r")
18872 (match_scratch:DI 1 "r")
18873 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18874 (clobber (reg:CC FLAGS_REG))])]
18875 ""
18876 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18877 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18878 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18879 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18880 "")
18881
18882 (define_peephole2
18883 [(match_scratch:DI 0 "r")
18884 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18885 (clobber (reg:CC FLAGS_REG))])]
18886 "optimize_size"
18887 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18888 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18889 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18890 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18891 "")
18892 \f
18893 ;; Convert imul by three, five and nine into lea
18894 (define_peephole2
18895 [(parallel
18896 [(set (match_operand:SI 0 "register_operand" "")
18897 (mult:SI (match_operand:SI 1 "register_operand" "")
18898 (match_operand:SI 2 "const_int_operand" "")))
18899 (clobber (reg:CC FLAGS_REG))])]
18900 "INTVAL (operands[2]) == 3
18901 || INTVAL (operands[2]) == 5
18902 || INTVAL (operands[2]) == 9"
18903 [(set (match_dup 0)
18904 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18905 (match_dup 1)))]
18906 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18907
18908 (define_peephole2
18909 [(parallel
18910 [(set (match_operand:SI 0 "register_operand" "")
18911 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18912 (match_operand:SI 2 "const_int_operand" "")))
18913 (clobber (reg:CC FLAGS_REG))])]
18914 "!optimize_size
18915 && (INTVAL (operands[2]) == 3
18916 || INTVAL (operands[2]) == 5
18917 || INTVAL (operands[2]) == 9)"
18918 [(set (match_dup 0) (match_dup 1))
18919 (set (match_dup 0)
18920 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18921 (match_dup 0)))]
18922 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18923
18924 (define_peephole2
18925 [(parallel
18926 [(set (match_operand:DI 0 "register_operand" "")
18927 (mult:DI (match_operand:DI 1 "register_operand" "")
18928 (match_operand:DI 2 "const_int_operand" "")))
18929 (clobber (reg:CC FLAGS_REG))])]
18930 "TARGET_64BIT
18931 && (INTVAL (operands[2]) == 3
18932 || INTVAL (operands[2]) == 5
18933 || INTVAL (operands[2]) == 9)"
18934 [(set (match_dup 0)
18935 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18936 (match_dup 1)))]
18937 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18938
18939 (define_peephole2
18940 [(parallel
18941 [(set (match_operand:DI 0 "register_operand" "")
18942 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18943 (match_operand:DI 2 "const_int_operand" "")))
18944 (clobber (reg:CC FLAGS_REG))])]
18945 "TARGET_64BIT
18946 && !optimize_size
18947 && (INTVAL (operands[2]) == 3
18948 || INTVAL (operands[2]) == 5
18949 || INTVAL (operands[2]) == 9)"
18950 [(set (match_dup 0) (match_dup 1))
18951 (set (match_dup 0)
18952 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18953 (match_dup 0)))]
18954 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18955
18956 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18957 ;; imul $32bit_imm, reg, reg is direct decoded.
18958 (define_peephole2
18959 [(match_scratch:DI 3 "r")
18960 (parallel [(set (match_operand:DI 0 "register_operand" "")
18961 (mult:DI (match_operand:DI 1 "memory_operand" "")
18962 (match_operand:DI 2 "immediate_operand" "")))
18963 (clobber (reg:CC FLAGS_REG))])]
18964 "TARGET_K8 && !optimize_size
18965 && (GET_CODE (operands[2]) != CONST_INT
18966 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18967 [(set (match_dup 3) (match_dup 1))
18968 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18969 (clobber (reg:CC FLAGS_REG))])]
18970 "")
18971
18972 (define_peephole2
18973 [(match_scratch:SI 3 "r")
18974 (parallel [(set (match_operand:SI 0 "register_operand" "")
18975 (mult:SI (match_operand:SI 1 "memory_operand" "")
18976 (match_operand:SI 2 "immediate_operand" "")))
18977 (clobber (reg:CC FLAGS_REG))])]
18978 "TARGET_K8 && !optimize_size
18979 && (GET_CODE (operands[2]) != CONST_INT
18980 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18981 [(set (match_dup 3) (match_dup 1))
18982 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18983 (clobber (reg:CC FLAGS_REG))])]
18984 "")
18985
18986 (define_peephole2
18987 [(match_scratch:SI 3 "r")
18988 (parallel [(set (match_operand:DI 0 "register_operand" "")
18989 (zero_extend:DI
18990 (mult:SI (match_operand:SI 1 "memory_operand" "")
18991 (match_operand:SI 2 "immediate_operand" ""))))
18992 (clobber (reg:CC FLAGS_REG))])]
18993 "TARGET_K8 && !optimize_size
18994 && (GET_CODE (operands[2]) != CONST_INT
18995 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18996 [(set (match_dup 3) (match_dup 1))
18997 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18998 (clobber (reg:CC FLAGS_REG))])]
18999 "")
19000
19001 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19002 ;; Convert it into imul reg, reg
19003 ;; It would be better to force assembler to encode instruction using long
19004 ;; immediate, but there is apparently no way to do so.
19005 (define_peephole2
19006 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19007 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19008 (match_operand:DI 2 "const_int_operand" "")))
19009 (clobber (reg:CC FLAGS_REG))])
19010 (match_scratch:DI 3 "r")]
19011 "TARGET_K8 && !optimize_size
19012 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19013 [(set (match_dup 3) (match_dup 2))
19014 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19015 (clobber (reg:CC FLAGS_REG))])]
19016 {
19017 if (!rtx_equal_p (operands[0], operands[1]))
19018 emit_move_insn (operands[0], operands[1]);
19019 })
19020
19021 (define_peephole2
19022 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19023 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19024 (match_operand:SI 2 "const_int_operand" "")))
19025 (clobber (reg:CC FLAGS_REG))])
19026 (match_scratch:SI 3 "r")]
19027 "TARGET_K8 && !optimize_size
19028 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19029 [(set (match_dup 3) (match_dup 2))
19030 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19031 (clobber (reg:CC FLAGS_REG))])]
19032 {
19033 if (!rtx_equal_p (operands[0], operands[1]))
19034 emit_move_insn (operands[0], operands[1]);
19035 })
19036
19037 (define_peephole2
19038 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19039 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19040 (match_operand:HI 2 "immediate_operand" "")))
19041 (clobber (reg:CC FLAGS_REG))])
19042 (match_scratch:HI 3 "r")]
19043 "TARGET_K8 && !optimize_size"
19044 [(set (match_dup 3) (match_dup 2))
19045 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19046 (clobber (reg:CC FLAGS_REG))])]
19047 {
19048 if (!rtx_equal_p (operands[0], operands[1]))
19049 emit_move_insn (operands[0], operands[1]);
19050 })
19051 \f
19052 ;; Call-value patterns last so that the wildcard operand does not
19053 ;; disrupt insn-recog's switch tables.
19054
19055 (define_insn "*call_value_pop_0"
19056 [(set (match_operand 0 "" "")
19057 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19058 (match_operand:SI 2 "" "")))
19059 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19060 (match_operand:SI 3 "immediate_operand" "")))]
19061 "!TARGET_64BIT"
19062 {
19063 if (SIBLING_CALL_P (insn))
19064 return "jmp\t%P1";
19065 else
19066 return "call\t%P1";
19067 }
19068 [(set_attr "type" "callv")])
19069
19070 (define_insn "*call_value_pop_1"
19071 [(set (match_operand 0 "" "")
19072 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19073 (match_operand:SI 2 "" "")))
19074 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19075 (match_operand:SI 3 "immediate_operand" "i")))]
19076 "!TARGET_64BIT"
19077 {
19078 if (constant_call_address_operand (operands[1], Pmode))
19079 {
19080 if (SIBLING_CALL_P (insn))
19081 return "jmp\t%P1";
19082 else
19083 return "call\t%P1";
19084 }
19085 if (SIBLING_CALL_P (insn))
19086 return "jmp\t%A1";
19087 else
19088 return "call\t%A1";
19089 }
19090 [(set_attr "type" "callv")])
19091
19092 (define_insn "*call_value_0"
19093 [(set (match_operand 0 "" "")
19094 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19095 (match_operand:SI 2 "" "")))]
19096 "!TARGET_64BIT"
19097 {
19098 if (SIBLING_CALL_P (insn))
19099 return "jmp\t%P1";
19100 else
19101 return "call\t%P1";
19102 }
19103 [(set_attr "type" "callv")])
19104
19105 (define_insn "*call_value_0_rex64"
19106 [(set (match_operand 0 "" "")
19107 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19108 (match_operand:DI 2 "const_int_operand" "")))]
19109 "TARGET_64BIT"
19110 {
19111 if (SIBLING_CALL_P (insn))
19112 return "jmp\t%P1";
19113 else
19114 return "call\t%P1";
19115 }
19116 [(set_attr "type" "callv")])
19117
19118 (define_insn "*call_value_1"
19119 [(set (match_operand 0 "" "")
19120 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19121 (match_operand:SI 2 "" "")))]
19122 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19123 {
19124 if (constant_call_address_operand (operands[1], Pmode))
19125 return "call\t%P1";
19126 return "call\t%A1";
19127 }
19128 [(set_attr "type" "callv")])
19129
19130 (define_insn "*sibcall_value_1"
19131 [(set (match_operand 0 "" "")
19132 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19133 (match_operand:SI 2 "" "")))]
19134 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19135 {
19136 if (constant_call_address_operand (operands[1], Pmode))
19137 return "jmp\t%P1";
19138 return "jmp\t%A1";
19139 }
19140 [(set_attr "type" "callv")])
19141
19142 (define_insn "*call_value_1_rex64"
19143 [(set (match_operand 0 "" "")
19144 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19145 (match_operand:DI 2 "" "")))]
19146 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19147 {
19148 if (constant_call_address_operand (operands[1], Pmode))
19149 return "call\t%P1";
19150 return "call\t%A1";
19151 }
19152 [(set_attr "type" "callv")])
19153
19154 (define_insn "*sibcall_value_1_rex64"
19155 [(set (match_operand 0 "" "")
19156 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19157 (match_operand:DI 2 "" "")))]
19158 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19159 "jmp\t%P1"
19160 [(set_attr "type" "callv")])
19161
19162 (define_insn "*sibcall_value_1_rex64_v"
19163 [(set (match_operand 0 "" "")
19164 (call (mem:QI (reg:DI 40))
19165 (match_operand:DI 1 "" "")))]
19166 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19167 "jmp\t*%%r11"
19168 [(set_attr "type" "callv")])
19169 \f
19170 (define_insn "trap"
19171 [(trap_if (const_int 1) (const_int 5))]
19172 ""
19173 "int\t$5")
19174
19175 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19176 ;;; for the sake of bounds checking. By emitting bounds checks as
19177 ;;; conditional traps rather than as conditional jumps around
19178 ;;; unconditional traps we avoid introducing spurious basic-block
19179 ;;; boundaries and facilitate elimination of redundant checks. In
19180 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19181 ;;; interrupt 5.
19182 ;;;
19183 ;;; FIXME: Static branch prediction rules for ix86 are such that
19184 ;;; forward conditional branches predict as untaken. As implemented
19185 ;;; below, pseudo conditional traps violate that rule. We should use
19186 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19187 ;;; section loaded at the end of the text segment and branch forward
19188 ;;; there on bounds-failure, and then jump back immediately (in case
19189 ;;; the system chooses to ignore bounds violations, or to report
19190 ;;; violations and continue execution).
19191
19192 (define_expand "conditional_trap"
19193 [(trap_if (match_operator 0 "comparison_operator"
19194 [(match_dup 2) (const_int 0)])
19195 (match_operand 1 "const_int_operand" ""))]
19196 ""
19197 {
19198 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19199 ix86_expand_compare (GET_CODE (operands[0]),
19200 NULL, NULL),
19201 operands[1]));
19202 DONE;
19203 })
19204
19205 (define_insn "*conditional_trap_1"
19206 [(trap_if (match_operator 0 "comparison_operator"
19207 [(reg FLAGS_REG) (const_int 0)])
19208 (match_operand 1 "const_int_operand" ""))]
19209 ""
19210 {
19211 operands[2] = gen_label_rtx ();
19212 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19213 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19214 CODE_LABEL_NUMBER (operands[2]));
19215 RET;
19216 })
19217
19218 (define_expand "sse_prologue_save"
19219 [(parallel [(set (match_operand:BLK 0 "" "")
19220 (unspec:BLK [(reg:DI 21)
19221 (reg:DI 22)
19222 (reg:DI 23)
19223 (reg:DI 24)
19224 (reg:DI 25)
19225 (reg:DI 26)
19226 (reg:DI 27)
19227 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19228 (use (match_operand:DI 1 "register_operand" ""))
19229 (use (match_operand:DI 2 "immediate_operand" ""))
19230 (use (label_ref:DI (match_operand 3 "" "")))])]
19231 "TARGET_64BIT"
19232 "")
19233
19234 (define_insn "*sse_prologue_save_insn"
19235 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19236 (match_operand:DI 4 "const_int_operand" "n")))
19237 (unspec:BLK [(reg:DI 21)
19238 (reg:DI 22)
19239 (reg:DI 23)
19240 (reg:DI 24)
19241 (reg:DI 25)
19242 (reg:DI 26)
19243 (reg:DI 27)
19244 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19245 (use (match_operand:DI 1 "register_operand" "r"))
19246 (use (match_operand:DI 2 "const_int_operand" "i"))
19247 (use (label_ref:DI (match_operand 3 "" "X")))]
19248 "TARGET_64BIT
19249 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19250 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19251 "*
19252 {
19253 int i;
19254 operands[0] = gen_rtx_MEM (Pmode,
19255 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19256 output_asm_insn (\"jmp\\t%A1\", operands);
19257 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19258 {
19259 operands[4] = adjust_address (operands[0], DImode, i*16);
19260 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19261 PUT_MODE (operands[4], TImode);
19262 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19263 output_asm_insn (\"rex\", operands);
19264 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19265 }
19266 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19267 CODE_LABEL_NUMBER (operands[3]));
19268 RET;
19269 }
19270 "
19271 [(set_attr "type" "other")
19272 (set_attr "length_immediate" "0")
19273 (set_attr "length_address" "0")
19274 (set_attr "length" "135")
19275 (set_attr "memory" "store")
19276 (set_attr "modrm" "0")
19277 (set_attr "mode" "DI")])
19278
19279 (define_expand "prefetch"
19280 [(prefetch (match_operand 0 "address_operand" "")
19281 (match_operand:SI 1 "const_int_operand" "")
19282 (match_operand:SI 2 "const_int_operand" ""))]
19283 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19284 {
19285 int rw = INTVAL (operands[1]);
19286 int locality = INTVAL (operands[2]);
19287
19288 if (rw != 0 && rw != 1)
19289 abort ();
19290 if (locality < 0 || locality > 3)
19291 abort ();
19292 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19293 abort ();
19294
19295 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19296 suported by SSE counterpart or the SSE prefetch is not available
19297 (K6 machines). Otherwise use SSE prefetch as it allows specifying
19298 of locality. */
19299 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19300 operands[2] = GEN_INT (3);
19301 else
19302 operands[1] = const0_rtx;
19303 })
19304
19305 (define_insn "*prefetch_sse"
19306 [(prefetch (match_operand:SI 0 "address_operand" "p")
19307 (const_int 0)
19308 (match_operand:SI 1 "const_int_operand" ""))]
19309 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19310 {
19311 static const char * const patterns[4] = {
19312 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19313 };
19314
19315 int locality = INTVAL (operands[1]);
19316 if (locality < 0 || locality > 3)
19317 abort ();
19318
19319 return patterns[locality];
19320 }
19321 [(set_attr "type" "sse")
19322 (set_attr "memory" "none")])
19323
19324 (define_insn "*prefetch_sse_rex"
19325 [(prefetch (match_operand:DI 0 "address_operand" "p")
19326 (const_int 0)
19327 (match_operand:SI 1 "const_int_operand" ""))]
19328 "TARGET_PREFETCH_SSE && TARGET_64BIT"
19329 {
19330 static const char * const patterns[4] = {
19331 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19332 };
19333
19334 int locality = INTVAL (operands[1]);
19335 if (locality < 0 || locality > 3)
19336 abort ();
19337
19338 return patterns[locality];
19339 }
19340 [(set_attr "type" "sse")
19341 (set_attr "memory" "none")])
19342
19343 (define_insn "*prefetch_3dnow"
19344 [(prefetch (match_operand:SI 0 "address_operand" "p")
19345 (match_operand:SI 1 "const_int_operand" "n")
19346 (const_int 3))]
19347 "TARGET_3DNOW && !TARGET_64BIT"
19348 {
19349 if (INTVAL (operands[1]) == 0)
19350 return "prefetch\t%a0";
19351 else
19352 return "prefetchw\t%a0";
19353 }
19354 [(set_attr "type" "mmx")
19355 (set_attr "memory" "none")])
19356
19357 (define_insn "*prefetch_3dnow_rex"
19358 [(prefetch (match_operand:DI 0 "address_operand" "p")
19359 (match_operand:SI 1 "const_int_operand" "n")
19360 (const_int 3))]
19361 "TARGET_3DNOW && TARGET_64BIT"
19362 {
19363 if (INTVAL (operands[1]) == 0)
19364 return "prefetch\t%a0";
19365 else
19366 return "prefetchw\t%a0";
19367 }
19368 [(set_attr "type" "mmx")
19369 (set_attr "memory" "none")])
19370
19371 (include "sse.md")
19372 (include "mmx.md")
This page took 0.887417 seconds and 5 git commands to generate.