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