]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/ns32k/ns32k.md
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / config / ns32k / ns32k.md
1 ;;- Machine description for GNU compiler, ns32000 Version
2 ;; Copyright (C) 1988, 1994, 1996, 1998, 1999, 2000, 2001
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5
6 ;; This file is part of GNU CC.
7
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
22
23
24 ; BUGS:
25 ;; Insert no-op between an insn with memory read-write operands
26 ;; following by a scale-indexing operation.
27 ;; The Sequent assembler does not allow addresses to be used
28 ;; except in insns which explicitly compute an effective address.
29 ;; I.e., one cannot say "cmpd _p,@_x"
30 ;; Implement unsigned multiplication??
31
32 ;;- Instruction patterns. When multiple patterns apply,
33 ;;- the first one in the file is chosen.
34 ;;-
35 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
36 ;;-
37 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
38 ;;- updates for most instructions.
39
40 ;; We don't want to allow a constant operand for test insns because
41 ;; (set (cc0) (const_int foo)) has no mode information. Such insns will
42 ;; be folded while optimizing anyway.
43 ;;
44 ;; In order for pic mode to work we cannot generate, for example
45 ;;
46 ;; addd _x+5,r1
47 ;;
48 ;; instead we must force gcc to generate something like
49 ;;
50 ;; addr 5(_x(sb)),r0
51 ;; addd r0,r1
52 ;;
53 ;; This was done through operand constraints (using "rmn" in place of "g"),
54 ;; but with the proper definition of LEGITIMATE_PIC_OPERAND (ns32k.h)
55 ;; this is unnecessary.
56 ;;
57
58 ;; It seems that in current CVS (2000-01-11), at least with
59 ;; libgcc2.a, that register allocation gets worse when changing
60 ;; "general_operand" "0" to "nonimmediate_operand" "0" (and
61 ;; similar "0"-containing constraints), if operand 0 is (e.g.)
62 ;; "nonimmediate_operand" "=rm". Revisit and test later.
63
64 (define_insn "tstsi"
65 [(set (cc0)
66 (match_operand:SI 0 "nonimmediate_operand" "rm"))]
67 ""
68 "*
69 { cc_status.flags |= CC_REVERSED;
70 operands[1] = const0_rtx;
71 return \"cmpqd %1,%0\"; }")
72
73 (define_insn "tsthi"
74 [(set (cc0)
75 (match_operand:HI 0 "nonimmediate_operand" "rm"))]
76 ""
77 "*
78 { cc_status.flags |= CC_REVERSED;
79 operands[1] = const0_rtx;
80 return \"cmpqw %1,%0\"; }")
81
82 (define_insn "tstqi"
83 [(set (cc0)
84 (match_operand:QI 0 "nonimmediate_operand" "rm"))]
85 ""
86 "*
87 { cc_status.flags |= CC_REVERSED;
88 operands[1] = const0_rtx;
89 return \"cmpqb %1,%0\"; }")
90
91 (define_insn "tstdf"
92 [(set (cc0)
93 (match_operand:DF 0 "general_operand" "lmF"))]
94 "TARGET_32081"
95 "*
96 { cc_status.flags |= CC_REVERSED;
97 if (TARGET_IEEE_COMPARE)
98 cc_status.flags |= CC_UNORD;
99 operands[1] = CONST0_RTX (DFmode);
100 return \"cmpl %1,%0\"; }")
101
102 (define_insn "tstsf"
103 [(set (cc0)
104 (match_operand:SF 0 "general_operand" "fmF"))]
105 "TARGET_32081"
106 "*
107 { cc_status.flags |= CC_REVERSED;
108 if (TARGET_IEEE_COMPARE)
109 cc_status.flags |= CC_UNORD;
110 operands[1] = CONST0_RTX (SFmode);
111 return \"cmpf %1,%0\"; }")
112
113 ;; See note 1
114 (define_insn "cmpsi"
115 [(set (cc0)
116 (compare (match_operand:SI 0 "general_operand" "g")
117 (match_operand:SI 1 "general_operand" "g")))]
118 ""
119 "*
120 {
121 if (GET_CODE (operands[1]) == CONST_INT)
122 {
123 int i = INTVAL (operands[1]);
124 if (i <= 7 && i >= -8)
125 {
126 cc_status.flags |= CC_REVERSED;
127 return \"cmpqd %1,%0\";
128 }
129 }
130 cc_status.flags &= ~CC_REVERSED;
131 if (GET_CODE (operands[0]) == CONST_INT)
132 {
133 int i = INTVAL (operands[0]);
134 if (i <= 7 && i >= -8)
135 return \"cmpqd %0,%1\";
136 }
137 return \"cmpd %0,%1\";
138 }")
139
140 (define_insn "cmphi"
141 [(set (cc0)
142 (compare (match_operand:HI 0 "general_operand" "g")
143 (match_operand:HI 1 "general_operand" "g")))]
144 ""
145 "*
146 {
147 if (GET_CODE (operands[1]) == CONST_INT)
148 {
149 short i = INTVAL (operands[1]);
150 if (i <= 7 && i >= -8)
151 {
152 cc_status.flags |= CC_REVERSED;
153 if (INTVAL (operands[1]) > 7)
154 operands[1] = GEN_INT (i);
155 return \"cmpqw %1,%0\";
156 }
157 }
158 cc_status.flags &= ~CC_REVERSED;
159 if (GET_CODE (operands[0]) == CONST_INT)
160 {
161 short i = INTVAL (operands[0]);
162 if (i <= 7 && i >= -8)
163 {
164 if (INTVAL (operands[0]) > 7)
165 operands[0] = GEN_INT (i);
166 return \"cmpqw %0,%1\";
167 }
168 }
169 return \"cmpw %0,%1\";
170 }")
171
172 (define_insn "cmpqi"
173 [(set (cc0)
174 (compare (match_operand:QI 0 "general_operand" "g")
175 (match_operand:QI 1 "general_operand" "g")))]
176 ""
177 "*
178 {
179 if (GET_CODE (operands[1]) == CONST_INT)
180 {
181 char i = INTVAL (operands[1]);
182 if (i <= 7 && i >= -8)
183 {
184 cc_status.flags |= CC_REVERSED;
185 if (INTVAL (operands[1]) > 7)
186 operands[1] = GEN_INT (i);
187 return \"cmpqb %1,%0\";
188 }
189 }
190 cc_status.flags &= ~CC_REVERSED;
191 if (GET_CODE (operands[0]) == CONST_INT)
192 {
193 char i = INTVAL (operands[0]);
194 if (i <= 7 && i >= -8)
195 {
196 if (INTVAL (operands[0]) > 7)
197 operands[0] = GEN_INT (i);
198 return \"cmpqb %0,%1\";
199 }
200 }
201 return \"cmpb %0,%1\";
202 }")
203
204 (define_insn "cmpdf"
205 [(set (cc0)
206 (compare (match_operand:DF 0 "general_operand" "lmF")
207 (match_operand:DF 1 "general_operand" "lmF")))]
208 "TARGET_32081"
209 "*
210 {
211 if (TARGET_IEEE_COMPARE)
212 cc_status.flags |= CC_UNORD;
213 return \"cmpl %0,%1\";}")
214
215 (define_insn "cmpsf"
216 [(set (cc0)
217 (compare (match_operand:SF 0 "general_operand" "fmF")
218 (match_operand:SF 1 "general_operand" "fmF")))]
219 "TARGET_32081"
220 "*
221 {
222 if (TARGET_IEEE_COMPARE)
223 cc_status.flags |= CC_UNORD;
224 return \"cmpf %0,%1\";}")
225 \f
226 ;; movdf and movsf copy between general and floating registers using
227 ;; the stack. In principle, we could get better code not allowing
228 ;; that case in the constraints and defining SECONDARY_MEMORY_NEEDED
229 ;; in practice, though the stack slots used are not available for
230 ;; optimization.
231 (define_insn "movdf"
232 [(set (match_operand:DF 0 "nonimmediate_operand" "=lrm<")
233 (match_operand:DF 1 "general_operand" "lFg"))]
234 ""
235 "*
236 {
237 if (FP_REG_P (operands[0]))
238 {
239 if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
240 return \"movl %1,%0\";
241 if (REG_P (operands[1]))
242 {
243 rtx xoperands[2];
244 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
245 output_asm_insn (\"movd %1,tos\", xoperands);
246 output_asm_insn (\"movd %1,tos\", operands);
247 return \"movl tos,%0\";
248 }
249 return \"movl %1,%0\";
250 }
251 else if (FP_REG_P (operands[1]))
252 {
253 if (REG_P (operands[0]))
254 {
255 output_asm_insn (\"movl %1,tos\;movd tos,%0\", operands);
256 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
257 return \"movd tos,%0\";
258 }
259 else
260 return \"movl %1,%0\";
261 }
262 return output_move_double (operands);
263 }")
264
265 (define_insn "movsf"
266 [(set (match_operand:SF 0 "nonimmediate_operand" "=frm<")
267 (match_operand:SF 1 "general_operand" "fFg"))]
268 ""
269 "*
270 {
271 if (FP_REG_P (operands[0]))
272 {
273 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM)
274 return \"movd %1,tos\;movf tos,%0\";
275 else
276 return \"movf %1,%0\";
277 }
278 else if (FP_REG_P (operands[1]))
279 {
280 if (REG_P (operands[0]))
281 return \"movf %1,tos\;movd tos,%0\";
282 return \"movf %1,%0\";
283 }
284 #if 0 /* Someone suggested this for the Sequent. Is it needed? */
285 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
286 return \"movf %1,%0\";
287 #endif
288 /* There was a #if 0 around this, but that was erroneous
289 for many machines -- rms. */
290 #ifndef MOVD_FLOAT_OK
291 /* GAS understands floating constants in ordinary movd instructions
292 but other assemblers might object. */
293 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
294 {
295 union {int i[2]; float f; double d;} convrt;
296 convrt.i[0] = CONST_DOUBLE_LOW (operands[1]);
297 convrt.i[1] = CONST_DOUBLE_HIGH (operands[1]);
298 convrt.f = convrt.d;
299
300 /* Is there a better machine-independent way to to this? */
301 operands[1] = GEN_INT (convrt.i[0]);
302 return \"movd %1,%0\";
303 }
304 #endif
305 else return \"movd %1,%0\";
306 }")
307
308 (define_insn "*movti"
309 [(set (match_operand:TI 0 "memory_operand" "=m")
310 (match_operand:TI 1 "memory_operand" "m"))]
311 ""
312 "movmd %1,%0,4")
313
314 (define_insn "movdi"
315 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm<,*f,rm")
316 (match_operand:DI 1 "general_operand" "gF,g,*f"))]
317 ""
318 "*
319 {
320 if (FP_REG_P (operands[0]))
321 {
322 if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
323 return \"movl %1,%0\";
324 if (REG_P (operands[1]))
325 {
326 rtx xoperands[2];
327 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
328 output_asm_insn (\"movd %1,tos\", xoperands);
329 output_asm_insn (\"movd %1,tos\", operands);
330 return \"movl tos,%0\";
331 }
332 return \"movl %1,%0\";
333 }
334 else if (FP_REG_P (operands[1]))
335 {
336 if (REG_P (operands[0]))
337 {
338 output_asm_insn (\"movl %1,tos\;movd tos,%0\", operands);
339 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
340 return \"movd tos,%0\";
341 }
342 else
343 return \"movl %1,%0\";
344 }
345 return output_move_double (operands);
346 }")
347
348 ;; This special case must precede movsi.
349 (define_insn "*ldsp"
350 [(set (reg:SI 25)
351 (match_operand:SI 0 "general_operand" "g"))]
352 ""
353 "lprd sp,%0")
354
355 (define_insn "movsi"
356 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<,rm<,*f,rm,x")
357 (match_operand:SI 1 "general_operand" "g,?xy,g,*f,rmn"))]
358 ""
359 "*
360 {
361 extern int flag_pic;
362
363 if (FP_REG_P (operands[0]))
364 {
365 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM)
366 return \"movd %1,tos\;movf tos,%0\";
367 else
368 return \"movf %1,%0\";
369 }
370 else if (FP_REG_P (operands[1]))
371 {
372 if (REG_P (operands[0]))
373 return \"movf %1,tos\;movd tos,%0\";
374 return \"movf %1,%0\";
375 }
376 if (GET_CODE (operands[0]) == REG
377 && REGNO (operands[0]) == FRAME_POINTER_REGNUM)
378 return \"lprd fp,%1\";
379 if (GET_CODE (operands[1]) == CONST_DOUBLE)
380 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
381 if (GET_CODE (operands[1]) == CONST_INT)
382 {
383 int i = INTVAL (operands[1]);
384 if (! TARGET_32532)
385 {
386 if (i <= 7 && i >= -8)
387 return \"movqd %1,%0\";
388 if (NS32K_DISPLACEMENT_P (i))
389 #if defined (GNX_V3) || defined (UTEK_ASM)
390 return \"addr %c1,%0\";
391 #else
392 return \"addr @%c1,%0\";
393 #endif
394 return \"movd %1,%0\";
395 }
396 else
397 return output_move_dconst(i, \"%1,%0\");
398 }
399 else if (GET_CODE (operands[1]) == CONST && ! flag_pic)
400 {
401 /* Must contain symbols so we don't know how big it is. In
402 * that case addr might lead to overflow. For PIC symbolic
403 * address loads always have to be done with addr.
404 */
405 return \"movd %1,%0\";
406 }
407 else if (GET_CODE (operands[1]) == REG)
408 {
409 if (REGNO (operands[1]) < F0_REGNUM)
410 return \"movd %1,%0\";
411 else if (REGNO (operands[1]) == FRAME_POINTER_REGNUM)
412 {
413 if (GET_CODE(operands[0]) == REG)
414 return \"sprd fp,%0\";
415 else
416 return \"addr 0(fp),%0\" ;
417 }
418 else if (REGNO (operands[1]) == STACK_POINTER_REGNUM)
419 {
420 if (GET_CODE(operands[0]) == REG)
421 return \"sprd sp,%0\";
422 else
423 return \"addr 0(sp),%0\" ;
424 }
425 else abort ();
426 }
427 else if (GET_CODE (operands[1]) == MEM)
428 return \"movd %1,%0\";
429
430 /* Check if this effective address can be
431 calculated faster by pulling it apart. */
432 if (REG_P (operands[0])
433 && GET_CODE (operands[1]) == MULT
434 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
435 && (INTVAL (XEXP (operands[1], 1)) == 2
436 || INTVAL (XEXP (operands[1], 1)) == 4))
437 {
438 rtx xoperands[3];
439 xoperands[0] = operands[0];
440 xoperands[1] = XEXP (operands[1], 0);
441 xoperands[2] = GEN_INT (INTVAL (XEXP (operands[1], 1)) >> 1);
442 return output_shift_insn (xoperands);
443 }
444 return \"addr %a1,%0\";
445 }")
446
447 (define_insn "movhi"
448 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<,*f,rm")
449 (match_operand:HI 1 "general_operand" "g,g,*f"))]
450 ""
451 "*
452 {
453 if (GET_CODE (operands[1]) == CONST_INT)
454 {
455 short i = INTVAL (operands[1]);
456 if (i <= 7 && i >= -8)
457 {
458 if (INTVAL (operands[1]) > 7)
459 operands[1] = GEN_INT (i);
460 return \"movqw %1,%0\";
461 }
462 return \"movw %1,%0\";
463 }
464 else if (FP_REG_P (operands[0]))
465 {
466 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM)
467 return \"movwf %1,tos\;movf tos,%0\";
468 else
469 return \"movwf %1,%0\";
470 }
471 else if (FP_REG_P (operands[1]))
472 {
473 if (REG_P (operands[0]))
474 return \"movf %1,tos\;movd tos,%0\";
475 return \"movf %1,%0\";
476 }
477 else
478 return \"movw %1,%0\";
479 }")
480
481 (define_insn "movstricthi"
482 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
483 (match_operand:HI 1 "general_operand" "g"))]
484 ""
485 "*
486 {
487 if (GET_CODE (operands[1]) == CONST_INT
488 && INTVAL(operands[1]) <= 7 && INTVAL(operands[1]) >= -8)
489 return \"movqw %1,%0\";
490 return \"movw %1,%0\";
491 }")
492
493 (define_insn "movqi"
494 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<,*f,rm")
495 (match_operand:QI 1 "general_operand" "g,g,*f"))]
496 ""
497 "*
498 { if (GET_CODE (operands[1]) == CONST_INT)
499 {
500 char char_val = (char)INTVAL (operands[1]);
501 if (char_val <= 7 && char_val >= -8)
502 {
503 if (INTVAL (operands[1]) > 7)
504 operands[1] = GEN_INT (char_val);
505 return \"movqb %1,%0\";
506 }
507 return \"movb %1,%0\";
508 }
509 else if (FP_REG_P (operands[0]))
510 {
511 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM)
512 return \"movbf %1,tos\;movf tos,%0\";
513 else
514 return \"movbf %1,%0\";
515 }
516 else if (FP_REG_P (operands[1]))
517 {
518 if (REG_P (operands[0]))
519 return \"movf %1,tos\;movd tos,%0\";
520 return \"movf %1,%0\";
521 }
522 else
523 return \"movb %1,%0\";
524 }")
525
526 (define_insn "movstrictqi"
527 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
528 (match_operand:QI 1 "general_operand" "g"))]
529 ""
530 "*
531 {
532 if (GET_CODE (operands[1]) == CONST_INT
533 && INTVAL(operands[1]) < 8 && INTVAL(operands[1]) > -9)
534 return \"movqb %1,%0\";
535 return \"movb %1,%0\";
536 }")
537 \f
538 ;; Block moves
539 ;; Argument 0 is the destination
540 ;; Argument 1 is the source
541 ;; Argument 2 is the length
542 ;; Argument 3 is the alignment
543 ;;
544 ;; Strategy: Use define_expand to
545 ;; either emit insns directly if it can be done simply or
546 ;; emit rtl to match movstrsi1 which has extra scratch registers
547 ;; which can be used to generate more complex code.
548
549 (define_expand "movstrsi"
550 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
551 (match_operand:BLK 1 "memory_operand" ""))
552 (use (match_operand:SI 2 "general_operand" ""))
553 (use (match_operand:SI 3 "const_int_operand" ""))])]
554 ""
555 "
556 {
557 if (operands[0]) /* avoid unused code messages */
558 {
559 expand_block_move (operands);
560 DONE;
561 }
562 }")
563
564 ;; Special Registers:
565 ;; r0 count
566 ;; r1 from
567 ;; r2 to
568 ;; r3 match
569
570
571 (define_insn "movstrsi1"
572 [(set (mem:BLK (reg:SI 2))
573 (mem:BLK (reg:SI 1)))
574 (use (reg:SI 0))
575 (set (reg:SI 2) (plus:SI (reg:SI 2) (mult:SI (reg:SI 0) (match_operand:SI 0 "const_int_operand" ""))))
576 (set (reg:SI 1) (plus:SI (reg:SI 1) (mult:SI (reg:SI 0) (match_dup 0))))
577 (set (reg:SI 0) (const_int 0))]
578 ""
579 "*
580 {
581 int align = INTVAL(operands[0]);
582 if (align == 4)
583 return \"movsd\";
584 else
585 return \"movsb\";
586 }")
587
588 (define_insn "movstrsi2"
589 [(set (mem:BLK (match_operand:SI 0 "address_operand" "p"))
590 (mem:BLK (match_operand:SI 1 "address_operand" "p")))
591 (use (match_operand 2 "immediate_operand" "i"))]
592 ""
593 "movmd %a1,%a0,%2")
594
595 \f
596 ;; Extension and truncation insns.
597 ;; Those for integer source operand
598 ;; are ordered widest source type first.
599
600 (define_insn "extendhisi2"
601 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
602 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
603 ""
604 "movxwd %1,%0")
605
606 (define_insn "extendqihi2"
607 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
608 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
609 ""
610 "movxbw %1,%0")
611
612 (define_insn "extendqisi2"
613 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
614 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
615 ""
616 "movxbd %1,%0")
617
618 (define_insn "extendsfdf2"
619 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm<")
620 (float_extend:DF (match_operand:SF 1 "general_operand" "fmF")))]
621 "TARGET_32081"
622 "movfl %1,%0")
623
624 (define_insn "truncdfsf2"
625 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm<")
626 (float_truncate:SF (match_operand:DF 1 "general_operand" "lmF")))]
627 "TARGET_32081"
628 "movlf %1,%0")
629
630 (define_insn "zero_extendhisi2"
631 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
632 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
633 ""
634 "movzwd %1,%0")
635
636 (define_insn "zero_extendqihi2"
637 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
638 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
639 ""
640 "movzbw %1,%0")
641
642 (define_insn "zero_extendqisi2"
643 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
644 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
645 ""
646 "movzbd %1,%0")
647 \f
648 ;; Fix-to-float conversion insns.
649 ;; Note that the ones that start with SImode come first.
650 ;; That is so that an operand that is a CONST_INT
651 ;; (and therefore lacks a specific machine mode).
652 ;; will be recognized as SImode (which is always valid)
653 ;; rather than as QImode or HImode.
654
655 ;; Rumor has it that the National part does not correctly convert
656 ;; constant ints to floats. This conversion is therefore disabled.
657 ;; A register must be used to perform the conversion.
658
659 (define_insn "floatsisf2"
660 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm<")
661 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
662 "TARGET_32081"
663 "movdf %1,%0")
664
665 (define_insn "floatsidf2"
666 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm<")
667 (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
668 "TARGET_32081"
669 "movdl %1,%0")
670
671 (define_insn "floathisf2"
672 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm<")
673 (float:SF (match_operand:HI 1 "nonimmediate_operand" "rm")))]
674 "TARGET_32081"
675 "movwf %1,%0")
676
677 (define_insn "floathidf2"
678 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm<")
679 (float:DF (match_operand:HI 1 "nonimmediate_operand" "rm")))]
680 "TARGET_32081"
681 "movwl %1,%0")
682
683 (define_insn "floatqisf2"
684 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm<")
685 (float:SF (match_operand:QI 1 "nonimmediate_operand" "rm")))]
686 "TARGET_32081"
687 "movbf %1,%0")
688
689 ; Some assemblers warn that this insn doesn't work.
690 ; Maybe they know something we don't.
691 ;(define_insn "floatqidf2"
692 ; [(set (match_operand:DF 0 "nonimmediate_operand" "=lm<")
693 ; (float:DF (match_operand:QI 1 "nonimmediate_operand" "rm")))]
694 ; "TARGET_32081"
695 ; "movbl %1,%0")
696 \f
697 ;; Float-to-fix conversion insns.
698 ;; The sequent compiler always generates "trunc" insns.
699
700 (define_insn "fixsfqi2"
701 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
702 (fix:QI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "fm"))))]
703 "TARGET_32081"
704 "truncfb %1,%0")
705
706 (define_insn "fixsfhi2"
707 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
708 (fix:HI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "fm"))))]
709 "TARGET_32081"
710 "truncfw %1,%0")
711
712 (define_insn "fixsfsi2"
713 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
714 (fix:SI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "fm"))))]
715 "TARGET_32081"
716 "truncfd %1,%0")
717
718 (define_insn "fixdfqi2"
719 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
720 (fix:QI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "lm"))))]
721 "TARGET_32081"
722 "trunclb %1,%0")
723
724 (define_insn "fixdfhi2"
725 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
726 (fix:HI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "lm"))))]
727 "TARGET_32081"
728 "trunclw %1,%0")
729
730 (define_insn "fixdfsi2"
731 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
732 (fix:SI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "lm"))))]
733 "TARGET_32081"
734 "truncld %1,%0")
735
736 ;; Unsigned
737
738 (define_insn "fixunssfqi2"
739 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
740 (unsigned_fix:QI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "fm"))))]
741 "TARGET_32081"
742 "truncfb %1,%0")
743
744 (define_insn "fixunssfhi2"
745 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
746 (unsigned_fix:HI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "fm"))))]
747 "TARGET_32081"
748 "truncfw %1,%0")
749
750 (define_insn "fixunssfsi2"
751 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
752 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "fm"))))]
753 "TARGET_32081"
754 "truncfd %1,%0")
755
756 (define_insn "fixunsdfqi2"
757 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
758 (unsigned_fix:QI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "lm"))))]
759 "TARGET_32081"
760 "trunclb %1,%0")
761
762 (define_insn "fixunsdfhi2"
763 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
764 (unsigned_fix:HI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "lm"))))]
765 "TARGET_32081"
766 "trunclw %1,%0")
767
768 (define_insn "fixunsdfsi2"
769 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
770 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "lm"))))]
771 "TARGET_32081"
772 "truncld %1,%0")
773
774 ;;; These are not yet used by GCC
775 (define_insn "fix_truncsfqi2"
776 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
777 (fix:QI (match_operand:SF 1 "nonimmediate_operand" "fm")))]
778 "TARGET_32081"
779 "truncfb %1,%0")
780
781 (define_insn "fix_truncsfhi2"
782 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
783 (fix:HI (match_operand:SF 1 "nonimmediate_operand" "fm")))]
784 "TARGET_32081"
785 "truncfw %1,%0")
786
787 (define_insn "fix_truncsfsi2"
788 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
789 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "fm")))]
790 "TARGET_32081"
791 "truncfd %1,%0")
792
793 (define_insn "fix_truncdfqi2"
794 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
795 (fix:QI (match_operand:DF 1 "nonimmediate_operand" "lm")))]
796 "TARGET_32081"
797 "trunclb %1,%0")
798
799 (define_insn "fix_truncdfhi2"
800 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
801 (fix:HI (match_operand:DF 1 "nonimmediate_operand" "lm")))]
802 "TARGET_32081"
803 "trunclw %1,%0")
804
805 (define_insn "fix_truncdfsi2"
806 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
807 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "lm")))]
808 "TARGET_32081"
809 "truncld %1,%0")
810 \f
811 ;; Multiply-add instructions
812 (define_insn "*madddf"
813 [(set (match_operand:DF 0 "nonimmediate_operand" "=v,v,&lm")
814 (plus:DF (mult:DF (match_operand:DF 1 "general_operand" "%lmF,0,0")
815 (match_operand:DF 2 "general_operand" "lmF,lmF,lmF"))
816 (match_operand:DF 3 "general_operand" "0,lmF,lmF")))]
817 "TARGET_MULT_ADD"
818 "@
819 dotl %1,%2
820 polyl %2,%3
821 mull %2,%0\;addl %3,%0")
822
823 (define_insn "*maddsf"
824 [(set (match_operand:SF 0 "nonimmediate_operand" "=u,u,&fm")
825 (plus:SF (mult:SF (match_operand:SF 1 "general_operand" "%fmF,0,0")
826 (match_operand:SF 2 "general_operand" "fmF,fmF,fmF"))
827 (match_operand:SF 3 "general_operand" "0,fmF,fmF")))]
828 "TARGET_MULT_ADD"
829 "@
830 dotf %1,%2
831 polyf %2,%3
832 mulf %2,%0\;addf %3,%0")
833
834
835 ;; Multiply-sub instructions
836 (define_insn "*msubdf"
837 [(set (match_operand:DF 0 "nonimmediate_operand" "=&v,&lm")
838 (minus:DF (mult:DF (match_operand:DF 1 "general_operand" "%lmF,0")
839 (match_operand:DF 2 "general_operand" "lmF,lmF"))
840 (match_operand:DF 3 "general_operand" "lmF,lmF")))]
841 "TARGET_MULT_ADD"
842 "@
843 negl %3,%0\;dotl %1,%2
844 mull %2,%0\;subl %3,%0")
845
846 (define_insn "*msubsf"
847 [(set (match_operand:SF 0 "nonimmediate_operand" "=&u,&fm")
848 (minus:SF (mult:SF (match_operand:SF 1 "general_operand" "%fmF,0")
849 (match_operand:SF 2 "general_operand" "fmF,fmF"))
850 (match_operand:SF 3 "general_operand" "fmF,fmF")))]
851 "TARGET_MULT_ADD"
852 "@
853 negf %3,%0\;dotf %1,%2
854 mulf %2,%0\;subf %3,%0")
855
856 ;;- All kinds of add instructions.
857
858 (define_insn "adddf3"
859 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm")
860 (plus:DF (match_operand:DF 1 "general_operand" "%0")
861 (match_operand:DF 2 "general_operand" "lmF")))]
862 "TARGET_32081"
863 "addl %2,%0")
864
865
866 (define_insn "addsf3"
867 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
868 (plus:SF (match_operand:SF 1 "general_operand" "%0")
869 (match_operand:SF 2 "general_operand" "fmF")))]
870 "TARGET_32081"
871 "addf %2,%0")
872
873 (define_insn "*add_to_sp"
874 [(set (reg:SI 25)
875 (plus:SI (reg:SI 25)
876 (match_operand:SI 0 "immediate_operand" "i")))]
877 "GET_CODE (operands[0]) == CONST_INT"
878 "*
879 {
880 #ifndef SEQUENT_ADJUST_STACK
881 if (TARGET_32532)
882 if (INTVAL (operands[0]) == 8)
883 return \"cmpd tos,tos\";
884 if (TARGET_32532 || TARGET_32332)
885 if (INTVAL (operands[0]) == 4)
886 return \"cmpqd %$0,tos\";
887 #endif
888 if (! TARGET_32532)
889 {
890 if (INTVAL (operands[0]) < 64 && INTVAL (operands[0]) > -64)
891 return \"adjspb %n0\";
892 else if (INTVAL (operands[0]) < 8192 && INTVAL (operands[0]) >= -8192)
893 return \"adjspw %n0\";
894 }
895 return \"adjspd %n0\";
896 }")
897
898 (define_insn "adddi3"
899 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
900 (plus:DI (match_operand:DI 1 "general_operand" "%0")
901 (match_operand:DI 2 "general_operand" "ron")))]
902 ""
903 "*
904 {
905 rtx low[3], high[3], xops[4];
906 split_di (operands, 3, low, high);
907 xops[0] = low[0];
908 xops[1] = high[0];
909 xops[2] = low[2];
910 xops[3] = high[2];
911
912 if (GET_CODE (xops[2]) == CONST_INT)
913 {
914 int i = INTVAL (xops[2]);
915
916 if (i <= 7 && i >= -8)
917 {
918 if (i == 0)
919 {
920 i = INTVAL (xops[3]);
921 if (i <= 7 && i >= -8)
922 output_asm_insn (\"addqd %3,%1\", xops);
923 else
924 output_asm_insn (\"addd %3,%1\", xops);
925 }
926 else
927 {
928 output_asm_insn (\"addqd %2,%0\", xops);
929 output_asm_insn (\"addcd %3,%1\", xops);
930 }
931 return \"\";
932 }
933 }
934 output_asm_insn (\"addd %2,%0\", xops);
935 output_asm_insn (\"addcd %3,%1\", xops);
936 return \"\";
937 }")
938
939 ;; See Note 1
940 (define_insn "addsi3"
941 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,=rm<,=rm<")
942 (plus:SI (match_operand:SI 1 "general_operand" "%0,r,xy")
943 (match_operand:SI 2 "general_operand" "g,i,i")))]
944 ""
945 "*
946 {
947 if (which_alternative == 1)
948 {
949 if (GET_CODE (operands[2]) == CONST_INT)
950 {
951 int i = INTVAL (operands[2]);
952 if (NS32K_DISPLACEMENT_P (i))
953 return \"addr %c2(%1),%0\";
954 else
955 return \"movd %1,%0\;addd %2,%0\";
956 }
957 else
958 {
959 if (flag_pic)
960 return \"addr %a2[%1:b],%0\";
961 else
962 return \"addr %c2(%1),%0\";
963 }
964 }
965 else if (which_alternative == 2)
966 {
967 if (GET_CODE (operands[2]) == CONST_INT &&
968 NS32K_DISPLACEMENT_P (INTVAL (operands[2])))
969 return \"addr %c2(%1),%0\";
970 else
971 return \"sprd %1,%0\;addd %2,%0\";
972 }
973 else if (GET_CODE (operands[2]) == CONST_INT)
974 {
975 int i = INTVAL (operands[2]);
976
977 if (i <= 7 && i >= -8)
978 return \"addqd %2,%0\";
979 else if (! TARGET_32532 && GET_CODE (operands[0]) == REG
980 && NS32K_DISPLACEMENT_P (i))
981 return \"addr %c2(%0),%0\";
982 }
983 return \"addd %2,%0\";
984 }")
985
986 (define_insn "addhi3"
987 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
988 (plus:HI (match_operand:HI 1 "general_operand" "%0")
989 (match_operand:HI 2 "general_operand" "g")))]
990 ""
991 "*
992 { if (GET_CODE (operands[2]) == CONST_INT)
993 {
994 int i = INTVAL (operands[2]);
995 if (i <= 7 && i >= -8)
996 return \"addqw %2,%0\";
997 }
998 return \"addw %2,%0\";
999 }")
1000
1001 (define_insn "*addhi_strict_low3"
1002 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1003 (plus:HI (match_operand:HI 1 "general_operand" "0")
1004 (match_operand:HI 2 "general_operand" "g")))]
1005 ""
1006 "*
1007 {
1008 if (GET_CODE (operands[1]) == CONST_INT
1009 && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8)
1010 return \"addqw %2,%0\";
1011 return \"addw %2,%0\";
1012 }")
1013
1014 (define_insn "addqi3"
1015 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1016 (plus:QI (match_operand:QI 1 "general_operand" "%0")
1017 (match_operand:QI 2 "general_operand" "g")))]
1018 ""
1019 "*
1020 { if (GET_CODE (operands[2]) == CONST_INT)
1021 {
1022 int i = INTVAL (operands[2]);
1023 if (i <= 7 && i >= -8)
1024 return \"addqb %2,%0\";
1025 }
1026 return \"addb %2,%0\";
1027 }")
1028
1029 (define_insn "*addqi_strict_low3"
1030 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
1031 (plus:QI (match_operand:QI 1 "general_operand" "0")
1032 (match_operand:QI 2 "general_operand" "g")))]
1033 ""
1034 "*
1035 {
1036 if (GET_CODE (operands[1]) == CONST_INT
1037 && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8)
1038 return \"addqb %2,%0\";
1039 return \"addb %2,%0\";
1040 }")
1041 \f
1042 ;;- All kinds of subtract instructions.
1043
1044 (define_insn "subdf3"
1045 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm")
1046 (minus:DF (match_operand:DF 1 "general_operand" "0")
1047 (match_operand:DF 2 "general_operand" "lmF")))]
1048 "TARGET_32081"
1049 "subl %2,%0")
1050
1051 (define_insn "subsf3"
1052 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
1053 (minus:SF (match_operand:SF 1 "general_operand" "0")
1054 (match_operand:SF 2 "general_operand" "fmF")))]
1055 "TARGET_32081"
1056 "subf %2,%0")
1057
1058 (define_insn "*sub_from_sp"
1059 [(set (reg:SI 25)
1060 (minus:SI (reg:SI 25)
1061 (match_operand:SI 0 "immediate_operand" "i")))]
1062 "GET_CODE (operands[0]) == CONST_INT"
1063 "*
1064 {
1065 if (! TARGET_32532 && GET_CODE(operands[0]) == CONST_INT
1066 && INTVAL(operands[0]) < 64 && INTVAL(operands[0]) > -64)
1067 return \"adjspb %0\";
1068 return \"adjspd %0\";
1069 }")
1070
1071 (define_insn "subdi3"
1072 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
1073 (minus:DI (match_operand:DI 1 "general_operand" "0")
1074 (match_operand:DI 2 "general_operand" "ron")))]
1075 ""
1076 "*
1077 {
1078 rtx low[3], high[3], xops[4];
1079 split_di (operands, 3, low, high);
1080 xops[0] = low[0];
1081 xops[1] = high[0];
1082 xops[2] = low[2];
1083 xops[3] = high[2];
1084
1085 if (GET_CODE (xops[2]) == CONST_INT)
1086 {
1087 int i = INTVAL (xops[2]);
1088
1089 if (i <= 8 && i >= -7)
1090 {
1091 if (i == 0)
1092 {
1093 i = INTVAL (xops[3]);
1094 if (i <= 8 && i >= -7)
1095 output_asm_insn (\"addqd %n3,%1\", xops);
1096 else
1097 output_asm_insn (\"subd %3,%1\", xops);
1098 }
1099 else
1100 {
1101 output_asm_insn (\"addqd %n2,%0\", xops);
1102 output_asm_insn (\"subcd %3,%1\", xops);
1103 }
1104 return \"\";
1105 }
1106 }
1107 output_asm_insn (\"subd %2,%0\", xops);
1108 output_asm_insn (\"subcd %3,%1\", xops);
1109 return \"\";
1110 }")
1111
1112 (define_insn "subsi3"
1113 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1114 (minus:SI (match_operand:SI 1 "general_operand" "0")
1115 (match_operand:SI 2 "general_operand" "g")))]
1116 ""
1117 "*
1118 { if (GET_CODE (operands[2]) == CONST_INT)
1119 {
1120 int i = INTVAL (operands[2]);
1121
1122 if (i <= 8 && i >= -7)
1123 return \"addqd %n2,%0\";
1124 }
1125 return \"subd %2,%0\";
1126 }")
1127
1128 (define_insn "subhi3"
1129 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1130 (minus:HI (match_operand:HI 1 "general_operand" "0")
1131 (match_operand:HI 2 "general_operand" "g")))]
1132 ""
1133 "*
1134 { if (GET_CODE (operands[2]) == CONST_INT)
1135 {
1136 int i = INTVAL (operands[2]);
1137
1138 if (i <= 8 && i >= -7)
1139 return \"addqw %n2,%0\";
1140 }
1141 return \"subw %2,%0\";
1142 }")
1143
1144 (define_insn "*subhi_strict_low3"
1145 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1146 (minus:HI (match_operand:HI 1 "general_operand" "0")
1147 (match_operand:HI 2 "general_operand" "g")))]
1148 ""
1149 "*
1150 {
1151 if (GET_CODE (operands[1]) == CONST_INT
1152 && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9)
1153 return \"addqw %n2,%0\";
1154 return \"subw %2,%0\";
1155 }")
1156
1157 (define_insn "subqi3"
1158 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1159 (minus:QI (match_operand:QI 1 "general_operand" "0")
1160 (match_operand:QI 2 "general_operand" "g")))]
1161 ""
1162 "*
1163 { if (GET_CODE (operands[2]) == CONST_INT)
1164 {
1165 int i = INTVAL (operands[2]);
1166
1167 if (i <= 8 && i >= -7)
1168 return \"addqb %n2,%0\";
1169 }
1170 return \"subb %2,%0\";
1171 }")
1172
1173 (define_insn "*subqi_strict_low3"
1174 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
1175 (minus:QI (match_operand:QI 1 "general_operand" "0")
1176 (match_operand:QI 2 "general_operand" "g")))]
1177 ""
1178 "*
1179 {
1180 if (GET_CODE (operands[1]) == CONST_INT
1181 && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9)
1182 return \"addqb %n2,%0\";
1183 return \"subb %2,%0\";
1184 }")
1185 \f
1186 ;;- Multiply instructions.
1187
1188 (define_insn "muldf3"
1189 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm")
1190 (mult:DF (match_operand:DF 1 "general_operand" "%0")
1191 (match_operand:DF 2 "general_operand" "lmF")))]
1192 "TARGET_32081"
1193 "mull %2,%0")
1194
1195 (define_insn "mulsf3"
1196 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
1197 (mult:SF (match_operand:SF 1 "general_operand" "%0")
1198 (match_operand:SF 2 "general_operand" "fmF")))]
1199 "TARGET_32081"
1200 "mulf %2,%0")
1201
1202 ;; See note 1
1203 (define_insn "mulsi3"
1204 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1205 (mult:SI (match_operand:SI 1 "general_operand" "%0")
1206 (match_operand:SI 2 "general_operand" "g")))]
1207 ""
1208 "muld %2,%0")
1209
1210 (define_insn "mulhi3"
1211 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1212 (mult:HI (match_operand:HI 1 "general_operand" "%0")
1213 (match_operand:HI 2 "general_operand" "g")))]
1214 ""
1215 "mulw %2,%0")
1216
1217 (define_insn "mulqi3"
1218 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1219 (mult:QI (match_operand:QI 1 "general_operand" "%0")
1220 (match_operand:QI 2 "general_operand" "g")))]
1221 ""
1222 "mulb %2,%0")
1223
1224 (define_insn "umulsidi3"
1225 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1226 (mult:DI (zero_extend:DI
1227 (match_operand:SI 1 "nonimmediate_operand" "0"))
1228 (zero_extend:DI
1229 (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
1230 ""
1231 "meid %2,%0")
1232 \f
1233 ;; divmod insns: We can only do the unsigned case.
1234 (define_expand "udivmodsi4"
1235 [(parallel
1236 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1237 (udiv:SI (match_operand:SI 1 "general_operand" "")
1238 (match_operand:SI 2 "general_operand" "")))
1239 (set (match_operand:SI 3 "nonimmediate_operand" "")
1240 (umod:SI (match_dup 1) (match_dup 2)))])]
1241 ""
1242 "
1243 {
1244 rtx temp = gen_reg_rtx(DImode);
1245 rtx insn, first, last;
1246 first = emit_move_insn(gen_lowpart(SImode, temp), operands[1]);
1247 emit_move_insn(gen_highpart(SImode, temp), const0_rtx);
1248 emit_insn(gen_udivmoddisi4_internal(temp, temp, operands[2]));
1249 last = emit_move_insn(temp, temp);
1250 {
1251 rtx divdi, moddi, divsi, modsi;
1252 divsi = gen_rtx (UDIV, SImode, operands[1], operands[2]);
1253 modsi = gen_rtx (UMOD, SImode, operands[1], operands[2]);
1254 divdi = gen_rtx (ZERO_EXTEND, DImode, divsi);
1255 moddi = gen_rtx (ZERO_EXTEND, DImode, modsi);
1256 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1257 REG_NOTES (first));
1258 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first,
1259 gen_rtx (EXPR_LIST, REG_EQUAL,
1260 gen_rtx (IOR, DImode, moddi,
1261 gen_rtx (ASHIFT, DImode, divdi, GEN_INT(32))),
1262 REG_NOTES (last)));
1263 }
1264
1265 insn = emit_move_insn(operands[0], gen_highpart(SImode, temp));
1266 insn = emit_move_insn(operands[3], gen_lowpart(SImode, temp));
1267 DONE;
1268 }")
1269
1270 ;; If we try and describe what this does, we have to zero-expand an
1271 ;; operand, which prevents it being a constant (VOIDmode) (see udivmoddisi4
1272 ;; below. This udivmoddisi4_internal never matches anything and is only
1273 ;; ever used when explicitly emitted by a define_expand.
1274 (define_insn "udivmoddisi4_internal"
1275 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1276 (unspec:DI [(match_operand:DI 1 "nonimmediate_operand" "0")
1277 (match_operand:SI 2 "general_operand" "g")] 0))]
1278 ""
1279 "deid %2,%0")
1280
1281 ;; Retain this insn which *does* have a pattern indicating what it does,
1282 ;; just in case the compiler is smart enough to recognize a substitution.
1283 (define_insn "udivmoddisi4"
1284 [(set (subreg:SI (match_operand:DI 0 "nonimmediate_operand" "=rm") 4)
1285 (truncate:SI (udiv:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1286 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))))
1287 (set (subreg:SI (match_operand:DI 3 "nonimmediate_operand" "=0") 0)
1288 (truncate:SI (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))]
1289 ""
1290 "deid %2,%0")
1291
1292 ;;;; Part word variants. These seem to never be used at the moment (gcc
1293 ;;;; 2.7.2.2). The code generation prefers to zero extend hi's and qi's
1294 ;;;; and use signed div and mod. Keep these insns incase that changes.
1295 ;;;; divmod should have an advantage when both div and mod are needed. However,
1296 ;;;; divmod uses two registers, so maybe the compiler knows best.
1297 ;;
1298 ;;(define_expand "udivmodhi4"
1299 ;; [(parallel
1300 ;; [(set (match_operand:HI 0 "nonimmediate_operand" "")
1301 ;; (udiv:HI (match_operand:HI 1 "general_operand" "")
1302 ;; (match_operand:HI 2 "general_operand" "")))
1303 ;; (set (match_operand:HI 3 "nonimmediate_operand" "")
1304 ;; (umod:HI (match_dup 1) (match_dup 2)))])]
1305 ;; ""
1306 ;; "
1307 ;;{
1308 ;; rtx temp = gen_reg_rtx(DImode);
1309 ;; rtx insn, first, last;
1310 ;; first = emit_move_insn(gen_lowpart(HImode, temp), operands[1]);
1311 ;; emit_move_insn(gen_highpart (HImode, temp), const0_rtx);
1312 ;; operands[2] = force_reg(HImode, operands[2]);
1313 ;; emit_insn(gen_udivmoddihi4_internal(temp, temp, operands[2]));
1314 ;; last = emit_move_insn(temp, temp);
1315 ;; {
1316 ;; rtx divdi, moddi, divhi, modhi;
1317 ;; divhi = gen_rtx (UDIV, HImode, operands[1], operands[2]);
1318 ;; modhi = gen_rtx (UMOD, HImode, operands[1], operands[2]);
1319 ;; divdi = gen_rtx (ZERO_EXTEND, DImode, divhi);
1320 ;; moddi = gen_rtx (ZERO_EXTEND, DImode, modhi);
1321 ;; REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1322 ;; REG_NOTES (first));
1323 ;; REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first,
1324 ;; gen_rtx (EXPR_LIST, REG_EQUAL,
1325 ;; gen_rtx(IOR, DImode, moddi,
1326 ;; gen_rtx(ASHIFT, DImode, divdi, GEN_INT(32))),
1327 ;; REG_NOTES (last)));
1328 ;; }
1329 ;;
1330 ;; insn = emit_move_insn(operands[0], gen_highpart(HImode, temp));
1331 ;; insn = emit_move_insn(operands[3], gen_lowpart(HImode, temp));
1332 ;; DONE;
1333 ;;}")
1334 ;;
1335 ;;;; deiw wants two hi's in separate registers or else they can be adjacent
1336 ;;;; in memory. DI mode will ensure two registers are available, but if we
1337 ;;;; want to allow memory as an operand we would need SI mode. There is no
1338 ;;;; way to do this, so just restrict operand 0 and 1 to be in registers.
1339 ;;(define_insn "udivmoddihi4_internal"
1340 ;; [(set (match_operand:DI 0 "register_operand" "=r")
1341 ;; (unspec:DI [(match_operand:DI 1 "register_operand" "0")
1342 ;; (match_operand:HI 2 "general_operand" "g")] 0))]
1343 ;; ""
1344 ;; "deiw %2,%0")
1345 ;;
1346 ;;(define_insn "udivmoddihi4"
1347 ;; [(set (subreg:HI (match_operand:DI 0 "register_operand" "=r") 2)
1348 ;; (truncate:HI (udiv:DI (match_operand:DI 1 "register_operand" "0")
1349 ;; (zero_extend:DI (match_operand:HI 2 "nonimmediate_operand" "rm")))))
1350 ;; (set (subreg:HI (match_operand:DI 3 "register_operand" "=0") 0)
1351 ;; (truncate:HI (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))]
1352 ;; ""
1353 ;; "deiw %2,%0")
1354 ;;
1355 ;;(define_expand "udivmodqi4"
1356 ;; [(parallel
1357 ;; [(set (match_operand:QI 0 "nonimmediate_operand" "")
1358 ;; (udiv:QI (match_operand:QI 1 "general_operand" "")
1359 ;; (match_operand:QI 2 "general_operand" "")))
1360 ;; (set (match_operand:QI 3 "nonimmediate_operand" "")
1361 ;; (umod:QI (match_dup 1) (match_dup 2)))])]
1362 ;; ""
1363 ;; "
1364 ;;{
1365 ;; rtx temp = gen_reg_rtx(DImode);
1366 ;; rtx insn, first, last;
1367 ;; first = emit_move_insn(gen_lowpart(QImode, temp), operands[1]);
1368 ;; emit_move_insn(gen_highpart(QImode, temp), const0_rtx);
1369 ;; operands[2] = force_reg(QImode, operands[2]);
1370 ;; emit_insn(gen_udivmoddiqi4_internal(temp, temp, operands[2]));
1371 ;; last = emit_move_insn(temp, temp);
1372 ;; {
1373 ;; rtx divdi, moddi, divqi, modqi;
1374 ;; divqi = gen_rtx (UDIV, QImode, operands[1], operands[2]);
1375 ;; modqi = gen_rtx (UMOD, QImode, operands[1], operands[2]);
1376 ;; divdi = gen_rtx (ZERO_EXTEND, DImode, divqi);
1377 ;; moddi = gen_rtx (ZERO_EXTEND, DImode, modqi);
1378 ;; REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1379 ;; REG_NOTES (first));
1380 ;; REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first,
1381 ;; gen_rtx (EXPR_LIST, REG_EQUAL,
1382 ;; gen_rtx(IOR, DImode, moddi,
1383 ;; gen_rtx(ASHIFT, DImode, divdi, GEN_INT(32))),
1384 ;; REG_NOTES (last)));
1385 ;; }
1386 ;;
1387 ;; insn = emit_move_insn(operands[0], gen_highpart(QImode, temp));
1388 ;; insn = emit_move_insn(operands[3], gen_lowpart(QImode, temp));
1389 ;; DONE;
1390 ;;}")
1391 ;;
1392 ;;;; deib wants two qi's in separate registers or else they can be adjacent
1393 ;;;; in memory. DI mode will ensure two registers are available, but if we
1394 ;;;; want to allow memory as an operand we would need HI mode. There is no
1395 ;;;; way to do this, so just restrict operand 0 and 1 to be in registers.
1396 ;;(define_insn "udivmoddiqi4_internal"
1397 ;; [(set (match_operand:DI 0 "register_operand" "=r")
1398 ;; (unspec:DI [(match_operand:DI 1 "register_operand" "0")
1399 ;; (match_operand:QI 2 "general_operand" "g")] 0))]
1400 ;; ""
1401 ;; "deib %2,%0")
1402 ;;
1403 ;;(define_insn "udivmoddiqi4"
1404 ;; [(set (subreg:QI (match_operand:DI 0 "register_operand" "=r") 1)
1405 ;; (truncate:QI (udiv:DI (match_operand:DI 1 "register_operand" "0")
1406 ;; (zero_extend:DI (match_operand:QI 2 "nonimmediate_operand" "rm")))))
1407 ;; (set (subreg:QI (match_operand:DI 3 "register_operand" "=0") 0)
1408 ;; (truncate:QI (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))]
1409 ;; ""
1410 ;; "deib %2,%0")
1411 \f
1412 ;;- Divide instructions.
1413
1414 (define_insn "divdf3"
1415 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm")
1416 (div:DF (match_operand:DF 1 "general_operand" "0")
1417 (match_operand:DF 2 "general_operand" "lmF")))]
1418 "TARGET_32081"
1419 "divl %2,%0")
1420
1421 (define_insn "divsf3"
1422 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
1423 (div:SF (match_operand:SF 1 "general_operand" "0")
1424 (match_operand:SF 2 "general_operand" "fmF")))]
1425 "TARGET_32081"
1426 "divf %2,%0")
1427
1428 ;; See note 1
1429 (define_insn "divsi3"
1430 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1431 (div:SI (match_operand:SI 1 "general_operand" "0")
1432 (match_operand:SI 2 "general_operand" "g")))]
1433 ""
1434 "quod %2,%0")
1435
1436 (define_insn "divhi3"
1437 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1438 (div:HI (match_operand:HI 1 "general_operand" "0")
1439 (match_operand:HI 2 "general_operand" "g")))]
1440 ""
1441 "quow %2,%0")
1442
1443 (define_insn "divqi3"
1444 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1445 (div:QI (match_operand:QI 1 "general_operand" "0")
1446 (match_operand:QI 2 "general_operand" "g")))]
1447 ""
1448 "quob %2,%0")
1449 \f
1450 ;; Remainder instructions.
1451
1452 ;; See note 1
1453 (define_insn "modsi3"
1454 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1455 (mod:SI (match_operand:SI 1 "general_operand" "0")
1456 (match_operand:SI 2 "general_operand" "g")))]
1457 ""
1458 "remd %2,%0")
1459
1460 (define_insn "modhi3"
1461 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1462 (mod:HI (match_operand:HI 1 "general_operand" "0")
1463 (match_operand:HI 2 "general_operand" "g")))]
1464 ""
1465 "remw %2,%0")
1466
1467 (define_insn "modqi3"
1468 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1469 (mod:QI (match_operand:QI 1 "general_operand" "0")
1470 (match_operand:QI 2 "general_operand" "g")))]
1471 ""
1472 "remb %2,%0")
1473
1474 \f
1475 ;;- Logical Instructions: AND
1476
1477 ;; See note 1
1478 (define_insn "andsi3"
1479 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1480 (and:SI (match_operand:SI 1 "general_operand" "%0")
1481 (match_operand:SI 2 "general_operand" "g")))]
1482 ""
1483 "*
1484 {
1485 if (GET_CODE (operands[2]) == CONST_INT)
1486 {
1487 if ((INTVAL (operands[2]) | 0xff) == 0xffffffff)
1488 {
1489 if (INTVAL (operands[2]) == 0xffffff00)
1490 return \"movqb %$0,%0\";
1491 else
1492 {
1493 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
1494 return \"andb %2,%0\";
1495 }
1496 }
1497 if ((INTVAL (operands[2]) | 0xffff) == 0xffffffff)
1498 {
1499 if (INTVAL (operands[2]) == 0xffff0000)
1500 return \"movqw %$0,%0\";
1501 else
1502 {
1503 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1504 return \"andw %2,%0\";
1505 }
1506 }
1507 }
1508 return \"andd %2,%0\";
1509 }")
1510
1511 (define_insn "andhi3"
1512 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1513 (and:HI (match_operand:HI 1 "general_operand" "%0")
1514 (match_operand:HI 2 "general_operand" "g")))]
1515 ""
1516 "*
1517 {
1518 if (GET_CODE (operands[2]) == CONST_INT
1519 && (INTVAL (operands[2]) | 0xff) == 0xffffffff)
1520 {
1521 if (INTVAL (operands[2]) == 0xffffff00)
1522 return \"movqb %$0,%0\";
1523 else
1524 {
1525 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
1526 return \"andb %2,%0\";
1527 }
1528 }
1529 return \"andw %2,%0\";
1530 }")
1531
1532 (define_insn "andqi3"
1533 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1534 (and:QI (match_operand:QI 1 "general_operand" "%0")
1535 (match_operand:QI 2 "general_operand" "g")))]
1536 ""
1537 "andb %2,%0")
1538
1539 ;; See note 1
1540 (define_insn "*bicsi"
1541 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1542 (and:SI (not:SI (match_operand:SI 1 "general_operand" "g"))
1543 (match_operand:SI 2 "general_operand" "0")))]
1544 ""
1545 "bicd %1,%0")
1546
1547 (define_insn "*bichi"
1548 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1549 (and:HI (not:HI (match_operand:HI 1 "general_operand" "g"))
1550 (match_operand:HI 2 "general_operand" "0")))]
1551 ""
1552 "bicw %1,%0")
1553
1554 (define_insn "*bicqi"
1555 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1556 (and:QI (not:QI (match_operand:QI 1 "general_operand" "g"))
1557 (match_operand:QI 2 "general_operand" "0")))]
1558 ""
1559 "bicb %1,%0")
1560 \f
1561 ;;- Bit set instructions.
1562
1563 ;; See note 1
1564 (define_insn "iorsi3"
1565 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1566 (ior:SI (match_operand:SI 1 "general_operand" "%0")
1567 (match_operand:SI 2 "general_operand" "g")))]
1568 ""
1569 "*
1570 {
1571 if (GET_CODE (operands[2]) == CONST_INT) {
1572 if ((INTVAL (operands[2]) & 0xffffff00) == 0)
1573 return \"orb %2,%0\";
1574 if ((INTVAL (operands[2]) & 0xffff0000) == 0)
1575 return \"orw %2,%0\";
1576 }
1577 return \"ord %2,%0\";
1578 }")
1579
1580 (define_insn "iorhi3"
1581 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1582 (ior:HI (match_operand:HI 1 "general_operand" "%0")
1583 (match_operand:HI 2 "general_operand" "g")))]
1584 ""
1585 "*
1586 {
1587 if (GET_CODE(operands[2]) == CONST_INT &&
1588 (INTVAL(operands[2]) & 0xffffff00) == 0)
1589 return \"orb %2,%0\";
1590 return \"orw %2,%0\";
1591 }")
1592
1593 (define_insn "iorqi3"
1594 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1595 (ior:QI (match_operand:QI 1 "general_operand" "%0")
1596 (match_operand:QI 2 "general_operand" "g")))]
1597 ""
1598 "orb %2,%0")
1599
1600 ;;- xor instructions.
1601
1602 ;; See note 1
1603 (define_insn "xorsi3"
1604 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1605 (xor:SI (match_operand:SI 1 "general_operand" "%0")
1606 (match_operand:SI 2 "general_operand" "g")))]
1607 ""
1608 "*
1609 {
1610 if (GET_CODE (operands[2]) == CONST_INT) {
1611 if ((INTVAL (operands[2]) & 0xffffff00) == 0)
1612 return \"xorb %2,%0\";
1613 if ((INTVAL (operands[2]) & 0xffff0000) == 0)
1614 return \"xorw %2,%0\";
1615 }
1616 return \"xord %2,%0\";
1617 }")
1618
1619 (define_insn "xorhi3"
1620 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1621 (xor:HI (match_operand:HI 1 "general_operand" "%0")
1622 (match_operand:HI 2 "general_operand" "g")))]
1623 ""
1624 "*
1625 {
1626 if (GET_CODE(operands[2]) == CONST_INT &&
1627 (INTVAL(operands[2]) & 0xffffff00) == 0)
1628 return \"xorb %2,%0\";
1629 return \"xorw %2,%0\";
1630 }")
1631
1632 (define_insn "xorqi3"
1633 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1634 (xor:QI (match_operand:QI 1 "general_operand" "%0")
1635 (match_operand:QI 2 "general_operand" "g")))]
1636 ""
1637 "xorb %2,%0")
1638 \f
1639 (define_insn "negdf2"
1640 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm<")
1641 (neg:DF (match_operand:DF 1 "general_operand" "lmF")))]
1642 "TARGET_32081"
1643 "negl %1,%0")
1644
1645 (define_insn "negsf2"
1646 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm<")
1647 (neg:SF (match_operand:SF 1 "general_operand" "fmF")))]
1648 "TARGET_32081"
1649 "negf %1,%0")
1650
1651 (define_insn "negdi2"
1652 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
1653 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "ro")))]
1654 ""
1655 "*
1656 {
1657 rtx low[2], high[2], xops[4];
1658 split_di (operands, 2, low, high);
1659 xops[0] = low[0];
1660 xops[1] = high[0];
1661 xops[2] = low[1];
1662 xops[3] = high[1];
1663
1664 if (rtx_equal_p (operands[0], operands[1]))
1665 {
1666 output_asm_insn (\"negd %3,%1\", xops);
1667 output_asm_insn (\"negd %2,%0\", xops);
1668 output_asm_insn (\"subcd %$0,%1\", xops);
1669 }
1670 else
1671 {
1672 output_asm_insn (\"negd %2,%0\", xops);
1673 output_asm_insn (\"movqd %$0,%1\", xops);
1674 output_asm_insn (\"subcd %3,%1\", xops);
1675 }
1676 return \"\";
1677 }")
1678
1679 ;; See note 1
1680 (define_insn "negsi2"
1681 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
1682 (neg:SI (match_operand:SI 1 "general_operand" "g")))]
1683 ""
1684 "negd %1,%0")
1685
1686 (define_insn "neghi2"
1687 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
1688 (neg:HI (match_operand:HI 1 "general_operand" "g")))]
1689 ""
1690 "negw %1,%0")
1691
1692 (define_insn "negqi2"
1693 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
1694 (neg:QI (match_operand:QI 1 "general_operand" "g")))]
1695 ""
1696 "negb %1,%0")
1697 \f
1698 ;; See note 1
1699 (define_insn "one_cmplsi2"
1700 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
1701 (not:SI (match_operand:SI 1 "general_operand" "g")))]
1702 ""
1703 "comd %1,%0")
1704
1705 (define_insn "one_cmplhi2"
1706 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
1707 (not:HI (match_operand:HI 1 "general_operand" "g")))]
1708 ""
1709 "comw %1,%0")
1710
1711 (define_insn "one_cmplqi2"
1712 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
1713 (not:QI (match_operand:QI 1 "general_operand" "g")))]
1714 ""
1715 "comb %1,%0")
1716 \f
1717 ;; arithmetic left and right shift operations
1718 ;; on the 32532 we will always use lshd for arithmetic left shifts,
1719 ;; because it is three times faster. Broken programs which
1720 ;; use negative shift counts are probably broken differently
1721 ;; than elsewhere.
1722
1723 ;; alternative 0 never matches on the 32532
1724 ;; See note 1
1725 (define_insn "ashlsi3"
1726 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1727 (ashift:SI (match_operand:SI 1 "general_operand" "r,0")
1728 (match_operand:SI 2 "general_operand" "I,g")))]
1729 ""
1730 "*
1731 { if (TARGET_32532)
1732 return \"lshd %2,%0\";
1733 else
1734 return output_shift_insn (operands);
1735 }")
1736
1737 (define_insn "ashlhi3"
1738 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1739 (ashift:HI (match_operand:HI 1 "general_operand" "0")
1740 (match_operand:SI 2 "general_operand" "g")))]
1741 ""
1742 "*
1743 { if (GET_CODE (operands[2]) == CONST_INT)
1744 {
1745 if (INTVAL (operands[2]) == 1)
1746 return \"addw %0,%0\";
1747 else if (! TARGET_32532 && INTVAL (operands[2]) == 2)
1748 return \"addw %0,%0\;addw %0,%0\";
1749 }
1750 if (TARGET_32532)
1751 return \"lshw %2,%0\";
1752 else
1753 return \"ashw %2,%0\";
1754 }")
1755
1756 (define_insn "ashlqi3"
1757 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1758 (ashift:QI (match_operand:QI 1 "general_operand" "0")
1759 (match_operand:SI 2 "general_operand" "g")))]
1760 ""
1761 "*
1762 { if (GET_CODE (operands[2]) == CONST_INT)
1763 {
1764 if (INTVAL (operands[2]) == 1)
1765 return \"addb %0,%0\";
1766 else if (! TARGET_32532 && INTVAL (operands[2]) == 2)
1767 return \"addb %0,%0\;addb %0,%0\";
1768 }
1769 if (TARGET_32532)
1770 return \"lshb %2,%0\";
1771 else
1772 return \"ashb %2,%0\";
1773 }")
1774
1775 ;; Arithmetic right shift on the 32k works by negating the shift count.
1776 (define_expand "ashrsi3"
1777 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1778 (ashiftrt:SI (match_operand:SI 1 "general_operand" "g")
1779 (match_operand:SI 2 "general_operand" "g")))]
1780 ""
1781 "
1782 {
1783 if (GET_CODE (operands[2]) != CONST_INT)
1784 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1785 }")
1786
1787 (define_insn "*ashrisi3"
1788 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1789 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
1790 (match_operand:SI 2 "immediate_operand" "i")))]
1791 ""
1792 "ashd %n2,%0")
1793
1794 (define_insn "*ashrsi3"
1795 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1796 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
1797 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1798 ""
1799 "ashd %2,%0")
1800
1801 (define_expand "ashrhi3"
1802 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1803 (ashiftrt:HI (match_operand:HI 1 "general_operand" "g")
1804 (match_operand:SI 2 "general_operand" "g")))]
1805 ""
1806 "
1807 {
1808 if (GET_CODE (operands[2]) != CONST_INT)
1809 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1810 }")
1811
1812 (define_insn "*ashrihi3"
1813 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1814 (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
1815 (match_operand:SI 2 "immediate_operand" "i")))]
1816 ""
1817 "ashw %n2,%0")
1818
1819 (define_insn "*ashrhi3"
1820 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1821 (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
1822 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1823 ""
1824 "ashw %2,%0")
1825
1826 (define_expand "ashrqi3"
1827 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1828 (ashiftrt:QI (match_operand:QI 1 "general_operand" "g")
1829 (match_operand:SI 2 "general_operand" "g")))]
1830 ""
1831 "
1832 {
1833 if (GET_CODE (operands[2]) != CONST_INT)
1834 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1835 }")
1836
1837 (define_insn "*ashriqi3"
1838 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1839 (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
1840 (match_operand:SI 2 "immediate_operand" "i")))]
1841 ""
1842 "ashb %n2,%0")
1843
1844 (define_insn "*ashrqi3"
1845 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1846 (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
1847 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1848 ""
1849 "ashb %2,%0")
1850
1851 ;; logical shift instructions
1852
1853 ;; Logical right shift on the 32k works by negating the shift count.
1854 (define_expand "lshrsi3"
1855 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1856 (lshiftrt:SI (match_operand:SI 1 "general_operand" "g")
1857 (match_operand:SI 2 "general_operand" "g")))]
1858 ""
1859 "
1860 {
1861 if (GET_CODE (operands[2]) != CONST_INT)
1862 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1863 }")
1864
1865 (define_insn "*lshrisi3"
1866 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1867 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1868 (match_operand:SI 2 "immediate_operand" "i")))]
1869 ""
1870 "lshd %n2,%0")
1871
1872 (define_insn "*lshrsi3"
1873 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1874 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1875 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1876 ""
1877 "lshd %2,%0")
1878
1879 (define_expand "lshrhi3"
1880 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1881 (lshiftrt:HI (match_operand:HI 1 "general_operand" "g")
1882 (match_operand:SI 2 "general_operand" "g")))]
1883 ""
1884 "
1885 {
1886 if (GET_CODE (operands[2]) != CONST_INT)
1887 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1888 }")
1889
1890 (define_insn "*lshrihi3"
1891 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1892 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1893 (match_operand:SI 2 "immediate_operand" "i")))]
1894 ""
1895 "lshw %n2,%0")
1896
1897 (define_insn "*lshrhi3"
1898 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1899 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1900 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1901 ""
1902 "lshw %2,%0")
1903
1904 (define_expand "lshrqi3"
1905 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1906 (lshiftrt:QI (match_operand:QI 1 "general_operand" "g")
1907 (match_operand:SI 2 "general_operand" "g")))]
1908 ""
1909 "
1910 {
1911 if (GET_CODE (operands[2]) != CONST_INT)
1912 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1913 }")
1914
1915 (define_insn "*lshriqi3"
1916 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1917 (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
1918 (match_operand:SI 2 "immediate_operand" "i")))]
1919 ""
1920 "lshb %n2,%0")
1921
1922 (define_insn "*lshrqi3"
1923 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1924 (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
1925 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1926 ""
1927 "lshb %2,%0")
1928
1929 ;; Rotate instructions
1930
1931 ;; See note 1
1932 (define_insn "rotlsi3"
1933 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1934 (rotate:SI (match_operand:SI 1 "general_operand" "0")
1935 (match_operand:SI 2 "general_operand" "g")))]
1936 ""
1937 "rotd %2,%0")
1938
1939 (define_insn "rotlhi3"
1940 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1941 (rotate:HI (match_operand:HI 1 "general_operand" "0")
1942 (match_operand:SI 2 "general_operand" "g")))]
1943 ""
1944 "rotw %2,%0")
1945
1946 (define_insn "rotlqi3"
1947 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1948 (rotate:QI (match_operand:QI 1 "general_operand" "0")
1949 (match_operand:SI 2 "general_operand" "g")))]
1950 ""
1951 "rotb %2,%0")
1952
1953 ;; Right rotate on the 32k works by negating the shift count.
1954 (define_expand "rotrsi3"
1955 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1956 (rotatert:SI (match_operand:SI 1 "general_operand" "g")
1957 (match_operand:SI 2 "general_operand" "g")))]
1958 ""
1959 "
1960 {
1961 if (GET_CODE (operands[2]) != CONST_INT)
1962 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1963 }")
1964
1965 (define_insn "*rotrisi3"
1966 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1967 (rotatert:SI (match_operand:SI 1 "general_operand" "0")
1968 (match_operand:SI 2 "immediate_operand" "i")))]
1969 ""
1970 "rotd %n2,%0")
1971
1972 (define_insn "*rotrsi3"
1973 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1974 (rotatert:SI (match_operand:SI 1 "general_operand" "0")
1975 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1976 ""
1977 "rotd %2,%0")
1978
1979 (define_expand "rotrhi3"
1980 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1981 (rotatert:HI (match_operand:HI 1 "general_operand" "g")
1982 (match_operand:SI 2 "general_operand" "g")))]
1983 ""
1984 "
1985 {
1986 if (GET_CODE (operands[2]) != CONST_INT)
1987 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1988 }")
1989
1990 (define_insn "*rotrihi3"
1991 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1992 (rotatert:HI (match_operand:HI 1 "general_operand" "0")
1993 (match_operand:SI 2 "immediate_operand" "i")))]
1994 ""
1995 "rotw %n2,%0")
1996
1997 (define_insn "*rotrhi3"
1998 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1999 (rotatert:HI (match_operand:HI 1 "general_operand" "0")
2000 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
2001 ""
2002 "rotw %2,%0")
2003
2004 (define_expand "rotrqi3"
2005 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
2006 (rotatert:QI (match_operand:QI 1 "general_operand" "g")
2007 (match_operand:SI 2 "general_operand" "g")))]
2008 ""
2009 "
2010 {
2011 if (GET_CODE (operands[2]) != CONST_INT)
2012 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
2013 }")
2014
2015 (define_insn "*rotriqi3"
2016 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
2017 (rotatert:QI (match_operand:QI 1 "general_operand" "0")
2018 (match_operand:SI 2 "immediate_operand" "i")))]
2019 ""
2020 "rotb %n2,%0")
2021
2022 (define_insn "*rotrqi3"
2023 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
2024 (rotatert:QI (match_operand:QI 1 "general_operand" "0")
2025 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
2026 ""
2027 "rotb %2,%0")
2028 \f
2029 ;;- load or push effective address
2030 ;; These come after the move, add, and multiply patterns
2031 ;; because we don't want pushl $1 turned into pushad 1.
2032
2033 (define_insn "*addrsi"
2034 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2035 (match_operand:QI 1 "address_operand" "p"))]
2036 ""
2037 "*
2038 {
2039 if (REG_P (operands[0])
2040 && GET_CODE (operands[1]) == MULT
2041 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
2042 && (INTVAL (XEXP (operands[1], 1)) == 2
2043 || INTVAL (XEXP (operands[1], 1)) == 4))
2044 {
2045 rtx xoperands[3];
2046 xoperands[0] = operands[0];
2047 xoperands[1] = XEXP (operands[1], 0);
2048 xoperands[2] = GEN_INT (INTVAL (XEXP (operands[1], 1)) >> 1);
2049 return output_shift_insn (xoperands);
2050 }
2051 return \"addr %a1,%0\";
2052 }")
2053 \f
2054 ;;; Index insns. These are about the same speed as multiply-add counterparts.
2055 ;;; but slower than using power-of-2 shifts if we can use them
2056 ;
2057 ;;; See note 1
2058 ;(define_insn ""
2059 ; [(set (match_operand:SI 0 "register_operand" "=r")
2060 ; (plus:SI (match_operand:SI 1 "general_operand" "g")
2061 ; (mult:SI (match_operand:SI 2 "register_operand" "0")
2062 ; (plus:SI (match_operand:SI 3 "general_operand" "g") (const_int 1)))))]
2063 ; "GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) > 8"
2064 ; "indexd %0,%3,%1")
2065 ;
2066 ;(define_insn ""
2067 ; [(set (match_operand:SI 0 "register_operand" "=r")
2068 ; (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
2069 ; (plus:SI (match_operand:SI 2 "general_operand" "g") (const_int 1)))
2070 ; (match_operand:SI 3 "general_operand" "g")))]
2071 ; "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 8"
2072 ; "indexd %0,%2,%3")
2073 \f
2074 ;; Set, Clear, and Invert bit
2075
2076 ;; See note 1
2077 (define_insn "*sbitsi"
2078 [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+rm")
2079 (const_int 1)
2080 (match_operand:SI 1 "general_operand" "g"))
2081 (const_int 1))]
2082 ""
2083 "sbitd %1,%0")
2084
2085 ;; See note 1
2086 (define_insn "*cbitsi"
2087 [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+rm")
2088 (const_int 1)
2089 (match_operand:SI 1 "general_operand" "g"))
2090 (const_int 0))]
2091 ""
2092 "cbitd %1,%0")
2093
2094 ;; See note 1
2095 (define_insn "*ibitsi"
2096 [(set (match_operand:SI 0 "nonimmediate_operand" "+rm")
2097 (xor:SI (ashift:SI (const_int 1)
2098 (match_operand:SI 1 "general_operand" "g"))
2099 (match_dup 0)))]
2100 ""
2101 "ibitd %1,%0")
2102
2103 ;; See note 1
2104 (define_insn "*ibitqi"
2105 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
2106 (xor:QI (subreg:QI
2107 (ashift:SI (const_int 1)
2108 (match_operand:QI 1 "general_operand" "g")) 0)
2109 (match_dup 0)))]
2110 ""
2111 "ibitb %1,%0")
2112
2113 ;; Recognize jbs and jbc instructions.
2114
2115 (define_insn "*tbit"
2116 [(set (cc0)
2117 (zero_extract (match_operand:SI 0 "nonimmediate_operand" "rm")
2118 (const_int 1)
2119 (match_operand:SI 1 "general_operand" "g")))]
2120 ""
2121 "*
2122 { cc_status.flags = CC_Z_IN_F;
2123 return \"tbitd %1,%0\";
2124 }")
2125
2126 ;; extract(base, width, offset)
2127 ;; Signed bit-field extraction is not supported in hardware on the
2128 ;; NS 32032. It is therefore better to let GCC figure out a
2129 ;; good strategy for generating the proper instruction sequence
2130 ;; and represent it as rtl.
2131
2132 ;; Optimize the case of extracting a byte or word from a register.
2133 ;; Otherwise we must load a register with the offset of the
2134 ;; chunk we want, and perform an extract insn (each of which
2135 ;; is very expensive). Since we use the stack to do our bit-twiddling
2136 ;; we cannot use it for a destination. Perhaps things are fast
2137 ;; enough on the 32532 that such hacks are not needed.
2138
2139 (define_insn "*extract_bytes"
2140 [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
2141 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
2142 (match_operand:SI 2 "const_int_operand" "i")
2143 (match_operand:SI 3 "const_int_operand" "i")))]
2144 "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
2145 && (INTVAL (operands[3]) == 8 || INTVAL (operands[3]) == 16 || INTVAL (operands[3]) == 24)"
2146 "*
2147 {
2148 output_asm_insn (\"movd %1,tos\", operands);
2149 if (INTVAL (operands[2]) == 16)
2150 {
2151 if (INTVAL (operands[3]) == 8)
2152 output_asm_insn (\"movzwd 1(sp),%0\", operands);
2153 else
2154 output_asm_insn (\"movzwd 2(sp),%0\", operands);
2155 }
2156 else
2157 {
2158 if (INTVAL (operands[3]) == 8)
2159 output_asm_insn (\"movzbd 1(sp),%0\", operands);
2160 else if (INTVAL (operands[3]) == 16)
2161 output_asm_insn (\"movzbd 2(sp),%0\", operands);
2162 else
2163 output_asm_insn (\"movzbd 3(sp),%0\", operands);
2164 }
2165 if (TARGET_32532 || TARGET_32332)
2166 return \"cmpqd %$0,tos\";
2167 else
2168 return \"adjspb %$-4\";
2169 }")
2170
2171 ;; The exts/ext instructions have the problem that they always access
2172 ;; 32 bits even if the bit-field is smaller. For example the instruction
2173 ;; extsd 7(r1),r0,2,5
2174 ;; would read not only at address 7(r1) but also at 8(r1) to 10(r1).
2175 ;; If these addresses are in a different (unmapped) page a memory fault
2176 ;; is the result.
2177 ;;
2178 ;; Timing considerations:
2179 ;; movd 0(r1),r0 3 bytes
2180 ;; lshd -26,r0 4
2181 ;; andd 0x1f,r0 5
2182 ;; takes about 13 cycles on the 532 while
2183 ;; extsd 7(r1),r0,2,5 5 bytes
2184 ;; takes about 21 cycles.
2185 ;;
2186 ;; The inss/ins instructions suffer from the same problem.
2187 ;;
2188 ;; A machine specific option (-mbitfield/-mnobitfield) is used
2189 ;; to allow/disallow the use of these instructions.
2190
2191 (define_insn "*bitfield_ext"
2192 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2193 (zero_extract:SI (match_operand:SI 1 "register_operand" "g")
2194 (match_operand:SI 2 "const_int_operand" "i")
2195 (match_operand:SI 3 "nonmemory_operand" "rK")))]
2196 "TARGET_BITFIELD"
2197 "*
2198 { if (GET_CODE (operands[3]) == CONST_INT)
2199 return \"extsd %1,%0,%3,%2\";
2200 else return \"extd %3,%1,%0,%2\";
2201 }")
2202
2203 (define_insn "extzv"
2204 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2205 (zero_extract:SI (match_operand:QI 1 "general_operand" "g")
2206 (match_operand:SI 2 "const_int_operand" "i")
2207 (match_operand:SI 3 "nonmemory_operand" "rK")))]
2208 "TARGET_BITFIELD"
2209 "*
2210 { if (GET_CODE (operands[3]) == CONST_INT)
2211 return \"extsd %1,%0,%3,%2\";
2212 else return \"extd %3,%1,%0,%2\";
2213 }")
2214
2215 (define_insn "*bitfield_set"
2216 [(set (zero_extract:SI (match_operand:SI 0 "memory_operand" "+o,+r")
2217 (match_operand:SI 1 "const_int_operand" "i,i")
2218 (match_operand:SI 2 "nonmemory_operand" "rn,rK"))
2219 (match_operand:SI 3 "nonimmediate_operand" "rm,rm"))]
2220 "TARGET_BITFIELD"
2221 "*
2222 { if (GET_CODE (operands[2]) == CONST_INT)
2223 {
2224 if (which_alternative == 0 && INTVAL (operands[2]) >= 8)
2225 {
2226 operands[0] = adjust_address (operands[0], QImode,
2227 INTVAL (operands[2]) / 8);
2228 operands[2] = GEN_INT (INTVAL (operands[2]) % 8);
2229 }
2230 if (INTVAL (operands[1]) <= 8)
2231 return \"inssb %3,%0,%2,%1\";
2232 else if (INTVAL (operands[1]) <= 16)
2233 return \"inssw %3,%0,%2,%1\";
2234 else
2235 return \"inssd %3,%0,%2,%1\";
2236 }
2237 return \"insd %2,%3,%0,%1\";
2238 }")
2239
2240
2241 (define_insn "insv"
2242 [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+rm")
2243 (match_operand:SI 1 "const_int_operand" "i")
2244 (match_operand:SI 2 "nonmemory_operand" "rK"))
2245 (match_operand:SI 3 "nonimmediate_operand" "rm"))]
2246 "TARGET_BITFIELD"
2247 "*
2248 { if (GET_CODE (operands[2]) == CONST_INT)
2249 {
2250 if (INTVAL (operands[1]) <= 8)
2251 return \"inssb %3,%0,%2,%1\";
2252 else if (INTVAL (operands[1]) <= 16)
2253 return \"inssw %3,%0,%2,%1\";
2254 else
2255 return \"inssd %3,%0,%2,%1\";
2256 }
2257 return \"insd %2,%3,%0,%1\";
2258 }")
2259
2260 \f
2261 (define_insn "jump"
2262 [(set (pc)
2263 (label_ref (match_operand 0 "" "")))]
2264 ""
2265 "br %l0")
2266
2267 (define_insn "beq"
2268 [(set (pc)
2269 (if_then_else (eq (cc0)
2270 (const_int 0))
2271 (label_ref (match_operand 0 "" ""))
2272 (pc)))]
2273 ""
2274 "*
2275 { if (cc_prev_status.flags & CC_Z_IN_F)
2276 return \"bfc %l0\";
2277 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2278 return \"bfs %l0\";
2279 else return \"beq %l0\";
2280 }")
2281
2282 (define_insn "bne"
2283 [(set (pc)
2284 (if_then_else (ne (cc0)
2285 (const_int 0))
2286 (label_ref (match_operand 0 "" ""))
2287 (pc)))]
2288 ""
2289 "*
2290 { if (cc_prev_status.flags & CC_Z_IN_F)
2291 return \"bfs %l0\";
2292 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2293 return \"bfc %l0\";
2294 else return \"bne %l0\";
2295 }")
2296
2297 (define_insn "bgt"
2298 [(set (pc)
2299 (if_then_else (gt (cc0)
2300 (const_int 0))
2301 (label_ref (match_operand 0 "" ""))
2302 (pc)))]
2303 ""
2304 "bgt %l0")
2305
2306 (define_insn "bgtu"
2307 [(set (pc)
2308 (if_then_else (gtu (cc0)
2309 (const_int 0))
2310 (label_ref (match_operand 0 "" ""))
2311 (pc)))]
2312 ""
2313 "bhi %l0")
2314
2315 (define_insn "blt"
2316 [(set (pc)
2317 (if_then_else (lt (cc0)
2318 (const_int 0))
2319 (label_ref (match_operand 0 "" ""))
2320 (pc)))]
2321 ""
2322 "*
2323 {
2324 if (cc_prev_status.flags & CC_UNORD)
2325 return \"bhi 0f\;blt %l0\;0:\";
2326 else
2327 return \"blt %l0\";
2328 }")
2329
2330 (define_insn "bltu"
2331 [(set (pc)
2332 (if_then_else (ltu (cc0)
2333 (const_int 0))
2334 (label_ref (match_operand 0 "" ""))
2335 (pc)))]
2336 ""
2337 "blo %l0")
2338
2339 (define_insn "bge"
2340 [(set (pc)
2341 (if_then_else (ge (cc0)
2342 (const_int 0))
2343 (label_ref (match_operand 0 "" ""))
2344 (pc)))]
2345 ""
2346 "bge %l0")
2347
2348 (define_insn "bgeu"
2349 [(set (pc)
2350 (if_then_else (geu (cc0)
2351 (const_int 0))
2352 (label_ref (match_operand 0 "" ""))
2353 (pc)))]
2354 ""
2355 "bhs %l0")
2356
2357 (define_insn "ble"
2358 [(set (pc)
2359 (if_then_else (le (cc0)
2360 (const_int 0))
2361 (label_ref (match_operand 0 "" ""))
2362 (pc)))]
2363 ""
2364 "*
2365 {
2366 if (cc_prev_status.flags & CC_UNORD)
2367 return \"bhi 0f\;ble %l0\;0:\";
2368 else
2369 return \"ble %l0\";
2370 }")
2371
2372 (define_insn "bleu"
2373 [(set (pc)
2374 (if_then_else (leu (cc0)
2375 (const_int 0))
2376 (label_ref (match_operand 0 "" ""))
2377 (pc)))]
2378 ""
2379 "bls %l0")
2380 \f
2381 ;; "Reversed" jump instructions. Are these ever generated?
2382
2383 (define_insn "*bne"
2384 [(set (pc)
2385 (if_then_else (eq (cc0)
2386 (const_int 0))
2387 (pc)
2388 (label_ref (match_operand 0 "" ""))))]
2389 ""
2390 "*
2391 { if (cc_prev_status.flags & CC_Z_IN_F)
2392 return \"bfs %l0\";
2393 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2394 return \"bfc %l0\";
2395 else return \"bne %l0\";
2396 }")
2397
2398 (define_insn "*beq"
2399 [(set (pc)
2400 (if_then_else (ne (cc0)
2401 (const_int 0))
2402 (pc)
2403 (label_ref (match_operand 0 "" ""))))]
2404 ""
2405 "*
2406 { if (cc_prev_status.flags & CC_Z_IN_F)
2407 return \"bfc %l0\";
2408 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2409 return \"bfs %l0\";
2410 else return \"beq %l0\";
2411 }")
2412
2413 (define_insn "*ble"
2414 [(set (pc)
2415 (if_then_else (gt (cc0)
2416 (const_int 0))
2417 (pc)
2418 (label_ref (match_operand 0 "" ""))))]
2419 ""
2420 "*
2421 {
2422 if (cc_prev_status.flags & CC_UNORD)
2423 return \"bhi 0f\;ble %l0\;0:\";
2424 else
2425 return \"ble %l0\";
2426 }")
2427
2428 (define_insn "*bleu"
2429 [(set (pc)
2430 (if_then_else (gtu (cc0)
2431 (const_int 0))
2432 (pc)
2433 (label_ref (match_operand 0 "" ""))))]
2434 ""
2435 "bls %l0")
2436
2437 (define_insn "*bge"
2438 [(set (pc)
2439 (if_then_else (lt (cc0)
2440 (const_int 0))
2441 (pc)
2442 (label_ref (match_operand 0 "" ""))))]
2443 ""
2444 "bge %l0")
2445
2446 (define_insn "*bgeu"
2447 [(set (pc)
2448 (if_then_else (ltu (cc0)
2449 (const_int 0))
2450 (pc)
2451 (label_ref (match_operand 0 "" ""))))]
2452 ""
2453 "bhs %l0")
2454
2455 (define_insn "*blt"
2456 [(set (pc)
2457 (if_then_else (ge (cc0)
2458 (const_int 0))
2459 (pc)
2460 (label_ref (match_operand 0 "" ""))))]
2461 ""
2462 "*
2463 {
2464 if (cc_prev_status.flags & CC_UNORD)
2465 return \"bhi 0f\;blt %l0\;0:\";
2466 else
2467 return \"blt %l0\";
2468 }")
2469
2470 (define_insn "*bltu"
2471 [(set (pc)
2472 (if_then_else (geu (cc0)
2473 (const_int 0))
2474 (pc)
2475 (label_ref (match_operand 0 "" ""))))]
2476 ""
2477 "blo %l0")
2478
2479 (define_insn "*bgt"
2480 [(set (pc)
2481 (if_then_else (le (cc0)
2482 (const_int 0))
2483 (pc)
2484 (label_ref (match_operand 0 "" ""))))]
2485 ""
2486 "bgt %l0")
2487
2488 (define_insn "*bgtu"
2489 [(set (pc)
2490 (if_then_else (leu (cc0)
2491 (const_int 0))
2492 (pc)
2493 (label_ref (match_operand 0 "" ""))))]
2494 ""
2495 "bhi %l0")
2496 \f
2497 ;; Subtract-and-jump and Add-and-jump insns.
2498 ;; These can actually be used for adding numbers in the range -8 to 7
2499
2500 (define_insn "*sub_br"
2501 [(set (pc)
2502 (if_then_else
2503 (ne (match_operand:SI 0 "nonimmediate_operand" "+rm")
2504 (match_operand:SI 1 "const_int_operand" "i"))
2505 (label_ref (match_operand 2 "" ""))
2506 (pc)))
2507 (set (match_dup 0)
2508 (minus:SI (match_dup 0)
2509 (match_dup 1)))]
2510 "INTVAL (operands[1]) > -8 && INTVAL (operands[1]) <= 8"
2511 "acbd %n1,%0,%l2")
2512
2513 (define_insn "*add_br"
2514 [(set (pc)
2515 (if_then_else
2516 (ne (match_operand:SI 0 "nonimmediate_operand" "+rm")
2517 (match_operand:SI 1 "const_int_operand" "i"))
2518 (label_ref (match_operand 2 "" ""))
2519 (pc)))
2520 (set (match_dup 0)
2521 (plus:SI (match_dup 0)
2522 (match_operand:SI 3 "const_int_operand" "i")))]
2523 "INTVAL (operands[1]) == - INTVAL (operands[3])
2524 && INTVAL (operands[3]) >= -8 && INTVAL (operands[3]) < 8"
2525 "acbd %3,%0,%l2")
2526 \f
2527 (define_insn "call"
2528 [(call (match_operand:QI 0 "memory_operand" "m")
2529 (match_operand 1 "" ""))]
2530 ;; Operand 1 is not used
2531 ""
2532 "*
2533 {
2534 #ifndef JSR_ALWAYS
2535 if (GET_CODE (operands[0]) == MEM)
2536 {
2537 rtx temp = XEXP (operands[0], 0);
2538 if (CONSTANT_ADDRESS_P (temp))
2539 {
2540 #ifdef ENCORE_ASM
2541 return \"bsr %?%0\";
2542 #else
2543 #ifdef CALL_MEMREF_IMPLICIT
2544 operands[0] = temp;
2545 return \"bsr %0\";
2546 #else
2547 #ifdef GNX_V3
2548 return \"bsr %0\";
2549 #else
2550 return \"bsr %?%a0\";
2551 #endif
2552 #endif
2553 #endif
2554 }
2555 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2556 #if defined (GNX_V3) || defined (CALL_MEMREF_IMPLICIT)
2557 return \"jsr %0\";
2558 #else
2559 return \"jsr %a0\";
2560 #endif
2561 }
2562 #endif /* not JSR_ALWAYS */
2563 return \"jsr %0\";
2564 }")
2565
2566 (define_insn "call_value"
2567 [(set (match_operand 0 "" "=rf")
2568 (call (match_operand:QI 1 "memory_operand" "m")
2569 (match_operand 2 "" "")))]
2570 ;; Operand 2 is not used
2571 ""
2572 "*
2573 {
2574 #ifndef JSR_ALWAYS
2575 if (GET_CODE (operands[1]) == MEM)
2576 {
2577 rtx temp = XEXP (operands[1], 0);
2578 if (CONSTANT_ADDRESS_P (temp))
2579 {
2580 #ifdef ENCORE_ASM
2581 return \"bsr %?%1\";
2582 #else
2583 #ifdef CALL_MEMREF_IMPLICIT
2584 operands[1] = temp;
2585 return \"bsr %1\";
2586 #else
2587 #ifdef GNX_V3
2588 return \"bsr %1\";
2589 #else
2590 return \"bsr %?%a1\";
2591 #endif
2592 #endif
2593 #endif
2594 }
2595 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2596 #if defined (GNX_V3) || defined (CALL_MEMREF_IMPLICIT)
2597 return \"jsr %1\";
2598 #else
2599 return \"jsr %a1\";
2600 #endif
2601 }
2602 #endif /* not JSR_ALWAYS */
2603 return \"jsr %1\";
2604 }")
2605
2606 ;; Call subroutine returning any type.
2607
2608 (define_expand "untyped_call"
2609 [(parallel [(call (match_operand 0 "" "")
2610 (const_int 0))
2611 (match_operand 1 "" "")
2612 (match_operand 2 "" "")])]
2613 ""
2614 "
2615 {
2616 int i;
2617
2618 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
2619
2620 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2621 {
2622 rtx set = XVECEXP (operands[2], 0, i);
2623 emit_move_insn (SET_DEST (set), SET_SRC (set));
2624 }
2625
2626 /* The optimizer does not know that the call sets the function value
2627 registers we stored in the result block. We avoid problems by
2628 claiming that all hard registers are used and clobbered at this
2629 point. */
2630 emit_insn (gen_blockage ());
2631
2632 DONE;
2633 }")
2634
2635 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2636 ;; all of memory. This blocks insns from being moved across this point.
2637
2638 (define_insn "blockage"
2639 [(unspec_volatile [(const_int 0)] 0)]
2640 ""
2641 "")
2642
2643 (define_insn "return"
2644 [(return)]
2645 "0"
2646 "ret 0")
2647
2648 (define_insn "abssf2"
2649 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm<")
2650 (abs:SF (match_operand:SF 1 "general_operand" "fmF")))]
2651 "TARGET_32081"
2652 "absf %1,%0")
2653
2654 (define_insn "absdf2"
2655 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm<")
2656 (abs:DF (match_operand:DF 1 "general_operand" "lmF")))]
2657 "TARGET_32081"
2658 "absl %1,%0")
2659
2660 ;; See note 1
2661 (define_insn "abssi2"
2662 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2663 (abs:SI (match_operand:SI 1 "general_operand" "g")))]
2664 ""
2665 "absd %1,%0")
2666
2667 (define_insn "abshi2"
2668 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
2669 (abs:HI (match_operand:HI 1 "general_operand" "g")))]
2670 ""
2671 "absw %1,%0")
2672
2673 (define_insn "absqi2"
2674 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
2675 (abs:QI (match_operand:QI 1 "general_operand" "g")))]
2676 ""
2677 "absb %1,%0")
2678
2679 (define_insn "nop"
2680 [(const_int 0)]
2681 ""
2682 "nop")
2683
2684 (define_insn "indirect_jump"
2685 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2686 ""
2687 "jump %0")
2688 \f
2689 (define_insn "tablejump"
2690 [(set (pc)
2691 (plus:SI (pc) (match_operand:SI 0 "general_operand" "g")))
2692 (use (label_ref (match_operand 1 "" "")))]
2693 ""
2694 "*
2695 {
2696 (*targetm.asm_out.internal_label) (asm_out_file, \"LI\",
2697 CODE_LABEL_NUMBER (operands[1]));
2698 return \"cased %0\";
2699 }")
2700
2701 ;; Scondi instructions
2702 (define_insn "seq"
2703 [(set (match_operand:SI 0 "nonimmediate_operand" "=r<")
2704 (eq:SI (cc0) (const_int 0)))]
2705 ""
2706 "*
2707 { if (cc_prev_status.flags & CC_Z_IN_F)
2708 return \"sfcd %0\";
2709 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2710 return \"sfsd %0\";
2711 else return \"seqd %0\";
2712 }")
2713
2714 (define_insn "*seqhi"
2715 [(set (match_operand:HI 0 "nonimmediate_operand" "=r<")
2716 (eq:HI (cc0) (const_int 0)))]
2717 ""
2718 "*
2719 { if (cc_prev_status.flags & CC_Z_IN_F)
2720 return \"sfcw %0\";
2721 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2722 return \"sfsw %0\";
2723 else return \"seqw %0\";
2724 }")
2725
2726 (define_insn "*seqqi"
2727 [(set (match_operand:QI 0 "nonimmediate_operand" "=r<")
2728 (eq:QI (cc0) (const_int 0)))]
2729 ""
2730 "*
2731 { if (cc_prev_status.flags & CC_Z_IN_F)
2732 return \"sfcb %0\";
2733 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2734 return \"sfsb %0\";
2735 else return \"seqb %0\";
2736 }")
2737
2738 (define_insn "sne"
2739 [(set (match_operand:SI 0 "nonimmediate_operand" "=r<")
2740 (ne:SI (cc0) (const_int 0)))]
2741 ""
2742 "*
2743 { if (cc_prev_status.flags & CC_Z_IN_F)
2744 return \"sfsd %0\";
2745 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2746 return \"sfcd %0\";
2747 else return \"sned %0\";
2748 }")
2749
2750 (define_insn "*snehi"
2751 [(set (match_operand:HI 0 "nonimmediate_operand" "=r<")
2752 (ne:HI (cc0) (const_int 0)))]
2753 ""
2754 "*
2755 { if (cc_prev_status.flags & CC_Z_IN_F)
2756 return \"sfsw %0\";
2757 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2758 return \"sfcw %0\";
2759 else return \"snew %0\";
2760 }")
2761
2762 (define_insn "*sneqi"
2763 [(set (match_operand:QI 0 "nonimmediate_operand" "=r<")
2764 (ne:QI (cc0) (const_int 0)))]
2765 ""
2766 "*
2767 { if (cc_prev_status.flags & CC_Z_IN_F)
2768 return \"sfsb %0\";
2769 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2770 return \"sfcb %0\";
2771 else return \"sneb %0\";
2772 }")
2773
2774 (define_insn "sgt"
2775 [(set (match_operand:SI 0 "nonimmediate_operand" "=r<")
2776 (gt:SI (cc0) (const_int 0)))]
2777 ""
2778 "sgtd %0")
2779
2780 (define_insn "*sgthi"
2781 [(set (match_operand:HI 0 "nonimmediate_operand" "=r<")
2782 (gt:HI (cc0) (const_int 0)))]
2783 ""
2784 "sgtw %0")
2785
2786 (define_insn "*sgtqi"
2787 [(set (match_operand:QI 0 "nonimmediate_operand" "=r<")
2788 (gt:QI (cc0) (const_int 0)))]
2789 ""
2790 "sgtb %0")
2791
2792 (define_insn "sgtu"
2793 [(set (match_operand:SI 0 "nonimmediate_operand" "=r<")
2794 (gtu:SI (cc0) (const_int 0)))]
2795 ""
2796 "shid %0")
2797
2798 (define_insn "*sgtuhi"
2799 [(set (match_operand:HI 0 "nonimmediate_operand" "=r<")
2800 (gtu:HI (cc0) (const_int 0)))]
2801 ""
2802 "shiw %0")
2803
2804 (define_insn "*sgtuqi"
2805 [(set (match_operand:QI 0 "nonimmediate_operand" "=r<")
2806 (gtu:QI (cc0) (const_int 0)))]
2807 ""
2808 "shib %0")
2809
2810 (define_insn "slt"
2811 [(set (match_operand:SI 0 "nonimmediate_operand" "=r<")
2812 (lt:SI (cc0) (const_int 0)))]
2813 ""
2814 "sltd %0")
2815
2816 (define_insn "*slthi"
2817 [(set (match_operand:HI 0 "nonimmediate_operand" "=r<")
2818 (lt:HI (cc0) (const_int 0)))]
2819 ""
2820 "sltw %0")
2821
2822 (define_insn "*sltqi"
2823 [(set (match_operand:QI 0 "nonimmediate_operand" "=r<")
2824 (lt:QI (cc0) (const_int 0)))]
2825 ""
2826 "sltb %0")
2827
2828 (define_insn "sltu"
2829 [(set (match_operand:SI 0 "nonimmediate_operand" "=r<")
2830 (ltu:SI (cc0) (const_int 0)))]
2831 ""
2832 "slod %0")
2833
2834 (define_insn "*sltuhi"
2835 [(set (match_operand:HI 0 "nonimmediate_operand" "=r<")
2836 (ltu:HI (cc0) (const_int 0)))]
2837 ""
2838 "slow %0")
2839
2840 (define_insn "*sltuqi"
2841 [(set (match_operand:QI 0 "nonimmediate_operand" "=r<")
2842 (ltu:QI (cc0) (const_int 0)))]
2843 ""
2844 "slob %0")
2845
2846 (define_insn "sge"
2847 [(set (match_operand:SI 0 "nonimmediate_operand" "=r<")
2848 (ge:SI (cc0) (const_int 0)))]
2849 ""
2850 "sged %0")
2851
2852 (define_insn "*sgehi"
2853 [(set (match_operand:HI 0 "nonimmediate_operand" "=r<")
2854 (ge:HI (cc0) (const_int 0)))]
2855 ""
2856 "sgew %0")
2857
2858 (define_insn "*sgeqi"
2859 [(set (match_operand:QI 0 "nonimmediate_operand" "=r<")
2860 (ge:QI (cc0) (const_int 0)))]
2861 ""
2862 "sgeb %0")
2863
2864 (define_insn "sgeu"
2865 [(set (match_operand:SI 0 "nonimmediate_operand" "=r<")
2866 (geu:SI (cc0) (const_int 0)))]
2867 ""
2868 "shsd %0")
2869
2870 (define_insn "*sgeuhi"
2871 [(set (match_operand:HI 0 "nonimmediate_operand" "=r<")
2872 (geu:HI (cc0) (const_int 0)))]
2873 ""
2874 "shsw %0")
2875
2876 (define_insn "*sgeuqi"
2877 [(set (match_operand:QI 0 "nonimmediate_operand" "=r<")
2878 (geu:QI (cc0) (const_int 0)))]
2879 ""
2880 "shsb %0")
2881
2882 (define_insn "sle"
2883 [(set (match_operand:SI 0 "nonimmediate_operand" "=r<")
2884 (le:SI (cc0) (const_int 0)))]
2885 ""
2886 "sled %0")
2887
2888 (define_insn "*slehi"
2889 [(set (match_operand:HI 0 "nonimmediate_operand" "=r<")
2890 (le:HI (cc0) (const_int 0)))]
2891 ""
2892 "slew %0")
2893
2894 (define_insn "*sleqi"
2895 [(set (match_operand:QI 0 "nonimmediate_operand" "=r<")
2896 (le:QI (cc0) (const_int 0)))]
2897 ""
2898 "sleb %0")
2899
2900 (define_insn "sleu"
2901 [(set (match_operand:SI 0 "nonimmediate_operand" "=r<")
2902 (leu:SI (cc0) (const_int 0)))]
2903 ""
2904 "slsd %0")
2905
2906 (define_insn "*sleuhi"
2907 [(set (match_operand:HI 0 "nonimmediate_operand" "=r<")
2908 (leu:HI (cc0) (const_int 0)))]
2909 ""
2910 "slsw %0")
2911
2912 (define_insn "*sleuqi"
2913 [(set (match_operand:QI 0 "nonimmediate_operand" "=r<")
2914 (leu:QI (cc0) (const_int 0)))]
2915 ""
2916 "slsb %0")
2917 \f
2918 ;; ffs instructions
2919
2920 (define_insn "*ffs"
2921 [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
2922 (minus:SI
2923 (plus:SI (ffs:SI (zero_extract:SI
2924 (match_operand:SI 1 "general_operand" "g")
2925 (minus:SI (const_int 32) (match_dup 0))
2926 (match_dup 0)))
2927 (match_dup 0))
2928 (const_int 1)))]
2929 ""
2930 "ffsd %1,%0; bfc 1f; addqd %$-1,%0; 1:")
2931
2932 (define_expand "ffssi2"
2933 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") (const_int 0))
2934 (set (match_dup 0)
2935 (minus:SI
2936 (plus:SI (ffs:SI (zero_extract:SI
2937 (match_operand:SI 1 "general_operand" "g")
2938 (minus:SI (const_int 32) (match_dup 0))
2939 (match_dup 0)))
2940 (match_dup 0))
2941 (const_int 1)))
2942 (set (match_dup 0)
2943 (plus:SI (match_dup 0)
2944 (const_int 1)))]
2945 ""
2946 "operands[1] = make_safe_from(operands[1], operands[0]);")
2947 \f
2948 ;; Speed up stack adjust followed by a HI fixedpoint push.
2949
2950 (define_peephole
2951 [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int -2)))
2952 (set (match_operand:HI 0 "push_operand" "=m")
2953 (match_operand:HI 1 "general_operand" "g"))]
2954 "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
2955 "*
2956 {
2957 if (GET_CODE (operands[1]) == CONST_INT)
2958 output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,tos\"),
2959 operands);
2960 else
2961 output_asm_insn (\"movzwd %1,tos\", operands);
2962 return \"\";
2963 }")
2964
2965 ;; Speed up stack adjust followed by a zero_extend:HI(QI) fixedpoint push.
2966
2967 (define_peephole
2968 [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int -2)))
2969 (set (match_operand:HI 0 "push_operand" "=m")
2970 (zero_extend:HI (match_operand:QI 1 "general_operand" "g")))]
2971 "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
2972 "*
2973 {
2974 if (GET_CODE (operands[1]) == CONST_INT)
2975 output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,tos\"),
2976 operands);
2977 else
2978 output_asm_insn (\"movzbd %1,tos\", operands);
2979 return \"\";
2980 }")
2981
2982 ;; Speed up stack adjust followed by a sign_extend:HI(QI) fixedpoint push.
2983
2984 (define_peephole
2985 [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int -2)))
2986 (set (match_operand:HI 0 "push_operand" "=m")
2987 (sign_extend:HI (match_operand:QI 1 "general_operand" "g")))]
2988 "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
2989 "*
2990 {
2991 if (GET_CODE (operands[1]) == CONST_INT)
2992 output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,tos\"),
2993 operands);
2994 else
2995 output_asm_insn (\"movxbd %1,tos\", operands);
2996 return \"\";
2997 }")
2998
2999 ;; Speed up stack adjust followed by a QI fixedpoint push.
3000
3001 (define_peephole
3002 [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int -3)))
3003 (set (match_operand:QI 0 "push_operand" "=m")
3004 (match_operand:QI 1 "general_operand" "g"))]
3005 "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
3006 "*
3007 {
3008 if (GET_CODE (operands[1]) == CONST_INT)
3009 output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,tos\"),
3010 operands);
3011 else
3012 output_asm_insn (\"movzbd %1,tos\", operands);
3013 return \"\";
3014 }")
3015
3016 ;; Speed up stack adjust followed by a SI fixedpoint push.
3017
3018 (define_peephole
3019 [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int 4)))
3020 (set (match_operand:SI 0 "push_operand" "=m")
3021 (match_operand:SI 1 "general_operand" "g"))]
3022 "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
3023 "*
3024 {
3025 if (GET_CODE (operands[1]) == CONST_INT)
3026 output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,0(sp)\"),
3027 operands);
3028 else if (GET_CODE (operands[1]) != REG
3029 && GET_CODE (operands[1]) != MEM
3030 && address_operand (operands[1], SImode))
3031 output_asm_insn (\"addr %a1,0(sp)\", operands);
3032 else
3033 output_asm_insn (\"movd %1,0(sp)\", operands);
3034 return \"\";
3035 }")
3036
3037 ;; Speed up stack adjust followed by two fullword fixedpoint pushes.
3038
3039 (define_peephole
3040 [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int 8)))
3041 (set (match_operand:SI 0 "push_operand" "=m")
3042 (match_operand:SI 1 "general_operand" "g"))
3043 (set (match_operand:SI 2 "push_operand" "=m")
3044 (match_operand:SI 3 "general_operand" "g"))]
3045 "! reg_mentioned_p (stack_pointer_rtx, operands[1])
3046 && ! reg_mentioned_p (stack_pointer_rtx, operands[3])"
3047 "*
3048 {
3049 if (GET_CODE (operands[1]) == CONST_INT)
3050 output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,4(sp)\"),
3051 operands);
3052 else if (GET_CODE (operands[1]) != REG
3053 && GET_CODE (operands[1]) != MEM
3054 && address_operand (operands[1], SImode))
3055 output_asm_insn (\"addr %a1,4(sp)\", operands);
3056 else
3057 output_asm_insn (\"movd %1,4(sp)\", operands);
3058
3059 if (GET_CODE (operands[3]) == CONST_INT)
3060 output_asm_insn (output_move_dconst (INTVAL (operands[3]), \"%3,0(sp)\"),
3061 operands);
3062 else if (GET_CODE (operands[3]) != REG
3063 && GET_CODE (operands[3]) != MEM
3064 && address_operand (operands[3], SImode))
3065 output_asm_insn (\"addr %a3,0(sp)\", operands);
3066 else
3067 output_asm_insn (\"movd %3,0(sp)\", operands);
3068 return \"\";
3069 }")