i386.md revision 52296
1; GCC machine description for Intel X86.
2;; Copyright (C) 1988, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
3;; Mostly by William Schelter.
4
5;; This file is part of GNU CC.
6
7;; GNU CC is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 2, or (at your option)
10;; any later version.
11
12;; GNU CC is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU CC; see the file COPYING.  If not, write to
19;; the Free Software Foundation, 59 Temple Place - Suite 330,
20;; Boston, MA 02111-1307, USA. */
21
22;; The original PO technology requires these to be ordered by speed,
23;; so that assigner will pick the fastest.
24
25;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
28;; updates for most instructions.
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;; 0  This is a `scas' operation.  The mode of the UNSPEC is always SImode.
53;;    operand 0 is the memory address to scan.
54;;    operand 1 is a register containing the value to scan for.  The mode
55;;       of the scas opcode will be the same as the mode of this operand.
56;;    operand 2 is the known alignment of operand 0.
57;; 1  This is a `sin' operation.  The mode of the UNSPEC is MODE_FLOAT.
58;;    operand 0 is the argument for `sin'.
59;; 2  This is a `cos' operation.  The mode of the UNSPEC is MODE_FLOAT.
60;;    operand 0 is the argument for `cos'.
61;; 3  This is part of a `stack probe' operation.  The mode of the UNSPEC is 
62;;    always SImode.  operand 0 is the size of the stack allocation.
63;; 4  This is the source of a fake SET of the frame pointer which is used to
64;;    prevent insns referencing it being scheduled across the initial
65;;    decrement of the stack pointer.
66;; 5  This is a `bsf' operation.
67;; 6  This is the @GOT offset of a PIC address.
68;; 7  This is the @GOTOFF offset of a PIC address.
69;; 8  This is a reference to a symbol's @PLT address.
70
71;; This shadows the processor_type enumeration, so changes must be made
72;; to i386.h at the same time.
73
74;; $FreeBSD: head/contrib/gcc/config/i386/i386.md 52296 1999-10-16 08:12:02Z obrien $
75
76(define_attr "type"
77  "integer,binary,memory,test,compare,fcompare,idiv,imul,lea,fld,fpop,fpdiv,fpmul"
78  (const_string "integer"))
79
80(define_attr "memory" "none,load,store"
81  (cond [(eq_attr "type" "idiv,lea")
82	 (const_string "none")
83
84	 (eq_attr "type" "fld")
85	 (const_string "load")
86
87	 (eq_attr "type" "test")
88	 (if_then_else (match_operand 0 "memory_operand" "")
89		       (const_string "load")
90		       (const_string "none"))
91
92	 (eq_attr "type" "compare,fcompare")
93	 (if_then_else (ior (match_operand 0 "memory_operand" "")
94			    (match_operand 1 "memory_operand" ""))
95		       (const_string "load")
96		       (const_string "none"))
97
98	 (and (eq_attr "type" "integer,memory,fpop")
99	      (match_operand 0 "memory_operand" ""))
100	 (const_string "store")
101
102	 (and (eq_attr "type" "integer,memory,fpop")
103	      (match_operand 1 "memory_operand" ""))
104	 (const_string "load")
105
106	 (and (eq_attr "type" "binary,imul,fpmul,fpdiv")
107	      (ior (match_operand 1 "memory_operand" "")
108		   (match_operand 2 "memory_operand" "")))
109	 (const_string "load")]
110
111	(const_string "none")))
112
113;; Functional units
114
115; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
116;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
117
118; pentiumpro has a reservation station with 5 ports
119; port  0 has integer, float add, integer divide, float divide, float 
120;        multiply, and shifter units.
121; port  1 has integer, and jump units.
122; port  2 has the load address generation unit
123; ports 3 and 4 have the store address generation units
124
125; pentium has two integer pipelines, the main u pipe and the secondary v pipe.
126; and a float pipeline
127
128;; Floating point
129
130(define_function_unit "fp" 1 0
131 (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "i386,i486"))
132 5 5)
133
134(define_function_unit "fp" 1 0
135 (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "pentium,pentiumpro")) 
136 3 0)
137
138(define_function_unit "fp" 1 0
139 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentium")) 
140 7 0)
141
142(define_function_unit "fp" 1 0
143 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentiumpro")) 
144 5 0)
145
146(define_function_unit "fp" 1 0
147 (and (eq_attr "type" "idiv") (eq_attr "cpu" "pentiumpro")) 
148 10 10)
149
150(define_function_unit "fp" 1 0
151 (and (eq_attr "type" "imul") (eq_attr "cpu" "pentiumpro")) 
152 6 0)
153
154(define_function_unit "fp" 1 0
155 (eq_attr "type" "fpdiv") 
156 10 10)
157
158(define_function_unit "fp" 1 0
159  (and (eq_attr "type" "fld") (eq_attr "cpu" "!pentiumpro,k6"))
160 1 0)
161
162;; K6 FPU is not pipelined.
163(define_function_unit "fp" 1 0
164  (and (eq_attr "type" "fpop,fpmul,fcompare") (eq_attr "cpu" "k6"))
165 2 2)
166
167;; i386 and i486 have one integer unit, which need not be modeled
168
169(define_function_unit "integer" 2 0
170  (and (eq_attr "type" "integer,binary,test,compare,lea") (eq_attr "cpu" "pentium,pentiumpro"))
171 1 0)
172
173(define_function_unit "integer" 2 0
174  (and (eq_attr "cpu" "k6")
175       (and (eq_attr "type" "integer,binary,test,compare")
176	    (eq_attr "memory" "!load")))
177  1 0)
178
179;; Internally, K6 converts REG OP MEM instructions into a load (2 cycles)
180;; and a register operation (1 cycle).
181(define_function_unit "integer" 2 0
182  (and (eq_attr "cpu" "k6")
183       (and (eq_attr "type" "integer,binary,test,compare")
184	    (eq_attr "memory" "load")))
185  3 0)
186
187;; Multiplies use one of the integer units
188(define_function_unit "integer" 2 0
189  (and (eq_attr "cpu" "pentium") (eq_attr "type" "imul"))
190  11 11)
191
192(define_function_unit "integer" 2 0
193  (and (eq_attr "cpu" "k6") (eq_attr "type" "imul"))
194  2 2)
195
196(define_function_unit "integer" 2 0
197  (and (eq_attr "cpu" "pentium") (eq_attr "type" "idiv"))
198  25 25)
199
200(define_function_unit "integer" 2 0
201  (and (eq_attr "cpu" "k6") (eq_attr "type" "idiv"))
202  17 17)
203
204;; Pentium Pro and K6 have a separate load unit.
205(define_function_unit "load" 1 0
206  (and (eq_attr "cpu" "pentiumpro") (eq_attr "memory" "load"))
207  3 0)
208
209(define_function_unit "load" 1 0
210  (and (eq_attr "cpu" "k6") (eq_attr "memory" "load"))
211  2 0)
212
213;; Pentium Pro and K6 have a separate store unit.
214(define_function_unit "store" 1 0
215  (and (eq_attr "cpu" "pentiumpro,k6") (eq_attr "memory" "store"))
216  1 0)
217
218;; lea executes in the K6 store unit with 1 cycle latency
219(define_function_unit "store" 1 0
220  (and (eq_attr "cpu" "k6") (eq_attr "type" "lea"))
221  1 0)
222
223
224;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
225;; But restricting MEM here would mean that gcc could not remove a redundant
226;; test in cases like "incl MEM / je TARGET".
227;;
228;; We don't want to allow a constant operand for test insns because
229;; (set (cc0) (const_int foo)) has no mode information.  Such insns will
230;; be folded while optimizing anyway.
231
232;; All test insns have expanders that save the operands away without
233;; actually generating RTL.  The bCOND or sCOND (emitted immediately
234;; after the tstM or cmp) will actually emit the tstM or cmpM.
235
236;; Processor type -- this attribute must exactly match the processor_type
237;; enumeration in i386.h.
238
239(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6"
240  (const (symbol_ref "ix86_cpu")))
241
242(define_insn "tstsi_1"
243  [(set (cc0)
244	(match_operand:SI 0 "nonimmediate_operand" "rm"))]
245  ""
246  "*
247{
248  if (REG_P (operands[0]))
249    return AS2 (test%L0,%0,%0);
250
251  operands[1] = const0_rtx;
252  return AS2 (cmp%L0,%1,%0);
253}"
254  [(set_attr "type" "test")])
255
256(define_expand "tstsi"
257  [(set (cc0)
258	(match_operand:SI 0 "nonimmediate_operand" ""))]
259  ""
260  "
261{
262  i386_compare_gen = gen_tstsi_1;
263  i386_compare_op0 = operands[0];
264  i386_compare_op1 = const0_rtx;
265  DONE;
266}")
267
268(define_insn "tsthi_1"
269  [(set (cc0)
270	(match_operand:HI 0 "nonimmediate_operand" "rm"))]
271  ""
272  "*
273{
274  if (REG_P (operands[0]))
275    return AS2 (test%W0,%0,%0);
276
277  operands[1] = const0_rtx;
278  return AS2 (cmp%W0,%1,%0);
279}"
280  [(set_attr "type" "test")])
281
282(define_expand "tsthi"
283  [(set (cc0)
284	(match_operand:HI 0 "nonimmediate_operand" ""))]
285  ""
286  "
287{
288  i386_compare_gen = gen_tsthi_1;
289  i386_compare_op0 = operands[0];
290  i386_compare_op1 = const0_rtx;
291  DONE;
292}")
293
294(define_insn "tstqi_1"
295  [(set (cc0)
296	(match_operand:QI 0 "nonimmediate_operand" "qm"))]
297  ""
298  "*
299{
300  if (REG_P (operands[0]))
301    return AS2 (test%B0,%0,%0);
302
303  operands[1] = const0_rtx;
304  return AS2 (cmp%B0,%1,%0);
305}"
306  [(set_attr "type" "test")])
307
308(define_expand "tstqi"
309  [(set (cc0)
310	(match_operand:QI 0 "nonimmediate_operand" ""))]
311  ""
312  "
313{
314  i386_compare_gen = gen_tstqi_1;
315  i386_compare_op0 = operands[0];
316  i386_compare_op1 = const0_rtx;
317  DONE;
318}")
319
320(define_insn "tstsf_cc"
321  [(set (cc0)
322	(match_operand:SF 0 "register_operand" "f"))
323   (clobber (match_scratch:HI 1 "=a"))]
324  "TARGET_80387 && ! TARGET_IEEE_FP"
325  "*
326{
327  if (! STACK_TOP_P (operands[0]))
328    abort ();
329
330  output_asm_insn (\"ftst\", operands);
331
332  if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
333    output_asm_insn (AS1 (fstp,%y0), operands);
334
335  return output_fp_cc0_set (insn);
336}"
337  [(set_attr "type" "test")])
338
339;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
340;; isn't IEEE compliant.
341
342(define_expand "tstsf"
343  [(parallel [(set (cc0)
344		   (match_operand:SF 0 "register_operand" ""))
345	      (clobber (match_scratch:HI 1 ""))])]
346  "TARGET_80387 && ! TARGET_IEEE_FP"
347  "
348{
349  i386_compare_gen = gen_tstsf_cc;
350  i386_compare_op0 = operands[0];
351  i386_compare_op1 = const0_rtx;
352  DONE;
353}")
354
355(define_insn "tstdf_cc"
356  [(set (cc0)
357	(match_operand:DF 0 "register_operand" "f"))
358   (clobber (match_scratch:HI 1 "=a"))]
359  "TARGET_80387 && ! TARGET_IEEE_FP"
360  "*
361{
362  if (! STACK_TOP_P (operands[0]))
363    abort ();
364
365  output_asm_insn (\"ftst\", operands);
366
367  if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
368    output_asm_insn (AS1 (fstp,%y0), operands);
369
370  return output_fp_cc0_set (insn);
371}"
372  [(set_attr "type" "test")])
373
374;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
375;; isn't IEEE compliant.
376
377(define_expand "tstdf"
378  [(parallel [(set (cc0)
379		   (match_operand:DF 0 "register_operand" ""))
380	      (clobber (match_scratch:HI 1 ""))])]
381  "TARGET_80387 && ! TARGET_IEEE_FP"
382  "
383{
384  i386_compare_gen = gen_tstdf_cc;
385  i386_compare_op0 = operands[0];
386  i386_compare_op1 = const0_rtx;
387  DONE;
388}")
389
390(define_insn "tstxf_cc"
391  [(set (cc0)
392	(match_operand:XF 0 "register_operand" "f"))
393   (clobber (match_scratch:HI 1 "=a"))]
394  "TARGET_80387 && ! TARGET_IEEE_FP"
395  "*
396{
397  if (! STACK_TOP_P (operands[0]))
398    abort ();
399
400  output_asm_insn (\"ftst\", operands);
401
402  if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
403    output_asm_insn (AS1 (fstp,%y0), operands);
404
405  return output_fp_cc0_set (insn);
406}"
407  [(set_attr "type" "test")])
408
409;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode
410;; isn't IEEE compliant.
411
412(define_expand "tstxf"
413  [(parallel [(set (cc0)
414		   (match_operand:XF 0 "register_operand" ""))
415	      (clobber (match_scratch:HI 1 ""))])]
416  "TARGET_80387 && ! TARGET_IEEE_FP"
417  "
418{
419  i386_compare_gen = gen_tstxf_cc;
420  i386_compare_op0 = operands[0];
421  i386_compare_op1 = const0_rtx;
422  DONE;
423}")
424
425;;- compare instructions.  See comments above tstM patterns about
426;;  expansion of these insns.
427
428(define_insn "cmpsi_1"
429  [(set (cc0)
430	(compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
431		 (match_operand:SI 1 "general_operand" "ri,mr")))]
432  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
433  "* return AS2 (cmp%L0,%1,%0);"
434  [(set_attr "type" "compare")])
435
436(define_expand "cmpsi"
437  [(set (cc0)
438	(compare (match_operand:SI 0 "nonimmediate_operand" "")
439		 (match_operand:SI 1 "general_operand" "")))]
440  ""
441  "
442{
443  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
444    operands[0] = force_reg (SImode, operands[0]);
445
446  i386_compare_gen = gen_cmpsi_1;
447  i386_compare_op0 = operands[0];
448  i386_compare_op1 = operands[1];
449  DONE;
450}")
451
452(define_insn "cmphi_1"
453  [(set (cc0)
454	(compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
455		 (match_operand:HI 1 "general_operand" "ri,mr")))]
456  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
457  "* return AS2 (cmp%W0,%1,%0);"
458  [(set_attr "type" "compare")])
459
460(define_expand "cmphi"
461  [(set (cc0)
462	(compare (match_operand:HI 0 "nonimmediate_operand" "")
463		 (match_operand:HI 1 "general_operand" "")))]
464  ""
465  "
466{
467  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468    operands[0] = force_reg (HImode, operands[0]);
469
470  i386_compare_gen = gen_cmphi_1;
471  i386_compare_op0 = operands[0];
472  i386_compare_op1 = operands[1];
473  DONE;
474}")
475
476(define_insn "cmpqi_1"
477  [(set (cc0)
478	(compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
479		 (match_operand:QI 1 "general_operand" "qm,nq")))]
480  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
481  "* return AS2 (cmp%B0,%1,%0);"
482  [(set_attr "type" "compare")])
483
484(define_expand "cmpqi"
485  [(set (cc0)
486	(compare (match_operand:QI 0 "nonimmediate_operand" "")
487		 (match_operand:QI 1 "general_operand" "")))]
488  ""
489  "
490{
491  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
492    operands[0] = force_reg (QImode, operands[0]);
493
494  i386_compare_gen = gen_cmpqi_1;
495  i386_compare_op0 = operands[0];
496  i386_compare_op1 = operands[1];
497  DONE;
498}")
499
500;; These implement float point compares.  For each of DFmode and
501;; SFmode, there is the normal insn, and an insn where the second operand
502;; is converted to the desired mode.
503
504(define_insn ""
505  [(set (cc0)
506	(match_operator 2 "VOIDmode_compare_op"
507			[(match_operand:XF 0 "register_operand" "f")
508			 (match_operand:XF 1 "register_operand" "f")]))
509   (clobber (match_scratch:HI 3 "=a"))]
510  "TARGET_80387"
511  "* return output_float_compare (insn, operands);"
512  [(set_attr "type" "fcompare")])
513
514(define_insn ""
515  [(set (cc0)
516	(match_operator 2 "VOIDmode_compare_op"
517			[(match_operand:XF 0 "register_operand" "f")
518			 (float_extend:XF
519			  (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
520   (clobber (match_scratch:HI 3 "=a"))]
521  "TARGET_80387"
522  "* return output_float_compare (insn, operands);"
523  [(set_attr "type" "fcompare")])
524
525(define_insn ""
526  [(set (cc0)
527	(match_operator 2 "VOIDmode_compare_op"
528			[(float_extend:XF
529			  (match_operand:DF 0 "nonimmediate_operand" "fm"))
530			 (match_operand:XF 1 "register_operand" "f")]))
531   (clobber (match_scratch:HI 3 "=a"))]
532  "TARGET_80387"
533  "* return output_float_compare (insn, operands);"
534  [(set_attr "type" "fcompare")])
535
536(define_insn ""
537  [(set (cc0)
538	(match_operator 2 "VOIDmode_compare_op"
539			[(match_operand:XF 0 "register_operand" "f")
540			 (float_extend:XF
541			  (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
542   (clobber (match_scratch:HI 3 "=a"))]
543  "TARGET_80387"
544  "* return output_float_compare (insn, operands);"
545  [(set_attr "type" "fcompare")])
546
547(define_insn ""
548  [(set (cc0)
549	(match_operator 2 "VOIDmode_compare_op"
550			[(float_extend:XF
551			  (match_operand:SF 0 "nonimmediate_operand" "fm"))
552			 (match_operand:XF 1 "register_operand" "f")]))
553   (clobber (match_scratch:HI 3 "=a"))]
554  "TARGET_80387"
555  "* return output_float_compare (insn, operands);"
556  [(set_attr "type" "fcompare")])
557
558(define_insn ""
559  [(set (cc0)
560	(compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
561			(match_operand:XF 1 "register_operand" "f")))
562   (clobber (match_scratch:HI 2 "=a"))]
563  "TARGET_80387"
564  "* return output_float_compare (insn, operands);"
565  [(set_attr "type" "fcompare")])
566
567(define_insn ""
568  [(set (cc0)
569	(match_operator 2 "VOIDmode_compare_op"
570			[(match_operand:DF 0 "nonimmediate_operand" "f,fm")
571			 (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
572   (clobber (match_scratch:HI 3 "=a,a"))]
573  "TARGET_80387
574   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
575  "* return output_float_compare (insn, operands);"
576  [(set_attr "type" "fcompare")])
577
578(define_insn ""
579  [(set (cc0)
580	(match_operator 2 "VOIDmode_compare_op"
581			[(match_operand:DF 0 "register_operand" "f")
582			 (float_extend:DF
583			  (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
584   (clobber (match_scratch:HI 3 "=a"))]
585  "TARGET_80387"
586  "* return output_float_compare (insn, operands);"
587  [(set_attr "type" "fcompare")])
588
589(define_insn ""
590  [(set (cc0)
591	(match_operator 2 "VOIDmode_compare_op"
592			[(float_extend:DF
593			  (match_operand:SF 0 "nonimmediate_operand" "fm"))
594			 (match_operand:DF 1 "register_operand" "f")]))
595   (clobber (match_scratch:HI 3 "=a"))]
596  "TARGET_80387"
597  "* return output_float_compare (insn, operands);"
598  [(set_attr "type" "fcompare")])
599
600(define_insn ""
601  [(set (cc0)
602	(match_operator 2 "VOIDmode_compare_op"
603			[(float_extend:DF
604			  (match_operand:SF 0 "register_operand" "f"))
605			 (match_operand:DF 1 "nonimmediate_operand" "fm")]))
606   (clobber (match_scratch:HI 3 "=a"))]
607  "TARGET_80387"
608  "* return output_float_compare (insn, operands);"
609  [(set_attr "type" "fcompare")])
610
611(define_insn ""
612  [(set (cc0)
613	(compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
614			(match_operand:DF 1 "register_operand" "f")))
615   (clobber (match_scratch:HI 2 "=a"))]
616  "TARGET_80387"
617  "* return output_float_compare (insn, operands);"
618  [(set_attr "type" "fcompare")])
619
620;; These two insns will never be generated by combine due to the mode of
621;; the COMPARE.
622;(define_insn ""
623;  [(set (cc0)
624;	(compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
625;			(float_extend:DF
626;			 (match_operand:SF 1 "register_operand" "f"))))
627;   (clobber (match_scratch:HI 2 "=a"))]
628;  "TARGET_80387"
629;  "* return output_float_compare (insn, operands);")
630;
631;(define_insn ""
632;  [(set (cc0)
633;	(compare:CCFPEQ (float_extend:DF
634;			 (match_operand:SF 0 "register_operand" "f"))
635;			(match_operand:DF 1 "register_operand" "f")))
636;   (clobber (match_scratch:HI 2 "=a"))]
637;  "TARGET_80387"
638;  "* return output_float_compare (insn, operands);")
639
640(define_insn "*cmpsf_cc_1"
641  [(set (cc0)
642	(match_operator 2 "VOIDmode_compare_op"
643			[(match_operand:SF 0 "nonimmediate_operand" "f,fm")
644			 (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
645   (clobber (match_scratch:HI 3 "=a,a"))]
646  "TARGET_80387
647   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
648  "* return output_float_compare (insn, operands);"
649  [(set_attr "type" "fcompare")])
650
651(define_insn ""
652  [(set (cc0)
653	(compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
654			(match_operand:SF 1 "register_operand" "f")))
655   (clobber (match_scratch:HI 2 "=a"))]
656  "TARGET_80387"
657  "* return output_float_compare (insn, operands);"
658  [(set_attr "type" "fcompare")])
659
660(define_expand "cmpxf"
661  [(set (cc0)
662	(compare (match_operand:XF 0 "register_operand" "")
663		 (match_operand:XF 1 "register_operand" "")))]
664  "TARGET_80387"
665  "
666{
667  i386_compare_gen = gen_cmpxf_cc;
668  i386_compare_gen_eq = gen_cmpxf_ccfpeq;
669  i386_compare_op0 = operands[0];
670  i386_compare_op1 = operands[1];
671  DONE;
672}")
673
674(define_expand "cmpdf"
675  [(set (cc0)
676	(compare (match_operand:DF 0 "register_operand" "")
677		 (match_operand:DF 1 "general_operand" "")))]
678  "TARGET_80387"
679  "
680{
681  i386_compare_gen = gen_cmpdf_cc;
682  i386_compare_gen_eq = gen_cmpdf_ccfpeq;
683  i386_compare_op0 = operands[0];
684  i386_compare_op1 = (immediate_operand (operands[1], DFmode))
685			? copy_to_mode_reg (DFmode, operands[1]) : operands[1];
686  DONE;
687}")
688
689(define_expand "cmpsf"
690  [(set (cc0)
691	(compare (match_operand:SF 0 "register_operand" "")
692		 (match_operand:SF 1 "general_operand" "")))]
693  "TARGET_80387"
694  "
695{
696  i386_compare_gen = gen_cmpsf_cc;
697  i386_compare_gen_eq = gen_cmpsf_ccfpeq;
698  i386_compare_op0 = operands[0];
699  i386_compare_op1 = (immediate_operand (operands[1], SFmode))
700			? copy_to_mode_reg (SFmode, operands[1]) : operands[1];
701  DONE;
702}")
703
704(define_expand "cmpxf_cc"
705  [(parallel [(set (cc0)
706		   (compare (match_operand:XF 0 "register_operand" "")
707			    (match_operand:XF 1 "register_operand" "")))
708	      (clobber (match_scratch:HI 2 ""))])]
709  "TARGET_80387"
710  "")
711
712(define_expand "cmpxf_ccfpeq"
713  [(parallel [(set (cc0)
714		   (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
715				   (match_operand:XF 1 "register_operand" "")))
716	      (clobber (match_scratch:HI 2 ""))])]
717  "TARGET_80387"
718  "")
719
720(define_expand "cmpdf_cc"
721  [(parallel [(set (cc0)
722		   (compare (match_operand:DF 0 "register_operand" "")
723			    (match_operand:DF 1 "register_operand" "")))
724	      (clobber (match_scratch:HI 2 ""))])]
725  "TARGET_80387"
726  "")
727
728(define_expand "cmpdf_ccfpeq"
729  [(parallel [(set (cc0)
730		   (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
731				   (match_operand:DF 1 "register_operand" "")))
732	      (clobber (match_scratch:HI 2 ""))])]
733  "TARGET_80387"
734  "
735{
736  if (! register_operand (operands[1], DFmode))
737    operands[1] = copy_to_mode_reg (DFmode, operands[1]);
738}")
739
740(define_expand "cmpsf_cc"
741  [(parallel [(set (cc0)
742		   (compare (match_operand:SF 0 "register_operand" "")
743			    (match_operand:SF 1 "register_operand" "")))
744	      (clobber (match_scratch:HI 2 ""))])]
745  "TARGET_80387"
746  "")
747
748(define_expand "cmpsf_ccfpeq"
749  [(parallel [(set (cc0)
750		   (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
751				   (match_operand:SF 1 "register_operand" "")))
752	      (clobber (match_scratch:HI 2 ""))])]
753  "TARGET_80387"
754  "
755{
756  if (! register_operand (operands[1], SFmode))
757    operands[1] = copy_to_mode_reg (SFmode, operands[1]);
758}")
759
760;; logical compare
761
762(define_insn ""
763  [(set (cc0)
764	(and:SI (match_operand:SI 0 "general_operand" "%ro")
765		(match_operand:SI 1 "nonmemory_operand" "ri")))]
766  ""
767  "*
768{
769  /* For small integers, we may actually use testb. */
770  if (GET_CODE (operands[1]) == CONST_INT
771      && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
772      && (! REG_P (operands[0]) || QI_REG_P (operands[0]))
773      /* A Pentium test is pairable only with eax. Not with ah or al.  */
774      && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
775          || optimize_size))
776    {
777      /* We may set the sign bit spuriously.  */
778
779      if ((INTVAL (operands[1]) & ~0xff) == 0)
780        {
781	  cc_status.flags |= CC_NOT_NEGATIVE;
782	  return AS2 (test%B0,%1,%b0);
783	}
784
785      if ((INTVAL (operands[1]) & ~0xff00) == 0)
786        {
787	  cc_status.flags |= CC_NOT_NEGATIVE;
788	  operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
789
790	  if (QI_REG_P (operands[0]))
791	    return AS2 (test%B0,%1,%h0);
792	  else
793	    {
794	      operands[0] = adj_offsettable_operand (operands[0], 1);
795	      return AS2 (test%B0,%1,%b0);
796	    }
797	}
798
799      if (GET_CODE (operands[0]) == MEM
800	  && (INTVAL (operands[1]) & ~0xff0000) == 0)
801        {
802	  cc_status.flags |= CC_NOT_NEGATIVE;
803	  operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
804	  operands[0] = adj_offsettable_operand (operands[0], 2);
805	  return AS2 (test%B0,%1,%b0);
806	}
807
808      if (GET_CODE (operands[0]) == MEM
809	  && (INTVAL (operands[1]) & ~0xff000000) == 0)
810        {
811	  operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
812	  operands[0] = adj_offsettable_operand (operands[0], 3);
813	  return AS2 (test%B0,%1,%b0);
814	}
815    }
816
817  if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
818    return AS2 (test%L0,%1,%0);
819
820  return AS2 (test%L1,%0,%1);
821}"
822  [(set_attr "type" "compare")])
823
824(define_insn ""
825  [(set (cc0)
826	(and:HI (match_operand:HI 0 "general_operand" "%ro")
827		(match_operand:HI 1 "nonmemory_operand" "ri")))]
828  ""
829  "*
830{
831  if (GET_CODE (operands[1]) == CONST_INT
832      && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
833      && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
834    {
835      if ((INTVAL (operands[1]) & 0xff00) == 0)
836	{
837	  /* ??? This might not be necessary. */
838	  if (INTVAL (operands[1]) & 0xffff0000)
839	    operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
840
841	  /* We may set the sign bit spuriously.  */
842	  cc_status.flags |= CC_NOT_NEGATIVE;
843	  return AS2 (test%B0,%1,%b0);
844	}
845
846      if ((INTVAL (operands[1]) & 0xff) == 0)
847        {
848	  operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
849
850	  if (QI_REG_P (operands[0]))
851	    return AS2 (test%B0,%1,%h0);
852	  else
853	    {
854	      operands[0] = adj_offsettable_operand (operands[0], 1);
855	      return AS2 (test%B0,%1,%b0);
856	    }
857	}
858    }
859
860  /* use 32-bit test instruction if there are no sign issues */
861  if (GET_CODE (operands[1]) == CONST_INT
862      && !(INTVAL (operands[1]) & ~0x7fff)
863      && i386_aligned_p (operands[0]))
864    return AS2 (test%L0,%1,%k0);
865
866  if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
867    return AS2 (test%W0,%1,%0);
868
869  return AS2 (test%W1,%0,%1);
870}"
871  [(set_attr "type" "compare")])
872
873(define_insn ""
874  [(set (cc0)
875	(and:QI (match_operand:QI 0 "nonimmediate_operand" "%qm")
876		(match_operand:QI 1 "nonmemory_operand" "qi")))]
877  ""
878  "*
879{
880  if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
881    return AS2 (test%B0,%1,%0);
882
883  return AS2 (test%B1,%0,%1);
884}"
885  [(set_attr "type" "compare")])
886
887;; move instructions.
888;; There is one for each machine mode,
889;; and each is preceded by a corresponding push-insn pattern
890;; (since pushes are not general_operands on the 386).
891
892(define_insn ""
893  [(set (match_operand:SI 0 "push_operand" "=<")
894	(match_operand:SI 1 "nonmemory_operand" "rn"))]
895  "flag_pic"
896  "* return AS1 (push%L0,%1);"
897  [(set_attr "memory" "store")])
898
899(define_insn ""
900  [(set (match_operand:SI 0 "push_operand" "=<")
901	(match_operand:SI 1 "nonmemory_operand" "ri"))]
902  "!flag_pic"
903  "* return AS1 (push%L0,%1);"
904  [(set_attr "memory" "store")])
905
906;; On a 386, it is faster to push MEM directly.
907
908(define_insn ""
909  [(set (match_operand:SI 0 "push_operand" "=<")
910	(match_operand:SI 1 "memory_operand" "m"))]
911  "TARGET_PUSH_MEMORY"
912  "* return AS1 (push%L0,%1);"
913  [(set_attr "type" "memory")
914   (set_attr "memory" "load")])
915
916;; General case of fullword move.
917
918;; If generating PIC code and operands[1] is a symbolic CONST, emit a
919;; move to get the address of the symbolic object from the GOT.
920
921(define_expand "movsi"
922  [(set (match_operand:SI 0 "general_operand" "")
923	(match_operand:SI 1 "general_operand" ""))]
924  ""
925  "
926{
927  extern int flag_pic;
928
929  if (flag_pic && SYMBOLIC_CONST (operands[1]))
930    emit_pic_move (operands, SImode);
931
932  /* Don't generate memory->memory moves, go through a register */
933  else if (TARGET_MOVE
934	   && no_new_pseudos == 0
935	   && GET_CODE (operands[0]) == MEM
936	   && GET_CODE (operands[1]) == MEM)
937    {
938      operands[1] = force_reg (SImode, operands[1]);
939    }
940}")
941
942;; On i486, incl reg is faster than movl $1,reg.
943
944(define_insn ""
945  [(set (match_operand:SI 0 "general_operand" "=g,r,r")
946	(match_operand:SI 1 "general_operand" "rn,i,m"))]
947  "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
948    || (GET_CODE (operands[1]) != MEM))
949   && flag_pic"
950  "*
951{
952  rtx link;
953
954  /* K6: mov reg,0 is slightly faster than xor reg,reg but is 3 bytes
955     longer.  */
956  if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
957      && operands[1] == const0_rtx && REG_P (operands[0]))
958    return AS2 (xor%L0,%0,%0);
959
960  if (operands[1] == const1_rtx
961      /* PPRO and K6 prefer mov to inc to reduce dependencies.  */
962      && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
963      && (link = find_reg_note (insn, REG_WAS_0, 0))
964      /* Make sure the insn that stored the 0 is still present.  */
965      && ! INSN_DELETED_P (XEXP (link, 0))
966      && GET_CODE (XEXP (link, 0)) != NOTE
967      /* Make sure cross jumping didn't happen here.  */
968      && no_labels_between_p (XEXP (link, 0), insn)
969      /* Make sure the reg hasn't been clobbered.  */
970      && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
971    /* Fastest way to change a 0 to a 1.  */
972    return AS1 (inc%L0,%0);
973
974  if (SYMBOLIC_CONST (operands[1]))
975    return AS2 (lea%L0,%a1,%0);
976
977  return AS2 (mov%L0,%1,%0);
978}"
979  [(set_attr "type" "integer,integer,memory")
980   (set_attr "memory" "*,*,load")])
981
982(define_insn ""
983  [(set (match_operand:SI 0 "general_operand" "=g,r")
984	(match_operand:SI 1 "general_operand" "ri,m"))]
985  "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
986    || (GET_CODE (operands[1]) != MEM))
987   && !flag_pic"
988  "*
989{
990  rtx link;
991
992  /* Use of xor was disabled for AMD K6 as recommended by the Optimization
993     Manual.  My test shows, that this generally hurts the performance, because
994     mov is longer and takes longer to decode and decoding is the main
995     bottleneck of K6 when executing GCC code.  */
996
997  if (operands[1] == const0_rtx && REG_P (operands[0]))
998    return AS2 (xor%L0,%0,%0);
999
1000  if (operands[1] == const1_rtx
1001      /* PPRO and K6 prefer mov to inc to reduce dependencies.  */
1002      && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1003      && (link = find_reg_note (insn, REG_WAS_0, 0))
1004      /* Make sure the insn that stored the 0 is still present.  */
1005      && ! INSN_DELETED_P (XEXP (link, 0))
1006      && GET_CODE (XEXP (link, 0)) != NOTE
1007      /* Make sure cross jumping didn't happen here.  */
1008      && no_labels_between_p (XEXP (link, 0), insn)
1009      /* Make sure the reg hasn't been clobbered.  */
1010      && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1011    /* Fastest way to change a 0 to a 1.  */
1012    return AS1 (inc%L0,%0);
1013
1014  return AS2 (mov%L0,%1,%0);
1015}"
1016  [(set_attr "type" "integer,memory")
1017   (set_attr "memory" "*,load")])
1018
1019(define_insn ""
1020  [(set (match_operand:HI 0 "push_operand" "=<")
1021	(match_operand:HI 1 "nonmemory_operand" "ri"))]
1022  ""
1023  "* return AS1 (push%W0,%1);"
1024  [(set_attr "type" "memory")
1025   (set_attr "memory" "store")])
1026
1027(define_insn ""
1028  [(set (match_operand:HI 0 "push_operand" "=<")
1029	(match_operand:HI 1 "memory_operand" "m"))]
1030  "TARGET_PUSH_MEMORY"
1031  "* return AS1 (push%W0,%1);"
1032  [(set_attr "type" "memory")
1033   (set_attr "memory" "load")])
1034
1035;; On i486, an incl and movl are both faster than incw and movw.
1036
1037(define_expand "movhi"
1038  [(set (match_operand:HI 0 "general_operand" "")
1039	(match_operand:HI 1 "general_operand" ""))]
1040  ""
1041  "
1042{
1043  /* Don't generate memory->memory moves, go through a register */
1044  if (TARGET_MOVE
1045      && no_new_pseudos == 0
1046      && GET_CODE (operands[0]) == MEM
1047      && GET_CODE (operands[1]) == MEM)
1048    {
1049      operands[1] = force_reg (HImode, operands[1]);
1050    }
1051}")
1052
1053(define_insn ""
1054  [(set (match_operand:HI 0 "general_operand" "=g,r")
1055	(match_operand:HI 1 "general_operand" "ri,m"))]
1056  "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1057  "*
1058{
1059  rtx link;
1060  if (REG_P (operands[0]) && operands[1] == const0_rtx)
1061    return AS2 (xor%L0,%k0,%k0);
1062
1063  if (REG_P (operands[0]) && operands[1] == const1_rtx 
1064      /* PPRO and K6 prefer mov to inc to reduce dependencies.  */
1065      && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1066      && (link = find_reg_note (insn, REG_WAS_0, 0))
1067      /* Make sure the insn that stored the 0 is still present.  */
1068      && ! INSN_DELETED_P (XEXP (link, 0))
1069      && GET_CODE (XEXP (link, 0)) != NOTE
1070      /* Make sure cross jumping didn't happen here.  */
1071      && no_labels_between_p (XEXP (link, 0), insn)
1072      /* Make sure the reg hasn't been clobbered.  */
1073      && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1074    /* Fastest way to change a 0 to a 1.  */
1075    return AS1 (inc%L0,%k0);
1076
1077  if (REG_P (operands[0]))
1078    {
1079      if (i386_aligned_p (operands[1]))
1080	{
1081	  operands[1] = i386_sext16_if_const (operands[1]);
1082	  return AS2 (mov%L0,%k1,%k0);
1083	}
1084      if (! TARGET_ZERO_EXTEND_WITH_AND)
1085	{
1086	  /* movzwl is faster than movw on the Pentium Pro,
1087	   * although not as fast as an aligned movl. */
1088#ifdef INTEL_SYNTAX
1089	  return AS2 (movzx,%1,%k0);
1090#else
1091	  return AS2 (movz%W0%L0,%1,%k0);
1092#endif
1093	}
1094    }
1095
1096  return AS2 (mov%W0,%1,%0);
1097}"
1098  [(set_attr "type" "integer,memory")
1099   (set_attr "memory" "*,load")])
1100
1101(define_expand "movstricthi"
1102  [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
1103	(match_operand:HI 1 "general_operand" ""))]
1104  ""
1105  "
1106{
1107  /* Don't generate memory->memory moves, go through a register */
1108  if (TARGET_MOVE
1109      && no_new_pseudos == 0
1110      && GET_CODE (operands[0]) == MEM
1111      && GET_CODE (operands[1]) == MEM)
1112    {
1113      operands[1] = force_reg (HImode, operands[1]);
1114    }
1115}")
1116
1117(define_insn ""
1118  [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
1119	(match_operand:HI 1 "general_operand" "ri,m"))]
1120  "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1121  "*
1122{
1123  rtx link;
1124
1125  /* Use of xor was disabled for AMD K6 as recommended by the Optimization
1126     Manual.  My test shows, that this generally hurts the performance, because
1127     mov is longer and takes longer to decode and decoding is the main
1128     bottleneck of K6 when executing GCC code.  */
1129
1130  if (operands[1] == const0_rtx && REG_P (operands[0]))
1131    return AS2 (xor%W0,%0,%0);
1132
1133  if (operands[1] == const1_rtx
1134      /* PPRO and K6 prefer mov to inc to reduce dependencies.  */
1135      && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1136      && (link = find_reg_note (insn, REG_WAS_0, 0))
1137      /* Make sure the insn that stored the 0 is still present.  */
1138      && ! INSN_DELETED_P (XEXP (link, 0))
1139      && GET_CODE (XEXP (link, 0)) != NOTE
1140      /* Make sure cross jumping didn't happen here.  */
1141      && no_labels_between_p (XEXP (link, 0), insn)
1142      /* Make sure the reg hasn't been clobbered.  */
1143      && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1144    /* Fastest way to change a 0 to a 1.  */
1145    return AS1 (inc%W0,%0);
1146
1147  return AS2 (mov%W0,%1,%0);
1148}"
1149  [(set_attr "type" "integer,memory")])
1150
1151;; emit_push_insn when it calls move_by_pieces
1152;; requires an insn to "push a byte".
1153;; But actually we use pushw, which has the effect of rounding
1154;; the amount pushed up to a halfword.
1155(define_insn ""
1156  [(set (match_operand:QI 0 "push_operand" "=<")
1157	(match_operand:QI 1 "const_int_operand" "n"))]
1158  ""
1159  "* return AS1(push%W0,%1);")
1160
1161(define_insn ""
1162  [(set (match_operand:QI 0 "push_operand" "=<")
1163	(match_operand:QI 1 "register_operand" "q"))]
1164  ""
1165  "*
1166{
1167  operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]));
1168  return AS1 (push%W0,%1);
1169}")
1170
1171;; On i486, incb reg is faster than movb $1,reg.
1172
1173;; ??? Do a recognizer for zero_extract that looks just like this, but reads
1174;; or writes %ah, %bh, %ch, %dh.
1175
1176(define_expand "movqi"
1177  [(set (match_operand:QI 0 "general_operand" "")
1178	(match_operand:QI 1 "general_operand" ""))]
1179  ""
1180  "
1181{
1182  /* Don't generate memory->memory moves, go through a register */
1183  if (TARGET_MOVE
1184      && no_new_pseudos == 0
1185      && GET_CODE (operands[0]) == MEM
1186      && GET_CODE (operands[1]) == MEM)
1187    {
1188      operands[1] = force_reg (QImode, operands[1]);
1189    }
1190}")
1191
1192(define_insn ""
1193  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,*r,qm")
1194	(match_operand:QI 1 "general_operand" "*g,*rn,qn"))]
1195  "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1196  "*
1197{
1198  rtx link;
1199
1200  /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8.
1201     It is at least as fast as xor on any processor except a Pentium. */
1202
1203  if (operands[1] == const1_rtx
1204      && TARGET_PENTIUM
1205      && (link = find_reg_note (insn, REG_WAS_0, 0))
1206      /* Make sure the insn that stored the 0 is still present.  */
1207      && ! INSN_DELETED_P (XEXP (link, 0))
1208      && GET_CODE (XEXP (link, 0)) != NOTE
1209      /* Make sure cross jumping didn't happen here.  */
1210      && no_labels_between_p (XEXP (link, 0), insn)
1211      /* Make sure the reg hasn't been clobbered.  */
1212      && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1213    {
1214      /* Fastest way to change a 0 to a 1.
1215	 If inc%B0 isn't allowed, use inc%L0.  */
1216      if (NON_QI_REG_P (operands[0]))
1217	return AS1 (inc%L0,%k0);
1218      else
1219	return AS1 (inc%B0,%0);
1220    }
1221
1222  /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
1223  if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1224    return (AS2 (mov%L0,%k1,%k0));
1225
1226  return (AS2 (mov%B0,%1,%0));
1227}")
1228
1229;; If it becomes necessary to support movstrictqi into %esi or %edi,
1230;; use the insn sequence:
1231;;
1232;;	shrdl $8,srcreg,dstreg
1233;;	rorl $24,dstreg
1234;;
1235;; If operands[1] is a constant, then an andl/orl sequence would be
1236;; faster.
1237
1238(define_expand "movstrictqi"
1239  [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
1240	(match_operand:QI 1 "general_operand" ""))]
1241  ""
1242  "
1243{
1244  /* Don't generate memory->memory moves, go through a register */
1245  if (TARGET_MOVE
1246      && no_new_pseudos == 0
1247      && GET_CODE (operands[0]) == MEM
1248      && GET_CODE (operands[1]) == MEM)
1249    {
1250      operands[1] = force_reg (QImode, operands[1]);
1251    }
1252}")
1253
1254(define_insn ""
1255  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1256	(match_operand:QI 1 "general_operand" "*qn,m"))]
1257  "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1258  "*
1259{
1260  rtx link;
1261
1262  /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8.  */
1263
1264  if (operands[1] == const1_rtx
1265      && TARGET_PENTIUM
1266      && ! NON_QI_REG_P (operands[0])
1267      && (link = find_reg_note (insn, REG_WAS_0, 0))
1268      /* Make sure the insn that stored the 0 is still present.  */
1269      && ! INSN_DELETED_P (XEXP (link, 0))
1270      && GET_CODE (XEXP (link, 0)) != NOTE
1271      /* Make sure cross jumping didn't happen here.  */
1272      && no_labels_between_p (XEXP (link, 0), insn)
1273      /* Make sure the reg hasn't been clobbered.  */
1274      && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1275    /* Fastest way to change a 0 to a 1.  */
1276    return AS1 (inc%B0,%0);
1277
1278  /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
1279  if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1280    {
1281      abort ();
1282      return (AS2 (mov%L0,%k1,%k0));
1283    }
1284
1285  return AS2 (mov%B0,%1,%0);
1286}")
1287
1288(define_insn "movsf_push"
1289  [(set (match_operand:SF 0 "push_operand" "=<,<")
1290	(match_operand:SF 1 "general_operand" "*rfF,m"))]
1291  "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM 
1292   || reload_in_progress || reload_completed"
1293  "*
1294{
1295  if (STACK_REG_P (operands[1]))
1296    {
1297      rtx xops[3];
1298
1299      if (! STACK_TOP_P (operands[1]))
1300        abort ();
1301
1302      xops[0] = AT_SP (SFmode);
1303      xops[1] = GEN_INT (4);
1304      xops[2] = stack_pointer_rtx;
1305
1306      output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1307
1308      if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1309        output_asm_insn (AS1 (fstp%S0,%0), xops);
1310      else
1311        output_asm_insn (AS1 (fst%S0,%0), xops);
1312
1313      RET;
1314    }
1315
1316  return AS1 (push%L0,%1);
1317}")
1318
1319(define_split
1320  [(set (match_operand:SF 0 "push_operand" "")
1321        (match_operand:SF 1 "general_operand" ""))]
1322  "reload_completed && STACK_REG_P (operands[1])"
1323  [(set (reg:SI 7)
1324        (minus:SI (reg:SI 7) (const_int 4)))
1325   (set (mem:SF (reg:SI 7))
1326        (match_dup 1))]
1327  "")
1328
1329(define_expand "movsf"
1330  [(set (match_operand:SF 0 "general_operand" "")
1331	(match_operand:SF 1 "general_operand" ""))]
1332  ""
1333  "
1334{
1335  /* Don't generate memory->memory moves, go through a register */
1336  if (TARGET_MOVE
1337      && no_new_pseudos == 0
1338      && GET_CODE (operands[0]) == MEM
1339      && GET_CODE (operands[1]) == MEM)
1340    {
1341      operands[1] = force_reg (SFmode, operands[1]);
1342    }
1343
1344  /* If we are loading a floating point constant that isn't 0 or 1
1345     into a register, force the value to memory now, since we'll 
1346     get better code out the back end.  */
1347  else if ((reload_in_progress | reload_completed) == 0
1348	   && GET_CODE (operands[0]) != MEM
1349	   && GET_CODE (operands[1]) == CONST_DOUBLE
1350	   && !standard_80387_constant_p (operands[1]))
1351    {
1352      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
1353    }
1354}")
1355
1356;; For the purposes of regclass, prefer FLOAT_REGS.
1357(define_insn ""
1358  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r,!m")
1359	(match_operand:SF 1 "general_operand" "fmG,f,*rmF,*rF"))]
1360  "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1361  "*
1362{
1363  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1364
1365  /* First handle a `pop' insn or a `fld %st(0)' */
1366
1367  if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1368    {
1369      if (stack_top_dies)
1370	return AS1 (fstp,%y0);
1371      else
1372        return AS1 (fld,%y0);
1373    }
1374
1375  /* Handle other kinds of writes from the 387 */
1376
1377  if (STACK_TOP_P (operands[1]))
1378    {
1379      if (stack_top_dies)
1380	return AS1 (fstp%z0,%y0);
1381      else
1382        return AS1 (fst%z0,%y0);
1383    }
1384
1385  /* Handle other kinds of reads to the 387 */
1386
1387  if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1388    return output_move_const_single (operands);
1389
1390  if (STACK_TOP_P (operands[0]))
1391    return AS1 (fld%z1,%y1);
1392
1393  /* Handle all SFmode moves not involving the 387 */
1394
1395  return singlemove_string (operands);
1396}"
1397  [(set_attr "type" "fld")])
1398
1399
1400(define_insn "swapsf"
1401  [(set (match_operand:SF 0 "register_operand" "f")
1402	(match_operand:SF 1 "register_operand" "f"))
1403   (set (match_dup 1)
1404	(match_dup 0))]
1405  ""
1406  "*
1407{
1408  if (STACK_TOP_P (operands[0]))
1409    return AS1 (fxch,%1);
1410  else
1411    return AS1 (fxch,%0);
1412}")
1413
1414
1415(define_insn "movdf_push"
1416  [(set (match_operand:DF 0 "push_operand" "=<,<")
1417	(match_operand:DF 1 "general_operand" "*rfF,o"))]
1418  "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM 
1419   || reload_in_progress || reload_completed"
1420  "*
1421{
1422  if (STACK_REG_P (operands[1]))
1423    {
1424      rtx xops[3];
1425
1426      xops[0] = AT_SP (DFmode);
1427      xops[1] = GEN_INT (8);
1428      xops[2] = stack_pointer_rtx;
1429
1430      output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1431
1432      if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1433        output_asm_insn (AS1 (fstp%Q0,%0), xops);
1434      else
1435        output_asm_insn (AS1 (fst%Q0,%0), xops);
1436
1437      RET;
1438    }
1439
1440  if (which_alternative == 1)
1441    return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 0, 0);
1442
1443  return output_move_double (operands);
1444}")
1445
1446(define_split
1447  [(set (match_operand:DF 0 "push_operand" "")
1448        (match_operand:DF 1 "register_operand" ""))]
1449  "reload_completed && STACK_REG_P (operands[1])"
1450  [(set (reg:SI 7)
1451        (minus:SI (reg:SI 7) (const_int 8)))
1452   (set (mem:DF (reg:SI 7))
1453        (match_dup 1))]
1454  "")
1455
1456(define_expand "movdf"
1457  [(set (match_operand:DF 0 "general_operand" "")
1458	(match_operand:DF 1 "general_operand" ""))]
1459  ""
1460  "
1461{
1462  /* Don't generate memory->memory moves, go through a register */
1463  if (TARGET_MOVE
1464      && no_new_pseudos == 0
1465      && GET_CODE (operands[0]) == MEM
1466      && GET_CODE (operands[1]) == MEM)
1467    {
1468      operands[1] = force_reg (DFmode, operands[1]);
1469    }
1470
1471  /* If we are loading a floating point constant that isn't 0 or 1 into a
1472     register, indicate we need the pic register loaded.  This could be
1473     optimized into stores of constants if the target eventually moves to
1474     memory, but better safe than sorry.  */
1475  else if ((reload_in_progress | reload_completed) == 0
1476	   && GET_CODE (operands[0]) != MEM
1477	   && GET_CODE (operands[1]) == CONST_DOUBLE
1478	   && !standard_80387_constant_p (operands[1]))
1479    {
1480      operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
1481    }
1482}")
1483
1484;; For the purposes of regclass, prefer FLOAT_REGS.
1485(define_insn ""
1486  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r,!o")
1487	(match_operand:DF 1 "general_operand" "fmG,f,*roF,*rF"))]
1488  "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1489   || (GET_CODE (operands[1]) != MEM)"
1490  "*
1491{
1492  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1493
1494  /* First handle a `pop' insn or a `fld %st(0)' */
1495
1496  if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1497    {
1498      if (stack_top_dies)
1499	return AS1 (fstp,%y0);
1500      else
1501        return AS1 (fld,%y0);
1502    }
1503
1504  /* Handle other kinds of writes from the 387 */
1505
1506  if (STACK_TOP_P (operands[1]))
1507    {
1508      if (stack_top_dies)
1509	return AS1 (fstp%z0,%y0);
1510      else
1511        return AS1 (fst%z0,%y0);
1512    }
1513
1514  /* Handle other kinds of reads to the 387 */
1515
1516  if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1517    return output_move_const_single (operands);
1518
1519  if (STACK_TOP_P (operands[0]))
1520    return AS1 (fld%z1,%y1);
1521
1522  /* Handle all DFmode moves not involving the 387 */
1523
1524  return output_move_double (operands);
1525}"
1526  [(set_attr "type" "fld")])
1527
1528
1529
1530(define_insn "swapdf"
1531  [(set (match_operand:DF 0 "register_operand" "f")
1532	(match_operand:DF 1 "register_operand" "f"))
1533   (set (match_dup 1)
1534	(match_dup 0))]
1535  ""
1536  "*
1537{
1538  if (STACK_TOP_P (operands[0]))
1539    return AS1 (fxch,%1);
1540  else
1541    return AS1 (fxch,%0);
1542}")
1543
1544(define_insn "movxf_push"
1545  [(set (match_operand:XF 0 "push_operand" "=<,<")
1546 	(match_operand:XF 1 "general_operand" "*rfF,o"))]
1547  "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM 
1548   || reload_in_progress || reload_completed"
1549  "*
1550{
1551  if (STACK_REG_P (operands[1]))
1552    {
1553      rtx xops[3];
1554
1555      xops[0] = AT_SP (XFmode);
1556      xops[1] = GEN_INT (12);
1557      xops[2] = stack_pointer_rtx;
1558
1559      output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1560
1561      output_asm_insn (AS1 (fstp%T0,%0), xops);
1562      if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1563	output_asm_insn (AS1 (fld%T0,%0), xops);
1564
1565      RET;
1566    }
1567
1568  if (which_alternative == 1)
1569    return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 0, 0);
1570
1571  return output_move_double (operands);
1572 }")
1573
1574(define_split
1575  [(set (match_operand:XF 0 "push_operand" "")
1576        (match_operand:XF 1 "register_operand" ""))]
1577  "reload_completed && STACK_REG_P (operands[1])"
1578  [(set (reg:SI 7)
1579        (minus:SI (reg:SI 7) (const_int 12)))
1580   (set (mem:XF (reg:SI 7))
1581        (match_dup 1))]
1582  "")
1583
1584(define_expand "movxf"
1585  [(set (match_operand:XF 0 "general_operand" "")
1586	(match_operand:XF 1 "general_operand" ""))]
1587  ""
1588  "
1589{
1590  /* Don't generate memory->memory moves, go through a register */
1591  if (TARGET_MOVE
1592      && no_new_pseudos == 0
1593      && GET_CODE (operands[0]) == MEM
1594      && GET_CODE (operands[1]) == MEM)
1595    {
1596      operands[1] = force_reg (XFmode, operands[1]);
1597    }
1598
1599  /* If we are loading a floating point constant that isn't 0 or 1
1600     into a register, indicate we need the pic register loaded.  This could
1601     be optimized into stores of constants if the target eventually moves
1602     to memory, but better safe than sorry.  */
1603  else if ((reload_in_progress | reload_completed) == 0
1604	   && GET_CODE (operands[0]) != MEM
1605	   && GET_CODE (operands[1]) == CONST_DOUBLE
1606	   && !standard_80387_constant_p (operands[1]))
1607    {
1608      operands[1] = validize_mem (force_const_mem (XFmode, operands[1]));
1609    }
1610}")
1611
1612
1613(define_insn ""
1614  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!*r,!o")
1615	(match_operand:XF 1 "general_operand" "fmG,f,*roF,*rF"))]
1616  "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1617   || (GET_CODE (operands[1]) != MEM)"
1618  "*
1619{
1620  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1621
1622  /* First handle a `pop' insn or a `fld %st(0)' */
1623
1624  if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1625    {
1626      if (stack_top_dies)
1627	return AS1 (fstp,%y0);
1628      else
1629        return AS1 (fld,%y0);
1630    }
1631
1632  /* Handle other kinds of writes from the 387 */
1633
1634  if (STACK_TOP_P (operands[1]))
1635    {
1636      output_asm_insn (AS1 (fstp%z0,%y0), operands);
1637      if (! stack_top_dies)
1638	return AS1 (fld%z0,%y0);
1639
1640      RET;
1641    }
1642
1643  /* Handle other kinds of reads to the 387 */
1644
1645  if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1646    return output_move_const_single (operands);
1647
1648  if (STACK_TOP_P (operands[0]))
1649       return AS1 (fld%z1,%y1);
1650
1651  /* Handle all XFmode moves not involving the 387 */
1652
1653  return output_move_double (operands);
1654}")
1655
1656(define_insn "swapxf" 
1657  [(set (match_operand:XF 0 "register_operand" "f")
1658	(match_operand:XF 1 "register_operand" "f"))
1659   (set (match_dup 1)
1660	(match_dup 0))]
1661  ""
1662  "*
1663{
1664  if (STACK_TOP_P (operands[0]))
1665    return AS1 (fxch,%1);
1666  else
1667    return AS1 (fxch,%0);
1668}")
1669
1670(define_insn ""
1671  [(set (match_operand:DI 0 "push_operand" "=<")
1672	(match_operand:DI 1 "general_operand" "riF"))]
1673  ""
1674  "* return output_move_double (operands);")
1675
1676(define_insn ""
1677  [(set (match_operand:DI 0 "push_operand" "=<")
1678	(match_operand:DI 1 "memory_operand" "o"))]
1679  "TARGET_PUSH_MEMORY"
1680  "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode),0,0);")
1681
1682(define_expand "movdi"
1683  [(set (match_operand:DI 0 "general_operand" "")
1684	(match_operand:DI 1 "general_operand" ""))]
1685  ""
1686  "
1687{
1688  /* Don't generate memory->memory moves, go through a register */
1689  if (TARGET_MOVE
1690      && no_new_pseudos == 0
1691      && GET_CODE (operands[0]) == MEM
1692      && GET_CODE (operands[1]) == MEM)
1693    {
1694      operands[1] = force_reg (DImode, operands[1]);
1695    }
1696}")
1697
1698(define_insn ""
1699  [(set (match_operand:DI 0 "general_operand" "=g,r")
1700	(match_operand:DI 1 "general_operand" "riF,m"))]
1701  "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1702   || (GET_CODE (operands[1]) != MEM)"
1703  "* return output_move_double (operands);"
1704  [(set_attr "type" "integer,memory")
1705   (set_attr "memory" "*,load")])
1706
1707(define_split
1708  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1709	(match_operand:DI 1 "general_operand" ""))]
1710  "reload_completed
1711   && (offsettable_memref_p (operands[0])
1712       || nonmemory_operand (operands[0], DImode))
1713   && (offsettable_memref_p (operands[1])
1714       || nonmemory_operand (operands[1], DImode))
1715   && (! reg_overlap_mentioned_p (gen_lowpart (SImode, operands[0]),
1716				  operands[1])
1717       || ! reg_overlap_mentioned_p (gen_highpart (SImode, operands[0]),
1718				     operands[1]))"
1719  [(set (match_dup 2)
1720	(match_dup 4))
1721   (set (match_dup 3)
1722	(match_dup 5))]
1723  "
1724{
1725  split_di (&operands[0], 1, &operands[2], &operands[3]);
1726  split_di (&operands[1], 1, &operands[4], &operands[5]);
1727
1728  if (reg_overlap_mentioned_p (operands[2], operands[1]))
1729    {
1730    rtx tmp;
1731
1732    tmp = operands[2];
1733    operands[2] = operands[3];
1734    operands[3] = tmp;
1735
1736    tmp = operands[4];
1737    operands[4] = operands[5];
1738    operands[5] = tmp;
1739    }
1740}")
1741
1742;;- conversion instructions
1743;;- NONE
1744
1745;;- zero extension instructions
1746;; See comments by `andsi' for when andl is faster than movzx.
1747
1748(define_expand "zero_extendhisi2"
1749  [(set (match_operand:SI 0 "register_operand" "")
1750	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1751  ""
1752  "")
1753
1754;; When optimizing for the PPro/PII or code size, always use movzwl.
1755;; We want to use a different pattern so we can use different constraints
1756;; than the generic pattern.
1757(define_insn ""
1758  [(set (match_operand:SI 0 "register_operand" "=r")
1759	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
1760  "(optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1761  "* return AS2 (movz%W0%L0,%1,%0);")
1762
1763(define_insn ""
1764  [(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
1765	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
1766  "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1767  "*
1768  {
1769  rtx xops[2];
1770
1771  if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) 
1772      && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1773    {
1774      xops[0] = operands[0];
1775      xops[1] = GEN_INT (0xffff);
1776      output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1777      RET;
1778    }
1779  if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1]))
1780    {
1781      output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1782      output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1783      RET;
1784    }
1785
1786  if (TARGET_ZERO_EXTEND_WITH_AND)
1787    {
1788      xops[0] = operands[0];
1789      xops[1] = GEN_INT (0xffff);
1790      if (i386_aligned_p (operands[1]))
1791	output_asm_insn (AS2 (mov%L0,%k1,%k0),operands);
1792      else
1793	output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1794      output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1795      RET;
1796    }
1797
1798#ifdef INTEL_SYNTAX
1799  return AS2 (movzx,%1,%0);
1800#else
1801  return AS2 (movz%W0%L0,%1,%0);
1802#endif
1803}")
1804
1805(define_split
1806  [(set (match_operand:SI 0 "register_operand" "")
1807	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1808 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])"
1809 [(set (match_dup 0)
1810       (const_int 0))
1811  (set (strict_low_part (match_dup 2))
1812       (match_dup 1))]
1813 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1814
1815
1816(define_split
1817  [(set (match_operand:SI 0 "register_operand" "")
1818	(zero_extend:SI (match_operand:HI 1 "memory_operand" "")))]
1819 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])"
1820 [(set (strict_low_part (match_dup 2))
1821       (match_dup 1))
1822  (set (match_dup 0)
1823       (and:SI (match_dup 0)
1824	       (const_int 65535)))]
1825  "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1826
1827(define_expand "zero_extendqihi2"
1828  [(set (match_operand:HI 0 "register_operand" "")
1829	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1830  ""
1831  "")
1832
1833(define_insn ""
1834  [(set (match_operand:HI 0 "register_operand" "=r")
1835	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1836  "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
1837
1838  "*  return AS2 (movz%B0%W0,%1,%0);")
1839
1840(define_insn ""
1841  [(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
1842	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1843  "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1844  "*
1845  {
1846  rtx xops[2];
1847
1848  if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1849      && REG_P (operands[1]) 
1850      && REGNO (operands[0]) == REGNO (operands[1]))
1851    {
1852      xops[0] = operands[0];
1853      xops[1] = GEN_INT (0xff);
1854      output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1855      RET;
1856    }
1857  if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1858    {
1859      if(!reg_overlap_mentioned_p(operands[0],operands[1]))
1860	{
1861	  output_asm_insn (AS2 (xor%L0,%k0,%k0), operands);
1862	  output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1863	}
1864      else
1865	{
1866	  xops[0] = operands[0];
1867	  xops[1] = GEN_INT (0xff);
1868	  output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1869	  output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1870	}
1871      RET;
1872    }
1873  
1874#ifdef INTEL_SYNTAX
1875  return AS2 (movzx,%1,%0);
1876#else
1877  return AS2 (movz%B0%W0,%1,%0);
1878#endif
1879}")
1880
1881(define_split
1882  [(set (match_operand:HI 0 "register_operand" "")
1883	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1884 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1885  && !reg_overlap_mentioned_p (operands[0], operands[1])"
1886 [(set (match_dup 0)
1887       (const_int 0))
1888  (set (strict_low_part (match_dup 2))
1889       (match_dup 1))]
1890 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1891
1892
1893(define_split
1894  [(set (match_operand:HI 0 "register_operand" "")
1895	(zero_extend:HI (match_operand:QI 1 "memory_operand" "")))]
1896 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1897  && reg_overlap_mentioned_p (operands[0], operands[1])"
1898 [(set (strict_low_part (match_dup 2))
1899       (match_dup 1))
1900  (set (match_dup 0)
1901       (and:HI (match_dup 0)
1902	       (const_int 255)))]
1903 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1904
1905(define_split
1906  [(set (match_operand:HI 0 "register_operand" "")
1907	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1908 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND"
1909 [(set (match_dup 0)
1910       (match_dup 2))
1911  (set (match_dup 0)
1912       (and:HI (match_dup 0)
1913	       (const_int 255)))]
1914 "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0)
1915    operands[1] = SUBREG_REG (operands[1]);
1916  if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG
1917      || REGNO (operands[0]) == REGNO (operands[1]))
1918    FAIL;
1919  operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));")
1920
1921(define_expand "zero_extendqisi2"
1922  [(set (match_operand:SI 0 "register_operand" "")
1923	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1924  ""
1925  "")
1926
1927(define_insn ""
1928  [(set (match_operand:SI 0 "register_operand" "=r")
1929	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1930  "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
1931  "* return AS2 (movz%B0%L0,%1,%0);")
1932
1933(define_insn ""
1934  [(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
1935	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1936  "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1937  "*
1938  {
1939  rtx xops[2];
1940
1941  if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1942      && REG_P (operands[1]) 
1943      && REGNO (operands[0]) == REGNO (operands[1]))
1944    {
1945      xops[0] = operands[0];
1946      xops[1] = GEN_INT (0xff);
1947      output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1948      RET;
1949    }
1950  if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1951    {
1952      if(!reg_overlap_mentioned_p (operands[0], operands[1]))
1953	{
1954	  output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1955	  output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1956	}
1957      else
1958	{
1959	  xops[0] = operands[0];
1960	  xops[1] = GEN_INT (0xff);
1961	  output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1962	  output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1963	}
1964      RET;
1965    }
1966
1967  if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG)
1968    {
1969      xops[0] = operands[0];
1970      xops[1] = GEN_INT (0xff);
1971      operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
1972      output_asm_insn (AS2 (mov%L0,%1,%0), operands);
1973      output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1974      RET;
1975    }
1976
1977#ifdef INTEL_SYNTAX
1978  return AS2 (movzx,%1,%0);
1979#else
1980  return AS2 (movz%B0%L0,%1,%0);
1981#endif
1982}")
1983
1984(define_split
1985  [(set (match_operand:SI 0 "register_operand" "")
1986	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1987 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1988  && !reg_overlap_mentioned_p (operands[0], operands[1])"
1989 [(set (match_dup 0)
1990       (const_int 0))
1991  (set (strict_low_part (match_dup 2))
1992       (match_dup 1))]
1993 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1994
1995
1996(define_split
1997  [(set (match_operand:SI 0 "register_operand" "")
1998	(zero_extend:SI (match_operand:QI 1 "memory_operand" "")))]
1999 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
2000  && reg_overlap_mentioned_p (operands[0], operands[1])"
2001 [(set (strict_low_part (match_dup 2))
2002       (match_dup 1))
2003  (set (match_dup 0)
2004       (and:SI (match_dup 0)
2005	       (const_int 255)))]
2006 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2007
2008(define_split
2009  [(set (match_operand:SI 0 "register_operand" "")
2010	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2011 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
2012  && ! reg_overlap_mentioned_p (operands[0], operands[1])"
2013 [(set (match_dup 0)
2014       (match_dup 2))
2015  (set (match_dup 0)
2016       (and:SI (match_dup 0)
2017	       (const_int 255)))]
2018 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
2019
2020(define_insn "zero_extendsidi2"
2021  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
2022	(zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))]
2023  ""
2024  "#")
2025
2026(define_split 
2027  [(set (match_operand:DI 0 "register_operand" "")
2028	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2029  "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
2030  [(set (match_dup 4) (const_int 0))]
2031  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2032
2033(define_split 
2034  [(set (match_operand:DI 0 "nonimmediate_operand" "")
2035	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
2036  "reload_completed"
2037  [(set (match_dup 3) (match_dup 1))
2038   (set (match_dup 4) (const_int 0))]
2039  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2040
2041;;- sign extension instructions
2042
2043(define_insn "extendsidi2"
2044  [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*o")
2045	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,*r")))
2046   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
2047  ""
2048  "#")
2049
2050;; Extend to memory case when source register does die.
2051(define_split 
2052  [(set (match_operand:DI 0 "memory_operand" "")
2053	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2054   (clobber (match_operand:SI 2 "register_operand" ""))]
2055  "(flow2_completed
2056    && dead_or_set_p (insn, operands[1])
2057    && !reg_mentioned_p (operands[1], operands[0]))"
2058  [(set (match_dup 3) (match_dup 1))
2059   (set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
2060   (set (match_dup 4) (match_dup 1))]
2061  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2062
2063;; Extend to memory case when source register does not die.
2064(define_split 
2065  [(set (match_operand:DI 0 "memory_operand" "")
2066	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2067   (clobber (match_operand:SI 2 "register_operand" ""))]
2068  "flow2_completed"
2069  [(const_int 0)]
2070  "
2071{
2072  split_di (&operands[0], 1, &operands[3], &operands[4]);
2073
2074  emit_move_insn (operands[3], operands[1]);
2075
2076  /* Generate a cltd if possible and doing so it profitable.  */
2077  if (true_regnum (operands[1]) == 0
2078      && true_regnum (operands[2]) == 1
2079      && (optimize_size || !TARGET_PENTIUM))
2080    {
2081      emit_insn (gen_ashrsi3_31 (operands[2], operands[1]));
2082    }
2083  else
2084    {
2085      emit_move_insn (operands[2], operands[1]);
2086      emit_insn (gen_ashrsi3_31 (operands[2], operands[2]));
2087    }
2088  emit_move_insn (operands[4], operands[2]);
2089  DONE;
2090}")
2091
2092;; Extend to register case.  Optimize case where source and destination
2093;; registers match and cases where we can use cltd.
2094(define_split 
2095  [(set (match_operand:DI 0 "register_operand" "")
2096	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2097   (clobber (match_scratch:SI 2 ""))]
2098  "reload_completed"
2099  [(const_int 0)]
2100  "
2101{
2102  split_di (&operands[0], 1, &operands[3], &operands[4]);
2103
2104  if (true_regnum (operands[3]) != true_regnum (operands[1]))
2105    emit_move_insn (operands[3], operands[1]);
2106
2107  /* Generate a cltd if possible and doing so it profitable.  */
2108  if (true_regnum (operands[3]) == 0
2109      && (optimize_size || !TARGET_PENTIUM))
2110    {
2111      emit_insn (gen_ashrsi3_31 (operands[4], operands[3]));
2112      DONE;
2113    }
2114
2115  if (true_regnum (operands[4]) != true_regnum (operands[1]))
2116    emit_move_insn (operands[4], operands[1]);
2117
2118  emit_insn (gen_ashrsi3_31 (operands[4], operands[4]));
2119  DONE;
2120}")
2121
2122;; Note that the i386 programmers' manual says that the opcodes
2123;; are named movsx..., but the assembler on Unix does not accept that.
2124;; We use what the Unix assembler expects.
2125
2126(define_insn "extendhisi2"
2127  [(set (match_operand:SI 0 "register_operand" "=r")
2128	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2129  ""
2130  "*
2131{
2132  if (REGNO (operands[0]) == 0
2133      && REG_P (operands[1]) && REGNO (operands[1]) == 0
2134      && (optimize_size || ix86_cpu != PROCESSOR_K6))
2135#ifdef INTEL_SYNTAX
2136    return \"cwde\";
2137#else
2138    return \"cwtl\";
2139#endif
2140
2141#ifdef INTEL_SYNTAX
2142  return AS2 (movsx,%1,%0);
2143#else
2144  return AS2 (movs%W0%L0,%1,%0);
2145#endif
2146}")
2147
2148(define_insn "extendqihi2"
2149  [(set (match_operand:HI 0 "register_operand" "=r")
2150	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2151  ""
2152  "*
2153{
2154  if (REGNO (operands[0]) == 0
2155      && REG_P (operands[1]) && REGNO (operands[1]) == 0
2156      && (optimize_size || ix86_cpu != PROCESSOR_K6))
2157    return \"cbtw\";
2158
2159#ifdef INTEL_SYNTAX
2160  return AS2 (movsx,%1,%0);
2161#else
2162  return AS2 (movs%B0%W0,%1,%0);
2163#endif
2164}")
2165
2166(define_insn "extendqisi2"
2167  [(set (match_operand:SI 0 "register_operand" "=r")
2168	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2169  ""
2170  "*
2171{
2172#ifdef INTEL_SYNTAX
2173  return AS2 (movsx,%1,%0);
2174#else
2175  return AS2 (movs%B0%L0,%1,%0);
2176#endif
2177}")
2178
2179
2180;; Truncation of long long -> 32 bit
2181
2182(define_expand "truncdisi2"
2183  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2184	(truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2185  ""
2186  "
2187{
2188  /* Don't generate memory->memory moves, go through a register */
2189  if (TARGET_MOVE
2190      && (reload_in_progress | reload_completed) == 0
2191      && GET_CODE (operands[0]) == MEM
2192      && GET_CODE (operands[1]) == MEM)
2193    {
2194      rtx target = gen_reg_rtx (SImode);
2195      emit_insn (gen_truncdisi2 (target, operands[1]));
2196      emit_move_insn (operands[0], target);
2197      DONE;
2198    }
2199}")
2200
2201(define_insn ""
2202  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2203	(truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2204  "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2205  "*
2206{
2207  rtx low[2], high[2], xops[2];
2208
2209  split_di (&operands[1], 1, low, high);
2210  xops[0] = operands[0];
2211  xops[1] = low[0];
2212  if (!rtx_equal_p (xops[0], xops[1]))
2213    output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2214
2215  RET;
2216}")
2217
2218(define_insn ""
2219  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2220	(truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
2221				  (const_int 32))))]
2222  "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2223  "*
2224{
2225  rtx low[2], high[2], xops[2];
2226
2227  split_di (&operands[1], 1, low, high);
2228  xops[0] = operands[0];
2229  xops[1] = high[0];
2230  if (!rtx_equal_p (xops[0], xops[1]))
2231    output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2232
2233  RET;
2234}")
2235
2236
2237
2238;; Conversions between float and double.
2239
2240(define_expand "extendsfdf2"
2241  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2242		   (float_extend:DF
2243		     (match_operand:SF 1 "nonimmediate_operand" "")))
2244     (clobber (match_dup 2))
2245     (clobber (match_dup 3))])]
2246  "TARGET_80387"
2247  "
2248{
2249  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2250    operands[1] = force_reg (SFmode, operands[1]);
2251
2252  operands[2] = assign_386_stack_local (SFmode, 0);
2253  operands[3] = assign_386_stack_local (DFmode, 0);
2254}")
2255
2256(define_insn ""
2257  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!f,!*r")
2258	(float_extend:DF
2259	  (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f")))
2260   (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m"))
2261   (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))]
2262  "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2263		    || GET_CODE (operands[1]) != MEM)"
2264  "*
2265{
2266  output_float_extend (insn, operands);
2267  return \"\";
2268}"
2269  [(set_attr "type" "fld,fpop,fld,fpop")])
2270
2271(define_split
2272  [(set (match_operand:DF 0 "register_operand" "")
2273	(float_extend:DF (match_operand:SF 1 "register_operand" "")))
2274   (clobber (match_operand:SF 2 "memory_operand" ""))
2275   (clobber (match_operand:DF 3 "memory_operand" ""))]
2276  "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
2277  [(set (match_dup 2)
2278	(match_dup 1))
2279   (set (match_dup 0)
2280	(float_extend:DF (match_dup 2)))]
2281  "")
2282
2283(define_split
2284  [(set (match_operand:DF 0 "register_operand" "")
2285	(float_extend:DF (match_operand:SF 1 "register_operand" "")))
2286   (clobber (match_operand:SF 2 "memory_operand" ""))
2287   (clobber (match_operand:DF 3 "memory_operand" ""))]
2288  "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
2289  [(set (match_dup 3)
2290	(float_extend:DF (match_dup 1)))
2291   (set (match_dup 0)
2292	(match_dup 3))]
2293  "")
2294
2295(define_split
2296  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2297	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))
2298   (clobber (match_operand:SF 2 "memory_operand" ""))
2299   (clobber (match_operand:DF 3 "memory_operand" ""))]
2300  "TARGET_80387 && reload_completed"
2301  [(set (match_dup 0)
2302	(float_extend:DF (match_dup 1)))]
2303  "")
2304
2305(define_insn ""
2306  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
2307	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2308  "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2309		    || GET_CODE (operands[1]) != MEM)"
2310  "*
2311{
2312    output_float_extend (insn, operands);
2313    return \"\";
2314}"
2315  [(set_attr "type" "fld,fpop")])
2316
2317(define_expand "extenddfxf2"
2318  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
2319		   (float_extend:XF
2320		     (match_operand:DF 1 "nonimmediate_operand" "")))
2321     (clobber (match_dup 2))
2322     (clobber (match_dup 3))])]
2323  "TARGET_80387"
2324  "
2325{
2326  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2327    operands[1] = force_reg (DFmode, operands[1]);
2328
2329  operands[2] = assign_386_stack_local (DFmode, 0);
2330  operands[3] = assign_386_stack_local (XFmode, 0);
2331}")
2332
2333(define_insn ""
2334  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r")
2335	(float_extend:XF
2336	  (match_operand:DF 1 "nonimmediate_operand" "fm,f,*r,f")))
2337   (clobber (match_operand:DF 2 "memory_operand" "m,m,o,m"))
2338   (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
2339  "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2340		    || GET_CODE (operands[1]) != MEM)"
2341  "*
2342{
2343    output_float_extend (insn, operands);
2344    return \"\";
2345}"
2346  [(set_attr "type" "fld,fpop,fld,fpop")])
2347
2348(define_split
2349  [(set (match_operand:XF 0 "register_operand" "")
2350	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
2351   (clobber (match_operand:DF 2 "memory_operand" ""))
2352   (clobber (match_operand:XF 3 "memory_operand" ""))]
2353  "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
2354  [(set (match_dup 2)
2355	(match_dup 1))
2356   (set (match_dup 0)
2357	(float_extend:XF (match_dup 2)))]
2358  "")
2359
2360(define_split
2361  [(set (match_operand:XF 0 "register_operand" "")
2362	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
2363   (clobber (match_operand:DF 2 "memory_operand" ""))
2364   (clobber (match_operand:XF 3 "memory_operand" ""))]
2365  "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
2366  [(set (match_dup 3)
2367	(float_extend:XF (match_dup 1)))
2368   (set (match_dup 0)
2369	(match_dup 3))]
2370  "")
2371
2372(define_split
2373  [(set (match_operand:XF 0 "nonimmediate_operand" "")
2374	(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))
2375   (clobber (match_operand:DF 2 "memory_operand" ""))
2376   (clobber (match_operand:XF 3 "memory_operand" ""))]
2377  "TARGET_80387 && reload_completed"
2378  [(set (match_dup 0)
2379	(float_extend:XF (match_dup 1)))]
2380  "")
2381
2382(define_insn ""
2383  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
2384	(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
2385  "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2386		    || GET_CODE (operands[1]) != MEM)"
2387  "*
2388{
2389    output_float_extend (insn, operands);
2390    return \"\";
2391}"
2392  [(set_attr "type" "fld,fpop")])
2393
2394(define_expand "extendsfxf2"
2395  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
2396		   (float_extend:XF
2397		     (match_operand:SF 1 "nonimmediate_operand" "")))
2398     (clobber (match_dup 2))
2399     (clobber (match_dup 3))])]
2400  "TARGET_80387"
2401  "
2402{
2403  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2404    operands[1] = force_reg (SFmode, operands[1]);
2405
2406  operands[2] = assign_386_stack_local (SFmode, 0);
2407  operands[3] = assign_386_stack_local (XFmode, 0);
2408}")
2409
2410(define_insn ""
2411  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r")
2412	(float_extend:XF
2413	  (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f")))
2414   (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m"))
2415   (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
2416  "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2417		    || GET_CODE (operands[1]) != MEM)"
2418  "*
2419{
2420    output_float_extend (insn, operands);
2421    return \"\";
2422}"
2423  [(set_attr "type" "fld,fpop,fld,fpop")])
2424
2425(define_split
2426  [(set (match_operand:XF 0 "register_operand" "")
2427	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
2428   (clobber (match_operand:SF 2 "memory_operand" ""))
2429   (clobber (match_operand:XF 3 "memory_operand" ""))]
2430  "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
2431  [(set (match_dup 2)
2432	(match_dup 1))
2433   (set (match_dup 0)
2434	(float_extend:XF (match_dup 2)))]
2435  "")
2436
2437(define_split
2438  [(set (match_operand:XF 0 "register_operand" "")
2439	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
2440   (clobber (match_operand:SF 2 "memory_operand" ""))
2441   (clobber (match_operand:XF 3 "memory_operand" ""))]
2442  "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
2443  [(set (match_dup 3)
2444	(float_extend:XF (match_dup 1)))
2445   (set (match_dup 0)
2446	(match_dup 3))]
2447  "")
2448
2449(define_split
2450  [(set (match_operand:XF 0 "nonimmediate_operand" "")
2451	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))
2452   (clobber (match_operand:SF 2 "memory_operand" ""))
2453   (clobber (match_operand:XF 3 "memory_operand" ""))]
2454  "TARGET_80387 && reload_completed"
2455  [(set (match_dup 0)
2456	(float_extend:XF (match_dup 1)))]
2457  "")
2458
2459(define_insn ""
2460  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
2461	(float_extend:XF
2462	 (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2463  "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2464		    || GET_CODE (operands[1]) != MEM)"
2465  "*
2466{
2467    output_float_extend (insn, operands);
2468    return \"\";
2469}"
2470  [(set_attr "type" "fld,fpop")])
2471
2472(define_expand "truncdfsf2"
2473  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2474		   (float_truncate:SF
2475		    (match_operand:DF 1 "register_operand" "")))
2476	      (clobber (match_dup 2))])]
2477  "TARGET_80387"
2478  "
2479{
2480  operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2481}")
2482
2483(define_insn ""
2484  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r")
2485	(float_truncate:SF
2486	  (match_operand:DF 1 "register_operand" "0,f,f")))
2487   (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))]
2488  "TARGET_80387"
2489  "*
2490{
2491  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2492  rtx xops[1];
2493
2494  xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
2495
2496  if (stack_top_dies || STACK_REG_P (operands[0]))
2497    output_asm_insn (AS1 (fstp%z0,%0), xops);
2498  else
2499    output_asm_insn (AS1 (fst%z0,%0), xops);
2500
2501  if (STACK_REG_P (operands[0]))
2502    return AS1 (fld%z2,%2);
2503  else if (NON_STACK_REG_P (operands[0]))
2504    return AS2 (mov%L0,%2,%0);
2505
2506  return \"\";
2507}"
2508  [(set_attr "type" "fpop")])
2509
2510(define_split
2511  [(set (match_operand:SF 0 "register_operand" "")
2512	(float_truncate:SF (match_operand:DF 1 "register_operand" "")))
2513   (clobber (match_operand:SF 2 "memory_operand" ""))]
2514  "TARGET_80387 && reload_completed"
2515  [(set (match_dup 2)
2516	(float_truncate:SF (match_dup 1)))
2517   (set (match_dup 0)
2518	(match_dup 2))]
2519  "")
2520
2521(define_split
2522  [(set (match_operand:SF 0 "memory_operand" "")
2523	(float_truncate:SF (match_operand:DF 1 "register_operand" "")))
2524   (clobber (match_operand:SF 2 "memory_operand" ""))]
2525  "TARGET_80387 && reload_completed"
2526  [(set (match_dup 0)
2527	(float_truncate:SF (match_dup 1)))]
2528  "")
2529
2530;; This cannot output into an f-reg because there is no way to be sure
2531;; of truncating in that case.
2532
2533(define_insn ""
2534  [(set (match_operand:SF 0 "memory_operand" "=m")
2535	(float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2536  "TARGET_80387"
2537  "*
2538{
2539  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2540
2541  if (stack_top_dies)
2542    return AS1 (fstp%z0,%0);
2543  else
2544    return AS1 (fst%z0,%0);
2545}"
2546  [(set_attr "type" "fpop")])
2547
2548(define_expand "truncxfsf2"
2549  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2550		   (float_truncate:SF
2551		    (match_operand:XF 1 "register_operand" "")))
2552	      (clobber (match_dup 2))])]
2553  "TARGET_80387"
2554  "
2555{
2556  operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2557}")
2558
2559(define_insn ""
2560  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r")
2561	(float_truncate:SF
2562	  (match_operand:XF 1 "register_operand" "0,f,f")))
2563   (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))]
2564  "TARGET_80387"
2565  "*
2566{
2567  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2568  rtx xops[1];
2569
2570  xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
2571
2572  if (stack_top_dies || STACK_REG_P (operands[0]))
2573    output_asm_insn (AS1 (fstp%z0,%0), xops);
2574  else
2575    output_asm_insn (AS1 (fst%z0,%0), xops);
2576
2577  if (STACK_REG_P (operands[0]))
2578    return AS1 (fld%z2,%2);
2579  else if (NON_STACK_REG_P (operands[0]))
2580    return AS2 (mov%L0,%2,%0);
2581
2582  return \"\";
2583}"
2584  [(set_attr "type" "fpop")])
2585
2586(define_split
2587  [(set (match_operand:SF 0 "register_operand" "")
2588	(float_truncate:SF (match_operand:XF 1 "register_operand" "")))
2589   (clobber (match_operand:SF 2 "memory_operand" ""))]
2590  "TARGET_80387 && reload_completed"
2591  [(set (match_dup 2)
2592	(float_truncate:SF (match_dup 1)))
2593   (set (match_dup 0)
2594	(match_dup 2))]
2595  "")
2596
2597(define_split
2598  [(set (match_operand:SF 0 "memory_operand" "")
2599	(float_truncate:SF (match_operand:XF 1 "register_operand" "")))
2600   (clobber (match_operand:SF 2 "memory_operand" ""))]
2601  "TARGET_80387 && reload_completed"
2602  [(set (match_dup 0)
2603	(float_truncate:SF (match_dup 1)))]
2604  "")
2605
2606(define_insn ""
2607  [(set (match_operand:SF 0 "memory_operand" "=m")
2608	(float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
2609  "TARGET_80387"
2610  "*
2611{
2612  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2613
2614  if (stack_top_dies)
2615    return AS1 (fstp%z0,%0);
2616  else
2617    return AS1 (fst%z0,%0);
2618}"
2619  [(set_attr "type" "fpop")])
2620
2621(define_expand "truncxfdf2"
2622  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2623		   (float_truncate:DF
2624		    (match_operand:XF 1 "register_operand" "")))
2625	      (clobber (match_dup 2))])]
2626  "TARGET_80387"
2627  "
2628{
2629  operands[2] = (rtx) assign_386_stack_local (DFmode, 0);
2630}")
2631
2632(define_insn ""
2633  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r")
2634	(float_truncate:DF
2635	  (match_operand:XF 1 "register_operand" "0,f,f")))
2636   (clobber (match_operand:DF 2 "memory_operand" "m,m,o"))]
2637  "TARGET_80387"
2638  "*
2639{
2640  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2641  rtx xops[2];
2642
2643  xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
2644
2645  if (stack_top_dies || STACK_REG_P (operands[0]))
2646    output_asm_insn (AS1 (fstp%z0,%0), xops);
2647  else
2648    output_asm_insn (AS1 (fst%z0,%0), xops);
2649
2650  if (STACK_REG_P (operands[0]))
2651    return AS1 (fld%z2,%2);
2652  else if (NON_STACK_REG_P (operands[0]))
2653    {
2654    xops[0] = operands[0];
2655    xops[1] = operands[2];
2656    output_asm_insn (output_move_double (xops), xops);
2657    }
2658
2659  return \"\";
2660}"
2661  [(set_attr "type" "fpop")])
2662
2663(define_split
2664  [(set (match_operand:DF 0 "register_operand" "")
2665	(float_truncate:DF (match_operand:XF 1 "register_operand" "")))
2666   (clobber (match_operand:DF 2 "memory_operand" ""))]
2667  "TARGET_80387 && reload_completed"
2668  [(set (match_dup 2)
2669	(float_truncate:DF (match_dup 1)))
2670   (set (match_dup 0)
2671	(match_dup 2))]
2672  "")
2673
2674(define_split
2675  [(set (match_operand:DF 0 "memory_operand" "")
2676	(float_truncate:DF (match_operand:XF 1 "register_operand" "")))
2677   (clobber (match_operand:DF 2 "memory_operand" ""))]
2678  "TARGET_80387 && reload_completed"
2679  [(set (match_dup 0)
2680	(float_truncate:DF (match_dup 1)))]
2681  "")
2682
2683(define_insn ""
2684  [(set (match_operand:DF 0 "memory_operand" "=m")
2685	(float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
2686  "TARGET_80387"
2687  "*
2688{
2689  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2690
2691  if (stack_top_dies)
2692    return AS1 (fstp%z0,%0);
2693  else
2694    return AS1 (fst%z0,%0);
2695}"
2696  [(set_attr "type" "fpop")])
2697
2698;; Conversions between floating point and fix point.
2699
2700(define_expand "fix_truncsfsi2"
2701  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2702		   (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))
2703	      (clobber (match_dup 2))
2704	      (clobber (match_dup 3))
2705	      (clobber (match_dup 4))
2706	      (clobber (match_scratch:HI 5 ""))])]
2707  "TARGET_80387"
2708  "
2709{
2710  operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2711  operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2712  operands[4] = (rtx) assign_386_stack_local (SImode, 0);
2713}")
2714
2715(define_insn ""
2716  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r")
2717	(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
2718   (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2719   (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2720   (clobber (match_operand:SI 4 "memory_operand" "m,m"))
2721   (clobber (match_scratch:HI 5 "=&r,&r"))]
2722  "TARGET_80387"
2723  "* return output_fix_trunc (insn, operands);"
2724  [(set_attr "type" "fpop")])
2725
2726(define_expand "fix_truncsfdi2"
2727  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2728		   (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
2729	      (clobber (match_dup 1))
2730	      (clobber (match_dup 2))
2731	      (clobber (match_dup 3))
2732	      (clobber (match_dup 4))
2733	      (clobber (match_scratch:HI 5 ""))])]
2734  "TARGET_80387"
2735  "
2736{
2737  operands[1] = copy_to_mode_reg (SFmode, operands[1]);
2738  operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2739  operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2740  operands[4] = (rtx) assign_386_stack_local (DImode, 0);
2741}")
2742
2743(define_insn ""
2744  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r")
2745	(fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
2746   (clobber (match_dup 1))
2747   (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2748   (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2749   (clobber (match_operand:DI 4 "memory_operand" "m,o"))
2750   (clobber (match_scratch:HI 5 "=&r,&r"))]
2751  "TARGET_80387"
2752  "* return output_fix_trunc (insn, operands);"
2753  [(set_attr "type" "fpop")])
2754
2755(define_expand "fix_truncdfsi2"
2756  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2757		   (fix:SI (fix:DF (match_operand:DF 1 "register_operand" ""))))
2758	      (clobber (match_dup 2))
2759	      (clobber (match_dup 3))
2760	      (clobber (match_dup 4))
2761	      (clobber (match_scratch:HI 5 ""))])]
2762  "TARGET_80387"
2763  "
2764{
2765  operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2766  operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2767  operands[4] = (rtx) assign_386_stack_local (SImode, 0);
2768}")
2769
2770(define_insn ""
2771  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r")
2772	(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
2773   (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2774   (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2775   (clobber (match_operand:SI 4 "memory_operand" "m,m"))
2776   (clobber (match_scratch:HI 5 "=&r,&r"))]
2777  "TARGET_80387"
2778  "* return output_fix_trunc (insn, operands);"
2779  [(set_attr "type" "fpop")])
2780
2781(define_expand "fix_truncdfdi2"
2782  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2783		   (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
2784	      (clobber (match_dup 1))
2785	      (clobber (match_dup 2))
2786	      (clobber (match_dup 3))
2787	      (clobber (match_dup 4))
2788	      (clobber (match_scratch:HI 5 ""))])]
2789  "TARGET_80387"
2790  "
2791{
2792  operands[1] = copy_to_mode_reg (DFmode, operands[1]);
2793  operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2794  operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2795  operands[4] = (rtx) assign_386_stack_local (DImode, 0);
2796}")
2797
2798(define_insn ""
2799  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r")
2800	(fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
2801   (clobber (match_dup 1))
2802   (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2803   (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2804   (clobber (match_operand:DI 4 "memory_operand" "m,o"))
2805   (clobber (match_scratch:HI 5 "=&r,&r"))]
2806  "TARGET_80387"
2807  "* return output_fix_trunc (insn, operands);"
2808  [(set_attr "type" "fpop")])
2809
2810(define_expand "fix_truncxfsi2"
2811  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2812		   (fix:SI (fix:XF (match_operand:XF 1 "register_operand" ""))))
2813	      (clobber (match_dup 2))
2814	      (clobber (match_dup 3))
2815	      (clobber (match_dup 4))
2816	      (clobber (match_scratch:HI 5 ""))])]
2817  "TARGET_80387"
2818  "
2819{
2820  operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2821  operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2822  operands[4] = (rtx) assign_386_stack_local (SImode, 0);
2823}")
2824
2825(define_insn ""
2826  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r")
2827	(fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
2828   (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2829   (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2830   (clobber (match_operand:SI 4 "memory_operand" "m,m"))
2831   (clobber (match_scratch:HI 5 "=&r,&r"))]
2832  "TARGET_80387"
2833  "* return output_fix_trunc (insn, operands);"
2834  [(set_attr "type" "fpop")])
2835
2836(define_expand "fix_truncxfdi2"
2837  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2838		   (fix:DI (fix:XF (match_operand:XF 1 "register_operand" ""))))
2839	      (clobber (match_dup 1))
2840	      (clobber (match_dup 2))
2841	      (clobber (match_dup 3))
2842	      (clobber (match_dup 4))
2843	      (clobber (match_scratch:HI 5 ""))])]
2844  "TARGET_80387"
2845  "
2846{
2847  operands[1] = copy_to_mode_reg (XFmode, operands[1]);
2848  operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2849  operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2850  operands[4] = (rtx) assign_386_stack_local (DImode, 0);
2851}")
2852
2853(define_insn ""
2854  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r")
2855	(fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
2856   (clobber (match_dup 1))
2857   (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2858   (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2859   (clobber (match_operand:DI 4 "memory_operand" "m,o"))
2860   (clobber (match_scratch:HI 5 "=&r,&r"))]
2861  "TARGET_80387"
2862  "* return output_fix_trunc (insn, operands);"
2863  [(set_attr "type" "fpop")])
2864
2865;; Conversion between fixed point and floating point.
2866
2867;; ??? Possibly represent floatunssidf2 here in gcc2.
2868
2869(define_expand "floatsisf2"
2870  [(parallel [(set (match_operand:SF 0 "register_operand" "")
2871		   (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))
2872	      (clobber (match_dup 2))])]
2873  "TARGET_80387"
2874  "operands[2] = assign_386_stack_local (SImode, 0);")
2875
2876(define_insn ""
2877  [(set (match_operand:SF 0 "register_operand" "=f,f")
2878	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
2879   (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
2880  "TARGET_80387"
2881  "#")
2882
2883(define_split
2884  [(set (match_operand:SF 0 "register_operand" "")
2885	(float:SF (match_operand:SI 1 "memory_operand" "")))
2886   (clobber (match_operand:SI 2 "memory_operand" ""))]
2887  "TARGET_80387 && reload_completed"
2888  [(set (match_dup 0)
2889	(float:SF (match_dup 1)))]
2890  "")
2891
2892(define_split
2893  [(set (match_operand:SF 0 "register_operand" "")
2894	(float:SF (match_operand:SI 1 "register_operand" "")))
2895   (clobber (match_operand:SI 2 "memory_operand" ""))]
2896  "TARGET_80387 && reload_completed"
2897  [(set (match_dup 2)
2898	(match_dup 1))
2899   (set (match_dup 0)
2900	(float:SF (match_dup 2)))]
2901  "")
2902
2903(define_insn ""
2904  [(set (match_operand:SF 0 "register_operand" "=f")
2905	(float:SF (match_operand:SI 1 "memory_operand" "m")))]
2906  "TARGET_80387"
2907  "* return AS1 (fild%z1,%1);"
2908  [(set_attr "type" "fpop")])
2909
2910(define_expand "floathisf2"
2911  [(parallel [(set (match_operand:SF 0 "register_operand" "")
2912		   (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))
2913	      (clobber (match_dup 2))])]
2914  "TARGET_80387"
2915  "operands[2] = assign_386_stack_local (HImode, 0);")
2916
2917(define_insn ""
2918  [(set (match_operand:SF 0 "register_operand" "=f,f")
2919	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
2920   (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
2921  "TARGET_80387"
2922  "#")
2923
2924(define_split
2925  [(set (match_operand:SF 0 "register_operand" "")
2926	(float:SF (match_operand:HI 1 "memory_operand" "")))
2927   (clobber (match_operand:HI 2 "memory_operand" ""))]
2928  "TARGET_80387 && reload_completed"
2929  [(set (match_dup 0)
2930	(float:SF (match_dup 1)))]
2931  "")
2932
2933(define_split
2934  [(set (match_operand:SF 0 "register_operand" "")
2935	(float:SF (match_operand:HI 1 "register_operand" "")))
2936   (clobber (match_operand:HI 2 "memory_operand" ""))]
2937  "TARGET_80387 && reload_completed"
2938  [(set (match_dup 2)
2939	(match_dup 1))
2940   (set (match_dup 0)
2941	(float:SF (match_dup 2)))]
2942  "")
2943
2944(define_insn ""
2945  [(set (match_operand:SF 0 "register_operand" "=f")
2946	(float:SF (match_operand:HI 1 "memory_operand" "m")))]
2947  "TARGET_80387"
2948  "* return AS1 (fild%z1,%1);"
2949  [(set_attr "type" "fpop")])
2950
2951(define_expand "floatdisf2"
2952  [(parallel [(set (match_operand:SF 0 "register_operand" "")
2953		   (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))
2954	      (clobber (match_dup 2))])]
2955  "TARGET_80387"
2956  "operands[2] = assign_386_stack_local (DImode, 0);")
2957
2958(define_insn ""
2959  [(set (match_operand:SF 0 "register_operand" "=f,f")
2960	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
2961      (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
2962  "TARGET_80387"
2963  "#")
2964
2965(define_split
2966  [(set (match_operand:SF 0 "register_operand" "")
2967	(float:SF (match_operand:DI 1 "memory_operand" "")))
2968   (clobber (match_operand:DI 2 "memory_operand" ""))]
2969  "TARGET_80387 && reload_completed"
2970  [(set (match_dup 0)
2971	(float:SF (match_dup 1)))]
2972  "")
2973
2974(define_split
2975  [(set (match_operand:SF 0 "register_operand" "")
2976	(float:SF (match_operand:DI 1 "register_operand" "")))
2977   (clobber (match_operand:DI 2 "memory_operand" ""))]
2978  "TARGET_80387 && reload_completed"
2979  [(set (match_dup 2)
2980	(match_dup 1))
2981   (set (match_dup 0)
2982	(float:SF (match_dup 2)))]
2983  "")
2984
2985(define_insn ""
2986  [(set (match_operand:SF 0 "register_operand" "=f")
2987	(float:SF (match_operand:DI 1 "memory_operand" "m")))]
2988  "TARGET_80387"
2989  "* return AS1 (fild%z1,%1);"
2990  [(set_attr "type" "fpop")])
2991
2992(define_expand "floatsidf2"
2993  [(parallel [(set (match_operand:DF 0 "register_operand" "")
2994		   (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
2995	      (clobber (match_dup 2))])]
2996  "TARGET_80387"
2997  "operands[2] = assign_386_stack_local (SImode, 0);")
2998
2999(define_insn ""
3000  [(set (match_operand:DF 0 "register_operand" "=f,f")
3001	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
3002   (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
3003  "TARGET_80387"
3004  "#")
3005
3006(define_split
3007  [(set (match_operand:DF 0 "register_operand" "")
3008	(float:DF (match_operand:SI 1 "memory_operand" "")))
3009   (clobber (match_operand:SI 2 "memory_operand" ""))]
3010  "TARGET_80387 && reload_completed"
3011  [(set (match_dup 0)
3012	(float:DF (match_dup 1)))]
3013  "")
3014
3015(define_split
3016  [(set (match_operand:DF 0 "register_operand" "")
3017	(float:DF (match_operand:SI 1 "register_operand" "")))
3018   (clobber (match_operand:SI 2 "memory_operand" ""))]
3019  "TARGET_80387 && reload_completed"
3020  [(set (match_dup 2)
3021	(match_dup 1))
3022   (set (match_dup 0)
3023	(float:DF (match_dup 2)))]
3024  "")
3025
3026(define_insn ""
3027  [(set (match_operand:DF 0 "register_operand" "=f")
3028	(float:DF (match_operand:SI 1 "memory_operand" "m")))]
3029  "TARGET_80387"
3030  "* return AS1 (fild%z1,%1);"
3031  [(set_attr "type" "fpop")])
3032
3033(define_expand "floathidf2"
3034  [(parallel [(set (match_operand:DF 0 "register_operand" "")
3035		   (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))
3036	      (clobber (match_dup 2))])]
3037  "TARGET_80387"
3038  "operands[2] = assign_386_stack_local (HImode, 0);")
3039
3040(define_insn ""
3041  [(set (match_operand:DF 0 "register_operand" "=f,f")
3042	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
3043   (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
3044  "TARGET_80387"
3045  "#")
3046
3047(define_split
3048  [(set (match_operand:DF 0 "register_operand" "")
3049	(float:DF (match_operand:HI 1 "memory_operand" "")))
3050   (clobber (match_operand:HI 2 "memory_operand" ""))]
3051  "TARGET_80387 && reload_completed"
3052  [(set (match_dup 0)
3053	(float:DF (match_dup 1)))]
3054  "")
3055
3056(define_split
3057  [(set (match_operand:DF 0 "register_operand" "")
3058	(float:DF (match_operand:HI 1 "register_operand" "")))
3059   (clobber (match_operand:HI 2 "memory_operand" ""))]
3060  "TARGET_80387 && reload_completed"
3061  [(set (match_dup 2)
3062	(match_dup 1))
3063   (set (match_dup 0)
3064	(float:DF (match_dup 2)))]
3065  "")
3066
3067(define_insn ""
3068  [(set (match_operand:DF 0 "register_operand" "=f")
3069	(float:DF (match_operand:HI 1 "memory_operand" "m")))]
3070  "TARGET_80387"
3071  "* return AS1 (fild%z1,%1);"
3072  [(set_attr "type" "fpop")])
3073
3074(define_expand "floatdidf2"
3075  [(parallel [(set (match_operand:DF 0 "register_operand" "")
3076		   (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))
3077	      (clobber (match_dup 2))])]
3078  "TARGET_80387"
3079  "operands[2] = assign_386_stack_local (DImode, 0);")
3080
3081(define_insn ""
3082  [(set (match_operand:DF 0 "register_operand" "=f,f")
3083	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
3084   (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
3085  "TARGET_80387"
3086  "#")
3087
3088(define_split
3089  [(set (match_operand:DF 0 "register_operand" "")
3090	(float:DF (match_operand:DI 1 "memory_operand" "")))
3091   (clobber (match_operand:DI 2 "memory_operand" ""))]
3092  "TARGET_80387 && reload_completed"
3093  [(set (match_dup 0)
3094	(float:DF (match_dup 1)))]
3095  "")
3096
3097(define_split
3098  [(set (match_operand:DF 0 "register_operand" "")
3099	(float:DF (match_operand:DI 1 "register_operand" "")))
3100   (clobber (match_operand:DI 2 "memory_operand" ""))]
3101  "TARGET_80387 && reload_completed"
3102  [(set (match_dup 2)
3103	(match_dup 1))
3104   (set (match_dup 0)
3105	(float:DF (match_dup 2)))]
3106  "")
3107
3108(define_insn ""
3109  [(set (match_operand:DF 0 "register_operand" "=f")
3110	(float:DF (match_operand:DI 1 "memory_operand" "m")))]
3111  "TARGET_80387"
3112  "* return AS1 (fild%z1,%1);"
3113  [(set_attr "type" "fpop")])
3114
3115(define_expand "floatsixf2"
3116  [(parallel [(set (match_operand:XF 0 "register_operand" "")
3117		   (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))
3118	      (clobber (match_dup 2))])]
3119  "TARGET_80387"
3120  "operands[2] = assign_386_stack_local (SImode, 0);")
3121
3122(define_insn ""
3123  [(set (match_operand:XF 0 "register_operand" "=f,f")
3124	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
3125   (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
3126  "TARGET_80387"
3127  "#")
3128
3129(define_split
3130  [(set (match_operand:XF 0 "register_operand" "")
3131	(float:XF (match_operand:SI 1 "memory_operand" "")))
3132   (clobber (match_operand:SI 2 "memory_operand" ""))]
3133  "TARGET_80387 && reload_completed"
3134  [(set (match_dup 0)
3135	(float:XF (match_dup 1)))]
3136  "")
3137
3138(define_split
3139  [(set (match_operand:XF 0 "register_operand" "")
3140	(float:XF (match_operand:SI 1 "register_operand" "")))
3141   (clobber (match_operand:SI 2 "memory_operand" ""))]
3142  "TARGET_80387 && reload_completed"
3143  [(set (match_dup 2)
3144	(match_dup 1))
3145   (set (match_dup 0)
3146	(float:XF (match_dup 2)))]
3147  "")
3148
3149(define_insn ""
3150  [(set (match_operand:XF 0 "register_operand" "=f")
3151	(float:XF (match_operand:SI 1 "memory_operand" "m")))]
3152  "TARGET_80387"
3153  "* return AS1 (fild%z1,%1);"
3154  [(set_attr "type" "fpop")])
3155
3156(define_expand "floathixf2"
3157  [(parallel [(set (match_operand:XF 0 "register_operand" "")
3158		   (float:XF (match_operand:HI 1 "nonimmediate_operand" "")))
3159	      (clobber (match_dup 2))])]
3160  "TARGET_80387"
3161  "operands[2] = assign_386_stack_local (HImode, 0);")
3162
3163(define_insn ""
3164  [(set (match_operand:XF 0 "register_operand" "=f,f")
3165	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
3166   (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
3167  "TARGET_80387"
3168  "#")
3169
3170(define_split
3171  [(set (match_operand:XF 0 "register_operand" "")
3172	(float:XF (match_operand:HI 1 "memory_operand" "")))
3173   (clobber (match_operand:HI 2 "memory_operand" ""))]
3174  "TARGET_80387 && reload_completed"
3175  [(set (match_dup 0)
3176	(float:XF (match_dup 1)))]
3177  "")
3178
3179(define_split
3180  [(set (match_operand:XF 0 "register_operand" "")
3181	(float:XF (match_operand:HI 1 "register_operand" "")))
3182   (clobber (match_operand:HI 2 "memory_operand" ""))]
3183  "TARGET_80387 && reload_completed"
3184  [(set (match_dup 2)
3185	(match_dup 1))
3186   (set (match_dup 0)
3187	(float:XF (match_dup 2)))]
3188  "")
3189
3190(define_insn ""
3191  [(set (match_operand:XF 0 "register_operand" "=f")
3192	(float:XF (match_operand:HI 1 "memory_operand" "m")))]
3193  "TARGET_80387"
3194  "* return AS1 (fild%z1,%1);"
3195  [(set_attr "type" "fpop")])
3196
3197(define_expand "floatdixf2"
3198  [(parallel [(set (match_operand:XF 0 "register_operand" "")
3199		   (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))
3200	      (clobber (match_dup 2))])]
3201  "TARGET_80387"
3202  "operands[2] = assign_386_stack_local (DImode, 0);")
3203
3204(define_insn ""
3205  [(set (match_operand:XF 0 "register_operand" "=f,f")
3206	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
3207   (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
3208  "TARGET_80387"
3209  "#")
3210
3211(define_split
3212  [(set (match_operand:XF 0 "register_operand" "")
3213	(float:XF (match_operand:DI 1 "memory_operand" "")))
3214   (clobber (match_operand:DI 2 "memory_operand" ""))]
3215  "TARGET_80387 && reload_completed"
3216  [(set (match_dup 0)
3217	(float:XF (match_dup 1)))]
3218  "")
3219
3220(define_split
3221  [(set (match_operand:XF 0 "register_operand" "")
3222	(float:XF (match_operand:DI 1 "register_operand" "")))
3223   (clobber (match_operand:DI 2 "memory_operand" ""))]
3224  "TARGET_80387 && reload_completed"
3225  [(set (match_dup 2)
3226	(match_dup 1))
3227   (set (match_dup 0)
3228	(float:XF (match_dup 2)))]
3229  "")
3230
3231(define_insn ""
3232  [(set (match_operand:XF 0 "register_operand" "=f")
3233	(float:XF (match_operand:DI 1 "memory_operand" "m")))]
3234  "TARGET_80387"
3235  "* return AS1 (fild%z1,%1);"
3236  [(set_attr "type" "fpop")])
3237
3238;;- add instructions
3239
3240(define_insn "*addsidi3_1"
3241  [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o")
3242	(plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o")
3243		 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri"))))
3244   (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))]
3245  ""
3246  "*
3247{
3248  rtx low[3], high[3], xops[7];
3249
3250  CC_STATUS_INIT;
3251
3252  split_di (operands, 2, low, high);
3253  high[2] = const0_rtx;
3254  low[2]  = operands[2];
3255
3256  if (!rtx_equal_p (operands[0], operands[1]))
3257    {
3258      xops[0] = high[0];
3259      xops[1] = low[0];
3260      xops[2] = high[1];
3261      xops[3] = low[1];
3262
3263      if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3264	{
3265	  output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3266	  output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3267	}
3268      else
3269	{
3270	  xops[4] = high[2];
3271	  xops[5] = low[2];
3272	  xops[6] = operands[3];
3273	  output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3274	  output_asm_insn (AS2 (add%L6,%5,%6), xops);
3275	  output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3276	  output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3277	  output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3278	  output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3279	  RET;
3280	}
3281    }
3282
3283  output_asm_insn (AS2 (add%L0,%2,%0), low);
3284  output_asm_insn (AS2 (adc%L0,%2,%0), high);
3285  cc_status.value1 = high[0];
3286  cc_status.flags = CC_NO_OVERFLOW;
3287  RET;
3288}"
3289  [(set_attr "type" "binary")])
3290
3291(define_insn "addsidi3_2"
3292  [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o")
3293	(plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r"))
3294		 (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o")))
3295   (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))]
3296  ""
3297  "*
3298{
3299  rtx low[3], high[3], xops[7];
3300
3301  CC_STATUS_INIT;
3302
3303  split_di (operands, 2, low, high);
3304  high[2] = const0_rtx;
3305  low[2]  = operands[2];
3306
3307  if (!rtx_equal_p (operands[0], operands[1]))
3308    {
3309      xops[0] = high[0];
3310      xops[1] = low[0];
3311      xops[2] = high[1];
3312      xops[3] = low[1];
3313
3314      if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3315	{
3316	  if (rtx_equal_p (low[0], operands[2]))
3317	    {
3318	      output_asm_insn (AS2 (mov%L0,%2,%0), high);
3319	      output_asm_insn (AS2 (add%L0,%1,%0), low);
3320	      output_asm_insn (AS2 (adc%L0,%1,%0), high);
3321	      RET;
3322	    }
3323	  if (rtx_equal_p (high[0], operands[2]))
3324	    {
3325	      if (GET_CODE (operands[0]) != MEM)
3326		{
3327		  output_asm_insn (AS2 (mov%L0,%2,%0), low);
3328		  output_asm_insn (AS2 (mov%L0,%2,%0), high);
3329		  output_asm_insn (AS2 (add%L0,%1,%0), low);
3330		  output_asm_insn (AS2 (adc%L0,%1,%0), high);
3331		}
3332	      else
3333		{
3334		  /* It's too late to ask for a scratch now - but this
3335		     will probably not happen too often.  */
3336		  output_asm_insn (AS2 (add%L1,%2,%1), low);
3337		  output_asm_insn (AS2 (mov%L0,%1,%0), low);
3338		  output_asm_insn (AS2 (mov%L1,%2,%1), low);
3339		  output_asm_insn (AS2 (mov%L0,%2,%0), high);
3340		  output_asm_insn (AS2 (adc%L0,%1,%0), high);
3341		  output_asm_insn (AS2 (sub%L1,%0,%1), low);
3342		  output_asm_insn (AS1 (neg%L1,%1), low);
3343		}
3344	      RET;
3345	    }
3346	  output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3347	  output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3348	}
3349      else
3350	{
3351	  xops[4] = high[2];
3352	  xops[5] = low[2];
3353	  xops[6] = operands[3];
3354	  output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3355	  output_asm_insn (AS2 (add%L6,%5,%6), xops);
3356	  output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3357	  output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3358	  output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3359	  output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3360	  RET;
3361	}
3362    }
3363
3364  output_asm_insn (AS2 (add%L0,%2,%0), low);
3365  output_asm_insn (AS2 (adc%L0,%2,%0), high);
3366  cc_status.value1 = high[0];
3367  cc_status.flags = CC_NO_OVERFLOW;
3368  RET;
3369}"
3370  [(set_attr "type" "binary")])
3371
3372(define_insn "adddi3"
3373  [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
3374	(plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
3375		 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
3376   (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
3377  ""
3378  "*
3379{
3380  rtx low[3], high[3], xops[7], temp;
3381
3382  CC_STATUS_INIT;
3383
3384  if (rtx_equal_p (operands[0], operands[2]))
3385    {
3386      temp = operands[1];
3387      operands[1] = operands[2];
3388      operands[2] = temp;
3389    }
3390
3391  split_di (operands, 3, low, high);
3392  if (!rtx_equal_p (operands[0], operands[1]))
3393    {
3394      xops[0] = high[0];
3395      xops[1] = low[0];
3396      xops[2] = high[1];
3397      xops[3] = low[1];
3398
3399      if (GET_CODE (operands[0]) != MEM)
3400	{
3401	  output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3402	  output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3403	}
3404      else
3405	{
3406	  xops[4] = high[2];
3407	  xops[5] = low[2];
3408	  xops[6] = operands[3];
3409	  output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3410	  output_asm_insn (AS2 (add%L6,%5,%6), xops);
3411	  output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3412	  output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3413	  output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3414	  output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3415	  RET;
3416	}
3417    }
3418
3419  cc_status.value1 = high[0];
3420  cc_status.flags = CC_NO_OVERFLOW;
3421
3422  if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
3423    {
3424      xops[0] = high[0];
3425      xops[1] = low[0];
3426      xops[2] = high[2];
3427      xops[3] = low[2];
3428      xops[4] = operands[3];
3429
3430      output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3431      output_asm_insn (AS2 (add%L1,%4,%1), xops);
3432      output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3433      output_asm_insn (AS2 (adc%L0,%4,%0), xops);
3434    }
3435
3436  else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
3437    {
3438      output_asm_insn (AS2 (add%L0,%2,%0), low);
3439      output_asm_insn (AS2 (adc%L0,%2,%0), high);
3440    }
3441
3442  else
3443    output_asm_insn (AS2 (add%L0,%2,%0), high);
3444
3445  RET;
3446}"
3447  [(set_attr "type" "binary")])
3448
3449;; On a 486, it is faster to do movl/addl than to do a single leal if
3450;; operands[1] and operands[2] are both registers.
3451
3452(define_expand "addsi3"
3453  [(set (match_operand:SI 0 "nonimmediate_operand" "")
3454	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3455		 (match_operand:SI 2 "general_operand" "")))]
3456  ""
3457  "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);")
3458
3459(define_insn ""
3460  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
3461	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
3462		 (match_operand:SI 2 "general_operand" "rmi,ri,ri")))]
3463  "ix86_binary_operator_ok (PLUS, SImode, operands)"
3464  "*
3465{
3466  if (REG_P (operands[0]) && REG_P (operands[1])
3467      && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
3468      && REGNO (operands[0]) != REGNO (operands[1]))
3469    {
3470      if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3471	return AS2 (add%L0,%1,%0);
3472
3473      if (operands[2] == stack_pointer_rtx)
3474	{
3475	  rtx temp;
3476
3477	  temp = operands[1];
3478	  operands[1] = operands[2];
3479	  operands[2] = temp;
3480	}
3481
3482      if (operands[2] != stack_pointer_rtx)
3483	{
3484	  CC_STATUS_INIT;
3485	  operands[1] = SET_SRC (PATTERN (insn));
3486	  return AS2 (lea%L0,%a1,%0);
3487	}
3488    }
3489
3490  if (!rtx_equal_p (operands[0], operands[1]))
3491    output_asm_insn (AS2 (mov%L0,%1,%0), operands);
3492
3493  if (operands[2] == const1_rtx)
3494    return AS1 (inc%L0,%0);
3495
3496  if (operands[2] == constm1_rtx)
3497    return AS1 (dec%L0,%0);
3498
3499  /* subl $-128,%ebx is smaller than addl $128,%ebx. */
3500  if (GET_CODE (operands[2]) == CONST_INT
3501      && INTVAL (operands[2]) == 128)
3502    {
3503      /* This doesn't compute the carry bit in the same way
3504       * as add%L0, but we use inc and dec above and they
3505       * don't set the carry bit at all.  If inc/dec don't need
3506       * a CC_STATUS_INIT, this doesn't either... */
3507      operands[2] = GEN_INT (-128);
3508      return AS2 (sub%L0,%2,%0);
3509    }
3510
3511  return AS2 (add%L0,%2,%0);
3512}"
3513  [(set_attr "type" "binary")])
3514
3515;; addsi3 is faster, so put this after.
3516
3517(define_insn "movsi_lea"
3518  [(set (match_operand:SI 0 "register_operand" "=r")
3519        (match_operand:QI 1 "address_operand" "p"))]
3520  ""
3521  "*
3522{
3523  /* Adding a constant to a register is faster with an add.  */
3524  /* ??? can this ever happen? */
3525  if (GET_CODE (operands[1]) == PLUS
3526      && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
3527      && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
3528    {
3529      operands[1] = XEXP (operands[1], 1);
3530
3531      if (operands[1] == const1_rtx)
3532        return AS1 (inc%L0,%0);
3533
3534      if (operands[1] == constm1_rtx)
3535        return AS1 (dec%L0,%0);
3536
3537      return AS2 (add%L0,%1,%0);
3538    }
3539
3540  CC_STATUS_INIT;
3541  return AS2 (lea%L0,%a1,%0);
3542}"
3543  [(set_attr "type" "lea")])
3544
3545;; ??? `lea' here, for three operand add?  If leaw is used, only %bx,
3546;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
3547;; able to handle the operand.  But leal always works?
3548
3549(define_expand "addhi3"
3550  [(set (match_operand:HI 0 "general_operand" "")
3551	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3552		 (match_operand:HI 2 "general_operand" "")))]
3553  ""
3554  "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);")
3555
3556(define_insn ""
3557  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,?r")
3558	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
3559		 (match_operand:HI 2 "general_operand" "ri,rm,ri")))]
3560  "ix86_binary_operator_ok (PLUS, HImode, operands)"
3561  "*
3562{
3563  if (REG_P (operands[0]) && REG_P (operands[1])
3564      && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
3565      && REGNO (operands[0]) != REGNO (operands[1]))
3566    {
3567      if (operands[2] == stack_pointer_rtx) 
3568	abort ();
3569
3570      CC_STATUS_INIT;
3571      operands[1]
3572	= gen_rtx_PLUS (SImode,
3573			gen_rtx_REG (SImode, REGNO (operands[1])),
3574			(! REG_P (operands[2])
3575			 ? operands[2]
3576			 : gen_rtx_REG (SImode, REGNO (operands[2]))));
3577      operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
3578      return AS2 (lea%L0,%a1,%0);
3579    }
3580
3581  /* ??? what about offsettable memory references? */
3582  if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */
3583      && QI_REG_P (operands[0])
3584      && GET_CODE (operands[2]) == CONST_INT
3585      && (INTVAL (operands[2]) & 0xff) == 0
3586      && i386_cc_probably_useless_p (insn))
3587    {
3588      int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
3589      CC_STATUS_INIT;
3590
3591      if (byteval == 1)
3592	return AS1 (inc%B0,%h0);
3593      else if (byteval == 255)
3594	return AS1 (dec%B0,%h0);
3595
3596      operands[2] = GEN_INT (byteval);
3597      return AS2 (add%B0,%2,%h0);
3598    }
3599
3600  /* Use a 32-bit operation when possible, to avoid the prefix penalty. */
3601  if (REG_P (operands[0])
3602      && i386_aligned_p (operands[2])
3603      && i386_cc_probably_useless_p (insn))
3604    {
3605      CC_STATUS_INIT;
3606
3607      if (GET_CODE (operands[2]) == CONST_INT)
3608	{
3609	  HOST_WIDE_INT intval = 0xffff & INTVAL (operands[2]);
3610
3611	  if (intval == 1)
3612	    return AS1 (inc%L0,%k0);
3613
3614	  if (intval == 0xffff)
3615	    return AS1 (dec%L0,%k0);
3616
3617	  operands[2] = i386_sext16_if_const (operands[2]);
3618	}
3619      return AS2 (add%L0,%k2,%k0);
3620    }
3621
3622  if (operands[2] == const1_rtx)
3623    return AS1 (inc%W0,%0);
3624
3625  if (operands[2] == constm1_rtx
3626      || (GET_CODE (operands[2]) == CONST_INT
3627	  && INTVAL (operands[2]) == 65535))
3628    return AS1 (dec%W0,%0);
3629
3630  return AS2 (add%W0,%2,%0);
3631}"
3632  [(set_attr "type" "binary")])
3633
3634(define_expand "addqi3"
3635  [(set (match_operand:QI 0 "general_operand" "")
3636	(plus:QI (match_operand:QI 1 "general_operand" "")
3637		 (match_operand:QI 2 "general_operand" "")))]
3638  ""
3639  "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);")
3640
3641(define_insn ""
3642  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,?q")
3643	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q")
3644		 (match_operand:QI 2 "general_operand" "qn,qmn,qn")))]
3645  "ix86_binary_operator_ok (PLUS, QImode, operands)"
3646  "*
3647{
3648  if (REG_P (operands[0]) && REG_P (operands[1])
3649      && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
3650      && (REGNO (operands[0]) != REGNO (operands[1])
3651	  || NON_QI_REG_P (operands[1])
3652	  || (REG_P (operands[2]) && NON_QI_REG_P (operands[2]))))
3653    {
3654      if (operands[2] == stack_pointer_rtx) 
3655	abort ();
3656
3657      CC_STATUS_INIT;
3658      operands[1]
3659	= gen_rtx_PLUS (SImode,
3660			gen_rtx_REG (SImode, REGNO (operands[1])),
3661			(! REG_P (operands[2])
3662			 ? operands[2]
3663			 : gen_rtx_REG (SImode, REGNO (operands[2]))));
3664      operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
3665      return AS2 (lea%L0,%a1,%0);
3666    }
3667  if (operands[2] == const1_rtx)
3668    return AS1 (inc%B0,%0);
3669
3670  if (operands[2] == constm1_rtx
3671      || (GET_CODE (operands[2]) == CONST_INT
3672	  && INTVAL (operands[2]) == 255))
3673    return AS1 (dec%B0,%0);
3674
3675  return AS2 (add%B0,%2,%0);
3676}"
3677  [(set_attr "type" "binary")])
3678
3679;Lennart Augustsson <augustss@cs.chalmers.se>
3680;says this pattern just makes slower code:
3681;	pushl	%ebp
3682;	addl	$-80,(%esp)
3683;instead of
3684;	leal	-80(%ebp),%eax
3685;	pushl	%eax
3686;
3687;(define_insn ""
3688;  [(set (match_operand:SI 0 "push_operand" "=<")
3689;	(plus:SI (match_operand:SI 1 "register_operand" "%r")
3690;		 (match_operand:SI 2 "nonmemory_operand" "ri")))]
3691;  ""
3692;  "*
3693;{
3694;  rtx xops[4];
3695;  xops[0] = operands[0];
3696;  xops[1] = operands[1];
3697;  xops[2] = operands[2];
3698;  xops[3] = gen_rtx_MEM (SImode, stack_pointer_rtx);
3699;  output_asm_insn (\"push%z1 %1\", xops);
3700;  output_asm_insn (AS2 (add%z3,%2,%3), xops);
3701;  RET;
3702;}")
3703
3704;; The patterns that match these are at the end of this file.
3705
3706(define_expand "addxf3"
3707  [(set (match_operand:XF 0 "register_operand" "")
3708	(plus:XF (match_operand:XF 1 "register_operand" "")
3709		 (match_operand:XF 2 "register_operand" "")))]
3710  "TARGET_80387"
3711  "")
3712
3713(define_expand "adddf3"
3714  [(set (match_operand:DF 0 "register_operand" "")
3715	(plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3716		 (match_operand:DF 2 "nonimmediate_operand" "")))]
3717  "TARGET_80387"
3718  "")
3719
3720(define_expand "addsf3"
3721  [(set (match_operand:SF 0 "register_operand" "")
3722	(plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3723		 (match_operand:SF 2 "nonimmediate_operand" "")))]
3724  "TARGET_80387"
3725  "")
3726
3727;;- subtract instructions
3728
3729(define_insn "subsidi3"
3730  [(set (match_operand:DI 0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o")
3731	(minus:DI (match_operand:DI 1 "general_operand" "0iF,0,roiF,roiF,riF,o,o")
3732		  (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,ri,i,r"))))
3733   (clobber (match_scratch:SI 3 "=X,X,X,X,X,&r,&r"))]
3734  ""
3735  "*
3736{
3737  rtx low[3], high[3], xops[7];
3738
3739  CC_STATUS_INIT;
3740
3741  split_di (operands, 2, low, high);
3742  high[2] = const0_rtx;
3743  low[2]  = operands[2];
3744
3745  if (!rtx_equal_p (operands[0], operands[1]))
3746    {
3747      xops[0] = high[0];
3748      xops[1] = low[0];
3749      xops[2] = high[1];
3750      xops[3] = low[1];
3751
3752      if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3753	{
3754	  output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3755	  output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3756	}
3757      else
3758	{
3759	  xops[4] = high[2];
3760	  xops[5] = low[2];
3761	  xops[6] = operands[3];
3762	  output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3763	  output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3764	  output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3765	  output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3766	  output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3767	  output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3768	  RET;
3769	}
3770    }
3771
3772  output_asm_insn (AS2 (sub%L0,%2,%0), low);
3773  output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3774  cc_status.value1 = high[0];
3775  cc_status.flags = CC_NO_OVERFLOW;
3776
3777  RET;
3778}"
3779  [(set_attr "type" "binary")])
3780
3781(define_insn "subdi3"
3782  [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
3783	(minus:DI (match_operand:DI 1 "general_operand" "0,0,0iF,or,roiF,roiF")
3784		  (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
3785   (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
3786  ""
3787  "*
3788{
3789  rtx low[3], high[3], xops[7];
3790
3791  CC_STATUS_INIT;
3792
3793  split_di (operands, 3, low, high);
3794
3795  if (!rtx_equal_p (operands[0], operands[1]))
3796    {
3797      xops[0] = high[0];
3798      xops[1] = low[0];
3799      xops[2] = high[1];
3800      xops[3] = low[1];
3801
3802      if (GET_CODE (operands[0]) != MEM)
3803	{
3804	  output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3805	  output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3806	}
3807      else
3808	{
3809	  xops[4] = high[2];
3810	  xops[5] = low[2];
3811	  xops[6] = operands[3];
3812	  output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3813	  output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3814	  output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3815	  output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3816	  output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3817	  output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3818	  RET;
3819	}
3820    }
3821
3822  cc_status.value1 = high[0];
3823  cc_status.flags = CC_NO_OVERFLOW;
3824
3825  if (GET_CODE (operands[3]) == REG)
3826    {
3827      xops[0] = high[0];
3828      xops[1] = low[0];
3829      xops[2] = high[2];
3830      xops[3] = low[2];
3831      xops[4] = operands[3];
3832
3833      output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3834      output_asm_insn (AS2 (sub%L1,%4,%1), xops);
3835      output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3836      output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
3837    }
3838
3839  else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
3840    {
3841      output_asm_insn (AS2 (sub%L0,%2,%0), low);
3842      output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3843    }
3844
3845  else
3846      output_asm_insn (AS2 (sub%L0,%2,%0), high);
3847
3848
3849  RET;
3850}"
3851  [(set_attr "type" "binary")])
3852
3853(define_expand "subsi3"
3854  [(set (match_operand:SI 0 "nonimmediate_operand" "")
3855	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3856		  (match_operand:SI 2 "general_operand" "")))]
3857  ""
3858  "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);")
3859
3860(define_insn ""
3861  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3862	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
3863		  (match_operand:SI 2 "general_operand" "ri,rm")))]
3864  "ix86_binary_operator_ok (MINUS, SImode, operands)"
3865  "* return AS2 (sub%L0,%2,%0);"
3866  [(set_attr "type" "binary")])
3867
3868(define_expand "subhi3"
3869  [(set (match_operand:HI 0 "general_operand" "")
3870	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3871		  (match_operand:HI 2 "general_operand" "")))]
3872  ""
3873  "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);")
3874
3875(define_insn ""
3876  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3877	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
3878		  (match_operand:HI 2 "general_operand" "ri,rm")))]
3879  "ix86_binary_operator_ok (MINUS, HImode, operands)"
3880  "*
3881{
3882  if (REG_P (operands[0])
3883      && i386_aligned_p (operands[2])
3884      && i386_cc_probably_useless_p (insn))
3885    {
3886      CC_STATUS_INIT;
3887      operands[2] = i386_sext16_if_const (operands[2]);
3888      return AS2 (sub%L0,%k2,%k0);
3889    }
3890 return AS2 (sub%W0,%2,%0);
3891}"
3892  [(set_attr "type" "binary")])
3893
3894(define_expand "subqi3"
3895  [(set (match_operand:QI 0 "general_operand" "")
3896	(minus:QI (match_operand:QI 1 "general_operand" "")
3897		  (match_operand:QI 2 "general_operand" "")))]
3898  ""
3899  "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);")
3900
3901(define_insn ""
3902  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3903	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
3904		  (match_operand:QI 2 "general_operand" "qn,qmn")))]
3905  "ix86_binary_operator_ok (MINUS, QImode, operands)"
3906  "* return AS2 (sub%B0,%2,%0);"
3907  [(set_attr "type" "binary")])
3908
3909;; The patterns that match these are at the end of this file.
3910
3911(define_expand "subxf3"
3912  [(set (match_operand:XF 0 "register_operand" "")
3913	(minus:XF (match_operand:XF 1 "register_operand" "")
3914		  (match_operand:XF 2 "register_operand" "")))]
3915  "TARGET_80387"
3916  "")
3917
3918(define_expand "subdf3"
3919  [(set (match_operand:DF 0 "register_operand" "")
3920	(minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3921		  (match_operand:DF 2 "nonimmediate_operand" "")))]
3922  "TARGET_80387"
3923  "")
3924
3925(define_expand "subsf3"
3926  [(set (match_operand:SF 0 "register_operand" "")
3927	(minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3928		  (match_operand:SF 2 "nonimmediate_operand" "")))]
3929  "TARGET_80387"
3930  "")
3931
3932;;- multiply instructions
3933
3934;(define_insn "mulqi3"
3935;  [(set (match_operand:QI 0 "register_operand" "=a")
3936;	(mult:QI (match_operand:QI 1 "register_operand" "%0")
3937;		 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
3938;  ""
3939;  "imul%B0 %2,%0")
3940
3941(define_insn "mulhi3"
3942  [(set (match_operand:HI 0 "register_operand" "=r,r")
3943	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%0,rm")
3944		 (match_operand:HI 2 "general_operand" "g,i")))]
3945  ""
3946  "*
3947{
3948  if (GET_CODE (operands[1]) == REG
3949      && REGNO (operands[1]) == REGNO (operands[0])
3950      && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3951    /* Assembler has weird restrictions.  */
3952    return AS2 (imul%W0,%2,%0);
3953  return AS3 (imul%W0,%2,%1,%0);
3954}"
3955  [(set_attr "type" "imul")])
3956
3957(define_insn "mulsi3"
3958  [(set (match_operand:SI 0 "register_operand" "=r,r")
3959	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
3960		 (match_operand:SI 2 "general_operand" "g,i")))]
3961  ""
3962  "*
3963{
3964  if (GET_CODE (operands[1]) == REG
3965      && REGNO (operands[1]) == REGNO (operands[0])
3966      && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3967    /* Assembler has weird restrictions.  */
3968    return AS2 (imul%L0,%2,%0);
3969  return AS3 (imul%L0,%2,%1,%0);
3970}"
3971  [(set_attr "type" "imul")])
3972
3973(define_insn "umulqihi3"
3974  [(set (match_operand:HI 0 "register_operand" "=a")
3975	(mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3976		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3977  ""
3978  "mul%B0 %2"
3979  [(set_attr "type" "imul")])
3980
3981(define_insn "mulqihi3"
3982  [(set (match_operand:HI 0 "register_operand" "=a")
3983	(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3984		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3985  ""
3986  "imul%B0 %2"
3987  [(set_attr "type" "imul")])
3988
3989(define_insn "umulsidi3"
3990  [(set (match_operand:DI 0 "register_operand" "=A")
3991	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3992		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
3993  "TARGET_WIDE_MULTIPLY"
3994  "mul%L0 %2"
3995  [(set_attr "type" "imul")])
3996
3997(define_insn "mulsidi3"
3998  [(set (match_operand:DI 0 "register_operand" "=A")
3999	(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
4000		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
4001  "TARGET_WIDE_MULTIPLY"
4002  "imul%L0 %2"
4003  [(set_attr "type" "imul")])
4004
4005(define_insn "umulsi3_highpart"
4006  [(set (match_operand:SI 0 "register_operand" "=d")
4007	(truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
4008					   (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
4009				  (const_int 32))))
4010   (clobber (match_scratch:SI 3 "=a"))]
4011  "TARGET_WIDE_MULTIPLY"
4012  "mul%L0 %2"
4013  [(set_attr "type" "imul")])
4014
4015(define_insn "smulsi3_highpart"
4016  [(set (match_operand:SI 0 "register_operand" "=d")
4017	(truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
4018					   (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
4019				  (const_int 32))))
4020   (clobber (match_scratch:SI 3 "=a"))]
4021  "TARGET_WIDE_MULTIPLY"
4022  "imul%L0 %2"
4023  [(set_attr "type" "imul")])
4024
4025;; The patterns that match these are at the end of this file.
4026
4027(define_expand "mulxf3"
4028  [(set (match_operand:XF 0 "register_operand" "")
4029	(mult:XF (match_operand:XF 1 "register_operand" "")
4030		 (match_operand:XF 2 "register_operand" "")))]
4031  "TARGET_80387"
4032  "")
4033
4034(define_expand "muldf3"
4035  [(set (match_operand:DF 0 "register_operand" "")
4036	(mult:DF (match_operand:DF 1 "register_operand" "")
4037		 (match_operand:DF 2 "nonimmediate_operand" "")))]
4038  "TARGET_80387"
4039  "")
4040
4041(define_expand "mulsf3"
4042  [(set (match_operand:SF 0 "register_operand" "")
4043	(mult:SF (match_operand:SF 1 "register_operand" "")
4044		 (match_operand:SF 2 "nonimmediate_operand" "")))]
4045  "TARGET_80387"
4046  "")
4047
4048;;- divide instructions
4049
4050(define_insn "divqi3"
4051  [(set (match_operand:QI 0 "register_operand" "=a")
4052	(div:QI (match_operand:HI 1 "register_operand" "0")
4053		(match_operand:QI 2 "nonimmediate_operand" "qm")))]
4054  ""
4055  "idiv%B0 %2")
4056
4057(define_insn "udivqi3"
4058  [(set (match_operand:QI 0 "register_operand" "=a")
4059	(udiv:QI (match_operand:HI 1 "register_operand" "0")
4060		 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
4061  ""
4062  "div%B0 %2"
4063  [(set_attr "type" "idiv")])
4064
4065;; The patterns that match these are at the end of this file.
4066
4067(define_expand "divxf3"
4068  [(set (match_operand:XF 0 "register_operand" "")
4069	(div:XF (match_operand:XF 1 "register_operand" "")
4070		(match_operand:XF 2 "register_operand" "")))]
4071  "TARGET_80387"
4072  "")
4073
4074(define_expand "divdf3"
4075  [(set (match_operand:DF 0 "register_operand" "")
4076 	(div:DF (match_operand:DF 1 "register_operand" "")
4077 		(match_operand:DF 2 "nonimmediate_operand" "")))]
4078   "TARGET_80387"
4079   "")
4080 
4081(define_expand "divsf3"
4082  [(set (match_operand:SF 0 "register_operand" "")
4083	(div:SF (match_operand:SF 1 "register_operand" "")
4084		(match_operand:SF 2 "nonimmediate_operand" "")))]
4085  "TARGET_80387"
4086  "")
4087
4088;; Remainder instructions.
4089
4090(define_insn "divmodsi4"
4091  [(set (match_operand:SI 0 "register_operand" "=a")
4092	(div:SI (match_operand:SI 1 "register_operand" "0")
4093		(match_operand:SI 2 "nonimmediate_operand" "rm")))
4094   (set (match_operand:SI 3 "register_operand" "=&d")
4095	(mod:SI (match_dup 1) (match_dup 2)))]
4096  ""
4097  "*
4098{
4099#ifdef INTEL_SYNTAX
4100  output_asm_insn (\"cdq\", operands);
4101#else
4102  output_asm_insn (\"cltd\", operands);
4103#endif
4104  return AS1 (idiv%L0,%2);
4105}"
4106  [(set_attr "type" "idiv")])
4107
4108(define_insn "divmodhi4"
4109  [(set (match_operand:HI 0 "register_operand" "=a")
4110	(div:HI (match_operand:HI 1 "register_operand" "0")
4111		(match_operand:HI 2 "nonimmediate_operand" "rm")))
4112   (set (match_operand:HI 3 "register_operand" "=&d")
4113	(mod:HI (match_dup 1) (match_dup 2)))]
4114  ""
4115  "cwtd\;idiv%W0 %2"
4116  [(set_attr "type" "idiv")])
4117
4118;; ??? Can we make gcc zero extend operand[0]?
4119(define_insn "udivmodsi4"
4120  [(set (match_operand:SI 0 "register_operand" "=a")
4121	(udiv:SI (match_operand:SI 1 "register_operand" "0")
4122		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4123   (set (match_operand:SI 3 "register_operand" "=&d")
4124	(umod:SI (match_dup 1) (match_dup 2)))]
4125  ""
4126  "*
4127{
4128  output_asm_insn (AS2 (xor%L3,%3,%3), operands);
4129  return AS1 (div%L0,%2);
4130}"
4131  [(set_attr "type" "idiv")])
4132
4133;; ??? Can we make gcc zero extend operand[0]?
4134(define_insn "udivmodhi4"
4135  [(set (match_operand:HI 0 "register_operand" "=a")
4136	(udiv:HI (match_operand:HI 1 "register_operand" "0")
4137		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
4138   (set (match_operand:HI 3 "register_operand" "=&d")
4139	(umod:HI (match_dup 1) (match_dup 2)))]
4140  ""
4141  "*
4142{
4143  output_asm_insn (AS2 (xor%W0,%3,%3), operands);
4144  return AS1 (div%W0,%2);
4145}"
4146  [(set_attr "type" "idiv")])
4147
4148/*
4149;;this should be a valid double division which we may want to add
4150
4151(define_insn ""
4152  [(set (match_operand:SI 0 "register_operand" "=a")
4153	(udiv:DI (match_operand:DI 1 "register_operand" "a")
4154		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4155   (set (match_operand:SI 3 "register_operand" "=d")
4156	(umod:SI (match_dup 1) (match_dup 2)))]
4157  ""
4158  "div%L0 %2,%0"
4159  [(set_attr "type" "idiv")])
4160*/
4161
4162;;- and instructions
4163
4164;; On i386,
4165;;			movzbl %bl,%ebx
4166;; is faster than
4167;;			andl $255,%ebx
4168;;
4169;; but if the reg is %eax, then the "andl" is faster.
4170;;
4171;; On i486, the "andl" is always faster than the "movzbl".
4172;;
4173;; On both i386 and i486, a three operand AND is as fast with movzbl or
4174;; movzwl as with andl, if operands[0] != operands[1].
4175
4176;; The `r' in `rm' for operand 3 looks redundant, but it causes
4177;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
4178
4179(define_insn "andsi3"
4180  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4181	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4182		(match_operand:SI 2 "general_operand" "ri,rm")))]
4183  ""
4184  "*
4185{
4186  HOST_WIDE_INT intval;
4187  if (!rtx_equal_p (operands[0], operands[1])
4188      && rtx_equal_p (operands[0], operands[2]))
4189    {
4190      rtx tmp;
4191      tmp = operands[1];
4192      operands[1] = operands[2];
4193      operands[2] = tmp;
4194    }
4195  switch (GET_CODE (operands[2]))
4196    {
4197    case CONST_INT:
4198      if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4199	break;
4200      intval = INTVAL (operands[2]);
4201      /* zero-extend 16->32? */
4202      if (intval == 0xffff && REG_P (operands[0])
4203	  && (! REG_P (operands[1])
4204	      || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
4205	  && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
4206	{
4207	  /* ??? tege: Should forget CC_STATUS only if we clobber a
4208	     remembered operand.  Fix that later.  */
4209	  CC_STATUS_INIT;
4210#ifdef INTEL_SYNTAX
4211	  return AS2 (movzx,%w1,%0);
4212#else
4213	  return AS2 (movz%W0%L0,%w1,%0);
4214#endif
4215	}
4216
4217      /* zero extend 8->32? */
4218      if (intval == 0xff && REG_P (operands[0])
4219	  && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
4220	  && (! REG_P (operands[1])
4221	      || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
4222	  && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
4223	{
4224	  /* ??? tege: Should forget CC_STATUS only if we clobber a
4225	     remembered operand.  Fix that later.  */
4226	  CC_STATUS_INIT;
4227#ifdef INTEL_SYNTAX
4228	  return AS2 (movzx,%b1,%0);
4229#else
4230	  return AS2 (movz%B0%L0,%b1,%0);
4231#endif
4232	}
4233
4234      /* Check partial bytes.. non-QI-regs are not available */
4235      if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4236	break;
4237
4238      /* only low byte has zero bits? */
4239      if (~(intval | 0xff) == 0)
4240	{
4241	  intval &= 0xff;
4242	  if (REG_P (operands[0]))
4243	    {
4244	      if (intval == 0)
4245		{
4246		  CC_STATUS_INIT;
4247		  return AS2 (xor%B0,%b0,%b0);
4248		}
4249
4250	      /* we're better off with the 32-bit version if reg != EAX */
4251	      /* the value is sign-extended in 8 bits */
4252	      if (REGNO (operands[0]) != 0 && (intval & 0x80))
4253		break;
4254	    }
4255
4256	  CC_STATUS_INIT;
4257
4258	  operands[2] = GEN_INT (intval);
4259
4260	  if (intval == 0)
4261	    return AS2 (mov%B0,%2,%b0);
4262
4263	  return AS2 (and%B0,%2,%b0);
4264	}
4265
4266      /* only second byte has zero? */
4267      if (~(intval | 0xff00) == 0)
4268	{
4269	  CC_STATUS_INIT;
4270
4271	  intval = (intval >> 8) & 0xff;
4272	  operands[2] = GEN_INT (intval);
4273	  if (intval == 0)
4274	    {
4275	      if (REG_P (operands[0]))
4276		return AS2 (xor%B0,%h0,%h0);
4277	      operands[0] = adj_offsettable_operand (operands[0], 1);
4278	      return AS2 (mov%B0,%2,%b0);
4279	    }
4280
4281	  if (REG_P (operands[0]))
4282	    return AS2 (and%B0,%2,%h0);
4283
4284	  operands[0] = adj_offsettable_operand (operands[0], 1);
4285	  return AS2 (and%B0,%2,%b0);
4286	}
4287
4288      if (REG_P (operands[0]))
4289	break;
4290
4291      /* third byte has zero bits? */
4292      if (~(intval | 0xff0000) == 0)
4293	{
4294	  intval = (intval >> 16) & 0xff;
4295	  operands[0] = adj_offsettable_operand (operands[0], 2);
4296byte_and_operation:
4297	  CC_STATUS_INIT;
4298	  operands[2] = GEN_INT (intval);
4299	  if (intval == 0)
4300	    return AS2 (mov%B0,%2,%b0);
4301	  return AS2 (and%B0,%2,%b0);
4302	}
4303
4304      /* fourth byte has zero bits? */
4305      if (~(intval | 0xff000000) == 0)
4306	{
4307	  intval = (intval >> 24) & 0xff;
4308	  operands[0] = adj_offsettable_operand (operands[0], 3);
4309	  goto byte_and_operation;
4310	}
4311
4312      /* Low word is zero? */
4313      if (intval == 0xffff0000)
4314        {
4315word_zero_and_operation:
4316	  CC_STATUS_INIT;
4317	  operands[2] = const0_rtx;
4318	  return AS2 (mov%W0,%2,%w0);
4319	}
4320
4321      /* High word is zero? */
4322      if (intval == 0x0000ffff)
4323        {
4324	  operands[0] = adj_offsettable_operand (operands[0], 2);
4325	  goto word_zero_and_operation;
4326	}
4327
4328    default:
4329      break;
4330    }
4331
4332  return AS2 (and%L0,%2,%0);
4333}"
4334  [(set_attr "type" "binary")])
4335
4336(define_insn "andhi3"
4337  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4338	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4339		(match_operand:HI 2 "general_operand" "ri,rm")))]
4340  ""
4341  "*
4342{
4343  if (GET_CODE (operands[2]) == CONST_INT
4344      && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
4345    {
4346      /* Can we ignore the upper byte? */
4347      if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
4348	  && (INTVAL (operands[2]) & 0xff00) == 0xff00)
4349	{
4350	  CC_STATUS_INIT;
4351
4352	  if ((INTVAL (operands[2]) & 0xff) == 0)
4353	    {
4354	      operands[2] = const0_rtx;
4355	      return AS2 (mov%B0,%2,%b0);
4356	    }
4357
4358	  operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
4359	  return AS2 (and%B0,%2,%b0);
4360	}
4361
4362      /* Can we ignore the lower byte? */
4363      /* ??? what about offsettable memory references? */
4364      if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
4365	{
4366	  CC_STATUS_INIT;
4367
4368	  if ((INTVAL (operands[2]) & 0xff00) == 0)
4369	    {
4370	      operands[2] = const0_rtx;
4371	      return AS2 (mov%B0,%2,%h0);
4372	    }
4373
4374	  operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
4375	  return AS2 (and%B0,%2,%h0);
4376	}
4377
4378      /* use 32-bit ops on registers when there are no sign issues.. */
4379      if (REG_P (operands[0]))
4380	{
4381	  if (!(INTVAL (operands[2]) & ~0x7fff))
4382	    return AS2 (and%L0,%2,%k0);
4383	}
4384    }
4385
4386  if (REG_P (operands[0])
4387      && i386_aligned_p (operands[2]))
4388    {
4389      CC_STATUS_INIT;
4390      /* If op[2] is constant, we should zero-extend it and */
4391      /* make a note that op[0] has been zero-extended, so  */
4392      /* that we could use 32-bit ops on it forthwith, but  */
4393      /* there is no such reg-note available. Instead we do */
4394      /* a sign extension as that can result in shorter asm */
4395      operands[2] = i386_sext16_if_const (operands[2]);
4396      return AS2 (and%L0,%k2,%k0);
4397    }
4398
4399  /* Use a 32-bit word with the upper bits set, invalidate CC */
4400  if (GET_CODE (operands[2]) == CONST_INT
4401      && i386_aligned_p (operands[0]))
4402    {
4403      HOST_WIDE_INT val = INTVAL (operands[2]);
4404      CC_STATUS_INIT;
4405      val |= ~0xffff;
4406      if (val != INTVAL (operands[2]))
4407	operands[2] = GEN_INT (val);
4408      return AS2 (and%L0,%k2,%k0);
4409    }
4410
4411  return AS2 (and%W0,%2,%0);
4412}"
4413  [(set_attr "type" "binary")])
4414
4415(define_insn "andqi3"
4416  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4417	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4418		(match_operand:QI 2 "general_operand" "qn,qmn")))]
4419  ""
4420  "* return AS2 (and%B0,%2,%0);"
4421  [(set_attr "type" "binary")])
4422
4423/* I am nervous about these two.. add them later..
4424;I presume this means that we have something in say op0= eax which is small
4425;and we want to and it with memory so we can do this by just an
4426;andb m,%al  and have success.
4427(define_insn ""
4428  [(set (match_operand:SI 0 "general_operand" "=r")
4429	(and:SI (zero_extend:SI
4430		 (match_operand:HI 1 "nonimmediate_operand" "rm"))
4431		(match_operand:SI 2 "general_operand" "0")))]
4432  "GET_CODE (operands[2]) == CONST_INT
4433   && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
4434  "and%W0 %1,%0")
4435
4436(define_insn ""
4437  [(set (match_operand:SI 0 "register_operand" "=q")
4438	(and:SI
4439	 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
4440		(match_operand:SI 2 "register_operand" "0")))]
4441  "GET_CODE (operands[2]) == CONST_INT
4442   && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
4443  "and%L0 %1,%0")
4444
4445*/
4446
4447;;- Bit set (inclusive or) instructions
4448
4449;; This optimizes known byte-wide operations to memory, and in some cases
4450;; to QI registers.. Note that we don't want to use the QI registers too
4451;; aggressively, because often the 32-bit register instruction is the same
4452;; size, and likely to be faster on PentiumPro.
4453(define_insn "iorsi3"
4454  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4455	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4456		(match_operand:SI 2 "general_operand" "ri,rm")))]
4457  ""
4458  "*
4459{
4460  HOST_WIDE_INT intval;
4461  switch (GET_CODE (operands[2]))
4462    {
4463    case CONST_INT:
4464
4465      if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4466	break;
4467
4468      /* don't try to optimize volatile accesses */
4469      if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4470	break;
4471
4472      intval = INTVAL (operands[2]);
4473      if ((intval & ~0xff) == 0)
4474        {
4475	  if (REG_P (operands[0]))
4476	    {
4477	      /* Do low byte access only for %eax or when high bit is set */
4478	      if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4479	        break;
4480	    }
4481
4482byte_or_operation:
4483	    CC_STATUS_INIT;
4484
4485	    if (intval != INTVAL (operands[2]))
4486	      operands[2] = GEN_INT (intval);
4487
4488	    if (intval == 0xff)
4489	      return AS2 (mov%B0,%2,%b0);
4490
4491	    return AS2 (or%B0,%2,%b0);
4492	}
4493
4494      /* second byte? */
4495      if ((intval & ~0xff00) == 0)
4496	{
4497	  intval >>= 8;
4498
4499	  if (REG_P (operands[0]))
4500	    {
4501	      CC_STATUS_INIT;
4502	      operands[2] = GEN_INT (intval);
4503	      if (intval == 0xff)
4504		return AS2 (mov%B0,%2,%h0);
4505
4506	      return AS2 (or%B0,%2,%h0);
4507	    }
4508
4509	  operands[0] = adj_offsettable_operand (operands[0], 1);
4510	  goto byte_or_operation;
4511	}
4512
4513      if (REG_P (operands[0]))
4514	break;
4515
4516      /* third byte? */
4517      if ((intval & ~0xff0000) == 0)
4518	{
4519	  intval >>= 16;
4520	  operands[0] = adj_offsettable_operand (operands[0], 2);
4521	  goto byte_or_operation;
4522	}
4523
4524      /* fourth byte? */
4525      if ((intval & ~0xff000000) == 0)
4526	{
4527	  intval = (intval >> 24) & 0xff;
4528	  operands[0] = adj_offsettable_operand (operands[0], 3);
4529	  goto byte_or_operation;
4530	}
4531
4532    default:
4533      break;
4534    }
4535
4536  return AS2 (or%L0,%2,%0);
4537}"
4538  [(set_attr "type" "binary")])
4539
4540(define_insn "iorhi3"
4541  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4542	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4543		(match_operand:HI 2 "general_operand" "ri,rm")))]
4544  ""
4545  "*
4546{
4547  HOST_WIDE_INT intval;
4548  switch (GET_CODE (operands[2]))
4549    {
4550    case CONST_INT:
4551
4552      if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4553	break;
4554
4555      /* don't try to optimize volatile accesses */
4556      if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4557	break;
4558
4559      intval = 0xffff & INTVAL (operands[2]);
4560
4561      if ((intval & 0xff00) == 0)
4562        {
4563	  if (REG_P (operands[0]))
4564	    {
4565	      /* Do low byte access only for %eax or when high bit is set */
4566	      if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4567	        break;
4568	    }
4569
4570byte_or_operation:
4571	    CC_STATUS_INIT;
4572
4573	    if (intval == 0xff)
4574	      return AS2 (mov%B0,%2,%b0);
4575
4576	    return AS2 (or%B0,%2,%b0);
4577	}
4578
4579      /* high byte? */
4580      if ((intval & 0xff) == 0)
4581	{
4582	  intval >>= 8;
4583	  operands[2] = GEN_INT (intval);
4584
4585	  if (REG_P (operands[0]))
4586	    {
4587	      CC_STATUS_INIT;
4588	      if (intval == 0xff)
4589		return AS2 (mov%B0,%2,%h0);
4590
4591	      return AS2 (or%B0,%2,%h0);
4592	    }
4593
4594	  operands[0] = adj_offsettable_operand (operands[0], 1);
4595
4596	  goto byte_or_operation;
4597	}
4598
4599    default:
4600      break;
4601    }
4602
4603  if (REG_P (operands[0])
4604      && i386_aligned_p (operands[2]))
4605    {
4606      CC_STATUS_INIT;
4607      operands[2] = i386_sext16_if_const (operands[2]);
4608      return AS2 (or%L0,%k2,%k0);
4609    }
4610
4611  if (GET_CODE (operands[2]) == CONST_INT
4612      && i386_aligned_p (operands[0]))
4613    {
4614      CC_STATUS_INIT;
4615      intval = 0xffff & INTVAL (operands[2]);
4616      if (intval != INTVAL (operands[2]))
4617	operands[2] = GEN_INT (intval);
4618      return AS2 (or%L0,%2,%k0);
4619    }
4620
4621  return AS2 (or%W0,%2,%0);
4622}"
4623  [(set_attr "type" "binary")])
4624
4625(define_insn "iorqi3"
4626  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4627	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4628		(match_operand:QI 2 "general_operand" "qn,qmn")))]
4629  ""
4630  "* return AS2 (or%B0,%2,%0);"
4631  [(set_attr "type" "binary")])
4632
4633;;- xor instructions
4634
4635(define_insn "xorsi3"
4636  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4637	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4638		(match_operand:SI 2 "general_operand" "ri,rm")))]
4639  ""
4640  "*
4641{
4642  HOST_WIDE_INT intval;
4643  switch (GET_CODE (operands[2]))
4644    {
4645    case CONST_INT:
4646
4647      if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4648	break;
4649
4650      /* don't try to optimize volatile accesses */
4651      if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4652	break;
4653
4654      intval = INTVAL (operands[2]);
4655      if ((intval & ~0xff) == 0)
4656        {
4657	  if (REG_P (operands[0]))
4658	    {
4659	      /* Do low byte access only for %eax or when high bit is set */
4660	      if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4661	        break;
4662	    }
4663
4664byte_xor_operation:
4665	    CC_STATUS_INIT;
4666	      
4667	    if (intval == 0xff
4668                && (!TARGET_PENTIUM || optimize_size
4669                    || (GET_CODE (operands[0]) == MEM 
4670                        && memory_address_info (XEXP (operands[0], 0), 1))))
4671	      return AS1 (not%B0,%b0);
4672
4673	    if (intval != INTVAL (operands[2]))
4674	      operands[2] = GEN_INT (intval);
4675	    return AS2 (xor%B0,%2,%b0);
4676	}
4677
4678      /* second byte? */
4679      if ((intval & ~0xff00) == 0)
4680	{
4681	  intval >>= 8;
4682
4683	  if (REG_P (operands[0]))
4684	    {
4685	      CC_STATUS_INIT;
4686	      if (intval == 0xff 
4687                  && (!TARGET_PENTIUM || optimize_size
4688                      || (GET_CODE (operands[0]) == MEM 
4689                          && memory_address_info (XEXP (operands[0], 0), 1))))
4690		return AS1 (not%B0,%h0);
4691
4692	      operands[2] = GEN_INT (intval);
4693	      return AS2 (xor%B0,%2,%h0);
4694	    }
4695
4696	  operands[0] = adj_offsettable_operand (operands[0], 1);
4697
4698	  goto byte_xor_operation;
4699	}
4700
4701      if (REG_P (operands[0]))
4702	break;
4703
4704      /* third byte? */
4705      if ((intval & ~0xff0000) == 0)
4706	{
4707	  intval >>= 16;
4708	  operands[0] = adj_offsettable_operand (operands[0], 2);
4709	  goto byte_xor_operation;
4710	}
4711
4712      /* fourth byte? */
4713      if ((intval & ~0xff000000) == 0)
4714	{
4715	  intval = (intval >> 24) & 0xff;
4716	  operands[0] = adj_offsettable_operand (operands[0], 3);
4717	  goto byte_xor_operation;
4718	}
4719
4720    default:
4721      break;
4722    }
4723
4724  return AS2 (xor%L0,%2,%0);
4725}"
4726  [(set_attr "type" "binary")])
4727
4728(define_insn "xorhi3"
4729  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4730	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4731		(match_operand:HI 2 "general_operand" "ri,rm")))]
4732  ""
4733  "*
4734{
4735  if (GET_CODE (operands[2]) == CONST_INT
4736      && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
4737    {
4738      /* Can we ignore the upper byte? */
4739      if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
4740	  && (INTVAL (operands[2]) & 0xff00) == 0)
4741	{
4742	  CC_STATUS_INIT;
4743	  if (INTVAL (operands[2]) & 0xffff0000)
4744	    operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
4745
4746	  if (INTVAL (operands[2]) == 0xff 
4747              && (!TARGET_PENTIUM || optimize_size
4748                  || (GET_CODE (operands[0]) == MEM 
4749                      && memory_address_info (XEXP (operands[0], 0), 1))))
4750	    return AS1 (not%B0,%b0);
4751
4752	  return AS2 (xor%B0,%2,%b0);
4753	}
4754
4755      /* Can we ignore the lower byte? */
4756      /* ??? what about offsettable memory references? */
4757      if (QI_REG_P (operands[0])
4758	  && (INTVAL (operands[2]) & 0xff) == 0)
4759	{
4760	  CC_STATUS_INIT;
4761	  operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
4762
4763	  if (INTVAL (operands[2]) == 0xff
4764              && (!TARGET_PENTIUM || optimize_size
4765                  || (GET_CODE (operands[0]) == MEM 
4766                      && memory_address_info (XEXP (operands[0], 0), 1))))
4767	    return AS1 (not%B0,%h0);
4768
4769	  return AS2 (xor%B0,%2,%h0);
4770	}
4771    }
4772
4773  if (REG_P (operands[0])
4774      && i386_aligned_p (operands[2]))
4775    {
4776      CC_STATUS_INIT;
4777      operands[2] = i386_sext16_if_const (operands[2]);
4778      return AS2 (xor%L0,%k2,%k0);
4779    }
4780
4781  if (GET_CODE (operands[2]) == CONST_INT
4782      && i386_aligned_p (operands[0]))
4783    {
4784      HOST_WIDE_INT intval;
4785      CC_STATUS_INIT;
4786      intval = 0xffff & INTVAL (operands[2]);
4787      if (intval != INTVAL (operands[2]))
4788	operands[2] = GEN_INT (intval);
4789      return AS2 (xor%L0,%2,%k0);
4790    }
4791
4792  return AS2 (xor%W0,%2,%0);
4793}"
4794  [(set_attr "type" "binary")])
4795
4796(define_insn "xorqi3"
4797  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4798	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4799		(match_operand:QI 2 "general_operand" "qn,qm")))]
4800  ""
4801  "* return AS2 (xor%B0,%2,%0);"
4802  [(set_attr "type" "binary")])
4803
4804;; logical operations for DImode
4805
4806(define_insn "anddi3"
4807  [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4808	(and:DI (match_operand:DI 1 "general_operand" "%0,0")
4809		(match_operand:DI 2 "general_operand" "oriF,riF")))]
4810  ""
4811  "#"
4812  [(set_attr "type" "binary")])
4813
4814
4815(define_insn "iordi3"
4816  [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4817	(ior:DI (match_operand:DI 1 "general_operand" "%0,0")
4818		(match_operand:DI 2 "general_operand" "oriF,riF")))]
4819  ""
4820  "#"
4821  [(set_attr "type" "binary")])
4822
4823(define_insn "xordi3"
4824  [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4825	(xor:DI (match_operand:DI 1 "general_operand" "%0,0")
4826		(match_operand:DI 2 "general_operand" "oriF,riF")))]
4827  ""
4828  "#"
4829  [(set_attr "type" "binary")])
4830
4831(define_split
4832  [(set (match_operand:DI 0 "general_operand" "")
4833	(match_operator:DI 3 "ix86_logical_operator"
4834	  [(match_operand:DI 1 "general_operand" "")
4835	   (match_operand:DI 2 "general_operand" "")]))]
4836  ""
4837  [(set (match_dup 4) (match_op_dup:SI 3 [(match_dup 6) (match_dup 8)]))
4838   (set (match_dup 5) (match_op_dup:SI 3 [(match_dup 7) (match_dup 9)]))]
4839  "split_di (&operands[0], 1, &operands[4], &operands[5]);
4840   split_di (&operands[1], 1, &operands[6], &operands[7]);
4841   split_di (&operands[2], 1, &operands[8], &operands[9]);")
4842
4843;;- negation instructions
4844
4845(define_insn "negdi2"
4846  [(set (match_operand:DI 0 "general_operand" "=&ro")
4847	(neg:DI (match_operand:DI 1 "general_operand" "0")))]
4848  ""
4849  "*
4850{
4851  rtx xops[2], low[1], high[1];
4852
4853  CC_STATUS_INIT;
4854
4855  split_di (operands, 1, low, high);
4856  xops[0] = const0_rtx;
4857  xops[1] = high[0];
4858
4859  output_asm_insn (AS1 (neg%L0,%0), low);
4860  output_asm_insn (AS2 (adc%L1,%0,%1), xops);
4861  output_asm_insn (AS1 (neg%L0,%0), high);
4862  RET;
4863}")
4864
4865(define_insn "negsi2"
4866  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4867	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
4868  ""
4869  "neg%L0 %0")
4870
4871(define_insn "neghi2"
4872  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4873	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
4874  ""
4875  "*
4876    if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn))
4877      {
4878	CC_STATUS_INIT;
4879	return AS1(neg%L0,%k0);
4880      }
4881    return AS1(neg%W0,%0);")
4882
4883(define_insn "negqi2"
4884  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4885	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
4886  ""
4887  "neg%B0 %0")
4888
4889(define_insn "negsf2"
4890  [(set (match_operand:SF 0 "register_operand" "=f")
4891	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
4892  "TARGET_80387"
4893  "fchs"
4894  [(set_attr "type" "fpop")])
4895
4896(define_insn "negdf2"
4897  [(set (match_operand:DF 0 "register_operand" "=f")
4898	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
4899  "TARGET_80387"
4900  "fchs"
4901  [(set_attr "type" "fpop")])
4902
4903(define_insn ""
4904  [(set (match_operand:DF 0 "register_operand" "=f")
4905	(neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
4906  "TARGET_80387"
4907  "fchs"
4908  [(set_attr "type" "fpop")])
4909
4910(define_insn "negxf2"
4911  [(set (match_operand:XF 0 "register_operand" "=f")
4912	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
4913  "TARGET_80387"
4914  "fchs"
4915  [(set_attr "type" "fpop")])
4916
4917(define_insn ""
4918  [(set (match_operand:XF 0 "register_operand" "=f")
4919	(neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4920  "TARGET_80387"
4921  "fchs"
4922  [(set_attr "type" "fpop")])
4923
4924;; Absolute value instructions
4925
4926(define_insn "abssf2"
4927  [(set (match_operand:SF 0 "register_operand" "=f")
4928	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
4929  "TARGET_80387"
4930  "fabs"
4931  [(set_attr "type" "fpop")])
4932
4933(define_insn "absdf2"
4934  [(set (match_operand:DF 0 "register_operand" "=f")
4935	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
4936  "TARGET_80387"
4937  "fabs"
4938  [(set_attr "type" "fpop")])
4939
4940(define_insn ""
4941  [(set (match_operand:DF 0 "register_operand" "=f")
4942	(abs:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
4943  "TARGET_80387"
4944  "fabs"
4945  [(set_attr "type" "fpop")])
4946
4947(define_insn "absxf2"
4948  [(set (match_operand:XF 0 "register_operand" "=f")
4949	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
4950  "TARGET_80387"
4951  "fabs"
4952  [(set_attr "type" "fpop")])
4953
4954(define_insn ""
4955  [(set (match_operand:XF 0 "register_operand" "=f")
4956	(abs:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4957  "TARGET_80387"
4958  "fabs"
4959  [(set_attr "type" "fpop")])
4960
4961(define_insn "sqrtsf2"
4962  [(set (match_operand:SF 0 "register_operand" "=f")
4963	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
4964  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4965  "fsqrt")
4966
4967(define_insn "sqrtdf2"
4968  [(set (match_operand:DF 0 "register_operand" "=f")
4969	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
4970  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4971   && (TARGET_IEEE_FP || flag_fast_math) "
4972  "fsqrt")
4973
4974(define_insn ""
4975  [(set (match_operand:DF 0 "register_operand" "=f")
4976	(sqrt:DF (float_extend:DF
4977		  (match_operand:SF 1 "register_operand" "0"))))]
4978  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4979  "fsqrt")
4980
4981(define_insn "sqrtxf2"
4982  [(set (match_operand:XF 0 "register_operand" "=f")
4983	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
4984  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
4985   && (TARGET_IEEE_FP || flag_fast_math) "
4986  "fsqrt")
4987
4988(define_insn ""
4989  [(set (match_operand:XF 0 "register_operand" "=f")
4990	(sqrt:XF (float_extend:XF
4991		  (match_operand:DF 1 "register_operand" "0"))))]
4992  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4993  "fsqrt")
4994
4995(define_insn ""
4996  [(set (match_operand:XF 0 "register_operand" "=f")
4997	(sqrt:XF (float_extend:XF
4998		  (match_operand:SF 1 "register_operand" "0"))))]
4999  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
5000  "fsqrt")
5001
5002(define_insn "sindf2"
5003  [(set (match_operand:DF 0 "register_operand" "=f")
5004	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
5005  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5006  "fsin")
5007
5008(define_insn "sinsf2"
5009  [(set (match_operand:SF 0 "register_operand" "=f")
5010	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
5011  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5012  "fsin")
5013
5014(define_insn ""
5015  [(set (match_operand:DF 0 "register_operand" "=f")
5016	(unspec:DF [(float_extend:DF
5017		     (match_operand:SF 1 "register_operand" "0"))] 1))]
5018  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5019  "fsin")
5020
5021(define_insn "sinxf2"
5022  [(set (match_operand:XF 0 "register_operand" "=f")
5023	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
5024  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5025  "fsin")
5026
5027(define_insn "cosdf2"
5028  [(set (match_operand:DF 0 "register_operand" "=f")
5029	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
5030  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5031  "fcos")
5032
5033(define_insn "cossf2"
5034  [(set (match_operand:SF 0 "register_operand" "=f")
5035	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
5036  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5037  "fcos")
5038
5039(define_insn ""
5040  [(set (match_operand:DF 0 "register_operand" "=f")
5041	(unspec:DF [(float_extend:DF
5042		     (match_operand:SF 1 "register_operand" "0"))] 2))]
5043  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5044  "fcos")
5045
5046(define_insn "cosxf2"
5047  [(set (match_operand:XF 0 "register_operand" "=f")
5048	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
5049  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5050  "fcos")
5051
5052;;- one complement instructions
5053
5054(define_insn "one_cmplsi2"
5055  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5056	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
5057  ""
5058  "*
5059{
5060  /* A Pentium NOT is not pariable.  Output it only in case of complex
5061     memory address, because XOR will be inpariable anyway because
5062     of immediate/displacement rule.  */
5063
5064  if (TARGET_PENTIUM && !optimize_size
5065      && (GET_CODE (operands[0]) != MEM 
5066	  || memory_address_info (XEXP (operands[0], 0), 1) == 0))
5067    {
5068      rtx xops[2];
5069      xops[0] = operands[0];
5070      xops[1] = GEN_INT (0xffffffff);
5071      output_asm_insn (AS2 (xor%L0,%1,%0), xops);
5072      RET;
5073    }
5074  else
5075    return AS1 (not%L0,%0);
5076}")
5077
5078(define_insn "one_cmplhi2"
5079  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5080	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
5081  ""
5082  "*
5083{
5084  /* A Pentium NOT is not pariable.  Output it only in case of complex
5085     memory address, because XOR will be inpariable anyway because
5086     of immediate/displacement rule.  */
5087
5088  if (TARGET_PENTIUM && !optimize_size
5089      && (GET_CODE (operands[0]) != MEM 
5090	  || memory_address_info (XEXP (operands[0], 0), 1) == 0))
5091    {
5092      rtx xops[2];
5093      xops[0] = operands[0];
5094      xops[1] = GEN_INT (0xffff);
5095      if (REG_P (operands[0])
5096	  && i386_cc_probably_useless_p (insn))
5097       {
5098	  CC_STATUS_INIT;
5099	  output_asm_insn (AS2 (xor%L0,%1,%k0), xops);
5100       }
5101      else
5102	output_asm_insn (AS2 (xor%W0,%1,%0), xops);
5103      RET;
5104    }
5105  else
5106    {
5107      if (REG_P (operands[0])
5108	  && i386_cc_probably_useless_p (insn))
5109	{
5110	  CC_STATUS_INIT;
5111	  return AS1 (not%L0,%k0);
5112	}
5113      return AS1 (not%W0,%0);
5114    }
5115}")
5116
5117(define_insn "one_cmplqi2"
5118  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5119	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
5120  ""
5121  "*
5122{
5123  /* A Pentium NOT is not pariable.  Output it only in case of complex
5124     memory address, because XOR will be inpariable anyway because
5125     of immediate/displacement rule.  */
5126
5127  if (TARGET_PENTIUM && !optimize_size
5128      && (GET_CODE (operands[0]) != MEM 
5129	  || memory_address_info (XEXP (operands[0], 0), 1) == 0))
5130    {
5131      rtx xops[2];
5132      xops[0] = operands[0];
5133      xops[1] = GEN_INT (0xff);
5134      output_asm_insn (AS2 (xor%B0,%1,%0), xops);
5135      RET;
5136    }
5137  else
5138    return AS1 (not%B0,%0);
5139}")
5140
5141;;- arithmetic shift instructions
5142
5143;; DImode shifts are implemented using the i386 "shift double" opcode,
5144;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
5145;; is variable, then the count is in %cl and the "imm" operand is dropped
5146;; from the assembler input.
5147
5148;; This instruction shifts the target reg/mem as usual, but instead of
5149;; shifting in zeros, bits are shifted in from reg operand.  If the insn
5150;; is a left shift double, bits are taken from the high order bits of
5151;; reg, else if the insn is a shift right double, bits are taken from the
5152;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
5153;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
5154
5155;; Since sh[lr]d does not change the `reg' operand, that is done
5156;; separately, making all shifts emit pairs of shift double and normal
5157;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
5158;; support a 63 bit shift, each shift where the count is in a reg expands
5159;; to a pair of shifts, a branch, a shift by 32 and a label.
5160
5161;; If the shift count is a constant, we need never emit more than one
5162;; shift pair, instead using moves and sign extension for counts greater
5163;; than 31.
5164
5165(define_expand "ashldi3"
5166  [(set (match_operand:DI 0 "register_operand" "")
5167	(ashift:DI (match_operand:DI 1 "register_operand" "")
5168		   (match_operand:QI 2 "nonmemory_operand" "")))]
5169  ""
5170  "
5171{
5172  if (GET_CODE (operands[2]) != CONST_INT
5173      || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
5174    {
5175      operands[2] = copy_to_mode_reg (QImode, operands[2]);
5176      emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
5177					    operands[2]));
5178    }
5179  else
5180    emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
5181
5182  DONE;
5183}")
5184
5185(define_insn "ashldi3_const_int"
5186  [(set (match_operand:DI 0 "register_operand" "=&r")
5187	(ashift:DI (match_operand:DI 1 "register_operand" "0")
5188		   (match_operand:QI 2 "const_int_operand" "J")))]
5189  "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
5190  "*
5191{
5192  rtx xops[4], low[1], high[1];
5193
5194  CC_STATUS_INIT;
5195
5196  split_di (operands, 1, low, high);
5197  xops[0] = operands[2];
5198  xops[1] = const1_rtx;
5199  xops[2] = low[0];
5200  xops[3] = high[0];
5201
5202  if (INTVAL (xops[0]) > 31)
5203    {
5204      output_asm_insn (AS2 (mov%L3,%2,%3), xops);	/* Fast shift by 32 */
5205      output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5206
5207      if (INTVAL (xops[0]) > 32)
5208        {
5209	  xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
5210	  output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
5211	}
5212    }
5213  else
5214    {
5215      output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
5216      output_asm_insn (AS2 (sal%L2,%0,%2), xops);
5217    }
5218  RET;
5219}")
5220
5221(define_insn "ashldi3_non_const_int"
5222  [(set (match_operand:DI 0 "register_operand" "=&r")
5223	(ashift:DI (match_operand:DI 1 "register_operand" "0")
5224		   (match_operand:QI 2 "register_operand" "c")))]
5225  ""
5226  "*
5227{
5228  rtx xops[5], low[1], high[1];
5229
5230  CC_STATUS_INIT;
5231
5232  split_di (operands, 1, low, high);
5233  xops[0] = operands[2];
5234  xops[1] = GEN_INT (32);
5235  xops[2] = low[0];
5236  xops[3] = high[0];
5237  xops[4] = gen_label_rtx ();
5238
5239  output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
5240  output_asm_insn (AS2 (sal%L2,%0,%2), xops);
5241  output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5242  output_asm_insn (AS1 (je,%X4), xops);
5243  output_asm_insn (AS2 (mov%L3,%2,%3), xops);	/* Fast shift by 32 */
5244  output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5245  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5246                             CODE_LABEL_NUMBER (xops[4]));
5247  RET;
5248}")
5249
5250(define_expand "ashlsi3"
5251  [(set (match_operand:SI 0 "nonimmediate_operand" "")
5252	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
5253		   (match_operand:SI 2 "nonmemory_operand" "")))]
5254  ""
5255  "")
5256
5257(define_expand "ashlhi3"
5258  [(set (match_operand:HI 0 "nonimmediate_operand" "")
5259	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
5260		   (match_operand:HI 2 "nonmemory_operand" "")))]
5261  ""
5262  "")
5263
5264(define_expand "ashlqi3"
5265  [(set (match_operand:QI 0 "nonimmediate_operand" "")
5266	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
5267		   (match_operand:QI 2 "nonmemory_operand" "")))]
5268  ""
5269  "")
5270
5271;; Pattern for shifts which can be encoded into an lea instruction.
5272;; This is kept as a separate pattern so that regmove can optimize cases
5273;; where we know the source and destination must match.
5274;;
5275;; Do not expose this pattern when optimizing for size since we never want
5276;; to use lea when optimizing for size since mov+sal is smaller than lea.
5277
5278(define_insn ""
5279  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
5280	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
5281		   (match_operand:SI 2 "small_shift_operand" "M,M")))]
5282  "! optimize_size"
5283  "* return output_ashl (insn, operands);")
5284
5285;; Generic left shift pattern to catch all cases not handled by the
5286;; shift pattern above.
5287(define_insn ""
5288  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5289	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5290		   (match_operand:SI 2 "nonmemory_operand" "cI")))]
5291  ""
5292  "* return output_ashl (insn, operands);")
5293
5294(define_insn ""
5295  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r")
5296	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
5297		   (match_operand:HI 2 "small_shift_operand" "M,M")))]
5298  "! optimize_size"
5299  "* return output_ashl (insn, operands);")
5300
5301(define_insn ""
5302  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5303	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5304		   (match_operand:HI 2 "nonmemory_operand" "cI")))]
5305  ""
5306  "* return output_ashl (insn, operands);")
5307
5308(define_insn ""
5309  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q")
5310	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,q")
5311		   (match_operand:QI 2 "small_shift_operand" "M,M")))]
5312  "! optimize_size"
5313  "* return output_ashl (insn, operands);")
5314
5315;; Generic left shift pattern to catch all cases not handled by the
5316;; shift pattern above.
5317(define_insn ""
5318  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5319	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5320		   (match_operand:QI 2 "nonmemory_operand" "cI")))]
5321  ""
5322  "* return output_ashl (insn, operands);")
5323
5324;; See comment above `ashldi3' about how this works.
5325
5326(define_expand "ashrdi3"
5327  [(set (match_operand:DI 0 "register_operand" "")
5328	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5329		     (match_operand:QI 2 "nonmemory_operand" "")))]
5330  ""
5331  "
5332{
5333  if (GET_CODE (operands[2]) != CONST_INT
5334      || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
5335    {
5336      operands[2] = copy_to_mode_reg (QImode, operands[2]);
5337      emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1],
5338					    operands[2]));
5339    }
5340  else
5341    emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2]));
5342
5343  DONE;
5344}")
5345
5346(define_insn "ashldi3_32"
5347  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
5348	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
5349		   (const_int 32)))]
5350  ""
5351  "*
5352{
5353  rtx low[2], high[2], xops[4];
5354
5355  split_di (operands, 2, low, high);
5356  xops[0] = high[0];
5357  xops[1] = low[1];
5358  xops[2] = low[0];
5359  xops[3] = const0_rtx;
5360  if (!rtx_equal_p (xops[0], xops[1]))
5361    output_asm_insn (AS2 (mov%L0,%1,%0), xops);
5362
5363  if (GET_CODE (low[0]) == MEM)
5364    output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5365  else
5366    output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5367
5368  RET;
5369}")
5370
5371(define_insn "ashrdi3_const_int"
5372  [(set (match_operand:DI 0 "register_operand" "=&r")
5373	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
5374		     (match_operand:QI 2 "const_int_operand" "J")))]
5375  "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
5376  "*
5377{
5378  rtx xops[4], low[1], high[1];
5379
5380  CC_STATUS_INIT;
5381
5382  split_di (operands, 1, low, high);
5383  xops[0] = operands[2];
5384  xops[1] = const1_rtx;
5385  xops[2] = low[0];
5386  xops[3] = high[0];
5387
5388  if (INTVAL (xops[0]) > 31)
5389    {
5390      xops[1] = GEN_INT (31);
5391      output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5392      output_asm_insn (AS2 (sar%L3,%1,%3), xops);	/* shift by 32 */
5393
5394      if (INTVAL (xops[0]) > 32)
5395        {
5396	  xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
5397	  output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */
5398	}
5399    }
5400  else
5401    {
5402      output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
5403      output_asm_insn (AS2 (sar%L3,%0,%3), xops);
5404    }
5405
5406  RET;
5407}")
5408
5409(define_insn "ashrdi3_non_const_int"
5410  [(set (match_operand:DI 0 "register_operand" "=&r")
5411	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
5412		     (match_operand:QI 2 "register_operand" "c")))]
5413  ""
5414  "*
5415{
5416  rtx xops[5], low[1], high[1];
5417
5418  CC_STATUS_INIT;
5419
5420  split_di (operands, 1, low, high);
5421  xops[0] = operands[2];
5422  xops[1] = GEN_INT (32);
5423  xops[2] = low[0];
5424  xops[3] = high[0];
5425  xops[4] = gen_label_rtx ();
5426
5427  output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
5428  output_asm_insn (AS2 (sar%L3,%0,%3), xops);
5429  output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5430  output_asm_insn (AS1 (je,%X4), xops);
5431  xops[1] = GEN_INT (31);
5432  output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5433  output_asm_insn (AS2 (sar%L3,%1,%3), xops);	/* shift by 32 */
5434  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5435                             CODE_LABEL_NUMBER (xops[4]));
5436  RET;
5437}")
5438
5439(define_insn "ashrsi3_31"
5440  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d")
5441	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a")
5442		     (const_int 31)))]
5443  "!TARGET_PENTIUM || optimize_size"
5444  "@
5445    sar%L0 $31,%0
5446    cltd")
5447
5448(define_insn "ashrsi3"
5449  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5450	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5451		     (match_operand:SI 2 "nonmemory_operand" "cI")))]
5452  ""
5453  "*
5454{
5455  if (REG_P (operands[2]))
5456    return AS2 (sar%L0,%b2,%0);
5457  else
5458    return AS2 (sar%L0,%2,%0);
5459}")
5460
5461(define_insn "ashrhi3"
5462  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5463	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5464		     (match_operand:HI 2 "nonmemory_operand" "cI")))]
5465  ""
5466  "*
5467{
5468  if (REG_P (operands[2]))
5469    return AS2 (sar%W0,%b2,%0);
5470  else
5471    return AS2 (sar%W0,%2,%0);
5472}")
5473
5474(define_insn "ashrqi3"
5475  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5476	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5477		     (match_operand:QI 2 "nonmemory_operand" "cI")))]
5478  ""
5479  "*
5480{
5481  if (REG_P (operands[2]))
5482    return AS2 (sar%B0,%b2,%0);
5483  else
5484    return AS2 (sar%B0,%2,%0);
5485}")
5486
5487;;- logical shift instructions
5488
5489;; See comment above `ashldi3' about how this works.
5490
5491(define_expand "lshrdi3"
5492  [(set (match_operand:DI 0 "register_operand" "")
5493	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5494		     (match_operand:QI 2 "nonmemory_operand" "")))]
5495  ""
5496  "
5497{
5498  if (GET_CODE (operands[2]) != CONST_INT
5499      || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
5500    {
5501      operands[2] = copy_to_mode_reg (QImode, operands[2]);
5502      emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
5503					    operands[2]));
5504    }
5505  else
5506    emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
5507
5508  DONE;
5509}")
5510
5511(define_insn "lshrdi3_32"
5512  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
5513	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
5514		     (const_int 32)))]
5515  ""
5516  "*
5517{
5518  rtx low[2], high[2], xops[4];
5519
5520  split_di (operands, 2, low, high);
5521  xops[0] = low[0];
5522  xops[1] = high[1];
5523  xops[2] = high[0];
5524  xops[3] = const0_rtx;
5525  if (!rtx_equal_p (xops[0], xops[1]))
5526    output_asm_insn (AS2 (mov%L0,%1,%0), xops);
5527
5528  if (GET_CODE (low[0]) == MEM)
5529    output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5530  else
5531    output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5532
5533  RET;
5534}")
5535
5536(define_insn "lshrdi3_const_int"
5537  [(set (match_operand:DI 0 "register_operand" "=&r")
5538	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5539		     (match_operand:QI 2 "const_int_operand" "J")))]
5540  "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
5541  "*
5542{
5543  rtx xops[4], low[1], high[1];
5544
5545  CC_STATUS_INIT;
5546
5547  split_di (operands, 1, low, high);
5548  xops[0] = operands[2];
5549  xops[1] = const1_rtx;
5550  xops[2] = low[0];
5551  xops[3] = high[0];
5552
5553  if (INTVAL (xops[0]) > 31)
5554    {
5555      output_asm_insn (AS2 (mov%L2,%3,%2), xops);	/* Fast shift by 32 */
5556      output_asm_insn (AS2 (xor%L3,%3,%3), xops);
5557
5558      if (INTVAL (xops[0]) > 32)
5559        {
5560	  xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
5561	  output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
5562	}
5563    }
5564  else
5565    {
5566      output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
5567      output_asm_insn (AS2 (shr%L3,%0,%3), xops);
5568    }
5569
5570  RET;
5571}")
5572
5573(define_insn "lshrdi3_non_const_int"
5574  [(set (match_operand:DI 0 "register_operand" "=&r")
5575	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5576		     (match_operand:QI 2 "register_operand" "c")))]
5577  ""
5578  "*
5579{
5580  rtx xops[5], low[1], high[1];
5581
5582  CC_STATUS_INIT;
5583
5584  split_di (operands, 1, low, high);
5585  xops[0] = operands[2];
5586  xops[1] = GEN_INT (32);
5587  xops[2] = low[0];
5588  xops[3] = high[0];
5589  xops[4] = gen_label_rtx ();
5590
5591  output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
5592  output_asm_insn (AS2 (shr%L3,%0,%3), xops);
5593  output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5594  output_asm_insn (AS1 (je,%X4), xops);
5595  output_asm_insn (AS2 (mov%L2,%3,%2), xops);	/* Fast shift by 32 */
5596  output_asm_insn (AS2 (xor%L3,%3,%3), xops);
5597  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5598                             CODE_LABEL_NUMBER (xops[4]));
5599  RET;
5600}")
5601
5602(define_insn "lshrsi3"
5603  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5604	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5605		     (match_operand:SI 2 "nonmemory_operand" "cI")))]
5606  ""
5607  "*
5608{
5609  if (REG_P (operands[2]))
5610    return AS2 (shr%L0,%b2,%0);
5611  else
5612    return AS2 (shr%L0,%2,%1);
5613}")
5614
5615(define_insn "lshrhi3"
5616  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5617	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5618		     (match_operand:HI 2 "nonmemory_operand" "cI")))]
5619  ""
5620  "*
5621{
5622  if (REG_P (operands[2]))
5623    return AS2 (shr%W0,%b2,%0);
5624  else
5625    return AS2 (shr%W0,%2,%0);
5626}")
5627
5628(define_insn "lshrqi3"
5629  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5630	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5631		     (match_operand:QI 2 "nonmemory_operand" "cI")))]
5632  ""
5633  "*
5634{
5635  if (REG_P (operands[2]))
5636    return AS2 (shr%B0,%b2,%0);
5637  else
5638    return AS2 (shr%B0,%2,%0);
5639}")
5640
5641;;- rotate instructions
5642
5643(define_insn "rotlsi3"
5644  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5645	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5646		   (match_operand:SI 2 "nonmemory_operand" "cI")))]
5647  ""
5648  "*
5649{
5650  if (REG_P (operands[2]))
5651    return AS2 (rol%L0,%b2,%0);
5652  else
5653    return AS2 (rol%L0,%2,%0);
5654}")
5655
5656(define_insn "rotlhi3"
5657  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5658	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5659		   (match_operand:HI 2 "nonmemory_operand" "cI")))]
5660  ""
5661  "*
5662{
5663  if (REG_P (operands[2]))
5664    return AS2 (rol%W0,%b2,%0);
5665  else
5666    return AS2 (rol%W0,%2,%0);
5667}")
5668
5669(define_insn "rotlqi3"
5670  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5671	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5672		   (match_operand:QI 2 "nonmemory_operand" "cI")))]
5673  ""
5674  "*
5675{
5676  if (REG_P (operands[2]))
5677    return AS2 (rol%B0,%b2,%0);
5678  else
5679    return AS2 (rol%B0,%2,%0);
5680}")
5681
5682(define_insn "rotrsi3"
5683  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5684	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5685		     (match_operand:SI 2 "nonmemory_operand" "cI")))]
5686  ""
5687  "*
5688{
5689  if (REG_P (operands[2]))
5690    return AS2 (ror%L0,%b2,%0);
5691  else
5692    return AS2 (ror%L0,%2,%0);
5693}")
5694
5695(define_insn "rotrhi3"
5696  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5697	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5698		     (match_operand:HI 2 "nonmemory_operand" "cI")))]
5699  ""
5700  "*
5701{
5702  if (REG_P (operands[2]))
5703    return AS2 (ror%W0,%b2,%0);
5704  else
5705    return AS2 (ror%W0,%2,%0);
5706}")
5707
5708(define_insn "rotrqi3"
5709  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5710	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5711		     (match_operand:QI 2 "nonmemory_operand" "cI")))]
5712  ""
5713  "*
5714{
5715  if (REG_P (operands[2]))
5716    return AS2 (ror%B0,%b2,%0);
5717  else
5718    return AS2 (ror%B0,%2,%0);
5719}")
5720
5721/*
5722;; This usually looses.  But try a define_expand to recognize a few case
5723;; we can do efficiently, such as accessing the "high" QImode registers,
5724;; %ah, %bh, %ch, %dh.
5725;; ??? Note this has a botch on the mode of operand 0, which needs to be
5726;; fixed if this is ever enabled.
5727(define_insn "insv"
5728  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
5729			 (match_operand:SI 1 "immediate_operand" "i")
5730			 (match_operand:SI 2 "immediate_operand" "i"))
5731	(match_operand:SI 3 "nonmemory_operand" "ri"))]
5732  ""
5733  "*
5734{
5735  if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
5736    abort ();
5737  if (GET_CODE (operands[3]) == CONST_INT)
5738    {
5739      unsigned int mask = (1 << INTVAL (operands[1])) - 1; 
5740      operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
5741      output_asm_insn (AS2 (and%L0,%1,%0), operands);
5742      operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
5743      output_asm_insn (AS2 (or%L0,%3,%0), operands);
5744    }
5745  else
5746    {
5747      operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
5748      if (INTVAL (operands[2]))
5749	output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5750      output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
5751      operands[2] = GEN_INT (BITS_PER_WORD
5752			     - INTVAL (operands[1]) - INTVAL (operands[2]));
5753      if (INTVAL (operands[2]))
5754	output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5755    }
5756  RET;
5757}")
5758*/
5759/*
5760;; ??? There are problems with the mode of operand[3].  The point of this
5761;; is to represent an HImode move to a "high byte" register.
5762
5763(define_expand "insv"
5764  [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
5765			 (match_operand:SI 1 "immediate_operand" "")
5766			 (match_operand:SI 2 "immediate_operand" ""))
5767	(match_operand:QI 3 "nonmemory_operand" "ri"))]
5768  ""
5769  "
5770{
5771  if (GET_CODE (operands[1]) != CONST_INT
5772      || GET_CODE (operands[2]) != CONST_INT)
5773    FAIL;
5774
5775  if (! (INTVAL (operands[1]) == 8
5776	 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
5777      && ! INTVAL (operands[1]) == 1)
5778    FAIL;
5779}")
5780*/
5781
5782;; On i386, the register count for a bit operation is *not* truncated,
5783;; so SHIFT_COUNT_TRUNCATED must not be defined.
5784
5785;; On i486, the shift & or/and code is faster than bts or btr.  If
5786;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
5787
5788;; On i386, bts is a little faster if operands[0] is a reg, and a
5789;; little slower if operands[0] is a MEM, than the shift & or/and code.
5790;; Use bts & btr, since they reload better.
5791
5792;; General bit set and clear.
5793(define_insn ""
5794  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm")
5795			 (const_int 1)
5796			 (match_operand:SI 2 "register_operand" "r"))
5797	(match_operand:SI 3 "const_int_operand" "n"))]
5798  "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5799  "*
5800{
5801  CC_STATUS_INIT;
5802
5803  if (INTVAL (operands[3]) == 1)
5804    return AS2 (bts%L0,%2,%0);
5805  else
5806    return AS2 (btr%L0,%2,%0);
5807}")
5808
5809;; Bit complement.  See comments on previous pattern.
5810;; ??? Is this really worthwhile?
5811(define_insn ""
5812  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5813	(xor:SI (ashift:SI (const_int 1)
5814			   (match_operand:SI 1 "register_operand" "r"))
5815		(match_operand:SI 2 "nonimmediate_operand" "0")))]
5816  "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT"
5817  "*
5818{
5819  CC_STATUS_INIT;
5820
5821  return AS2 (btc%L0,%1,%0);
5822}")
5823
5824(define_insn ""
5825  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5826	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5827		(ashift:SI (const_int 1)
5828			   (match_operand:SI 2 "register_operand" "r"))))]
5829  "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5830  "*
5831{
5832  CC_STATUS_INIT;
5833
5834  return AS2 (btc%L0,%2,%0);
5835}")
5836
5837;; Recognizers for bit-test instructions.
5838
5839;; The bt opcode allows a MEM in operands[0].  But on both i386 and
5840;; i486, it is faster to copy a MEM to REG and then use bt, than to use
5841;; bt on the MEM directly.
5842
5843;; ??? The first argument of a zero_extract must not be reloaded, so
5844;; don't allow a MEM in the operand predicate without allowing it in the
5845;; constraint.
5846
5847(define_insn ""
5848  [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5849			    (const_int 1)
5850			    (match_operand:SI 1 "register_operand" "r")))]
5851  "GET_CODE (operands[1]) != CONST_INT"
5852  "*
5853{
5854  cc_status.flags |= CC_Z_IN_NOT_C;
5855  return AS2 (bt%L0,%1,%0);
5856}")
5857
5858(define_insn ""
5859  [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5860			    (match_operand:SI 1 "const_int_operand" "n")
5861			    (match_operand:SI 2 "const_int_operand" "n")))]
5862  ""
5863  "*
5864{
5865  unsigned int mask;
5866
5867  mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5868  operands[1] = GEN_INT (mask);
5869
5870  if (QI_REG_P (operands[0])
5871      /* A Pentium test is pairable only with eax. Not with ah or al.  */
5872      && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
5873          || optimize_size))
5874    {
5875      if ((mask & ~0xff) == 0)
5876        {
5877	  cc_status.flags |= CC_NOT_NEGATIVE;
5878	  return AS2 (test%B0,%1,%b0);
5879	}
5880
5881      if ((mask & ~0xff00) == 0)
5882        {
5883	  cc_status.flags |= CC_NOT_NEGATIVE;
5884	  operands[1] = GEN_INT (mask >> 8);
5885	  return AS2 (test%B0,%1,%h0);
5886	}
5887    }
5888
5889  return AS2 (test%L0,%1,%0);
5890}")
5891
5892;; ??? All bets are off if operand 0 is a volatile MEM reference.
5893;; The CPU may access unspecified bytes around the actual target byte.
5894
5895(define_insn ""
5896  [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
5897			    (match_operand:SI 1 "const_int_operand" "n")
5898			    (match_operand:SI 2 "const_int_operand" "n")))]
5899  "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
5900  "*
5901{
5902  unsigned int mask;
5903
5904  mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5905  operands[1] = GEN_INT (mask);
5906
5907  if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
5908      /* A Pentium test is pairable only with eax. Not with ah or al.  */
5909      && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
5910          || optimize_size))
5911    {
5912      if ((mask & ~0xff) == 0)
5913        {
5914	  cc_status.flags |= CC_NOT_NEGATIVE;
5915	  return AS2 (test%B0,%1,%b0);
5916	}
5917
5918      if ((mask & ~0xff00) == 0)
5919        {
5920	  cc_status.flags |= CC_NOT_NEGATIVE;
5921	  operands[1] = GEN_INT (mask >> 8);
5922
5923	  if (QI_REG_P (operands[0]))
5924	    return AS2 (test%B0,%1,%h0);
5925	  else
5926	    {
5927	      operands[0] = adj_offsettable_operand (operands[0], 1);
5928	      return AS2 (test%B0,%1,%b0);
5929	    }
5930	}
5931
5932      if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
5933        {
5934	  cc_status.flags |= CC_NOT_NEGATIVE;
5935	  operands[1] = GEN_INT (mask >> 16);
5936	  operands[0] = adj_offsettable_operand (operands[0], 2);
5937	  return AS2 (test%B0,%1,%b0);
5938	}
5939
5940      if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
5941        {
5942	  cc_status.flags |= CC_NOT_NEGATIVE;
5943	  operands[1] = GEN_INT (mask >> 24);
5944	  operands[0] = adj_offsettable_operand (operands[0], 3);
5945	  return AS2 (test%B0,%1,%b0);
5946	}
5947    }
5948
5949  if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
5950    return AS2 (test%L0,%1,%0);
5951
5952  return AS2 (test%L1,%0,%1);
5953}")
5954
5955;; Store-flag instructions.
5956
5957;; For all sCOND expanders, also expand the compare or test insn that
5958;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
5959
5960(define_expand "seq"
5961  [(match_dup 1)
5962   (set (match_operand:QI 0 "register_operand" "")
5963	(eq:QI (cc0) (const_int 0)))]
5964  ""
5965  "
5966{
5967  if (TARGET_IEEE_FP
5968      && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5969    operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5970  else
5971    operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5972}")
5973
5974(define_expand "sne"
5975  [(match_dup 1)
5976   (set (match_operand:QI 0 "register_operand" "")
5977	(ne:QI (cc0) (const_int 0)))]
5978  ""
5979  "
5980{
5981  if (TARGET_IEEE_FP
5982      && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5983    operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5984  else
5985    operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5986}")
5987
5988(define_expand "sgt"
5989  [(match_dup 1)
5990   (set (match_operand:QI 0 "register_operand" "")
5991	(gt:QI (cc0) (const_int 0)))]
5992  ""
5993  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5994
5995(define_expand "sgtu"
5996  [(match_dup 1)
5997   (set (match_operand:QI 0 "register_operand" "")
5998	(gtu:QI (cc0) (const_int 0)))]
5999  ""
6000  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6001
6002(define_expand "slt"
6003  [(match_dup 1)
6004   (set (match_operand:QI 0 "register_operand" "")
6005	(lt:QI (cc0) (const_int 0)))]
6006  ""
6007  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6008
6009(define_expand "sltu"
6010  [(match_dup 1)
6011   (set (match_operand:QI 0 "register_operand" "")
6012	(ltu:QI (cc0) (const_int 0)))]
6013  ""
6014  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6015
6016(define_expand "sge"
6017  [(match_dup 1)
6018   (set (match_operand:QI 0 "register_operand" "")
6019	(ge:QI (cc0) (const_int 0)))]
6020  ""
6021  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6022
6023(define_expand "sgeu"
6024  [(match_dup 1)
6025   (set (match_operand:QI 0 "register_operand" "")
6026	(geu:QI (cc0) (const_int 0)))]
6027  ""
6028  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6029
6030(define_expand "sle"
6031  [(match_dup 1)
6032   (set (match_operand:QI 0 "register_operand" "")
6033	(le:QI (cc0) (const_int 0)))]
6034  ""
6035  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6036
6037(define_expand "sleu"
6038  [(match_dup 1)
6039   (set (match_operand:QI 0 "register_operand" "")
6040	(leu:QI (cc0) (const_int 0)))]
6041  ""
6042  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6043
6044;; The 386 sCOND opcodes can write to memory.  But a gcc sCOND insn may
6045;; not have any input reloads.  A MEM write might need an input reload
6046;; for the address of the MEM.  So don't allow MEM as the SET_DEST.
6047
6048(define_insn "*setcc"
6049  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6050	(match_operator:QI 1 "comparison_operator" [(cc0) (const_int 0)]))]
6051  "reload_completed || register_operand (operands[0], QImode)"
6052  "*
6053{
6054  enum rtx_code code = GET_CODE (operands[1]);
6055  if (cc_prev_status.flags & CC_TEST_AX)
6056    {
6057      int eq;
6058      HOST_WIDE_INT c;
6059      operands[2] = gen_rtx_REG (SImode, 0);
6060      switch (code)
6061	{
6062	case EQ:
6063	  c = 0x4000;
6064	  eq = 0;
6065	  break;
6066	case NE:
6067	  c = 0x4000;
6068	  eq = 1;
6069	  break;
6070	case GT:
6071	  c = 0x4100;
6072	  eq = 1;
6073	  break;
6074	case LT:
6075	  c = 0x100;
6076	  eq = 0;
6077	  break;
6078	case GE:
6079	  c = 0x100;
6080	  eq = 1;
6081	  break;
6082	case LE:
6083	  c = 0x4100;
6084	  eq = 0;
6085	  break;
6086	default:
6087	  abort ();
6088	}
6089      if (!TARGET_PENTIUM || optimize_size)
6090        {
6091          operands[3] = GEN_INT (c >> 8);
6092          output_asm_insn (AS2 (test%B0,%3,%h2), operands);
6093        }
6094      else
6095        {
6096          operands[3] = GEN_INT (c);
6097          output_asm_insn (AS2 (test%L0,%3,%2), operands);
6098        }
6099      return eq ? AS1 (sete,%0) : AS1 (setne, %0);
6100    }
6101
6102  if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
6103    return (char *)0;
6104  return AS1(set%D1,%0);
6105}")
6106
6107
6108;; Basic conditional jump instructions.
6109;; We ignore the overflow flag for signed branch instructions.
6110
6111;; For all bCOND expanders, also expand the compare or test insn that
6112;; generates cc0.  Generate an equality comparison if `beq' or `bne'.
6113
6114(define_expand "beq"
6115  [(match_dup 1)
6116   (set (pc)
6117	(if_then_else (eq (cc0)
6118			  (const_int 0))
6119		      (label_ref (match_operand 0 "" ""))
6120		      (pc)))]
6121  ""
6122  "
6123{
6124  if (TARGET_IEEE_FP
6125      && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
6126    operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
6127  else
6128    operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
6129}")
6130
6131(define_expand "bne"
6132  [(match_dup 1)
6133   (set (pc)
6134	(if_then_else (ne (cc0)
6135			  (const_int 0))
6136		      (label_ref (match_operand 0 "" ""))
6137		      (pc)))]
6138  ""
6139  "
6140{
6141  if (TARGET_IEEE_FP
6142      && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
6143    operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
6144  else
6145    operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
6146}")
6147
6148
6149(define_expand "bgt"
6150  [(match_dup 1)
6151   (set (pc)
6152	(if_then_else (gt (cc0)
6153			  (const_int 0))
6154		      (label_ref (match_operand 0 "" ""))
6155		      (pc)))]
6156  ""
6157  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6158
6159(define_expand "bgtu"
6160  [(match_dup 1)
6161   (set (pc)
6162	(if_then_else (gtu (cc0)
6163			   (const_int 0))
6164		      (label_ref (match_operand 0 "" ""))
6165		      (pc)))]
6166  ""
6167  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6168
6169(define_expand "blt"
6170  [(match_dup 1)
6171   (set (pc)
6172	(if_then_else (lt (cc0)
6173			  (const_int 0))
6174		      (label_ref (match_operand 0 "" ""))
6175		      (pc)))]
6176  ""
6177  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6178
6179
6180(define_expand "bltu"
6181  [(match_dup 1)
6182   (set (pc)
6183	(if_then_else (ltu (cc0)
6184			   (const_int 0))
6185		      (label_ref (match_operand 0 "" ""))
6186		      (pc)))]
6187  ""
6188  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6189
6190(define_expand "bge"
6191  [(match_dup 1)
6192   (set (pc)
6193	(if_then_else (ge (cc0)
6194			  (const_int 0))
6195		      (label_ref (match_operand 0 "" ""))
6196		      (pc)))]
6197  ""
6198  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6199
6200(define_expand "bgeu"
6201  [(match_dup 1)
6202   (set (pc)
6203	(if_then_else (geu (cc0)
6204			   (const_int 0))
6205		      (label_ref (match_operand 0 "" ""))
6206		      (pc)))]
6207  ""
6208  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6209
6210(define_expand "ble"
6211  [(match_dup 1)
6212   (set (pc)
6213	(if_then_else (le (cc0)
6214			  (const_int 0))
6215		      (label_ref (match_operand 0 "" ""))
6216		      (pc)))]
6217  ""
6218  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6219
6220(define_expand "bleu"
6221  [(match_dup 1)
6222   (set (pc)
6223	(if_then_else (leu (cc0)
6224			   (const_int 0))
6225		      (label_ref (match_operand 0 "" ""))
6226		      (pc)))]
6227  ""
6228  "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6229
6230(define_insn ""
6231  [(set (pc)
6232	(if_then_else (match_operator 0 "comparison_operator"
6233				      [(cc0) (const_int 0)])
6234		      (label_ref (match_operand 1 "" ""))
6235		      (pc)))]
6236  ""
6237  "*
6238{
6239  enum rtx_code code = GET_CODE (operands[0]);
6240  if (cc_prev_status.flags & CC_TEST_AX)
6241    {
6242      int eq;
6243      HOST_WIDE_INT c;
6244      operands[2] = gen_rtx_REG (SImode, 0);
6245      switch (code)
6246	{
6247	case EQ:
6248	  c = 0x4000;
6249	  eq = 0;
6250	  break;
6251	case NE:
6252	  c = 0x4000;
6253	  eq = 1;
6254	  break;
6255	case GT:
6256	  c = 0x4100;
6257	  eq = 1;
6258	  break;
6259	case LT:
6260	  c = 0x100;
6261	  eq = 0;
6262	  break;
6263	case GE:
6264	  c = 0x100;
6265	  eq = 1;
6266	  break;
6267	case LE:
6268	  c = 0x4100;
6269	  eq = 0;
6270	  break;
6271	default:
6272	  abort ();
6273	}
6274      if (!TARGET_PENTIUM || optimize_size)
6275        {
6276          operands[3] = GEN_INT (c >> 8);
6277          output_asm_insn (AS2 (test%B0,%3,%h2), operands);
6278        }
6279      else
6280        {
6281          operands[3] = GEN_INT (c);
6282          output_asm_insn (AS2 (test%L0,%3,%2), operands);
6283        }
6284      return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
6285    }
6286  if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
6287    return (char *)0;
6288
6289  return AS1(j%D0,%l1);
6290}")
6291
6292(define_insn ""
6293  [(set (pc)
6294	(if_then_else (match_operator 0 "comparison_operator"
6295				      [(cc0) (const_int 0)])
6296		      (pc)
6297		      (label_ref (match_operand 1 "" ""))))]
6298  ""
6299  "*
6300{
6301  enum rtx_code code = GET_CODE (operands[0]);
6302  if (cc_prev_status.flags & CC_TEST_AX)
6303    {
6304      int eq;
6305      HOST_WIDE_INT c;
6306      operands[2] = gen_rtx_REG (SImode, 0);
6307      switch (code)
6308	{
6309	case EQ:
6310	  c = 0x4000;
6311	  eq = 1;
6312	  break;
6313	case NE:
6314	  c = 0x4000;
6315	  eq = 0;
6316	  break;
6317	case GT:
6318	  c = 0x4100;
6319	  eq = 0;
6320	  break;
6321	case LT:
6322	  c = 0x100;
6323	  eq = 1;
6324	  break;
6325	case GE:
6326	  c = 0x100;
6327	  eq = 0;
6328	  break;
6329	case LE:
6330	  c = 0x4100;
6331	  eq = 1;
6332	  break;
6333	default:
6334	  abort ();
6335	}
6336      if (!TARGET_PENTIUM || optimize_size)
6337        {
6338          operands[3] = GEN_INT (c >> 8);
6339          output_asm_insn (AS2 (test%B0,%3,%h2), operands);
6340        }
6341      else
6342        {
6343          operands[3] = GEN_INT (c);
6344          output_asm_insn (AS2 (test%L0,%3,%2), operands);
6345        }
6346      return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
6347    }
6348  if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
6349    return (char *)0;
6350
6351  return AS1(j%d0,%l1);
6352}")
6353
6354;; Unconditional and other jump instructions
6355
6356(define_insn "jump"
6357  [(set (pc)
6358	(label_ref (match_operand 0 "" "")))]
6359  ""
6360  "jmp %l0"
6361  [(set_attr "memory" "none")])
6362
6363(define_insn "indirect_jump"
6364  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
6365  ""
6366  "*
6367{
6368  CC_STATUS_INIT;
6369
6370  return AS1 (jmp,%*%0);
6371}"
6372  [(set_attr "memory" "none")])
6373
6374;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
6375;;     if S does not change i
6376
6377(define_expand "decrement_and_branch_until_zero"
6378  [(parallel [(set (pc)
6379		   (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "")
6380					      (const_int -1))
6381				     (const_int 0))
6382				 (label_ref (match_operand 1 "" ""))
6383				 (pc)))
6384	      (set (match_dup 0)
6385		   (plus:SI (match_dup 0)
6386			    (const_int -1)))])]
6387  ""
6388  "")
6389
6390(define_insn ""
6391  [(set (pc)
6392	(if_then_else (match_operator 0 "arithmetic_comparison_operator"
6393				      [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+c*r,m")
6394						(match_operand:SI 2 "general_operand" "rmi,ri"))
6395				       (const_int 0)])
6396		      (label_ref (match_operand 3 "" ""))
6397		      (pc)))
6398   (set (match_dup 1)
6399	(plus:SI (match_dup 1)
6400		 (match_dup 2)))]
6401  ""
6402  "*
6403{
6404  CC_STATUS_INIT;
6405
6406  if (GET_CODE (operands[1]) == REG && REGNO (operands[2]) == 2 &&
6407      operands[2] == constm1_rtx && ix86_cpu == PROCESSOR_K6)
6408    return \"loop %l3\";
6409
6410  if (operands[2] == constm1_rtx)
6411    output_asm_insn (AS1 (dec%L1,%1), operands);
6412
6413  else if (operands[2] == const1_rtx)
6414    output_asm_insn (AS1 (inc%L1,%1), operands);
6415
6416  else
6417    output_asm_insn (AS2 (add%L1,%2,%1), operands);
6418
6419  return AS1 (%J0,%l3);
6420}")
6421
6422(define_insn ""
6423  [(set (pc)
6424	(if_then_else (match_operator 0 "arithmetic_comparison_operator"
6425				      [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
6426						 (match_operand:SI 2 "general_operand" "rmi,ri"))
6427				       (const_int 0)])
6428		      (label_ref (match_operand 3 "" ""))
6429		      (pc)))
6430   (set (match_dup 1)
6431	(minus:SI (match_dup 1)
6432		  (match_dup 2)))]
6433  ""
6434  "*
6435{
6436  CC_STATUS_INIT;
6437  if (operands[2] == const1_rtx)
6438    output_asm_insn (AS1 (dec%L1,%1), operands);
6439
6440  else if (operands[1] == constm1_rtx)
6441    output_asm_insn (AS1 (inc%L1,%1), operands);
6442
6443  else
6444    output_asm_insn (AS2 (sub%L1,%2,%1), operands);
6445
6446  return AS1 (%J0,%l3);
6447}")
6448
6449(define_insn ""
6450  [(set (pc)
6451	(if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6452			  (const_int 0))
6453		      (label_ref (match_operand 1 "" ""))
6454		      (pc)))
6455   (set (match_dup 0)
6456	(plus:SI (match_dup 0)
6457		 (const_int -1)))]
6458  ""
6459  "*
6460{
6461  CC_STATUS_INIT;
6462  operands[2] = const1_rtx;
6463  output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6464  return \"jnc %l1\";
6465}")
6466
6467(define_insn ""
6468  [(set (pc)
6469	(if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6470			  (const_int 0))
6471		      (label_ref (match_operand 1 "" ""))
6472		      (pc)))
6473   (set (match_dup 0)
6474	(plus:SI (match_dup 0)
6475		 (const_int -1)))]
6476  ""
6477  "*
6478{
6479  CC_STATUS_INIT;
6480  operands[2] = const1_rtx;
6481  output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6482  return \"jc %l1\";
6483}")
6484
6485(define_insn ""
6486  [(set (pc)
6487	(if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6488			  (const_int 1))
6489		      (label_ref (match_operand 1 "" ""))
6490		      (pc)))
6491   (set (match_dup 0)
6492	(plus:SI (match_dup 0)
6493		 (const_int -1)))]
6494  ""
6495  "*
6496{
6497  CC_STATUS_INIT;
6498  output_asm_insn (AS1 (dec%L0,%0), operands);
6499  return \"jnz %l1\";
6500}")
6501
6502(define_insn ""
6503  [(set (pc)
6504	(if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6505			  (const_int 1))
6506		      (label_ref (match_operand 1 "" ""))
6507		      (pc)))
6508   (set (match_dup 0)
6509	(plus:SI (match_dup 0)
6510		 (const_int -1)))]
6511  ""
6512  "*
6513{
6514  CC_STATUS_INIT;
6515  output_asm_insn (AS1 (dec%L0,%0), operands);
6516  return \"jz %l1\";
6517}")
6518
6519(define_insn ""
6520  [(set (pc)
6521	(if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6522			  (const_int -1))
6523		      (label_ref (match_operand 1 "" ""))
6524		      (pc)))
6525   (set (match_dup 0)
6526	(plus:SI (match_dup 0)
6527		 (const_int 1)))]
6528  ""
6529  "*
6530{
6531  CC_STATUS_INIT;
6532  output_asm_insn (AS1 (inc%L0,%0), operands);
6533  return \"jnz %l1\";
6534}")
6535
6536(define_insn ""
6537  [(set (pc)
6538	(if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6539			  (const_int -1))
6540		      (label_ref (match_operand 1 "" ""))
6541		      (pc)))
6542   (set (match_dup 0)
6543	(plus:SI (match_dup 0)
6544		 (const_int 1)))]
6545  ""
6546  "*
6547{
6548  CC_STATUS_INIT;
6549  output_asm_insn (AS1 (inc%L0,%0), operands);
6550  return \"jz %l1\";
6551}")
6552
6553;; Implement switch statements when generating PIC code.  Switches are
6554;; implemented by `tablejump' when not using -fpic.
6555
6556;; Emit code here to do the range checking and make the index zero based.
6557
6558(define_expand "casesi"
6559  [(set (match_dup 5)
6560	(match_operand:SI 0 "general_operand" ""))
6561   (set (match_dup 6)
6562	(minus:SI (match_dup 5)
6563		  (match_operand:SI 1 "general_operand" "")))
6564   (set (cc0)
6565	(compare:CC (match_dup 6)
6566		    (match_operand:SI 2 "general_operand" "")))
6567   (set (pc)
6568	(if_then_else (gtu (cc0)
6569			   (const_int 0))
6570		      (label_ref (match_operand 4 "" ""))
6571		      (pc)))
6572   (parallel
6573    [(set (pc)
6574	  (minus:SI (reg:SI 3)
6575		    (mem:SI (plus:SI (mult:SI (match_dup 6)
6576					      (const_int 4))
6577				     (label_ref (match_operand 3 "" ""))))))
6578     (clobber (match_scratch:SI 7 ""))])]
6579  "flag_pic"
6580  "
6581{
6582  operands[5] = gen_reg_rtx (SImode);
6583  operands[6] = gen_reg_rtx (SImode);
6584  current_function_uses_pic_offset_table = 1;
6585}")
6586
6587;; Implement a casesi insn.
6588
6589;; Each entry in the "addr_diff_vec" looks like this as the result of the
6590;; two rules below:
6591;; 
6592;; 	.long _GLOBAL_OFFSET_TABLE_+[.-.L2]
6593;; 
6594;; 1. An expression involving an external reference may only use the
6595;;    addition operator, and only with an assembly-time constant.
6596;;    The example above satisfies this because ".-.L2" is a constant.
6597;; 
6598;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
6599;;    given the value of "GOT - .", where GOT is the actual address of
6600;;    the Global Offset Table.  Therefore, the .long above actually
6601;;    stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2".  The
6602;;    expression "GOT - .L2" by itself would generate an error from as(1).
6603;; 
6604;; The pattern below emits code that looks like this:
6605;; 
6606;; 	movl %ebx,reg
6607;; 	subl TABLE@GOTOFF(%ebx,index,4),reg
6608;; 	jmp reg
6609;; 
6610;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
6611;; the addr_diff_vec is known to be part of this module.
6612;; 
6613;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
6614;; evaluates to just ".L2".
6615
6616(define_insn ""
6617  [(set (pc)
6618	(minus:SI (reg:SI 3)
6619		  (mem:SI (plus:SI
6620			   (mult:SI (match_operand:SI 0 "register_operand" "r")
6621				    (const_int 4))
6622			   (label_ref (match_operand 1 "" ""))))))
6623   (clobber (match_scratch:SI 2 "=&r"))]
6624  ""
6625  "*
6626{
6627  rtx xops[4];
6628
6629  xops[0] = operands[0];
6630  xops[1] = operands[1];
6631  xops[2] = operands[2];
6632  xops[3] = pic_offset_table_rtx;
6633
6634  output_asm_insn (AS2 (mov%L2,%3,%2), xops);
6635  output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
6636  output_asm_insn (AS1 (jmp,%*%2), xops);
6637  ASM_OUTPUT_ALIGN (asm_out_file, i386_align_jumps);
6638  RET;
6639}")
6640
6641(define_insn "tablejump"
6642  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
6643   (use (label_ref (match_operand 1 "" "")))]
6644  ""
6645  "*
6646{
6647  CC_STATUS_INIT;
6648
6649  return AS1 (jmp,%*%0);
6650}")
6651
6652;; Call insns.
6653
6654;; If generating PIC code, the predicate indirect_operand will fail
6655;; for operands[0] containing symbolic references on all of the named
6656;; call* patterns.  Each named pattern is followed by an unnamed pattern
6657;; that matches any call to a symbolic CONST (ie, a symbol_ref).  The
6658;; unnamed patterns are only used while generating PIC code, because
6659;; otherwise the named patterns match.
6660
6661;; Call subroutine returning no value.
6662
6663(define_expand "call_pop"
6664  [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
6665		    (match_operand:SI 1 "general_operand" ""))
6666	      (set (reg:SI 7)
6667		   (plus:SI (reg:SI 7)
6668			    (match_operand:SI 3 "immediate_operand" "")))])]
6669  ""
6670  "
6671{
6672  rtx addr;
6673
6674  if (operands[3] == const0_rtx)
6675    {
6676      emit_insn (gen_call (operands[0], operands[1]));
6677      DONE;
6678    }
6679
6680  if (flag_pic)
6681    current_function_uses_pic_offset_table = 1;
6682
6683  /* With half-pic, force the address into a register.  */
6684  addr = XEXP (operands[0], 0);
6685  if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6686    XEXP (operands[0], 0) = force_reg (Pmode, addr);
6687
6688  if (! expander_call_insn_operand (operands[0], QImode))
6689    operands[0]
6690      = change_address (operands[0], VOIDmode,
6691			copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
6692}")
6693
6694(define_insn ""
6695  [(call (match_operand:QI 0 "call_insn_operand" "m")
6696	 (match_operand:SI 1 "general_operand" "g"))
6697   (set (reg:SI 7) (plus:SI (reg:SI 7)
6698			    (match_operand:SI 3 "immediate_operand" "i")))]
6699  ""
6700  "*
6701{
6702  if (GET_CODE (operands[0]) == MEM
6703      && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6704    {
6705      operands[0] = XEXP (operands[0], 0);
6706      return AS1 (call,%*%0);
6707    }
6708  else
6709    return AS1 (call,%P0);
6710}")
6711
6712(define_insn ""
6713  [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6714	 (match_operand:SI 1 "general_operand" "g"))
6715   (set (reg:SI 7) (plus:SI (reg:SI 7)
6716			    (match_operand:SI 3 "immediate_operand" "i")))]
6717  "!HALF_PIC_P ()"
6718  "call %P0")
6719
6720(define_expand "call"
6721  [(call (match_operand:QI 0 "indirect_operand" "")
6722	 (match_operand:SI 1 "general_operand" ""))]
6723  ;; Operand 1 not used on the i386.
6724  ""
6725  "
6726{
6727  rtx addr;
6728
6729  if (flag_pic)
6730    current_function_uses_pic_offset_table = 1;
6731
6732  /* With half-pic, force the address into a register.  */
6733  addr = XEXP (operands[0], 0);
6734  if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6735    XEXP (operands[0], 0) = force_reg (Pmode, addr);
6736
6737  if (! expander_call_insn_operand (operands[0], QImode))
6738    operands[0]
6739      = change_address (operands[0], VOIDmode,
6740			copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
6741}")
6742
6743(define_insn ""
6744  [(call (match_operand:QI 0 "call_insn_operand" "m")
6745	 (match_operand:SI 1 "general_operand" "g"))]
6746  ;; Operand 1 not used on the i386.
6747  ""
6748  "*
6749{
6750  if (GET_CODE (operands[0]) == MEM
6751      && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6752    {
6753      operands[0] = XEXP (operands[0], 0);
6754      return AS1 (call,%*%0);
6755    }
6756  else
6757    return AS1 (call,%P0);
6758}")
6759
6760(define_insn ""
6761  [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6762	 (match_operand:SI 1 "general_operand" "g"))]
6763  ;; Operand 1 not used on the i386.
6764  "!HALF_PIC_P ()"
6765  "call %P0")
6766
6767;; Call subroutine, returning value in operand 0
6768;; (which must be a hard register).
6769
6770(define_expand "call_value_pop"
6771  [(parallel [(set (match_operand 0 "" "")
6772		   (call (match_operand:QI 1 "indirect_operand" "")
6773			 (match_operand:SI 2 "general_operand" "")))
6774	      (set (reg:SI 7)
6775		   (plus:SI (reg:SI 7)
6776			    (match_operand:SI 4 "immediate_operand" "")))])]
6777  ""
6778  "
6779{
6780  rtx addr;
6781
6782  if (operands[4] == const0_rtx)
6783    {
6784      emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
6785      DONE;
6786    }
6787
6788  if (flag_pic)
6789    current_function_uses_pic_offset_table = 1;
6790
6791  /* With half-pic, force the address into a register.  */
6792  addr = XEXP (operands[1], 0);
6793  if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6794    XEXP (operands[1], 0) = force_reg (Pmode, addr);
6795
6796  if (! expander_call_insn_operand (operands[1], QImode))
6797    operands[1]
6798      = change_address (operands[1], VOIDmode,
6799			copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
6800}")
6801
6802(define_insn ""
6803  [(set (match_operand 0 "" "=rf")
6804	(call (match_operand:QI 1 "call_insn_operand" "m")
6805	      (match_operand:SI 2 "general_operand" "g")))
6806   (set (reg:SI 7) (plus:SI (reg:SI 7)
6807			    (match_operand:SI 4 "immediate_operand" "i")))]
6808  ""
6809  "*
6810{
6811  if (GET_CODE (operands[1]) == MEM
6812      && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6813    {
6814      operands[1] = XEXP (operands[1], 0);
6815      output_asm_insn (AS1 (call,%*%1), operands);
6816    }
6817  else
6818    output_asm_insn (AS1 (call,%P1), operands);
6819
6820  RET;
6821}")
6822
6823(define_insn ""
6824  [(set (match_operand 0 "" "=rf")
6825	(call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6826	      (match_operand:SI 2 "general_operand" "g")))
6827   (set (reg:SI 7) (plus:SI (reg:SI 7)
6828			    (match_operand:SI 4 "immediate_operand" "i")))]
6829  "!HALF_PIC_P ()"
6830  "call %P1")
6831
6832(define_expand "call_value"
6833  [(set (match_operand 0 "" "")
6834	(call (match_operand:QI 1 "indirect_operand" "")
6835	      (match_operand:SI 2 "general_operand" "")))]
6836  ;; Operand 2 not used on the i386.
6837  ""
6838  "
6839{
6840  rtx addr;
6841
6842  if (flag_pic)
6843    current_function_uses_pic_offset_table = 1;
6844
6845  /* With half-pic, force the address into a register.  */
6846  addr = XEXP (operands[1], 0);
6847  if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6848    XEXP (operands[1], 0) = force_reg (Pmode, addr);
6849
6850  if (! expander_call_insn_operand (operands[1], QImode))
6851    operands[1]
6852      = change_address (operands[1], VOIDmode,
6853			copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
6854}")
6855
6856(define_insn ""
6857  [(set (match_operand 0 "" "=rf")
6858	(call (match_operand:QI 1 "call_insn_operand" "m")
6859	      (match_operand:SI 2 "general_operand" "g")))]
6860  ;; Operand 2 not used on the i386.
6861  ""
6862  "*
6863{
6864  if (GET_CODE (operands[1]) == MEM
6865      && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6866    {
6867      operands[1] = XEXP (operands[1], 0);
6868      output_asm_insn (AS1 (call,%*%1), operands);
6869    }
6870  else
6871    output_asm_insn (AS1 (call,%P1), operands);
6872
6873  RET;
6874}")
6875
6876(define_insn ""
6877  [(set (match_operand 0 "" "=rf")
6878	(call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6879	      (match_operand:SI 2 "general_operand" "g")))]
6880  ;; Operand 2 not used on the i386.
6881  "!HALF_PIC_P ()"
6882  "call %P1")
6883
6884;; Call subroutine returning any type.
6885
6886(define_expand "untyped_call"
6887  [(parallel [(call (match_operand 0 "" "")
6888		    (const_int 0))
6889	      (match_operand 1 "" "")
6890	      (match_operand 2 "" "")])]
6891  ""
6892  "
6893{
6894  int i;
6895
6896  /* In order to give reg-stack an easier job in validating two
6897     coprocessor registers as containing a possible return value,
6898     simply pretend the untyped call returns a complex long double
6899     value.  */
6900
6901  emit_call_insn (TARGET_80387
6902                  ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
6903				    operands[0], const0_rtx)
6904                  : gen_call (operands[0], const0_rtx));
6905
6906  for (i = 0; i < XVECLEN (operands[2], 0); i++)
6907    {
6908      rtx set = XVECEXP (operands[2], 0, i);
6909      emit_move_insn (SET_DEST (set), SET_SRC (set));
6910    }
6911
6912  /* The optimizer does not know that the call sets the function value
6913     registers we stored in the result block.  We avoid problems by
6914     claiming that all hard registers are used and clobbered at this
6915     point.  */
6916  emit_insn (gen_blockage ());
6917
6918  DONE;
6919}")
6920
6921;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6922;; all of memory.  This blocks insns from being moved across this point.
6923
6924(define_insn "blockage"
6925  [(unspec_volatile [(const_int 0)] 0)]
6926  ""
6927  ""
6928  [(set_attr "memory" "none")])
6929
6930;; Insn emitted into the body of a function to return from a function.
6931;; This is only done if the function's epilogue is known to be simple.
6932;; See comments for simple_386_epilogue in i386.c.
6933
6934(define_expand "return"
6935  [(return)]
6936  "ix86_can_use_return_insn_p ()"
6937  "")
6938
6939(define_insn "return_internal"
6940  [(return)]
6941  "reload_completed"
6942  "ret"
6943  [(set_attr "memory" "none")])
6944
6945(define_insn "return_pop_internal"
6946  [(return)
6947   (use (match_operand:SI 0 "const_int_operand" ""))]
6948  "reload_completed"
6949  "ret %0"
6950  [(set_attr "memory" "none")])
6951
6952(define_insn "nop"
6953  [(const_int 0)]
6954  ""
6955  "nop"
6956  [(set_attr "memory" "none")])
6957
6958(define_expand "prologue"
6959  [(const_int 1)]
6960  ""
6961  "
6962{
6963  ix86_expand_prologue ();
6964  DONE;
6965}")
6966
6967;; The use of UNSPEC here is currently not necessary - a simple SET of ebp
6968;; to itself would be enough. But this way we are safe even if some optimizer
6969;; becomes too clever in the future.
6970(define_insn "prologue_set_stack_ptr"
6971  [(set (reg:SI 7)
6972	(minus:SI (reg:SI 7) (match_operand:SI 0 "immediate_operand" "i")))
6973   (set (reg:SI 6) (unspec:SI [(reg:SI 6)] 4))]
6974  ""
6975  "*
6976{
6977  rtx xops [2];
6978
6979  xops[0] = operands[0];
6980  xops[1] = stack_pointer_rtx;
6981  output_asm_insn (AS2 (sub%L1,%0,%1), xops);
6982  RET;
6983}"
6984  [(set_attr "memory" "none")])
6985
6986(define_insn "prologue_set_got"
6987  [(set (match_operand:SI 0 "" "")
6988	(unspec_volatile
6989	 [(plus:SI (match_dup 0)
6990		   (plus:SI (match_operand:SI 1 "symbolic_operand" "")
6991			    (minus:SI (pc) (match_operand 2 "" ""))))] 1))]
6992  ""
6993  "*
6994{
6995  char buffer[64];
6996
6997  if (TARGET_DEEP_BRANCH_PREDICTION) 
6998    {
6999      sprintf (buffer, \"addl %s,%%0\", XSTR (operands[1], 0));
7000      output_asm_insn (buffer, operands);
7001    }
7002  else  
7003    {
7004      sprintf (buffer, \"addl %s+[.-%%X2],%%0\", XSTR (operands[1], 0));
7005      output_asm_insn (buffer, operands);
7006    }    
7007  RET;
7008}")
7009
7010(define_insn "prologue_get_pc"
7011  [(set (match_operand:SI 0 "" "")
7012    (unspec_volatile [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
7013  ""
7014  "*
7015{
7016  output_asm_insn (AS1 (call,%X1), operands);
7017  if (! TARGET_DEEP_BRANCH_PREDICTION) 
7018    {
7019      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1]));
7020    }    
7021  RET;
7022}"
7023  [(set_attr "memory" "none")])
7024
7025(define_insn "prologue_get_pc_and_set_got"
7026  [(unspec_volatile [(match_operand:SI 0 "" "")] 3)]
7027  ""
7028  "*
7029{
7030  operands[1] = gen_label_rtx ();
7031  output_asm_insn (AS1 (call,%X1), operands);
7032  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
7033			     CODE_LABEL_NUMBER (operands[1]));
7034  output_asm_insn (AS1 (pop%L0,%0), operands);
7035  output_asm_insn (\"addl $%__GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands);
7036  RET;
7037}"
7038  [(set_attr "memory" "none")])
7039
7040(define_expand "epilogue"
7041  [(const_int 1)]
7042  ""
7043  "
7044{
7045  ix86_expand_epilogue ();
7046  DONE;
7047}")
7048
7049(define_insn "epilogue_set_stack_ptr"
7050  [(set (reg:SI 7) (reg:SI 6))
7051	(clobber (reg:SI 6))]
7052  ""
7053  "*
7054{
7055  rtx xops [2];
7056
7057    xops[0] = frame_pointer_rtx;
7058    xops[1] = stack_pointer_rtx;
7059    output_asm_insn (AS2 (mov%L0,%0,%1), xops);
7060    RET;
7061}"
7062  [(set_attr "memory" "none")])
7063
7064(define_insn "leave"
7065  [(const_int 2)
7066      (clobber (reg:SI 6))
7067      (clobber (reg:SI 7))]
7068  ""
7069  "leave"
7070  [(set_attr "memory" "none")])
7071
7072(define_insn "pop"
7073  [(set (match_operand:SI 0 "register_operand" "r")
7074	(mem:SI (reg:SI 7)))
7075   (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))]
7076  ""
7077  "*
7078{
7079    output_asm_insn (AS1 (pop%L0,%P0), operands);
7080    RET;
7081}"
7082  [(set_attr "memory" "load")])
7083
7084(define_expand "movstrsi"
7085  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
7086		   (match_operand:BLK 1 "memory_operand" ""))
7087	      (use (match_operand:SI 2 "const_int_operand" ""))
7088	      (use (match_operand:SI 3 "const_int_operand" ""))
7089	      (clobber (match_scratch:SI 4 ""))
7090	      (clobber (match_dup 5))
7091	      (clobber (match_dup 6))])]
7092  ""
7093  "
7094{
7095  rtx addr0, addr1;
7096
7097  if (GET_CODE (operands[2]) != CONST_INT)
7098    FAIL;
7099
7100  addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7101  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
7102
7103  operands[5] = addr0;
7104  operands[6] = addr1;
7105
7106  operands[0] = change_address (operands[0], VOIDmode, addr0);
7107  operands[1] = change_address (operands[1], VOIDmode, addr1);
7108}")
7109
7110;; It might seem that operands 0 & 1 could use predicate register_operand.
7111;; But strength reduction might offset the MEM expression.  So we let
7112;; reload put the address into %edi & %esi.
7113
7114(define_insn ""
7115  [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
7116	(mem:BLK (match_operand:SI 1 "address_operand" "S")))
7117   (use (match_operand:SI 2 "const_int_operand" "n"))
7118   (use (match_operand:SI 3 "immediate_operand" "i"))
7119   (clobber (match_scratch:SI 4 "=&c"))
7120   (clobber (match_dup 0))
7121   (clobber (match_dup 1))]
7122  ""
7123  "*
7124{
7125  rtx xops[2];
7126
7127  output_asm_insn (\"cld\", operands);
7128  if (GET_CODE (operands[2]) == CONST_INT)
7129    {
7130      if (INTVAL (operands[2]) & ~0x03)
7131	{
7132	  xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
7133	  xops[1] = operands[4];
7134
7135	  output_asm_insn (AS2 (mov%L1,%0,%1), xops);
7136#ifdef INTEL_SYNTAX
7137	  output_asm_insn (\"rep movsd\", xops);
7138#else
7139	  output_asm_insn (\"rep\;movsl\", xops);
7140#endif
7141	}
7142      if (INTVAL (operands[2]) & 0x02)
7143	output_asm_insn (\"movsw\", operands);
7144      if (INTVAL (operands[2]) & 0x01)
7145	output_asm_insn (\"movsb\", operands);
7146    }
7147  else
7148    abort ();
7149  RET;
7150}")
7151
7152(define_expand "clrstrsi"
7153  [(set (match_dup 3) (const_int 0))
7154   (parallel [(set (match_operand:BLK 0 "memory_operand" "")
7155		   (const_int 0))
7156	      (use (match_operand:SI 1 "const_int_operand" ""))
7157	      (use (match_operand:SI 2 "const_int_operand" ""))
7158	      (use (match_dup 3))
7159	      (clobber (match_scratch:SI 4 ""))
7160	      (clobber (match_dup 5))])]
7161  ""
7162  "
7163{
7164  rtx addr0;
7165
7166  if (GET_CODE (operands[1]) != CONST_INT)
7167    FAIL;
7168
7169  addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7170
7171  operands[3] = gen_reg_rtx (SImode);
7172  operands[5] = addr0;
7173
7174  operands[0] = gen_rtx_MEM (BLKmode, addr0);
7175}")
7176
7177;; It might seem that operand 0 could use predicate register_operand.
7178;; But strength reduction might offset the MEM expression.  So we let
7179;; reload put the address into %edi.
7180
7181(define_insn "*bzero"
7182  [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
7183	(const_int 0))
7184   (use (match_operand:SI 1 "const_int_operand" "n"))
7185   (use (match_operand:SI 2 "immediate_operand" "i"))
7186   (use (match_operand:SI 3 "register_operand" "a"))
7187   (clobber (match_scratch:SI 4 "=&c"))
7188   (clobber (match_dup 0))]
7189  ""
7190  "*
7191{
7192  rtx xops[2];
7193
7194  output_asm_insn (\"cld\", operands);
7195  if (GET_CODE (operands[1]) == CONST_INT)
7196    {
7197      unsigned int count = INTVAL (operands[1]) & 0xffffffff;
7198      if (count & ~0x03)
7199	{
7200	  xops[0] = GEN_INT (count / 4);
7201	  xops[1] = operands[4];
7202
7203	  /* K6: stos takes 1 cycle, rep stos takes 8 + %ecx cycles.
7204	     80386: 4/5+5n (+2 for set of ecx)
7205	     80486: 5/7+5n (+1 for set of ecx)
7206	     */
7207	  if (count / 4 < ((int) ix86_cpu < (int)PROCESSOR_PENTIUM ? 4 : 6))
7208	    {
7209	      do
7210#ifdef INTEL_SYNTAX
7211		output_asm_insn (\"stosd\", xops);
7212#else
7213		output_asm_insn (\"stosl\", xops);
7214#endif
7215	      while ((count -= 4) > 3);
7216	    }
7217	  else
7218	    {
7219	      output_asm_insn (AS2 (mov%L1,%0,%1), xops);
7220#ifdef INTEL_SYNTAX
7221	      output_asm_insn (\"rep stosd\", xops);
7222#else
7223	      output_asm_insn (\"rep\;stosl\", xops);
7224#endif
7225	    }
7226	}
7227      if (INTVAL (operands[1]) & 0x02)
7228	output_asm_insn (\"stosw\", operands);
7229      if (INTVAL (operands[1]) & 0x01)
7230	output_asm_insn (\"stosb\", operands);
7231    }
7232  else
7233    abort ();
7234  RET;
7235}")
7236
7237(define_expand "cmpstrsi"
7238  [(parallel [(set (match_operand:SI 0 "general_operand" "")
7239		   (compare:SI (match_operand:BLK 1 "general_operand" "")
7240			       (match_operand:BLK 2 "general_operand" "")))
7241	      (use (match_operand:SI 3 "general_operand" ""))
7242	      (use (match_operand:SI 4 "immediate_operand" ""))
7243	      (clobber (match_dup 5))
7244	      (clobber (match_dup 6))
7245	      (clobber (match_dup 3))])]
7246  ""
7247  "
7248{
7249  rtx addr1, addr2;
7250
7251  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
7252  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
7253  operands[3] = copy_to_mode_reg (SImode, operands[3]);
7254
7255  operands[5] = addr1;
7256  operands[6] = addr2;
7257
7258  operands[1] = gen_rtx_MEM (BLKmode, addr1);
7259  operands[2] = gen_rtx_MEM (BLKmode, addr2);
7260
7261}")
7262
7263;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
7264;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
7265
7266;; It might seem that operands 0 & 1 could use predicate register_operand.
7267;; But strength reduction might offset the MEM expression.  So we let
7268;; reload put the address into %edi & %esi.
7269
7270;; ??? Most comparisons have a constant length, and it's therefore
7271;; possible to know that the length is non-zero, and to avoid the extra
7272;; code to handle zero-length compares.
7273
7274(define_insn ""
7275  [(set (match_operand:SI 0 "register_operand" "=&r")
7276	(compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
7277		    (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
7278   (use (match_operand:SI 3 "register_operand" "c"))
7279   (use (match_operand:SI 4 "immediate_operand" "i"))
7280   (clobber (match_dup 1))
7281   (clobber (match_dup 2))
7282   (clobber (match_dup 3))]
7283  ""
7284  "*
7285{
7286  rtx xops[2], label;
7287
7288  label = gen_label_rtx ();
7289
7290  output_asm_insn (\"cld\", operands);
7291  output_asm_insn (AS2 (xor%L0,%0,%0), operands);
7292  output_asm_insn (\"repz\;cmps%B2\", operands);
7293  output_asm_insn (\"je %l0\", &label);
7294
7295  xops[0] = operands[0];
7296  xops[1] = const1_rtx;
7297  output_asm_insn (AS2 (sbb%L0,%0,%0), xops);
7298  if (QI_REG_P (xops[0]))
7299     output_asm_insn (AS2 (or%B0,%1,%b0), xops);
7300  else
7301     output_asm_insn (AS2 (or%L0,%1,%0), xops);
7302	
7303  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
7304  RET;
7305}")
7306
7307(define_insn ""
7308  [(set (cc0)
7309	(compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
7310		    (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
7311   (use (match_operand:SI 2 "register_operand" "c"))
7312   (use (match_operand:SI 3 "immediate_operand" "i"))
7313   (clobber (match_dup 0))
7314   (clobber (match_dup 1))
7315   (clobber (match_dup 2))]
7316  ""
7317  "*
7318{
7319  rtx xops[2];
7320
7321  cc_status.flags |= CC_NOT_SIGNED;
7322
7323  xops[0] = gen_rtx_REG (QImode, 0);
7324  xops[1] = CONST0_RTX (QImode);
7325
7326  output_asm_insn (\"cld\", operands);
7327  output_asm_insn (AS2 (test%B0,%1,%0), xops);
7328  return \"repz\;cmps%B2\";
7329}")
7330
7331
7332;; Note, you cannot optimize away the branch following the bsfl by assuming
7333;; that the destination is not modified if the input is 0, since not all
7334;; x86 implementations do this.
7335
7336(define_expand "ffssi2"
7337  [(set (match_operand:SI 0 "general_operand" "") 
7338	(ffs:SI (match_operand:SI 1 "general_operand" "")))]
7339  ""
7340  "
7341{
7342  rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode);
7343
7344  emit_insn (gen_ffssi_1 (temp, operands[1]));
7345  emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0);
7346  emit_jump_insn (gen_bne (label));
7347  emit_move_insn (temp, constm1_rtx);
7348  emit_label (label);
7349  temp = expand_binop (SImode, add_optab, temp, const1_rtx,
7350		       operands[0], 0, OPTAB_WIDEN);
7351
7352  if (temp != operands[0])
7353    emit_move_insn (operands[0], temp);
7354  DONE;  
7355}")
7356
7357(define_insn "ffssi_1"
7358  [(set (match_operand:SI 0 "register_operand" "=r")
7359	(unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
7360  ""
7361  "* return AS2 (bsf%L0,%1,%0);")
7362
7363(define_expand "ffshi2"
7364  [(set (match_operand:SI 0 "general_operand" "") 
7365	(ffs:HI (match_operand:HI 1 "general_operand" "")))]
7366  ""
7367  "
7368{
7369  rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode);
7370
7371  emit_insn (gen_ffshi_1 (temp, operands[1]));
7372  emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0);
7373  emit_jump_insn (gen_bne (label));
7374  emit_move_insn (temp, constm1_rtx);
7375  emit_label (label);
7376  temp = expand_binop (HImode, add_optab, temp, const1_rtx,
7377		       operands[0], 0, OPTAB_WIDEN);
7378
7379  if (temp != operands[0])
7380    emit_move_insn (operands[0], temp);
7381  DONE;  
7382}")
7383
7384(define_insn "ffshi_1"
7385  [(set (match_operand:HI 0 "register_operand" "=r")
7386	(unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
7387  ""
7388  "* return AS2 (bsf%W0,%1,%0);")
7389
7390;; These patterns match the binary 387 instructions for addM3, subM3,
7391;; mulM3 and divM3.  There are three patterns for each of DFmode and
7392;; SFmode.  The first is the normal insn, the second the same insn but
7393;; with one operand a conversion, and the third the same insn but with
7394;; the other operand a conversion.
7395
7396(define_insn ""
7397  [(set (match_operand:DF 0 "register_operand" "=f,f")
7398	(match_operator:DF 3 "binary_387_op"
7399			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
7400			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
7401  "TARGET_80387"
7402  "* return output_387_binary_op (insn, operands);"
7403  [(set (attr "type") 
7404        (cond [(match_operand:DF 3 "is_mul" "") 
7405                 (const_string "fpmul")
7406               (match_operand:DF 3 "is_div" "") 
7407                 (const_string "fpdiv")
7408              ]
7409               (const_string "fpop")
7410        )
7411  )])
7412
7413(define_insn ""
7414  [(set (match_operand:XF 0 "register_operand" "=f,f")
7415	(match_operator:XF 3 "binary_387_op"
7416			[(match_operand:XF 1 "register_operand" "0,f")
7417			 (match_operand:XF 2 "register_operand" "f,0")]))]
7418  "TARGET_80387"
7419  "* return output_387_binary_op (insn, operands);"
7420  [(set (attr "type") 
7421        (cond [(match_operand:DF 3 "is_mul" "") 
7422                 (const_string "fpmul")
7423               (match_operand:DF 3 "is_div" "") 
7424                 (const_string "fpdiv")
7425              ]
7426               (const_string "fpop")
7427        )
7428  )])
7429
7430(define_insn ""
7431  [(set (match_operand:XF 0 "register_operand" "=f,f")
7432	(match_operator:XF 3 "binary_387_op"
7433	   [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7434	    (match_operand:XF 2 "register_operand" "0,f")]))]
7435  "TARGET_80387"
7436  "* return output_387_binary_op (insn, operands);"
7437  [(set (attr "type") 
7438        (cond [(match_operand:DF 3 "is_mul" "") 
7439                 (const_string "fpmul")
7440               (match_operand:DF 3 "is_div" "") 
7441                 (const_string "fpdiv")
7442              ]
7443               (const_string "fpop")
7444        )
7445  )])
7446
7447(define_insn ""
7448  [(set (match_operand:XF 0 "register_operand" "=f,f")
7449	(match_operator:XF 3 "binary_387_op"
7450	  [(match_operand:XF 1 "register_operand" "0,f")
7451	   (float_extend:XF
7452	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7453  "TARGET_80387"
7454  "* return output_387_binary_op (insn, operands);"
7455  [(set (attr "type") 
7456        (cond [(match_operand:DF 3 "is_mul" "") 
7457                 (const_string "fpmul")
7458               (match_operand:DF 3 "is_div" "") 
7459                 (const_string "fpdiv")
7460              ]
7461               (const_string "fpop")
7462        )
7463  )])
7464
7465(define_insn ""
7466  [(set (match_operand:DF 0 "register_operand" "=f,f")
7467	(match_operator:DF 3 "binary_387_op"
7468	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7469	    (match_operand:DF 2 "register_operand" "0,f")]))]
7470  "TARGET_80387"
7471  "* return output_387_binary_op (insn, operands);"
7472  [(set (attr "type") 
7473        (cond [(match_operand:DF 3 "is_mul" "") 
7474                 (const_string "fpmul")
7475               (match_operand:DF 3 "is_div" "") 
7476                 (const_string "fpdiv")
7477              ]
7478               (const_string "fpop")
7479        )
7480  )])
7481
7482(define_insn ""
7483  [(set (match_operand:DF 0 "register_operand" "=f,f")
7484	(match_operator:DF 3 "binary_387_op"
7485	  [(match_operand:DF 1 "register_operand" "0,f")
7486	   (float_extend:DF
7487	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7488  "TARGET_80387"
7489  "* return output_387_binary_op (insn, operands);"
7490  [(set (attr "type") 
7491        (cond [(match_operand:DF 3 "is_mul" "") 
7492                 (const_string "fpmul")
7493               (match_operand:DF 3 "is_div" "") 
7494                 (const_string "fpdiv")
7495              ]
7496               (const_string "fpop")
7497        )
7498  )])
7499
7500(define_insn ""
7501  [(set (match_operand:SF 0 "register_operand" "=f,f")
7502	(match_operator:SF 3 "binary_387_op"
7503			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
7504			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
7505  "TARGET_80387"
7506  "* return output_387_binary_op (insn, operands);"
7507  [(set (attr "type") 
7508        (cond [(match_operand:DF 3 "is_mul" "") 
7509                 (const_string "fpmul")
7510               (match_operand:DF 3 "is_div" "") 
7511                 (const_string "fpdiv")
7512              ]
7513               (const_string "fpop")
7514        )
7515  )])
7516
7517(define_expand "strlensi"
7518  [(parallel [(set (match_dup 4)
7519		   (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
7520			       (match_operand:QI 2 "immediate_operand" "")
7521			       (match_operand:SI 3 "immediate_operand" "")] 0))
7522	      (clobber (match_dup 1))])
7523   (set (match_dup 5)
7524	(not:SI (match_dup 4)))
7525   (set (match_operand:SI 0 "register_operand" "")
7526	(plus:SI (match_dup 5)
7527	         (const_int -1)))]
7528  ""
7529  "
7530{
7531  if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1)
7532    {
7533      rtx address;
7534      rtx scratch;
7535
7536	/* well it seems that some optimizer does not combine a call like
7537	     foo(strlen(bar), strlen(bar));
7538	   when the move and the subtraction is done here.  It does calculate
7539	   the length just once when these instructions are done inside of
7540	   output_strlen_unroll().  But I think since &bar[strlen(bar)] is
7541	   often used and I use one fewer register for the lifetime of
7542	   output_strlen_unroll() this is better.  */
7543      scratch = gen_reg_rtx (SImode);
7544      address = force_reg (SImode, XEXP (operands[1], 0));
7545
7546	/* move address to scratch-register
7547	   this is done here because the i586 can do the following and
7548	   in the same cycle with the following move.  */
7549      if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4)
7550	  emit_insn (gen_movsi (scratch, address));
7551
7552      emit_insn (gen_movsi (operands[0], address));
7553
7554      if(TARGET_USE_Q_REG)
7555	emit_insn (gen_strlensi_unroll5 (operands[0],
7556					operands[3],
7557					scratch,
7558					operands[0]));
7559      else
7560	emit_insn (gen_strlensi_unroll4 (operands[0],
7561					operands[3],
7562					scratch,
7563					operands[0]));
7564
7565        /* gen_strlensi_unroll[45] returns the address of the zero
7566           at the end of the string, like memchr(), so compute the
7567           length by subtracting the startaddress.  */
7568      emit_insn (gen_subsi3 (operands[0], operands[0], address));
7569      DONE;
7570    }
7571
7572  operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7573  operands[4] = gen_reg_rtx (SImode);
7574  operands[5] = gen_reg_rtx (SImode);
7575}")
7576
7577;; It might seem that operands 0 & 1 could use predicate register_operand.
7578;; But strength reduction might offset the MEM expression.  So we let
7579;; reload put the address into %edi.
7580
7581(define_insn ""
7582  [(set (match_operand:SI 0 "register_operand" "=&c")
7583	(unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
7584		    (match_operand:QI 2 "immediate_operand" "a")
7585		    (match_operand:SI 3 "immediate_operand" "i")] 0))
7586   (clobber (match_dup 1))]
7587  ""
7588  "*
7589{
7590  rtx xops[2];
7591
7592  xops[0] = operands[0];
7593  xops[1] = constm1_rtx;
7594  output_asm_insn (\"cld\", operands);
7595  output_asm_insn (AS2 (mov%L0,%1,%0), xops);
7596  return \"repnz\;scas%B2\";
7597}")
7598
7599/* Conditional move define_insns.  */
7600
7601(define_expand "movsicc"
7602  [(set (match_operand:SI 0 "register_operand" "")
7603	(if_then_else:SI (match_operand 1 "comparison_operator" "")
7604			 (match_operand:SI 2 "nonimmediate_operand" "")
7605			 (match_operand:SI 3 "nonimmediate_operand" "")))]
7606  "TARGET_CMOVE"
7607  "
7608{
7609  if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7610    FAIL;
7611
7612  operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7613			GET_MODE (i386_compare_op0),
7614			i386_compare_op0, i386_compare_op1);
7615}")
7616
7617(define_insn ""
7618  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
7619	(if_then_else:SI (match_operator 1 "comparison_operator" 
7620	      [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7621		(match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7622	      (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0")
7623	      (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7624  "TARGET_CMOVE"
7625  "#")
7626
7627(define_insn ""
7628  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
7629	(if_then_else:SI (match_operator 1 "comparison_operator" 
7630	      [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7631		(match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7632	      (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0")
7633	      (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7634  "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7635  "#")
7636
7637(define_split
7638  [(set (match_operand:SI 0 "register_operand" "")
7639	(if_then_else:SI (match_operator 1 "comparison_operator" 
7640				[(match_operand 2 "nonimmediate_operand" "")
7641				 (const_int 0)])
7642		      (match_operand:SI 3 "nonimmediate_operand" "")
7643		      (match_operand:SI 4 "nonimmediate_operand" "")))]
7644  "TARGET_CMOVE && reload_completed"
7645  [(set (cc0)
7646	(match_dup 2))
7647   (set (match_dup 0)
7648	(if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7649		      (match_dup 3) (match_dup 4)))]
7650  "")
7651
7652(define_split
7653  [(set (match_operand:SI 0 "register_operand" "")
7654	(if_then_else:SI (match_operator 1 "comparison_operator" 
7655				[(match_operand 2 "nonimmediate_operand" "")
7656				 (match_operand 3 "general_operand" "")])
7657		      (match_operand:SI 4 "nonimmediate_operand" "")
7658		      (match_operand:SI 5 "nonimmediate_operand" "")))]
7659  "TARGET_CMOVE && reload_completed"
7660  [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7661   (set (match_dup 0)
7662	(if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7663		      (match_dup 4) (match_dup 5)))]
7664  "")
7665
7666(define_insn ""
7667  [(set (match_operand:SI 0 "register_operand" "=r,r")
7668	(if_then_else:SI (match_operator 1 "comparison_operator" 
7669				[(cc0) (const_int 0)])
7670		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
7671		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
7672  "TARGET_CMOVE && reload_completed"
7673  "* return output_int_conditional_move (which_alternative, operands);")
7674
7675(define_expand "movhicc"
7676  [(set (match_operand:HI 0 "register_operand" "")
7677	(if_then_else:HI (match_operand 1 "comparison_operator" "")
7678			 (match_operand:HI 2 "nonimmediate_operand" "")
7679			 (match_operand:HI 3 "nonimmediate_operand" "")))]
7680  "TARGET_CMOVE"
7681  "
7682{
7683  if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7684    FAIL;
7685
7686  operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7687			GET_MODE (i386_compare_op0),
7688			i386_compare_op0, i386_compare_op1);
7689}")
7690
7691(define_insn ""
7692  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
7693	(if_then_else:HI (match_operator 1 "comparison_operator" 
7694	      [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7695		(match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7696	      (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0")
7697	      (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7698  "TARGET_CMOVE"
7699  "#")
7700
7701(define_insn ""
7702  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
7703	(if_then_else:HI (match_operator 1 "comparison_operator" 
7704	      [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7705		(match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7706	      (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0")
7707	      (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7708  "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7709  "#")
7710
7711(define_split
7712  [(set (match_operand:HI 0 "register_operand" "")
7713	(if_then_else:HI (match_operator 1 "comparison_operator" 
7714				[(match_operand 2 "nonimmediate_operand" "")
7715				 (const_int 0)])
7716		      (match_operand:HI 3 "nonimmediate_operand" "")
7717		      (match_operand:HI 4 "nonimmediate_operand" "")))]
7718  "TARGET_CMOVE && reload_completed"
7719  [(set (cc0)
7720	(match_dup 2))
7721   (set (match_dup 0)
7722	(if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7723		      (match_dup 3) (match_dup 4)))]
7724  "")
7725
7726(define_split
7727  [(set (match_operand:HI 0 "register_operand" "")
7728	(if_then_else:HI (match_operator 1 "comparison_operator" 
7729				[(match_operand 2 "nonimmediate_operand" "")
7730				 (match_operand 3 "general_operand" "")])
7731		      (match_operand:HI 4 "nonimmediate_operand" "")
7732		      (match_operand:HI 5 "nonimmediate_operand" "")))]
7733  "TARGET_CMOVE && reload_completed"
7734  [(set (cc0)
7735	(compare (match_dup 2) (match_dup 3)))
7736   (set (match_dup 0)
7737	(if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7738		      (match_dup 4) (match_dup 5)))]
7739  "")
7740
7741(define_insn ""
7742  [(set (match_operand:HI 0 "register_operand" "=r,r")
7743	(if_then_else:HI (match_operator 1 "comparison_operator" 
7744				[(cc0) (const_int 0)])
7745		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
7746		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
7747  "TARGET_CMOVE && reload_completed"
7748  "* return output_int_conditional_move (which_alternative, operands);")
7749
7750(define_expand "movsfcc"
7751  [(set (match_operand:SF 0 "register_operand" "")
7752	(if_then_else:SF (match_operand 1 "comparison_operator" "")
7753			 (match_operand:SF 2 "register_operand" "")
7754			 (match_operand:SF 3 "register_operand" "")))]
7755  "TARGET_CMOVE"
7756  "
7757{
7758  rtx temp;
7759
7760  if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7761    FAIL;
7762
7763  /* The floating point conditional move instructions don't directly
7764     support conditions resulting from a signed integer comparison. */
7765
7766  switch (GET_CODE (operands[1]))
7767    {
7768    case LT:
7769    case LE:
7770    case GE:
7771    case GT:
7772      temp = emit_store_flag (gen_reg_rtx (QImode),
7773		GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7774		VOIDmode, 0, 0);
7775
7776      if (!temp)
7777        FAIL;
7778
7779      operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7780      break;
7781
7782    default:
7783      operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7784			GET_MODE (i386_compare_op0),
7785			i386_compare_op0, i386_compare_op1);
7786      break;
7787    }
7788}")
7789
7790(define_insn ""
7791  [(set (match_operand:SF 0 "register_operand" "=f,f,f,f")
7792	(if_then_else:SF (match_operator 1 "comparison_operator" 
7793	      [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7794		(match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7795	      (match_operand:SF 4 "register_operand" "f,f,0,0")
7796	      (match_operand:SF 5 "register_operand" "0,0,f,f")))]
7797  "TARGET_CMOVE
7798    && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7799    && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7800  "#")
7801
7802(define_insn ""
7803  [(set (match_operand:SF 0 "register_operand" "=f,f,f,f")
7804	(if_then_else:SF (match_operator 1 "comparison_operator" 
7805		[(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7806		 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7807	      (match_operand:SF 4 "register_operand" "f,f,0,0")
7808	      (match_operand:SF 5 "register_operand" "0,0,f,f")))]
7809  "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7810    && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7811    && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7812  "#")
7813
7814(define_split
7815  [(set (match_operand:SF 0 "register_operand" "")
7816	(if_then_else:SF (match_operator 1 "comparison_operator" 
7817				[(match_operand 2 "nonimmediate_operand" "")
7818				 (const_int 0)])
7819		      (match_operand:SF 3 "register_operand" "")
7820		      (match_operand:SF 4 "register_operand" "")))]
7821  "TARGET_CMOVE && reload_completed"
7822  [(set (cc0)
7823	(match_dup 2))
7824   (set (match_dup 0)
7825	(if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7826		      (match_dup 3) (match_dup 4)))]
7827  "")
7828
7829(define_split
7830  [(set (match_operand:SF 0 "register_operand" "")
7831	(if_then_else:SF (match_operator 1 "comparison_operator" 
7832				[(match_operand 2 "nonimmediate_operand" "")
7833				 (match_operand 3 "general_operand" "")])
7834		      (match_operand:SF 4 "register_operand" "")
7835		      (match_operand:SF 5 "register_operand" "")))]
7836  "TARGET_CMOVE && reload_completed"
7837  [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7838   (set (match_dup 0)
7839	(if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7840		      (match_dup 4) (match_dup 5)))]
7841  "")
7842
7843(define_insn ""
7844  [(set (match_operand:SF 0 "register_operand" "=f,f")
7845	(if_then_else:SF (match_operator 1 "comparison_operator" 
7846				[(cc0) (const_int 0)])
7847		      (match_operand:SF 2 "register_operand" "f,0")
7848		      (match_operand:SF 3 "register_operand" "0,f")))]
7849  "TARGET_CMOVE && reload_completed"
7850  "* return output_fp_conditional_move (which_alternative, operands);")
7851
7852(define_expand "movdfcc"
7853  [(set (match_operand:DF 0 "register_operand" "")
7854	(if_then_else:DF (match_operand 1 "comparison_operator" "")
7855			 (match_operand:DF 2 "register_operand" "")
7856			 (match_operand:DF 3 "register_operand" "")))]
7857  "TARGET_CMOVE"
7858  "
7859{
7860  rtx temp;
7861
7862  if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7863    FAIL;
7864
7865  /* The floating point conditional move instructions don't directly
7866     support conditions resulting from a signed integer comparison. */
7867
7868  switch (GET_CODE (operands[1]))
7869    {
7870    case LT:
7871    case LE:
7872    case GE:
7873    case GT:
7874      temp = emit_store_flag (gen_reg_rtx (QImode),
7875		GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7876		VOIDmode, 0, 0);
7877
7878      if (!temp)
7879        FAIL;
7880
7881      operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7882      break;
7883
7884    default:
7885      operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7886			GET_MODE (i386_compare_op0),
7887			i386_compare_op0, i386_compare_op1);
7888      break;
7889    }
7890}")
7891
7892(define_insn ""
7893  [(set (match_operand:DF 0 "register_operand" "=f,f,f,f")
7894	(if_then_else:DF (match_operator 1 "comparison_operator" 
7895	      [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7896		(match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7897	      (match_operand:DF 4 "register_operand" "f,f,0,0")
7898	      (match_operand:DF 5 "register_operand" "0,0,f,f")))]
7899  "TARGET_CMOVE
7900    && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7901    && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7902  "#")
7903
7904(define_insn ""
7905  [(set (match_operand:DF 0 "register_operand" "=f,f,f,f")
7906	(if_then_else:DF (match_operator 1 "comparison_operator" 
7907	      [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7908		(match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7909	      (match_operand:DF 4 "register_operand" "f,f,0,0")
7910	      (match_operand:DF 5 "register_operand" "0,0,f,f")))]
7911  "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7912    && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7913    && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7914  "#")
7915
7916(define_split
7917  [(set (match_operand:DF 0 "register_operand" "")
7918	(if_then_else:DF (match_operator 1 "comparison_operator" 
7919				[(match_operand 2 "nonimmediate_operand" "")
7920				 (const_int 0)])
7921		      (match_operand:DF 3 "register_operand" "")
7922		      (match_operand:DF 4 "register_operand" "")))]
7923  "TARGET_CMOVE && reload_completed"
7924  [(set (cc0)
7925	(match_dup 2))
7926   (set (match_dup 0)
7927	(if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7928		      (match_dup 3) (match_dup 4)))]
7929  "")
7930
7931(define_split
7932  [(set (match_operand:DF 0 "register_operand" "")
7933	(if_then_else:DF (match_operator 1 "comparison_operator" 
7934				[(match_operand 2 "nonimmediate_operand" "")
7935				 (match_operand 3 "general_operand" "")])
7936		      (match_operand:DF 4 "register_operand" "")
7937		      (match_operand:DF 5 "register_operand" "")))]
7938  "TARGET_CMOVE && reload_completed"
7939  [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7940   (set (match_dup 0)
7941	(if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7942		      (match_dup 4) (match_dup 5)))]
7943  "")
7944
7945(define_insn ""
7946  [(set (match_operand:DF 0 "register_operand" "=f,f")
7947	(if_then_else:DF (match_operator 1 "comparison_operator" 
7948				[(cc0) (const_int 0)])
7949		      (match_operand:DF 2 "register_operand" "f,0")
7950		      (match_operand:DF 3 "register_operand" "0,f")))]
7951  "TARGET_CMOVE && reload_completed"
7952  "* return output_fp_conditional_move (which_alternative, operands);")
7953
7954(define_expand "movxfcc"
7955  [(set (match_operand:XF 0 "register_operand" "")
7956	(if_then_else:XF (match_operand 1 "comparison_operator" "")
7957			 (match_operand:XF 2 "register_operand" "")
7958			 (match_operand:XF 3 "register_operand" "")))]
7959  "TARGET_CMOVE"
7960  "
7961{
7962  rtx temp;
7963
7964  if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7965    FAIL;
7966
7967  /* The floating point conditional move instructions don't directly
7968     support conditions resulting from a signed integer comparison. */
7969
7970  switch (GET_CODE (operands[1]))
7971    {
7972    case LT:
7973    case LE:
7974    case GE:
7975    case GT:
7976      temp = emit_store_flag (gen_reg_rtx (QImode),
7977		GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7978		VOIDmode, 0, 0);
7979
7980      if (!temp)
7981        FAIL;
7982
7983      operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7984      break;
7985
7986    default:
7987      operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7988			GET_MODE (i386_compare_op0),
7989			i386_compare_op0, i386_compare_op1);
7990      break;
7991    }
7992}")
7993
7994(define_insn ""
7995  [(set (match_operand:XF 0 "register_operand" "=f,f,f,f")
7996	(if_then_else:XF (match_operator 1 "comparison_operator" 
7997	      [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7998		(match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7999	      (match_operand:XF 4 "register_operand" "f,f,0,0")
8000	      (match_operand:XF 5 "register_operand" "0,0,f,f")))]
8001  "TARGET_CMOVE
8002    && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
8003    && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
8004  "#")
8005
8006(define_insn ""
8007  [(set (match_operand:XF 0 "register_operand" "=f,f,f,f")
8008	(if_then_else:XF (match_operator 1 "comparison_operator" 
8009	      [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
8010		(match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
8011	      (match_operand:XF 4 "register_operand" "f,f,0,0")
8012	      (match_operand:XF 5 "register_operand" "0,0,f,f")))]
8013  "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
8014    && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
8015    && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
8016  "#")
8017
8018(define_split
8019  [(set (match_operand:XF 0 "register_operand" "")
8020	(if_then_else:XF (match_operator 1 "comparison_operator" 
8021				[(match_operand 2 "nonimmediate_operand" "")
8022				 (const_int 0)])
8023		      (match_operand:XF 3 "register_operand" "")
8024		      (match_operand:XF 4 "register_operand" "")))]
8025  "TARGET_CMOVE && reload_completed"
8026  [(set (cc0)
8027	(match_dup 2))
8028   (set (match_dup 0)
8029	(if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
8030		      (match_dup 3) (match_dup 4)))]
8031  "")
8032
8033(define_split
8034  [(set (match_operand:XF 0 "register_operand" "")
8035	(if_then_else:XF (match_operator 1 "comparison_operator" 
8036				[(match_operand 2 "nonimmediate_operand" "")
8037				 (match_operand 3 "general_operand" "")])
8038		      (match_operand:XF 4 "register_operand" "")
8039		      (match_operand:XF 5 "register_operand" "")))]
8040  "TARGET_CMOVE && reload_completed"
8041  [(set (cc0) (compare (match_dup 2) (match_dup 3)))
8042   (set (match_dup 0)
8043	(if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
8044		      (match_dup 4) (match_dup 5)))]
8045  "")
8046
8047(define_insn ""
8048  [(set (match_operand:XF 0 "register_operand" "=f,f")
8049	(if_then_else:XF (match_operator 1 "comparison_operator" 
8050				[(cc0) (const_int 0)])
8051		      (match_operand:XF 2 "register_operand" "f,0")
8052		      (match_operand:XF 3 "register_operand" "0,f")))]
8053  "TARGET_CMOVE && reload_completed"
8054  "* return output_fp_conditional_move (which_alternative, operands);")
8055
8056(define_expand "movdicc"
8057  [(set (match_operand:DI 0 "register_operand" "")
8058	(if_then_else:DI (match_operand 1 "comparison_operator" "")
8059			 (match_operand:DI 2 "nonimmediate_operand" "")
8060			 (match_operand:DI 3 "nonimmediate_operand" "")))]
8061  "TARGET_CMOVE"
8062  "
8063{
8064  if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
8065    FAIL;
8066
8067  operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
8068			GET_MODE (i386_compare_op0),
8069			i386_compare_op0, i386_compare_op1);
8070}")
8071
8072(define_insn ""
8073  [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r")
8074	(if_then_else:DI (match_operator 1 "comparison_operator" 
8075	      [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
8076		(match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
8077	      (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0")
8078	      (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))]
8079  "TARGET_CMOVE"
8080  "#")
8081
8082(define_insn ""
8083  [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r")
8084	(if_then_else:DI (match_operator 1 "comparison_operator" 
8085	      [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
8086		(match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
8087	      (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0")
8088	      (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))]
8089  "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
8090  "#")
8091
8092(define_split
8093  [(set (match_operand:DI 0 "register_operand" "")
8094	(if_then_else:DI (match_operator 1 "comparison_operator" 
8095				[(match_operand 2 "nonimmediate_operand" "")
8096				 (const_int 0)])
8097		      (match_operand:DI 3 "nonimmediate_operand" "")
8098		      (match_operand:DI 4 "nonimmediate_operand" "")))]
8099  "TARGET_CMOVE && reload_completed"
8100  [(set (cc0)
8101	(match_dup 2))
8102   (set (match_dup 5)
8103	(if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8104		      (match_dup 7) (match_dup 9)))
8105   (set (match_dup 6)
8106	(if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8107		      (match_dup 8) (match_dup 10)))]
8108  "split_di (&operands[0], 1, &operands[5], &operands[6]);
8109   split_di (&operands[3], 1, &operands[7], &operands[8]);
8110   split_di (&operands[4], 1, &operands[9], &operands[10]);")
8111
8112(define_split
8113  [(set (match_operand:DI 0 "register_operand" "")
8114	(if_then_else:DI (match_operator 1 "comparison_operator" 
8115				[(match_operand 2 "nonimmediate_operand" "")
8116				 (match_operand 3 "general_operand" "")])
8117		      (match_operand:DI 4 "nonimmediate_operand" "")
8118		      (match_operand:DI 5 "nonimmediate_operand" "")))]
8119  "TARGET_CMOVE && reload_completed"
8120  [(set (cc0) (compare (match_dup 2) (match_dup 3)))
8121   (set (match_dup 6)
8122	(if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8123		      (match_dup 8) (match_dup 10)))
8124   (set (match_dup 7)
8125	(if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8126		      (match_dup 9) (match_dup 11)))]
8127  "split_di (&operands[0], 1, &operands[6], &operands[7]);
8128   split_di (&operands[4], 1, &operands[8], &operands[9]);
8129   split_di (&operands[5], 1, &operands[10], &operands[11]);")
8130
8131(define_insn "strlensi_unroll"
8132  [(set (match_operand:SI 0 "register_operand" "=&r,&r")
8133	(unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r"))
8134		    (match_operand:SI 2 "immediate_operand" "i,i")] 0))
8135   (clobber (match_scratch:SI 3 "=&q,&r"))]
8136  "optimize > 1"
8137  "* return output_strlen_unroll (operands);")
8138
8139;; the only difference between the following patterns is the register preference
8140;; on a pentium using a q-register saves one clock cycle per 4 characters
8141
8142(define_insn "strlensi_unroll4"
8143  [(set (match_operand:SI 0 "register_operand" "=r,r")
8144		   (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0"))
8145			       (match_operand:SI 1 "immediate_operand" "i,i")
8146			       (match_operand:SI 2 "register_operand" "+q,!r")] 0))
8147   (clobber (match_dup 2))]
8148  "(TARGET_USE_ANY_REG && optimize > 1)"
8149  "* return output_strlen_unroll (operands);")
8150
8151(define_insn "strlensi_unroll5"
8152  [(set (match_operand:SI 0 "register_operand" "=r")
8153		   (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0"))
8154			       (match_operand:SI 1 "immediate_operand" "i")
8155			       (match_operand:SI 2 "register_operand" "+q")] 0))
8156   (clobber (match_dup 2))]
8157  "(TARGET_USE_Q_REG && optimize > 1)"
8158  "* return output_strlen_unroll (operands);"
8159)
8160
8161(define_insn "allocate_stack_worker"
8162  [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
8163   (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
8164   (clobber (match_dup 0))]
8165  "TARGET_STACK_PROBE"
8166  "* return AS1(call,__alloca);"
8167  [(set_attr "memory" "none")])
8168
8169(define_expand "allocate_stack"
8170  [(set (match_operand:SI 0 "register_operand" "=r")
8171  	(minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" "")))
8172   (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))]
8173   "TARGET_STACK_PROBE"
8174  "
8175{
8176#ifdef CHECK_STACK_LIMIT
8177  if (GET_CODE (operands[1]) == CONST_INT
8178      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
8179    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
8180			   operands[1]));
8181  else 
8182#endif
8183    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
8184							    operands[1])));
8185
8186  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
8187  DONE;
8188}")
8189
8190(define_expand "exception_receiver"
8191  [(const_int 0)]
8192  "flag_pic"
8193  "
8194{
8195  load_pic_register (1);
8196  DONE;
8197}")
8198