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