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