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)
6 ;; This file is part of GNU CC.
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)
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.
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.
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??
32 ;;- Instruction patterns. When multiple patterns apply,
33 ;;- the first one in the file is chosen.
35 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
37 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
38 ;;- updates for most instructions.
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.
44 ;; In order for pic mode to work we cannot generate, for example
48 ;; instead we must force gcc to generate something like
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.
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.
66 (match_operand:SI 0 "nonimmediate_operand" "rm"))]
69 { cc_status.flags |= CC_REVERSED;
70 operands[1] = const0_rtx;
71 return \"cmpqd %1,%0\"; }")
75 (match_operand:HI 0 "nonimmediate_operand" "rm"))]
78 { cc_status.flags |= CC_REVERSED;
79 operands[1] = const0_rtx;
80 return \"cmpqw %1,%0\"; }")
84 (match_operand:QI 0 "nonimmediate_operand" "rm"))]
87 { cc_status.flags |= CC_REVERSED;
88 operands[1] = const0_rtx;
89 return \"cmpqb %1,%0\"; }")
93 (match_operand:DF 0 "general_operand" "lmF"))]
96 { cc_status.flags |= CC_REVERSED;
97 operands[1] = CONST0_RTX (DFmode);
98 return \"cmpl %1,%0\"; }")
102 (match_operand:SF 0 "general_operand" "fmF"))]
105 { cc_status.flags |= CC_REVERSED;
106 operands[1] = CONST0_RTX (SFmode);
107 return \"cmpf %1,%0\"; }")
112 (compare (match_operand:SI 0 "general_operand" "g")
113 (match_operand:SI 1 "general_operand" "g")))]
117 if (GET_CODE (operands[1]) == CONST_INT)
119 int i = INTVAL (operands[1]);
120 if (i <= 7 && i >= -8)
122 cc_status.flags |= CC_REVERSED;
123 return \"cmpqd %1,%0\";
126 cc_status.flags &= ~CC_REVERSED;
127 if (GET_CODE (operands[0]) == CONST_INT)
129 int i = INTVAL (operands[0]);
130 if (i <= 7 && i >= -8)
131 return \"cmpqd %0,%1\";
133 return \"cmpd %0,%1\";
138 (compare (match_operand:HI 0 "general_operand" "g")
139 (match_operand:HI 1 "general_operand" "g")))]
143 if (GET_CODE (operands[1]) == CONST_INT)
145 short i = INTVAL (operands[1]);
146 if (i <= 7 && i >= -8)
148 cc_status.flags |= CC_REVERSED;
149 if (INTVAL (operands[1]) > 7)
150 operands[1] = GEN_INT (i);
151 return \"cmpqw %1,%0\";
154 cc_status.flags &= ~CC_REVERSED;
155 if (GET_CODE (operands[0]) == CONST_INT)
157 short i = INTVAL (operands[0]);
158 if (i <= 7 && i >= -8)
160 if (INTVAL (operands[0]) > 7)
161 operands[0] = GEN_INT (i);
162 return \"cmpqw %0,%1\";
165 return \"cmpw %0,%1\";
170 (compare (match_operand:QI 0 "general_operand" "g")
171 (match_operand:QI 1 "general_operand" "g")))]
175 if (GET_CODE (operands[1]) == CONST_INT)
177 char i = INTVAL (operands[1]);
178 if (i <= 7 && i >= -8)
180 cc_status.flags |= CC_REVERSED;
181 if (INTVAL (operands[1]) > 7)
182 operands[1] = GEN_INT (i);
183 return \"cmpqb %1,%0\";
186 cc_status.flags &= ~CC_REVERSED;
187 if (GET_CODE (operands[0]) == CONST_INT)
189 char i = INTVAL (operands[0]);
190 if (i <= 7 && i >= -8)
192 if (INTVAL (operands[0]) > 7)
193 operands[0] = GEN_INT (i);
194 return \"cmpqb %0,%1\";
197 return \"cmpb %0,%1\";
202 (compare (match_operand:DF 0 "general_operand" "lmF")
203 (match_operand:DF 1 "general_operand" "lmF")))]
209 (compare (match_operand:SF 0 "general_operand" "fmF")
210 (match_operand:SF 1 "general_operand" "fmF")))]
214 ;; movdf and movsf copy between general and floating registers using
215 ;; the stack. In principle, we could get better code not allowing
216 ;; that case in the constraints and defining SECONDARY_MEMORY_NEEDED
217 ;; in practice, though the stack slots used are not available for
220 [(set (match_operand:DF 0 "nonimmediate_operand" "=lrm<")
221 (match_operand:DF 1 "general_operand" "lFg"))]
225 if (FP_REG_P (operands[0]))
227 if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
228 return \"movl %1,%0\";
229 if (REG_P (operands[1]))
232 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
233 output_asm_insn (\"movd %1,tos\", xoperands);
234 output_asm_insn (\"movd %1,tos\", operands);
235 return \"movl tos,%0\";
237 return \"movl %1,%0\";
239 else if (FP_REG_P (operands[1]))
241 if (REG_P (operands[0]))
243 output_asm_insn (\"movl %1,tos\;movd tos,%0\", operands);
244 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
245 return \"movd tos,%0\";
248 return \"movl %1,%0\";
250 return output_move_double (operands);
254 [(set (match_operand:SF 0 "nonimmediate_operand" "=frm<")
255 (match_operand:SF 1 "general_operand" "fFg"))]
259 if (FP_REG_P (operands[0]))
261 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM)
262 return \"movd %1,tos\;movf tos,%0\";
264 return \"movf %1,%0\";
266 else if (FP_REG_P (operands[1]))
268 if (REG_P (operands[0]))
269 return \"movf %1,tos\;movd tos,%0\";
270 return \"movf %1,%0\";
272 #if 0 /* Someone suggested this for the Sequent. Is it needed? */
273 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
274 return \"movf %1,%0\";
276 /* There was a #if 0 around this, but that was erroneous
277 for many machines -- rms. */
278 #ifndef MOVD_FLOAT_OK
279 /* GAS understands floating constants in ordinary movd instructions
280 but other assemblers might object. */
281 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
283 union {int i[2]; float f; double d;} convrt;
284 convrt.i[0] = CONST_DOUBLE_LOW (operands[1]);
285 convrt.i[1] = CONST_DOUBLE_HIGH (operands[1]);
288 /* Is there a better machine-independent way to to this? */
289 operands[1] = GEN_INT (convrt.i[0]);
290 return \"movd %1,%0\";
293 else return \"movd %1,%0\";
297 [(set (match_operand:TI 0 "memory_operand" "=m")
298 (match_operand:TI 1 "memory_operand" "m"))]
303 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm<,*f,rm")
304 (match_operand:DI 1 "general_operand" "gF,g,*f"))]
308 if (FP_REG_P (operands[0]))
310 if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
311 return \"movl %1,%0\";
312 if (REG_P (operands[1]))
315 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
316 output_asm_insn (\"movd %1,tos\", xoperands);
317 output_asm_insn (\"movd %1,tos\", operands);
318 return \"movl tos,%0\";
320 return \"movl %1,%0\";
322 else if (FP_REG_P (operands[1]))
324 if (REG_P (operands[0]))
326 output_asm_insn (\"movl %1,tos\;movd tos,%0\", operands);
327 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
328 return \"movd tos,%0\";
331 return \"movl %1,%0\";
333 return output_move_double (operands);
336 ;; This special case must precede movsi.
339 (match_operand:SI 0 "general_operand" "g"))]
344 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<,rm<,*f,rm,x")
345 (match_operand:SI 1 "general_operand" "g,?xy,g,*f,rmn"))]
351 if (FP_REG_P (operands[0]))
353 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM)
354 return \"movd %1,tos\;movf tos,%0\";
356 return \"movf %1,%0\";
358 else if (FP_REG_P (operands[1]))
360 if (REG_P (operands[0]))
361 return \"movf %1,tos\;movd tos,%0\";
362 return \"movf %1,%0\";
364 if (GET_CODE (operands[0]) == REG
365 && REGNO (operands[0]) == FRAME_POINTER_REGNUM)
366 return \"lprd fp,%1\";
367 if (GET_CODE (operands[1]) == CONST_DOUBLE)
368 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
369 if (GET_CODE (operands[1]) == CONST_INT)
371 int i = INTVAL (operands[1]);
374 if (i <= 7 && i >= -8)
375 return \"movqd %1,%0\";
376 if (NS32K_DISPLACEMENT_P (i))
377 #if defined (GNX_V3) || defined (UTEK_ASM)
378 return \"addr %c1,%0\";
380 return \"addr @%c1,%0\";
382 return \"movd %1,%0\";
385 return output_move_dconst(i, \"%1,%0\");
387 else if (GET_CODE (operands[1]) == CONST && ! flag_pic)
389 /* Must contain symbols so we don't know how big it is. In
390 * that case addr might lead to overflow. For PIC symbolic
391 * address loads always have to be done with addr.
393 return \"movd %1,%0\";
395 else if (GET_CODE (operands[1]) == REG)
397 if (REGNO (operands[1]) < F0_REGNUM)
398 return \"movd %1,%0\";
399 else if (REGNO (operands[1]) == FRAME_POINTER_REGNUM)
401 if (GET_CODE(operands[0]) == REG)
402 return \"sprd fp,%0\";
404 return \"addr 0(fp),%0\" ;
406 else if (REGNO (operands[1]) == STACK_POINTER_REGNUM)
408 if (GET_CODE(operands[0]) == REG)
409 return \"sprd sp,%0\";
411 return \"addr 0(sp),%0\" ;
415 else if (GET_CODE (operands[1]) == MEM)
416 return \"movd %1,%0\";
418 /* Check if this effective address can be
419 calculated faster by pulling it apart. */
420 if (REG_P (operands[0])
421 && GET_CODE (operands[1]) == MULT
422 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
423 && (INTVAL (XEXP (operands[1], 1)) == 2
424 || INTVAL (XEXP (operands[1], 1)) == 4))
427 xoperands[0] = operands[0];
428 xoperands[1] = XEXP (operands[1], 0);
429 xoperands[2] = GEN_INT (INTVAL (XEXP (operands[1], 1)) >> 1);
430 return output_shift_insn (xoperands);
432 return \"addr %a1,%0\";
436 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<,*f,rm")
437 (match_operand:HI 1 "general_operand" "g,g,*f"))]
441 if (GET_CODE (operands[1]) == CONST_INT)
443 short i = INTVAL (operands[1]);
444 if (i <= 7 && i >= -8)
446 if (INTVAL (operands[1]) > 7)
447 operands[1] = GEN_INT (i);
448 return \"movqw %1,%0\";
450 return \"movw %1,%0\";
452 else if (FP_REG_P (operands[0]))
454 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM)
455 return \"movwf %1,tos\;movf tos,%0\";
457 return \"movwf %1,%0\";
459 else if (FP_REG_P (operands[1]))
461 if (REG_P (operands[0]))
462 return \"movf %1,tos\;movd tos,%0\";
463 return \"movf %1,%0\";
466 return \"movw %1,%0\";
469 (define_insn "movstricthi"
470 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
471 (match_operand:HI 1 "general_operand" "g"))]
475 if (GET_CODE (operands[1]) == CONST_INT
476 && INTVAL(operands[1]) <= 7 && INTVAL(operands[1]) >= -8)
477 return \"movqw %1,%0\";
478 return \"movw %1,%0\";
482 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<,*f,rm")
483 (match_operand:QI 1 "general_operand" "g,g,*f"))]
486 { if (GET_CODE (operands[1]) == CONST_INT)
488 char char_val = (char)INTVAL (operands[1]);
489 if (char_val <= 7 && char_val >= -8)
491 if (INTVAL (operands[1]) > 7)
492 operands[1] = GEN_INT (char_val);
493 return \"movqb %1,%0\";
495 return \"movb %1,%0\";
497 else if (FP_REG_P (operands[0]))
499 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM)
500 return \"movbf %1,tos\;movf tos,%0\";
502 return \"movbf %1,%0\";
504 else if (FP_REG_P (operands[1]))
506 if (REG_P (operands[0]))
507 return \"movf %1,tos\;movd tos,%0\";
508 return \"movf %1,%0\";
511 return \"movb %1,%0\";
514 (define_insn "movstrictqi"
515 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
516 (match_operand:QI 1 "general_operand" "g"))]
520 if (GET_CODE (operands[1]) == CONST_INT
521 && INTVAL(operands[1]) < 8 && INTVAL(operands[1]) > -9)
522 return \"movqb %1,%0\";
523 return \"movb %1,%0\";
527 ;; Argument 0 is the destination
528 ;; Argument 1 is the source
529 ;; Argument 2 is the length
530 ;; Argument 3 is the alignment
532 ;; Strategy: Use define_expand to
533 ;; either emit insns directly if it can be done simply or
534 ;; emit rtl to match movstrsi1 which has extra scratch registers
535 ;; which can be used to generate more complex code.
537 (define_expand "movstrsi"
538 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
539 (match_operand:BLK 1 "memory_operand" ""))
540 (use (match_operand:SI 2 "general_operand" ""))
541 (use (match_operand:SI 3 "const_int_operand" ""))])]
545 if (operands[0]) /* avoid unused code messages */
547 expand_block_move (operands);
552 ;; Special Registers:
559 (define_insn "movstrsi1"
560 [(set (mem:BLK (reg:SI 2))
561 (mem:BLK (reg:SI 1)))
563 (set (reg:SI 2) (plus:SI (reg:SI 2) (mult:SI (reg:SI 0) (match_operand:SI 0 "const_int_operand" ""))))
564 (set (reg:SI 1) (plus:SI (reg:SI 1) (mult:SI (reg:SI 0) (match_dup 0))))
565 (set (reg:SI 0) (const_int 0))]
569 int align = INTVAL(operands[0]);
576 (define_insn "movstrsi2"
577 [(set (mem:BLK (match_operand:SI 0 "address_operand" "p"))
578 (mem:BLK (match_operand:SI 1 "address_operand" "p")))
579 (use (match_operand 2 "immediate_operand" "i"))]
584 ;; Extension and truncation insns.
585 ;; Those for integer source operand
586 ;; are ordered widest source type first.
588 (define_insn "extendhisi2"
589 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
590 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
594 (define_insn "extendqihi2"
595 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
596 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
600 (define_insn "extendqisi2"
601 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
602 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
606 (define_insn "extendsfdf2"
607 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm<")
608 (float_extend:DF (match_operand:SF 1 "general_operand" "fmF")))]
612 (define_insn "truncdfsf2"
613 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm<")
614 (float_truncate:SF (match_operand:DF 1 "general_operand" "lmF")))]
618 (define_insn "zero_extendhisi2"
619 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
620 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
624 (define_insn "zero_extendqihi2"
625 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
626 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
630 (define_insn "zero_extendqisi2"
631 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
632 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
636 ;; Fix-to-float conversion insns.
637 ;; Note that the ones that start with SImode come first.
638 ;; That is so that an operand that is a CONST_INT
639 ;; (and therefore lacks a specific machine mode).
640 ;; will be recognized as SImode (which is always valid)
641 ;; rather than as QImode or HImode.
643 ;; Rumor has it that the National part does not correctly convert
644 ;; constant ints to floats. This conversion is therefore disabled.
645 ;; A register must be used to perform the conversion.
647 (define_insn "floatsisf2"
648 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm<")
649 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
653 (define_insn "floatsidf2"
654 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm<")
655 (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
659 (define_insn "floathisf2"
660 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm<")
661 (float:SF (match_operand:HI 1 "nonimmediate_operand" "rm")))]
665 (define_insn "floathidf2"
666 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm<")
667 (float:DF (match_operand:HI 1 "nonimmediate_operand" "rm")))]
671 (define_insn "floatqisf2"
672 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm<")
673 (float:SF (match_operand:QI 1 "nonimmediate_operand" "rm")))]
677 ; Some assemblers warn that this insn doesn't work.
678 ; Maybe they know something we don't.
679 ;(define_insn "floatqidf2"
680 ; [(set (match_operand:DF 0 "nonimmediate_operand" "=lm<")
681 ; (float:DF (match_operand:QI 1 "nonimmediate_operand" "rm")))]
685 ;; Float-to-fix conversion insns.
686 ;; The sequent compiler always generates "trunc" insns.
688 (define_insn "fixsfqi2"
689 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
690 (fix:QI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "fm"))))]
694 (define_insn "fixsfhi2"
695 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
696 (fix:HI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "fm"))))]
700 (define_insn "fixsfsi2"
701 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
702 (fix:SI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "fm"))))]
706 (define_insn "fixdfqi2"
707 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
708 (fix:QI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "lm"))))]
712 (define_insn "fixdfhi2"
713 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
714 (fix:HI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "lm"))))]
718 (define_insn "fixdfsi2"
719 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
720 (fix:SI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "lm"))))]
726 (define_insn "fixunssfqi2"
727 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
728 (unsigned_fix:QI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "fm"))))]
732 (define_insn "fixunssfhi2"
733 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
734 (unsigned_fix:HI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "fm"))))]
738 (define_insn "fixunssfsi2"
739 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
740 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "fm"))))]
744 (define_insn "fixunsdfqi2"
745 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
746 (unsigned_fix:QI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "lm"))))]
750 (define_insn "fixunsdfhi2"
751 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
752 (unsigned_fix:HI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "lm"))))]
756 (define_insn "fixunsdfsi2"
757 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
758 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "lm"))))]
762 ;;; These are not yet used by GCC
763 (define_insn "fix_truncsfqi2"
764 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
765 (fix:QI (match_operand:SF 1 "nonimmediate_operand" "fm")))]
769 (define_insn "fix_truncsfhi2"
770 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
771 (fix:HI (match_operand:SF 1 "nonimmediate_operand" "fm")))]
775 (define_insn "fix_truncsfsi2"
776 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
777 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "fm")))]
781 (define_insn "fix_truncdfqi2"
782 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
783 (fix:QI (match_operand:DF 1 "nonimmediate_operand" "lm")))]
787 (define_insn "fix_truncdfhi2"
788 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
789 (fix:HI (match_operand:DF 1 "nonimmediate_operand" "lm")))]
793 (define_insn "fix_truncdfsi2"
794 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
795 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "lm")))]
799 ;; Multiply-add instructions
801 [(set (match_operand:DF 0 "nonimmediate_operand" "=v,v,lm")
802 (plus:DF (mult:DF (match_operand:DF 1 "general_operand" "%lmF,0,0")
803 (match_operand:DF 2 "general_operand" "lmF,lmF,lmF"))
804 (match_operand:DF 3 "general_operand" "0,lmF,lmF")))]
809 mull %2,%0\;addl %3,%0")
812 [(set (match_operand:SF 0 "nonimmediate_operand" "=u,u,fm")
813 (plus:SF (mult:SF (match_operand:SF 1 "general_operand" "%fmF,0,0")
814 (match_operand:SF 2 "general_operand" "fmF,fmF,fmF"))
815 (match_operand:SF 3 "general_operand" "0,fmF,fmF")))]
820 mulf %2,%0\;addf %3,%0")
823 ;; Multiply-sub instructions
825 [(set (match_operand:DF 0 "nonimmediate_operand" "=v,lm")
826 (minus:DF (mult:DF (match_operand:DF 1 "general_operand" "%lmF,0")
827 (match_operand:DF 2 "general_operand" "lmF,lmF"))
828 (match_operand:DF 3 "general_operand" "lmF,lmF")))]
831 negl %3,%0\;dotl %1,%2
832 mull %2,%0\;subl %3,%0")
835 [(set (match_operand:SF 0 "nonimmediate_operand" "=u,fm")
836 (minus:SF (mult:SF (match_operand:SF 1 "general_operand" "%fmF,0")
837 (match_operand:SF 2 "general_operand" "fmF,fmF"))
838 (match_operand:SF 3 "general_operand" "fmF,fmF")))]
841 negf %3,%0\;dotf %1,%2
842 mulf %2,%0\;subf %3,%0")
844 ;;- All kinds of add instructions.
846 (define_insn "adddf3"
847 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm")
848 (plus:DF (match_operand:DF 1 "general_operand" "%0")
849 (match_operand:DF 2 "general_operand" "lmF")))]
854 (define_insn "addsf3"
855 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
856 (plus:SF (match_operand:SF 1 "general_operand" "%0")
857 (match_operand:SF 2 "general_operand" "fmF")))]
864 (match_operand:SI 0 "immediate_operand" "i")))]
865 "GET_CODE (operands[0]) == CONST_INT"
868 #ifndef SEQUENT_ADJUST_STACK
870 if (INTVAL (operands[0]) == 8)
871 return \"cmpd tos,tos\";
872 if (TARGET_32532 || TARGET_32332)
873 if (INTVAL (operands[0]) == 4)
874 return \"cmpqd %$0,tos\";
878 if (INTVAL (operands[0]) < 64 && INTVAL (operands[0]) > -64)
879 return \"adjspb %n0\";
880 else if (INTVAL (operands[0]) < 8192 && INTVAL (operands[0]) >= -8192)
881 return \"adjspw %n0\";
883 return \"adjspd %n0\";
887 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
889 (match_operand:SI 1 "immediate_operand" "i")))]
890 "GET_CODE (operands[1]) == CONST_INT"
894 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
896 (match_operand:SI 1 "immediate_operand" "i")))]
897 "GET_CODE (operands[1]) == CONST_INT"
900 (define_insn "adddi3"
901 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
902 (plus:DI (match_operand:DI 1 "general_operand" "%0")
903 (match_operand:DI 2 "general_operand" "ron")))]
907 rtx low[3], high[3], xops[4];
908 split_di (operands, 3, low, high);
914 if (GET_CODE (xops[2]) == CONST_INT)
916 int i = INTVAL (xops[2]);
918 if (i <= 7 && i >= -8)
922 i = INTVAL (xops[3]);
923 if (i <= 7 && i >= -8)
924 output_asm_insn (\"addqd %3,%1\", xops);
926 output_asm_insn (\"addd %3,%1\", xops);
930 output_asm_insn (\"addqd %2,%0\", xops);
931 output_asm_insn (\"addcd %3,%1\", xops);
936 output_asm_insn (\"addd %2,%0\", xops);
937 output_asm_insn (\"addcd %3,%1\", xops);
942 (define_insn "addsi3"
943 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,=rm&<")
944 (plus:SI (match_operand:SI 1 "general_operand" "%0,r")
945 (match_operand:SI 2 "general_operand" "g,i")))]
949 if (which_alternative == 1)
951 if (GET_CODE (operands[2]) == CONST_INT)
953 int i = INTVAL (operands[2]);
954 if (NS32K_DISPLACEMENT_P (i))
955 return \"addr %c2(%1),%0\";
957 return \"movd %1,%0\;addd %2,%0\";
962 return \"addr %a2[%1:b],%0\";
964 return \"addr %c2(%1),%0\";
967 else if (GET_CODE (operands[2]) == CONST_INT)
969 int i = INTVAL (operands[2]);
971 if (i <= 7 && i >= -8)
972 return \"addqd %2,%0\";
973 else if (! TARGET_32532 && GET_CODE (operands[0]) == REG
974 && NS32K_DISPLACEMENT_P (i))
975 return \"addr %c2(%0),%0\";
977 return \"addd %2,%0\";
980 (define_insn "addhi3"
981 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
982 (plus:HI (match_operand:HI 1 "general_operand" "%0")
983 (match_operand:HI 2 "general_operand" "g")))]
986 { if (GET_CODE (operands[2]) == CONST_INT)
988 int i = INTVAL (operands[2]);
989 if (i <= 7 && i >= -8)
990 return \"addqw %2,%0\";
992 return \"addw %2,%0\";
996 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
997 (plus:HI (match_operand:HI 1 "general_operand" "0")
998 (match_operand:HI 2 "general_operand" "g")))]
1002 if (GET_CODE (operands[1]) == CONST_INT
1003 && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8)
1004 return \"addqw %2,%0\";
1005 return \"addw %2,%0\";
1008 (define_insn "addqi3"
1009 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1010 (plus:QI (match_operand:QI 1 "general_operand" "%0")
1011 (match_operand:QI 2 "general_operand" "g")))]
1014 { if (GET_CODE (operands[2]) == CONST_INT)
1016 int i = INTVAL (operands[2]);
1017 if (i <= 7 && i >= -8)
1018 return \"addqb %2,%0\";
1020 return \"addb %2,%0\";
1024 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
1025 (plus:QI (match_operand:QI 1 "general_operand" "0")
1026 (match_operand:QI 2 "general_operand" "g")))]
1030 if (GET_CODE (operands[1]) == CONST_INT
1031 && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8)
1032 return \"addqb %2,%0\";
1033 return \"addb %2,%0\";
1036 ;;- All kinds of subtract instructions.
1038 (define_insn "subdf3"
1039 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm")
1040 (minus:DF (match_operand:DF 1 "general_operand" "0")
1041 (match_operand:DF 2 "general_operand" "lmF")))]
1045 (define_insn "subsf3"
1046 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
1047 (minus:SF (match_operand:SF 1 "general_operand" "0")
1048 (match_operand:SF 2 "general_operand" "fmF")))]
1054 (minus:SI (reg:SI 25)
1055 (match_operand:SI 0 "immediate_operand" "i")))]
1056 "GET_CODE (operands[0]) == CONST_INT"
1059 if (! TARGET_32532 && GET_CODE(operands[0]) == CONST_INT
1060 && INTVAL(operands[0]) < 64 && INTVAL(operands[0]) > -64)
1061 return \"adjspb %0\";
1062 return \"adjspd %0\";
1065 (define_insn "subdi3"
1066 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
1067 (minus:DI (match_operand:DI 1 "general_operand" "0")
1068 (match_operand:DI 2 "general_operand" "ron")))]
1072 rtx low[3], high[3], xops[4];
1073 split_di (operands, 3, low, high);
1079 if (GET_CODE (xops[2]) == CONST_INT)
1081 int i = INTVAL (xops[2]);
1083 if (i <= 8 && i >= -7)
1087 i = INTVAL (xops[3]);
1088 if (i <= 8 && i >= -7)
1089 output_asm_insn (\"addqd %n3,%1\", xops);
1091 output_asm_insn (\"subd %3,%1\", xops);
1095 output_asm_insn (\"addqd %n2,%0\", xops);
1096 output_asm_insn (\"subcd %3,%1\", xops);
1101 output_asm_insn (\"subd %2,%0\", xops);
1102 output_asm_insn (\"subcd %3,%1\", xops);
1106 (define_insn "subsi3"
1107 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1108 (minus:SI (match_operand:SI 1 "general_operand" "0")
1109 (match_operand:SI 2 "general_operand" "g")))]
1112 { if (GET_CODE (operands[2]) == CONST_INT)
1114 int i = INTVAL (operands[2]);
1116 if (i <= 8 && i >= -7)
1117 return \"addqd %n2,%0\";
1119 return \"subd %2,%0\";
1122 (define_insn "subhi3"
1123 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1124 (minus:HI (match_operand:HI 1 "general_operand" "0")
1125 (match_operand:HI 2 "general_operand" "g")))]
1128 { if (GET_CODE (operands[2]) == CONST_INT)
1130 int i = INTVAL (operands[2]);
1132 if (i <= 8 && i >= -7)
1133 return \"addqw %n2,%0\";
1135 return \"subw %2,%0\";
1139 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1140 (minus:HI (match_operand:HI 1 "general_operand" "0")
1141 (match_operand:HI 2 "general_operand" "g")))]
1145 if (GET_CODE (operands[1]) == CONST_INT
1146 && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9)
1147 return \"addqw %n2,%0\";
1148 return \"subw %2,%0\";
1151 (define_insn "subqi3"
1152 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1153 (minus:QI (match_operand:QI 1 "general_operand" "0")
1154 (match_operand:QI 2 "general_operand" "g")))]
1157 { if (GET_CODE (operands[2]) == CONST_INT)
1159 int i = INTVAL (operands[2]);
1161 if (i <= 8 && i >= -7)
1162 return \"addqb %n2,%0\";
1164 return \"subb %2,%0\";
1168 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
1169 (minus:QI (match_operand:QI 1 "general_operand" "0")
1170 (match_operand:QI 2 "general_operand" "g")))]
1174 if (GET_CODE (operands[1]) == CONST_INT
1175 && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9)
1176 return \"addqb %n2,%0\";
1177 return \"subb %2,%0\";
1180 ;;- Multiply instructions.
1182 (define_insn "muldf3"
1183 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm")
1184 (mult:DF (match_operand:DF 1 "general_operand" "%0")
1185 (match_operand:DF 2 "general_operand" "lmF")))]
1189 (define_insn "mulsf3"
1190 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
1191 (mult:SF (match_operand:SF 1 "general_operand" "%0")
1192 (match_operand:SF 2 "general_operand" "fmF")))]
1197 (define_insn "mulsi3"
1198 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1199 (mult:SI (match_operand:SI 1 "general_operand" "%0")
1200 (match_operand:SI 2 "general_operand" "g")))]
1204 (define_insn "mulhi3"
1205 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1206 (mult:HI (match_operand:HI 1 "general_operand" "%0")
1207 (match_operand:HI 2 "general_operand" "g")))]
1211 (define_insn "mulqi3"
1212 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1213 (mult:QI (match_operand:QI 1 "general_operand" "%0")
1214 (match_operand:QI 2 "general_operand" "g")))]
1218 (define_insn "umulsidi3"
1219 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1220 (mult:DI (zero_extend:DI
1221 (match_operand:SI 1 "nonimmediate_operand" "0"))
1223 (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
1227 ;; divmod insns: We can only do the unsigned case.
1228 (define_expand "udivmodsi4"
1230 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1231 (udiv:SI (match_operand:SI 1 "general_operand" "")
1232 (match_operand:SI 2 "general_operand" "")))
1233 (set (match_operand:SI 3 "nonimmediate_operand" "")
1234 (umod:SI (match_dup 1) (match_dup 2)))])]
1238 rtx temp = gen_reg_rtx(DImode);
1239 rtx insn, first, last;
1240 first = emit_move_insn(gen_lowpart(SImode, temp), operands[1]);
1241 emit_move_insn(gen_highpart(SImode, temp), const0_rtx);
1242 emit_insn(gen_udivmoddisi4_internal(temp, temp, operands[2]));
1243 last = emit_move_insn(temp, temp);
1245 rtx divdi, moddi, divsi, modsi;
1246 divsi = gen_rtx (UDIV, SImode, operands[1], operands[2]);
1247 modsi = gen_rtx (UMOD, SImode, operands[1], operands[2]);
1248 divdi = gen_rtx (ZERO_EXTEND, DImode, divsi);
1249 moddi = gen_rtx (ZERO_EXTEND, DImode, modsi);
1250 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1252 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first,
1253 gen_rtx (EXPR_LIST, REG_EQUAL,
1254 gen_rtx (IOR, DImode, moddi,
1255 gen_rtx (ASHIFT, DImode, divdi, GEN_INT(32))),
1259 insn = emit_move_insn(operands[0], gen_highpart(SImode, temp));
1260 insn = emit_move_insn(operands[3], gen_lowpart(SImode, temp));
1264 ;; If we try and describe what this does, we have to zero-expand an
1265 ;; operand, which prevents it being a constant (VOIDmode) (see udivmoddisi4
1266 ;; below. This udivmoddisi4_internal never matches anything and is only
1267 ;; ever used when explicitly emitted by a define_expand.
1268 (define_insn "udivmoddisi4_internal"
1269 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1270 (unspec:DI [(match_operand:DI 1 "nonimmediate_operand" "0")
1271 (match_operand:SI 2 "general_operand" "g")] 0))]
1275 ;; Retain this insn which *does* have a pattern indicating what it does,
1276 ;; just in case the compiler is smart enough to recognize a substitution.
1277 (define_insn "udivmoddisi4"
1278 [(set (subreg:SI (match_operand:DI 0 "nonimmediate_operand" "=rm") 4)
1279 (truncate:SI (udiv:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1280 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))))
1281 (set (subreg:SI (match_operand:DI 3 "nonimmediate_operand" "=0") 0)
1282 (truncate:SI (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))]
1286 ;; Part word variants. These seem to never be used at the moment (gcc
1287 ;; 2.7.2.2). The code generation prefers to zero extend hi's and qi's
1288 ;; and use signed div and mod. Keep these insns incase that changes.
1289 ;; divmod should have an advantage when both div and mod are needed. However,
1290 ;; divmod uses two registers, so maybe the compiler knows best.
1292 (define_expand "udivmodhi4"
1294 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1295 (udiv:HI (match_operand:HI 1 "general_operand" "")
1296 (match_operand:HI 2 "general_operand" "")))
1297 (set (match_operand:HI 3 "nonimmediate_operand" "")
1298 (umod:HI (match_dup 1) (match_dup 2)))])]
1302 rtx temp = gen_reg_rtx(DImode);
1303 rtx insn, first, last;
1304 first = emit_move_insn(gen_lowpart(HImode, temp), operands[1]);
1305 emit_move_insn(gen_highpart (HImode, temp), const0_rtx);
1306 operands[2] = force_reg(HImode, operands[2]);
1307 emit_insn(gen_udivmoddihi4_internal(temp, temp, operands[2]));
1308 last = emit_move_insn(temp, temp);
1310 rtx divdi, moddi, divhi, modhi;
1311 divhi = gen_rtx (UDIV, HImode, operands[1], operands[2]);
1312 modhi = gen_rtx (UMOD, HImode, operands[1], operands[2]);
1313 divdi = gen_rtx (ZERO_EXTEND, DImode, divhi);
1314 moddi = gen_rtx (ZERO_EXTEND, DImode, modhi);
1315 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1317 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first,
1318 gen_rtx (EXPR_LIST, REG_EQUAL,
1319 gen_rtx(IOR, DImode, moddi,
1320 gen_rtx(ASHIFT, DImode, divdi, GEN_INT(32))),
1324 insn = emit_move_insn(operands[0], gen_highpart(HImode, temp));
1325 insn = emit_move_insn(operands[3], gen_lowpart(HImode, temp));
1329 ;; deiw wants two hi's in separate registers or else they can be adjacent
1330 ;; in memory. DI mode will ensure two registers are available, but if we
1331 ;; want to allow memory as an operand we would need SI mode. There is no
1332 ;; way to do this, so just restrict operand 0 and 1 to be in registers.
1333 (define_insn "udivmoddihi4_internal"
1334 [(set (match_operand:DI 0 "register_operand" "=r")
1335 (unspec:DI [(match_operand:DI 1 "register_operand" "0")
1336 (match_operand:HI 2 "general_operand" "g")] 0))]
1340 (define_insn "udivmoddihi4"
1341 [(set (subreg:HI (match_operand:DI 0 "register_operand" "=r") 2)
1342 (truncate:HI (udiv:DI (match_operand:DI 1 "register_operand" "0")
1343 (zero_extend:DI (match_operand:HI 2 "nonimmediate_operand" "rm")))))
1344 (set (subreg:HI (match_operand:DI 3 "register_operand" "=0") 0)
1345 (truncate:HI (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))]
1349 (define_expand "udivmodqi4"
1351 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1352 (udiv:QI (match_operand:QI 1 "general_operand" "")
1353 (match_operand:QI 2 "general_operand" "")))
1354 (set (match_operand:QI 3 "nonimmediate_operand" "")
1355 (umod:QI (match_dup 1) (match_dup 2)))])]
1359 rtx temp = gen_reg_rtx(DImode);
1360 rtx insn, first, last;
1361 first = emit_move_insn(gen_lowpart(QImode, temp), operands[1]);
1362 emit_move_insn(gen_highpart(QImode, temp), const0_rtx);
1363 operands[2] = force_reg(QImode, operands[2]);
1364 emit_insn(gen_udivmoddiqi4_internal(temp, temp, operands[2]));
1365 last = emit_move_insn(temp, temp);
1367 rtx divdi, moddi, divqi, modqi;
1368 divqi = gen_rtx (UDIV, QImode, operands[1], operands[2]);
1369 modqi = gen_rtx (UMOD, QImode, operands[1], operands[2]);
1370 divdi = gen_rtx (ZERO_EXTEND, DImode, divqi);
1371 moddi = gen_rtx (ZERO_EXTEND, DImode, modqi);
1372 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1374 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first,
1375 gen_rtx (EXPR_LIST, REG_EQUAL,
1376 gen_rtx(IOR, DImode, moddi,
1377 gen_rtx(ASHIFT, DImode, divdi, GEN_INT(32))),
1381 insn = emit_move_insn(operands[0], gen_highpart(QImode, temp));
1382 insn = emit_move_insn(operands[3], gen_lowpart(QImode, temp));
1386 ;; deib wants two qi's in separate registers or else they can be adjacent
1387 ;; in memory. DI mode will ensure two registers are available, but if we
1388 ;; want to allow memory as an operand we would need HI mode. There is no
1389 ;; way to do this, so just restrict operand 0 and 1 to be in registers.
1390 (define_insn "udivmoddiqi4_internal"
1391 [(set (match_operand:DI 0 "register_operand" "=r")
1392 (unspec:DI [(match_operand:DI 1 "register_operand" "0")
1393 (match_operand:QI 2 "general_operand" "g")] 0))]
1397 (define_insn "udivmoddiqi4"
1398 [(set (subreg:QI (match_operand:DI 0 "register_operand" "=r") 1)
1399 (truncate:QI (udiv:DI (match_operand:DI 1 "register_operand" "0")
1400 (zero_extend:DI (match_operand:QI 2 "nonimmediate_operand" "rm")))))
1401 (set (subreg:QI (match_operand:DI 3 "register_operand" "=0") 0)
1402 (truncate:QI (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))]
1406 ;;- Divide instructions.
1408 (define_insn "divdf3"
1409 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm")
1410 (div:DF (match_operand:DF 1 "general_operand" "0")
1411 (match_operand:DF 2 "general_operand" "lmF")))]
1415 (define_insn "divsf3"
1416 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
1417 (div:SF (match_operand:SF 1 "general_operand" "0")
1418 (match_operand:SF 2 "general_operand" "fmF")))]
1423 (define_insn "divsi3"
1424 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1425 (div:SI (match_operand:SI 1 "general_operand" "0")
1426 (match_operand:SI 2 "general_operand" "g")))]
1430 (define_insn "divhi3"
1431 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1432 (div:HI (match_operand:HI 1 "general_operand" "0")
1433 (match_operand:HI 2 "general_operand" "g")))]
1437 (define_insn "divqi3"
1438 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1439 (div:QI (match_operand:QI 1 "general_operand" "0")
1440 (match_operand:QI 2 "general_operand" "g")))]
1444 ;; Remainder instructions.
1447 (define_insn "modsi3"
1448 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1449 (mod:SI (match_operand:SI 1 "general_operand" "0")
1450 (match_operand:SI 2 "general_operand" "g")))]
1454 (define_insn "modhi3"
1455 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1456 (mod:HI (match_operand:HI 1 "general_operand" "0")
1457 (match_operand:HI 2 "general_operand" "g")))]
1461 (define_insn "modqi3"
1462 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1463 (mod:QI (match_operand:QI 1 "general_operand" "0")
1464 (match_operand:QI 2 "general_operand" "g")))]
1469 ;;- Logical Instructions: AND
1472 (define_insn "andsi3"
1473 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1474 (and:SI (match_operand:SI 1 "general_operand" "%0")
1475 (match_operand:SI 2 "general_operand" "g")))]
1479 if (GET_CODE (operands[2]) == CONST_INT)
1481 if ((INTVAL (operands[2]) | 0xff) == 0xffffffff)
1483 if (INTVAL (operands[2]) == 0xffffff00)
1484 return \"movqb %$0,%0\";
1487 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
1488 return \"andb %2,%0\";
1491 if ((INTVAL (operands[2]) | 0xffff) == 0xffffffff)
1493 if (INTVAL (operands[2]) == 0xffff0000)
1494 return \"movqw %$0,%0\";
1497 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1498 return \"andw %2,%0\";
1502 return \"andd %2,%0\";
1505 (define_insn "andhi3"
1506 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1507 (and:HI (match_operand:HI 1 "general_operand" "%0")
1508 (match_operand:HI 2 "general_operand" "g")))]
1512 if (GET_CODE (operands[2]) == CONST_INT
1513 && (INTVAL (operands[2]) | 0xff) == 0xffffffff)
1515 if (INTVAL (operands[2]) == 0xffffff00)
1516 return \"movqb %$0,%0\";
1519 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
1520 return \"andb %2,%0\";
1523 return \"andw %2,%0\";
1526 (define_insn "andqi3"
1527 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1528 (and:QI (match_operand:QI 1 "general_operand" "%0")
1529 (match_operand:QI 2 "general_operand" "g")))]
1535 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1536 (and:SI (not:SI (match_operand:SI 1 "general_operand" "g"))
1537 (match_operand:SI 2 "general_operand" "0")))]
1542 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1543 (and:HI (not:HI (match_operand:HI 1 "general_operand" "g"))
1544 (match_operand:HI 2 "general_operand" "0")))]
1549 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1550 (and:QI (not:QI (match_operand:QI 1 "general_operand" "g"))
1551 (match_operand:QI 2 "general_operand" "0")))]
1555 ;;- Bit set instructions.
1558 (define_insn "iorsi3"
1559 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1560 (ior:SI (match_operand:SI 1 "general_operand" "%0")
1561 (match_operand:SI 2 "general_operand" "g")))]
1565 if (GET_CODE (operands[2]) == CONST_INT) {
1566 if ((INTVAL (operands[2]) & 0xffffff00) == 0)
1567 return \"orb %2,%0\";
1568 if ((INTVAL (operands[2]) & 0xffff0000) == 0)
1569 return \"orw %2,%0\";
1571 return \"ord %2,%0\";
1574 (define_insn "iorhi3"
1575 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1576 (ior:HI (match_operand:HI 1 "general_operand" "%0")
1577 (match_operand:HI 2 "general_operand" "g")))]
1581 if (GET_CODE(operands[2]) == CONST_INT &&
1582 (INTVAL(operands[2]) & 0xffffff00) == 0)
1583 return \"orb %2,%0\";
1584 return \"orw %2,%0\";
1587 (define_insn "iorqi3"
1588 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1589 (ior:QI (match_operand:QI 1 "general_operand" "%0")
1590 (match_operand:QI 2 "general_operand" "g")))]
1594 ;;- xor instructions.
1597 (define_insn "xorsi3"
1598 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1599 (xor:SI (match_operand:SI 1 "general_operand" "%0")
1600 (match_operand:SI 2 "general_operand" "g")))]
1604 if (GET_CODE (operands[2]) == CONST_INT) {
1605 if ((INTVAL (operands[2]) & 0xffffff00) == 0)
1606 return \"xorb %2,%0\";
1607 if ((INTVAL (operands[2]) & 0xffff0000) == 0)
1608 return \"xorw %2,%0\";
1610 return \"xord %2,%0\";
1613 (define_insn "xorhi3"
1614 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1615 (xor:HI (match_operand:HI 1 "general_operand" "%0")
1616 (match_operand:HI 2 "general_operand" "g")))]
1620 if (GET_CODE(operands[2]) == CONST_INT &&
1621 (INTVAL(operands[2]) & 0xffffff00) == 0)
1622 return \"xorb %2,%0\";
1623 return \"xorw %2,%0\";
1626 (define_insn "xorqi3"
1627 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1628 (xor:QI (match_operand:QI 1 "general_operand" "%0")
1629 (match_operand:QI 2 "general_operand" "g")))]
1633 (define_insn "negdf2"
1634 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm<")
1635 (neg:DF (match_operand:DF 1 "general_operand" "lmF")))]
1639 (define_insn "negsf2"
1640 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm<")
1641 (neg:SF (match_operand:SF 1 "general_operand" "fmF")))]
1645 (define_insn "negdi2"
1646 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
1647 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "ro")))]
1651 rtx low[2], high[2], xops[4];
1652 split_di (operands, 2, low, high);
1658 if (rtx_equal_p (operands[0], operands[1]))
1660 output_asm_insn (\"negd %3,%1\", xops);
1661 output_asm_insn (\"negd %2,%0\", xops);
1662 output_asm_insn (\"subcd %$0,%1\", xops);
1666 output_asm_insn (\"negd %2,%0\", xops);
1667 output_asm_insn (\"movqd %$0,%1\", xops);
1668 output_asm_insn (\"subcd %3,%1\", xops);
1674 (define_insn "negsi2"
1675 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
1676 (neg:SI (match_operand:SI 1 "general_operand" "g")))]
1680 (define_insn "neghi2"
1681 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
1682 (neg:HI (match_operand:HI 1 "general_operand" "g")))]
1686 (define_insn "negqi2"
1687 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
1688 (neg:QI (match_operand:QI 1 "general_operand" "g")))]
1693 (define_insn "one_cmplsi2"
1694 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
1695 (not:SI (match_operand:SI 1 "general_operand" "g")))]
1699 (define_insn "one_cmplhi2"
1700 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
1701 (not:HI (match_operand:HI 1 "general_operand" "g")))]
1705 (define_insn "one_cmplqi2"
1706 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
1707 (not:QI (match_operand:QI 1 "general_operand" "g")))]
1711 ;; arithmetic left and right shift operations
1712 ;; on the 32532 we will always use lshd for arithmetic left shifts,
1713 ;; because it is three times faster. Broken programs which
1714 ;; use negative shift counts are probably broken differently
1717 ;; alternative 0 never matches on the 32532
1719 (define_insn "ashlsi3"
1720 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1721 (ashift:SI (match_operand:SI 1 "general_operand" "r,0")
1722 (match_operand:SI 2 "general_operand" "I,g")))]
1726 return \"lshd %2,%0\";
1728 return output_shift_insn (operands);
1731 (define_insn "ashlhi3"
1732 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1733 (ashift:HI (match_operand:HI 1 "general_operand" "0")
1734 (match_operand:SI 2 "general_operand" "g")))]
1737 { if (GET_CODE (operands[2]) == CONST_INT)
1739 if (INTVAL (operands[2]) == 1)
1740 return \"addw %0,%0\";
1741 else if (! TARGET_32532 && INTVAL (operands[2]) == 2)
1742 return \"addw %0,%0\;addw %0,%0\";
1745 return \"lshw %2,%0\";
1747 return \"ashw %2,%0\";
1750 (define_insn "ashlqi3"
1751 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1752 (ashift:QI (match_operand:QI 1 "general_operand" "0")
1753 (match_operand:SI 2 "general_operand" "g")))]
1756 { if (GET_CODE (operands[2]) == CONST_INT)
1758 if (INTVAL (operands[2]) == 1)
1759 return \"addb %0,%0\";
1760 else if (! TARGET_32532 && INTVAL (operands[2]) == 2)
1761 return \"addb %0,%0\;addb %0,%0\";
1764 return \"lshb %2,%0\";
1766 return \"ashb %2,%0\";
1769 ;; Arithmetic right shift on the 32k works by negating the shift count.
1770 (define_expand "ashrsi3"
1771 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1772 (ashiftrt:SI (match_operand:SI 1 "general_operand" "g")
1773 (match_operand:SI 2 "general_operand" "g")))]
1777 if (GET_CODE (operands[2]) != CONST_INT)
1778 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1782 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1783 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
1784 (match_operand:SI 2 "immediate_operand" "i")))]
1789 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1790 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
1791 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1795 (define_expand "ashrhi3"
1796 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1797 (ashiftrt:HI (match_operand:HI 1 "general_operand" "g")
1798 (match_operand:SI 2 "general_operand" "g")))]
1802 if (GET_CODE (operands[2]) != CONST_INT)
1803 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1807 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1808 (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
1809 (match_operand:SI 2 "immediate_operand" "i")))]
1814 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1815 (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
1816 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1820 (define_expand "ashrqi3"
1821 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1822 (ashiftrt:QI (match_operand:QI 1 "general_operand" "g")
1823 (match_operand:SI 2 "general_operand" "g")))]
1827 if (GET_CODE (operands[2]) != CONST_INT)
1828 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1832 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1833 (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
1834 (match_operand:SI 2 "immediate_operand" "i")))]
1839 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1840 (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
1841 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1845 ;; logical shift instructions
1847 ;; Logical right shift on the 32k works by negating the shift count.
1848 (define_expand "lshrsi3"
1849 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1850 (lshiftrt:SI (match_operand:SI 1 "general_operand" "g")
1851 (match_operand:SI 2 "general_operand" "g")))]
1855 if (GET_CODE (operands[2]) != CONST_INT)
1856 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1860 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1861 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1862 (match_operand:SI 2 "immediate_operand" "i")))]
1867 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1868 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1869 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1873 (define_expand "lshrhi3"
1874 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1875 (lshiftrt:HI (match_operand:HI 1 "general_operand" "g")
1876 (match_operand:SI 2 "general_operand" "g")))]
1880 if (GET_CODE (operands[2]) != CONST_INT)
1881 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1885 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1886 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1887 (match_operand:SI 2 "immediate_operand" "i")))]
1892 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1893 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1894 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1898 (define_expand "lshrqi3"
1899 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1900 (lshiftrt:QI (match_operand:QI 1 "general_operand" "g")
1901 (match_operand:SI 2 "general_operand" "g")))]
1905 if (GET_CODE (operands[2]) != CONST_INT)
1906 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1910 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1911 (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
1912 (match_operand:SI 2 "immediate_operand" "i")))]
1917 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1918 (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
1919 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1923 ;; Rotate instructions
1926 (define_insn "rotlsi3"
1927 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1928 (rotate:SI (match_operand:SI 1 "general_operand" "0")
1929 (match_operand:SI 2 "general_operand" "g")))]
1933 (define_insn "rotlhi3"
1934 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1935 (rotate:HI (match_operand:HI 1 "general_operand" "0")
1936 (match_operand:SI 2 "general_operand" "g")))]
1940 (define_insn "rotlqi3"
1941 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1942 (rotate:QI (match_operand:QI 1 "general_operand" "0")
1943 (match_operand:SI 2 "general_operand" "g")))]
1947 ;; Right rotate on the 32k works by negating the shift count.
1948 (define_expand "rotrsi3"
1949 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1950 (rotatert:SI (match_operand:SI 1 "general_operand" "g")
1951 (match_operand:SI 2 "general_operand" "g")))]
1955 if (GET_CODE (operands[2]) != CONST_INT)
1956 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1960 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1961 (rotatert:SI (match_operand:SI 1 "general_operand" "0")
1962 (match_operand:SI 2 "immediate_operand" "i")))]
1967 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1968 (rotatert:SI (match_operand:SI 1 "general_operand" "0")
1969 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1973 (define_expand "rotrhi3"
1974 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1975 (rotatert:HI (match_operand:HI 1 "general_operand" "g")
1976 (match_operand:SI 2 "general_operand" "g")))]
1980 if (GET_CODE (operands[2]) != CONST_INT)
1981 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
1985 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1986 (rotatert:HI (match_operand:HI 1 "general_operand" "0")
1987 (match_operand:SI 2 "immediate_operand" "i")))]
1992 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1993 (rotatert:HI (match_operand:HI 1 "general_operand" "0")
1994 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
1998 (define_expand "rotrqi3"
1999 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
2000 (rotatert:QI (match_operand:QI 1 "general_operand" "g")
2001 (match_operand:SI 2 "general_operand" "g")))]
2005 if (GET_CODE (operands[2]) != CONST_INT)
2006 operands[2] = gen_rtx_NEG (SImode, negate_rtx (SImode, operands[2]));
2010 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
2011 (rotatert:QI (match_operand:QI 1 "general_operand" "0")
2012 (match_operand:SI 2 "immediate_operand" "i")))]
2017 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
2018 (rotatert:QI (match_operand:QI 1 "general_operand" "0")
2019 (neg:SI (match_operand:SI 2 "register_operand" "r"))))]
2023 ;;- load or push effective address
2024 ;; These come after the move, add, and multiply patterns
2025 ;; because we don't want pushl $1 turned into pushad 1.
2028 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2029 (match_operand:QI 1 "address_operand" "p"))]
2033 if (REG_P (operands[0])
2034 && GET_CODE (operands[1]) == MULT
2035 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
2036 && (INTVAL (XEXP (operands[1], 1)) == 2
2037 || INTVAL (XEXP (operands[1], 1)) == 4))
2040 xoperands[0] = operands[0];
2041 xoperands[1] = XEXP (operands[1], 0);
2042 xoperands[2] = GEN_INT (INTVAL (XEXP (operands[1], 1)) >> 1);
2043 return output_shift_insn (xoperands);
2045 return \"addr %a1,%0\";
2048 ;;; Index insns. These are about the same speed as multiply-add counterparts.
2049 ;;; but slower than using power-of-2 shifts if we can use them
2053 ; [(set (match_operand:SI 0 "register_operand" "=r")
2054 ; (plus:SI (match_operand:SI 1 "general_operand" "g")
2055 ; (mult:SI (match_operand:SI 2 "register_operand" "0")
2056 ; (plus:SI (match_operand:SI 3 "general_operand" "g") (const_int 1)))))]
2057 ; "GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) > 8"
2058 ; "indexd %0,%3,%1")
2061 ; [(set (match_operand:SI 0 "register_operand" "=r")
2062 ; (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
2063 ; (plus:SI (match_operand:SI 2 "general_operand" "g") (const_int 1)))
2064 ; (match_operand:SI 3 "general_operand" "g")))]
2065 ; "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 8"
2066 ; "indexd %0,%2,%3")
2068 ;; Set, Clear, and Invert bit
2072 [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+rm")
2074 (match_operand:SI 1 "general_operand" "g"))
2081 [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+rm")
2083 (match_operand:SI 1 "general_operand" "g"))
2090 [(set (match_operand:SI 0 "nonimmediate_operand" "+rm")
2091 (xor:SI (ashift:SI (const_int 1)
2092 (match_operand:SI 1 "general_operand" "g"))
2099 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
2101 (ashift:SI (const_int 1)
2102 (match_operand:QI 1 "general_operand" "g")) 0)
2107 ;; Recognize jbs and jbc instructions.
2111 (zero_extract (match_operand:SI 0 "nonimmediate_operand" "rm")
2113 (match_operand:SI 1 "general_operand" "g")))]
2116 { cc_status.flags = CC_Z_IN_F;
2117 return \"tbitd %1,%0\";
2120 ;; extract(base, width, offset)
2121 ;; Signed bitfield extraction is not supported in hardware on the
2122 ;; NS 32032. It is therefore better to let GCC figure out a
2123 ;; good strategy for generating the proper instruction sequence
2124 ;; and represent it as rtl.
2126 ;; Optimize the case of extracting a byte or word from a register.
2127 ;; Otherwise we must load a register with the offset of the
2128 ;; chunk we want, and perform an extract insn (each of which
2129 ;; is very expensive). Since we use the stack to do our bit-twiddling
2130 ;; we cannot use it for a destination. Perhaps things are fast
2131 ;; enough on the 32532 that such hacks are not needed.
2134 [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
2135 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
2136 (match_operand:SI 2 "const_int_operand" "i")
2137 (match_operand:SI 3 "const_int_operand" "i")))]
2138 "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
2139 && (INTVAL (operands[3]) == 8 || INTVAL (operands[3]) == 16 || INTVAL (operands[3]) == 24)"
2142 output_asm_insn (\"movd %1,tos\", operands);
2143 if (INTVAL (operands[2]) == 16)
2145 if (INTVAL (operands[3]) == 8)
2146 output_asm_insn (\"movzwd 1(sp),%0\", operands);
2148 output_asm_insn (\"movzwd 2(sp),%0\", operands);
2152 if (INTVAL (operands[3]) == 8)
2153 output_asm_insn (\"movzbd 1(sp),%0\", operands);
2154 else if (INTVAL (operands[3]) == 16)
2155 output_asm_insn (\"movzbd 2(sp),%0\", operands);
2157 output_asm_insn (\"movzbd 3(sp),%0\", operands);
2159 if (TARGET_32532 || TARGET_32332)
2160 return \"cmpqd %$0,tos\";
2162 return \"adjspb %$-4\";
2165 ;; The exts/ext instructions have the problem that they always access
2166 ;; 32 bits even if the bitfield is smaller. For example the instruction
2167 ;; extsd 7(r1),r0,2,5
2168 ;; would read not only at address 7(r1) but also at 8(r1) to 10(r1).
2169 ;; If these addresses are in a different (unmapped) page a memory fault
2172 ;; Timing considerations:
2173 ;; movd 0(r1),r0 3 bytes
2176 ;; takes about 13 cycles on the 532 while
2177 ;; extsd 7(r1),r0,2,5 5 bytes
2178 ;; takes about 21 cycles.
2180 ;; The inss/ins instructions suffer from the same problem.
2182 ;; A machine specific option (-mbitfield/-mnobitfield) is used
2183 ;; to allow/disallow the use of these instructions.
2186 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2187 (zero_extract:SI (match_operand:SI 1 "register_operand" "g")
2188 (match_operand:SI 2 "const_int_operand" "i")
2189 (match_operand:SI 3 "nonmemory_operand" "rK")))]
2192 { if (GET_CODE (operands[3]) == CONST_INT)
2193 return \"extsd %1,%0,%3,%2\";
2194 else return \"extd %3,%1,%0,%2\";
2197 (define_insn "extzv"
2198 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2199 (zero_extract:SI (match_operand:QI 1 "general_operand" "g")
2200 (match_operand:SI 2 "const_int_operand" "i")
2201 (match_operand:SI 3 "nonmemory_operand" "rK")))]
2204 { if (GET_CODE (operands[3]) == CONST_INT)
2205 return \"extsd %1,%0,%3,%2\";
2206 else return \"extd %3,%1,%0,%2\";
2210 [(set (zero_extract:SI (match_operand:SI 0 "memory_operand" "+o")
2211 (match_operand:SI 1 "const_int_operand" "i")
2212 (match_operand:SI 2 "nonmemory_operand" "rn"))
2213 (match_operand:SI 3 "nonimmediate_operand" "rm"))]
2216 { if (GET_CODE (operands[2]) == CONST_INT)
2218 if (INTVAL (operands[2]) >= 8)
2220 operands[0] = adjust_address (operands[0], QImode,
2221 INTVAL (operands[2]) / 8);
2222 operands[2] = GEN_INT (INTVAL (operands[2]) % 8);
2224 if (INTVAL (operands[1]) <= 8)
2225 return \"inssb %3,%0,%2,%1\";
2226 else if (INTVAL (operands[1]) <= 16)
2227 return \"inssw %3,%0,%2,%1\";
2229 return \"inssd %3,%0,%2,%1\";
2231 return \"insd %2,%3,%0,%1\";
2235 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2236 (match_operand:SI 1 "const_int_operand" "i")
2237 (match_operand:SI 2 "nonmemory_operand" "rK"))
2238 (match_operand:SI 3 "nonimmediate_operand" "rm"))]
2241 { if (GET_CODE (operands[2]) == CONST_INT)
2243 if (INTVAL (operands[1]) <= 8)
2244 return \"inssb %3,%0,%2,%1\";
2245 else if (INTVAL (operands[1]) <= 16)
2246 return \"inssw %3,%0,%2,%1\";
2248 return \"inssd %3,%0,%2,%1\";
2250 return \"insd %2,%3,%0,%1\";
2254 [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+rm")
2255 (match_operand:SI 1 "const_int_operand" "i")
2256 (match_operand:SI 2 "nonmemory_operand" "rK"))
2257 (match_operand:SI 3 "nonimmediate_operand" "rm"))]
2260 { if (GET_CODE (operands[2]) == CONST_INT)
2262 if (INTVAL (operands[1]) <= 8)
2263 return \"inssb %3,%0,%2,%1\";
2264 else if (INTVAL (operands[1]) <= 16)
2265 return \"inssw %3,%0,%2,%1\";
2267 return \"inssd %3,%0,%2,%1\";
2269 return \"insd %2,%3,%0,%1\";
2275 (label_ref (match_operand 0 "" "")))]
2281 (if_then_else (eq (cc0)
2283 (label_ref (match_operand 0 "" ""))
2287 { if (cc_prev_status.flags & CC_Z_IN_F)
2289 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2291 else return \"beq %l0\";
2296 (if_then_else (ne (cc0)
2298 (label_ref (match_operand 0 "" ""))
2302 { if (cc_prev_status.flags & CC_Z_IN_F)
2304 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2306 else return \"bne %l0\";
2311 (if_then_else (gt (cc0)
2313 (label_ref (match_operand 0 "" ""))
2320 (if_then_else (gtu (cc0)
2322 (label_ref (match_operand 0 "" ""))
2329 (if_then_else (lt (cc0)
2331 (label_ref (match_operand 0 "" ""))
2338 (if_then_else (ltu (cc0)
2340 (label_ref (match_operand 0 "" ""))
2347 (if_then_else (ge (cc0)
2349 (label_ref (match_operand 0 "" ""))
2356 (if_then_else (geu (cc0)
2358 (label_ref (match_operand 0 "" ""))
2365 (if_then_else (le (cc0)
2367 (label_ref (match_operand 0 "" ""))
2374 (if_then_else (leu (cc0)
2376 (label_ref (match_operand 0 "" ""))
2383 (if_then_else (eq (cc0)
2386 (label_ref (match_operand 0 "" ""))))]
2389 { if (cc_prev_status.flags & CC_Z_IN_F)
2391 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2393 else return \"bne %l0\";
2398 (if_then_else (ne (cc0)
2401 (label_ref (match_operand 0 "" ""))))]
2404 { if (cc_prev_status.flags & CC_Z_IN_F)
2406 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2408 else return \"beq %l0\";
2413 (if_then_else (gt (cc0)
2416 (label_ref (match_operand 0 "" ""))))]
2422 (if_then_else (gtu (cc0)
2425 (label_ref (match_operand 0 "" ""))))]
2431 (if_then_else (lt (cc0)
2434 (label_ref (match_operand 0 "" ""))))]
2440 (if_then_else (ltu (cc0)
2443 (label_ref (match_operand 0 "" ""))))]
2449 (if_then_else (ge (cc0)
2452 (label_ref (match_operand 0 "" ""))))]
2458 (if_then_else (geu (cc0)
2461 (label_ref (match_operand 0 "" ""))))]
2467 (if_then_else (le (cc0)
2470 (label_ref (match_operand 0 "" ""))))]
2476 (if_then_else (leu (cc0)
2479 (label_ref (match_operand 0 "" ""))))]
2483 ;; Subtract-and-jump and Add-and-jump insns.
2484 ;; These can actually be used for adding numbers in the range -8 to 7
2489 (ne (match_operand:SI 0 "nonimmediate_operand" "+rm")
2490 (match_operand:SI 1 "const_int_operand" "i"))
2491 (label_ref (match_operand 2 "" ""))
2494 (minus:SI (match_dup 0)
2496 "INTVAL (operands[1]) > -8 && INTVAL (operands[1]) <= 8"
2502 (ne (match_operand:SI 0 "nonimmediate_operand" "+rm")
2503 (match_operand:SI 1 "const_int_operand" "i"))
2504 (label_ref (match_operand 2 "" ""))
2507 (plus:SI (match_dup 0)
2508 (match_operand:SI 3 "const_int_operand" "i")))]
2509 "INTVAL (operands[1]) == - INTVAL (operands[3])
2510 && INTVAL (operands[3]) >= -8 && INTVAL (operands[3]) < 8"
2514 [(call (match_operand:QI 0 "memory_operand" "m")
2515 (match_operand:QI 1 "general_operand" "g"))]
2520 if (GET_CODE (operands[0]) == MEM)
2522 rtx temp = XEXP (operands[0], 0);
2523 if (CONSTANT_ADDRESS_P (temp))
2526 return \"bsr %?%0\";
2528 #ifdef CALL_MEMREF_IMPLICIT
2535 return \"bsr %?%a0\";
2540 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2541 #if defined (GNX_V3) || defined (CALL_MEMREF_IMPLICIT)
2547 #endif /* not JSR_ALWAYS */
2551 (define_insn "call_value"
2552 [(set (match_operand 0 "" "=rf")
2553 (call (match_operand:QI 1 "memory_operand" "m")
2554 (match_operand:QI 2 "general_operand" "g")))]
2559 if (GET_CODE (operands[1]) == MEM)
2561 rtx temp = XEXP (operands[1], 0);
2562 if (CONSTANT_ADDRESS_P (temp))
2565 return \"bsr %?%1\";
2567 #ifdef CALL_MEMREF_IMPLICIT
2574 return \"bsr %?%a1\";
2579 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2580 #if defined (GNX_V3) || defined (CALL_MEMREF_IMPLICIT)
2586 #endif /* not JSR_ALWAYS */
2590 ;; Call subroutine returning any type.
2592 (define_expand "untyped_call"
2593 [(parallel [(call (match_operand 0 "" "")
2595 (match_operand 1 "" "")
2596 (match_operand 2 "" "")])]
2602 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
2604 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2606 rtx set = XVECEXP (operands[2], 0, i);
2607 emit_move_insn (SET_DEST (set), SET_SRC (set));
2610 /* The optimizer does not know that the call sets the function value
2611 registers we stored in the result block. We avoid problems by
2612 claiming that all hard registers are used and clobbered at this
2614 emit_insn (gen_blockage ());
2619 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2620 ;; all of memory. This blocks insns from being moved across this point.
2622 (define_insn "blockage"
2623 [(unspec_volatile [(const_int 0)] 0)]
2627 (define_insn "return"
2632 (define_insn "abssf2"
2633 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm<")
2634 (abs:SF (match_operand:SF 1 "general_operand" "fmF")))]
2638 (define_insn "absdf2"
2639 [(set (match_operand:DF 0 "nonimmediate_operand" "=lm<")
2640 (abs:DF (match_operand:DF 1 "general_operand" "lmF")))]
2645 (define_insn "abssi2"
2646 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2647 (abs:SI (match_operand:SI 1 "general_operand" "g")))]
2651 (define_insn "abshi2"
2652 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
2653 (abs:HI (match_operand:HI 1 "general_operand" "g")))]
2657 (define_insn "absqi2"
2658 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
2659 (abs:QI (match_operand:QI 1 "general_operand" "g")))]
2668 (define_insn "indirect_jump"
2669 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2673 (define_insn "tablejump"
2675 (plus:SI (pc) (match_operand:SI 0 "general_operand" "g")))
2676 (use (label_ref (match_operand 1 "" "")))]
2680 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\",
2681 CODE_LABEL_NUMBER (operands[1]));
2682 return \"cased %0\";
2685 ;; Scondi instructions
2687 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2688 (eq:SI (cc0) (const_int 0)))]
2691 { if (cc_prev_status.flags & CC_Z_IN_F)
2693 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2695 else return \"seqd %0\";
2699 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
2700 (eq:HI (cc0) (const_int 0)))]
2703 { if (cc_prev_status.flags & CC_Z_IN_F)
2705 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2707 else return \"seqw %0\";
2711 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
2712 (eq:QI (cc0) (const_int 0)))]
2715 { if (cc_prev_status.flags & CC_Z_IN_F)
2717 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2719 else return \"seqb %0\";
2723 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2724 (ne:SI (cc0) (const_int 0)))]
2727 { if (cc_prev_status.flags & CC_Z_IN_F)
2729 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2731 else return \"sned %0\";
2735 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
2736 (ne:HI (cc0) (const_int 0)))]
2739 { if (cc_prev_status.flags & CC_Z_IN_F)
2741 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2743 else return \"snew %0\";
2747 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
2748 (ne:QI (cc0) (const_int 0)))]
2751 { if (cc_prev_status.flags & CC_Z_IN_F)
2753 else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
2755 else return \"sneb %0\";
2759 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2760 (gt:SI (cc0) (const_int 0)))]
2765 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
2766 (gt:HI (cc0) (const_int 0)))]
2771 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
2772 (gt:QI (cc0) (const_int 0)))]
2777 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2778 (gtu:SI (cc0) (const_int 0)))]
2783 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
2784 (gtu:HI (cc0) (const_int 0)))]
2789 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
2790 (gtu:QI (cc0) (const_int 0)))]
2795 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2796 (lt:SI (cc0) (const_int 0)))]
2801 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
2802 (lt:HI (cc0) (const_int 0)))]
2807 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
2808 (lt:QI (cc0) (const_int 0)))]
2813 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2814 (ltu:SI (cc0) (const_int 0)))]
2819 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
2820 (ltu:HI (cc0) (const_int 0)))]
2825 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
2826 (ltu:QI (cc0) (const_int 0)))]
2831 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2832 (ge:SI (cc0) (const_int 0)))]
2837 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
2838 (ge:HI (cc0) (const_int 0)))]
2843 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
2844 (ge:QI (cc0) (const_int 0)))]
2849 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2850 (geu:SI (cc0) (const_int 0)))]
2855 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
2856 (geu:HI (cc0) (const_int 0)))]
2861 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
2862 (geu:QI (cc0) (const_int 0)))]
2867 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2868 (le:SI (cc0) (const_int 0)))]
2873 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
2874 (le:HI (cc0) (const_int 0)))]
2879 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
2880 (le:QI (cc0) (const_int 0)))]
2885 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm<")
2886 (leu:SI (cc0) (const_int 0)))]
2891 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm<")
2892 (leu:HI (cc0) (const_int 0)))]
2897 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm<")
2898 (leu:QI (cc0) (const_int 0)))]
2905 [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
2907 (plus:SI (ffs:SI (zero_extract:SI
2908 (match_operand:SI 1 "general_operand" "g")
2909 (minus:SI (const_int 32) (match_dup 0))
2914 "ffsd %1,%0; bfc 1f; addqd %$-1,%0; 1:")
2916 (define_expand "ffssi2"
2917 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") (const_int 0))
2920 (plus:SI (ffs:SI (zero_extract:SI
2921 (match_operand:SI 1 "general_operand" "g")
2922 (minus:SI (const_int 32) (match_dup 0))
2927 (plus:SI (match_dup 0)
2930 "operands[1] = make_safe_from(operands[1], operands[0]);")
2932 ;; Speed up stack adjust followed by a HI fixedpoint push.
2935 [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int -2)))
2936 (set (match_operand:HI 0 "push_operand" "=m")
2937 (match_operand:HI 1 "general_operand" "g"))]
2938 "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
2941 if (GET_CODE (operands[1]) == CONST_INT)
2942 output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,tos\"),
2945 output_asm_insn (\"movzwd %1,tos\", operands);
2949 ;; Speed up stack adjust followed by a zero_extend:HI(QI) fixedpoint push.
2952 [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int -2)))
2953 (set (match_operand:HI 0 "push_operand" "=m")
2954 (zero_extend:HI (match_operand:QI 1 "general_operand" "g")))]
2955 "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
2958 if (GET_CODE (operands[1]) == CONST_INT)
2959 output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,tos\"),
2962 output_asm_insn (\"movzbd %1,tos\", operands);
2966 ;; Speed up stack adjust followed by a sign_extend:HI(QI) fixedpoint push.
2969 [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int -2)))
2970 (set (match_operand:HI 0 "push_operand" "=m")
2971 (sign_extend:HI (match_operand:QI 1 "general_operand" "g")))]
2972 "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
2975 if (GET_CODE (operands[1]) == CONST_INT)
2976 output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,tos\"),
2979 output_asm_insn (\"movxbd %1,tos\", operands);
2983 ;; Speed up stack adjust followed by a QI fixedpoint push.
2986 [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int -3)))
2987 (set (match_operand:QI 0 "push_operand" "=m")
2988 (match_operand:QI 1 "general_operand" "g"))]
2989 "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
2992 if (GET_CODE (operands[1]) == CONST_INT)
2993 output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,tos\"),
2996 output_asm_insn (\"movzbd %1,tos\", operands);
3000 ;; Speed up stack adjust followed by a SI fixedpoint push.
3003 [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int 4)))
3004 (set (match_operand:SI 0 "push_operand" "=m")
3005 (match_operand:SI 1 "general_operand" "g"))]
3006 "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
3009 if (GET_CODE (operands[1]) == CONST_INT)
3010 output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,0(sp)\"),
3012 else if (GET_CODE (operands[1]) != REG
3013 && GET_CODE (operands[1]) != MEM
3014 && address_operand (operands[1], SImode))
3015 output_asm_insn (\"addr %a1,0(sp)\", operands);
3017 output_asm_insn (\"movd %1,0(sp)\", operands);
3021 ;; Speed up stack adjust followed by two fullword fixedpoint pushes.
3024 [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int 8)))
3025 (set (match_operand:SI 0 "push_operand" "=m")
3026 (match_operand:SI 1 "general_operand" "g"))
3027 (set (match_operand:SI 2 "push_operand" "=m")
3028 (match_operand:SI 3 "general_operand" "g"))]
3029 "! reg_mentioned_p (stack_pointer_rtx, operands[1])
3030 && ! reg_mentioned_p (stack_pointer_rtx, operands[3])"
3033 if (GET_CODE (operands[1]) == CONST_INT)
3034 output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,4(sp)\"),
3036 else if (GET_CODE (operands[1]) != REG
3037 && GET_CODE (operands[1]) != MEM
3038 && address_operand (operands[1], SImode))
3039 output_asm_insn (\"addr %a1,4(sp)\", operands);
3041 output_asm_insn (\"movd %1,4(sp)\", operands);
3043 if (GET_CODE (operands[3]) == CONST_INT)
3044 output_asm_insn (output_move_dconst (INTVAL (operands[3]), \"%3,0(sp)\"),
3046 else if (GET_CODE (operands[3]) != REG
3047 && GET_CODE (operands[3]) != MEM
3048 && address_operand (operands[3], SImode))
3049 output_asm_insn (\"addr %a3,0(sp)\", operands);
3051 output_asm_insn (\"movd %3,0(sp)\", operands);