1750a.md, [...]: Use GEN_INT consistently.
[gcc.git] / gcc / config / gmicro / gmicro.md
1 ;;- Machine description for GNU compiler, Fujitsu Gmicro Version
2 ;; Copyright (C) 1990, 1994, 1996 Free Software Foundation, Inc.
3 ;; Contributed by M.Yuhara, Fujitsu Laboratories LTD.
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 ;; Among other things, the copyright
17 ;; notice and this notice must be preserved on all copies.
18
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25
26 ;;- instruction definitions
27
28 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29
30 ;;- When naming insn's (operand 0 of define_insn) be careful about using
31 ;;- names from other targets machine descriptions.
32
33 ;;- cpp macro #define NOTICE_UPDATE_CC is essentially a no-op for the
34 ;;- gmicro; no compares are eliminated.
35
36 ;;- The original structure of this file is m68k.md.
37
38 ;; ??? Work to be done:
39 ;; Add patterns for ACB and SCB instructions.
40 ;; Add define_insn patterns to recognize the insns that extend a byte
41 ;; to a word and add it into a word, etc.
42
43 ;;- Some of these insn's are composites of several Gmicro op codes.
44 ;;- The assembler (or final @@??) insures that the appropriate one is
45 ;;- selected.
46 \f
47 (define_insn ""
48 [(set (match_operand:DF 0 "push_operand" "=m")
49 (match_operand:DF 1 "general_operand" "rmfF"))]
50 ""
51 "*
52 {
53 if (FPU_REG_P (operands[1]))
54 return \"fmov.d %f1,%0\";
55 return output_move_double (operands);
56 }")
57
58 (define_insn ""
59 [(set (match_operand:DI 0 "push_operand" "=m")
60 (match_operand:DF 1 "general_operand" "rmF"))]
61 ""
62 "*
63 {
64 return output_move_double (operands);
65 }")
66 \f
67 ;; We don't want to allow a constant operand for test insns because
68 ;; (set (cc0) (const_int foo)) has no mode information. Such insns will
69 ;; be folded while optimizing anyway.
70
71 (define_insn "tstsi"
72 [(set (cc0)
73 (match_operand:SI 0 "nonimmediate_operand" "rm"))]
74 ""
75 "cmp:z.w #0,%0")
76
77 (define_insn "tsthi"
78 [(set (cc0)
79 (match_operand:HI 0 "nonimmediate_operand" "rm"))]
80 ""
81 "cmp:z.h #0,%0")
82
83 (define_insn "tstqi"
84 [(set (cc0)
85 (match_operand:QI 0 "nonimmediate_operand" "rm"))]
86 ""
87 "cmp:z.b #0,%0")
88
89
90 (define_insn "tstsf"
91 [(set (cc0)
92 (match_operand:SF 0 "general_operand" "fmF"))]
93 "TARGET_FPU"
94 "*
95 {
96 cc_status.flags = CC_IN_FPU;
97 return \"ftst.s %0\";
98 }")
99
100
101 (define_insn "tstdf"
102 [(set (cc0)
103 (match_operand:DF 0 "general_operand" "fmF"))]
104 "TARGET_FPU"
105 "*
106 {
107 cc_status.flags = CC_IN_FPU;
108 return \"ftst.d %0\";
109 }")
110 \f
111 ;; compare instructions.
112
113 ;; (operand0 - operand1)
114 (define_insn "cmpsi"
115 [(set (cc0)
116 (compare (match_operand:SI 0 "nonimmediate_operand" "ri,rm")
117 (match_operand:SI 1 "general_operand" "rm,rmi")))]
118 ""
119 "*
120 {
121 int signed_flag = my_signed_comp (insn);
122
123 if (which_alternative == 0)
124 {
125 cc_status.flags |= CC_REVERSED;
126 if (signed_flag && GET_CODE (operands[0]) == CONST_INT)
127 {
128 register rtx xfoo;
129 xfoo = operands[1];
130 operands[0] = operands[1];
131 operands[1] = xfoo;
132 return cmp_imm_word (INTVAL (operands[1]), operands[0]);
133 }
134 if (signed_flag)
135 return \"cmp.w %0,%1\";
136 return \"cmpu.w %0,%1\";
137 }
138 if (signed_flag)
139 {
140 if (GET_CODE (operands[1]) == CONST_INT)
141 return cmp_imm_word (INTVAL (operands[1]), operands[0]);
142 return \"cmp.w %1,%0\";
143 }
144 else
145 return \"cmpu.w %1,%0\";
146 }")
147
148 (define_insn "cmphi"
149 [(set (cc0)
150 (compare (match_operand:HI 0 "nonimmediate_operand" "ri,rm")
151 (match_operand:HI 1 "general_operand" "rm,rmi")))]
152 ""
153 "*
154 {
155 int signed_flag = my_signed_comp (insn);
156
157 if (which_alternative == 0)
158 {
159 cc_status.flags |= CC_REVERSED;
160 if (signed_flag)
161 return \"cmp.h %0,%1\";
162 return \"cmpu.h %0,%1\";
163 }
164 if (signed_flag)
165 return \"cmp.h %1,%0\";
166 return \"cmpu.h %1,%0\";
167 }")
168
169 (define_insn "cmpqi"
170 [(set (cc0)
171 (compare (match_operand:QI 0 "nonimmediate_operand" "ri,rm")
172 (match_operand:QI 1 "general_operand" "rm,rmi")))]
173 ""
174 "*
175 {
176 int signed_flag = my_signed_comp (insn);
177
178 if (which_alternative == 0)
179 {
180 cc_status.flags |= CC_REVERSED;
181 if (signed_flag)
182 return \"cmp.b %0,%1\";
183 return \"cmpu.b %0,%1\";
184 }
185 if (signed_flag)
186 return \"cmp.b %1,%0\";
187 return \"cmpu.b %1,%0\";
188 }")
189
190
191 (define_insn "cmpdf"
192 [(set (cc0)
193 (compare (match_operand:DF 0 "general_operand" "f,mG")
194 (match_operand:DF 1 "general_operand" "fmG,f")))]
195 "TARGET_FPU"
196 "*
197 {
198 cc_status.flags = CC_IN_FPU;
199
200 if (FPU_REG_P (operands[0]))
201 return \"fcmp.d %f1,%f0\";
202 cc_status.flags |= CC_REVERSED;
203 return \"fcmp.d %f0,%f1\";
204 }")
205
206
207 (define_insn "cmpsf"
208 [(set (cc0)
209 (compare (match_operand:SF 0 "general_operand" "f,mG")
210 (match_operand:SF 1 "general_operand" "fmG,f")))]
211 "TARGET_FPU"
212 "*
213 {
214 cc_status.flags = CC_IN_FPU;
215 if (FPU_REG_P (operands[0]))
216 return \"fcmp.s %f1,%0\";
217 cc_status.flags |= CC_REVERSED;
218 return \"fcmp.s %f0,%1\";
219 }")
220 \f
221 ;; Recognizers for btst instructions.
222
223 (define_insn ""
224 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
225 (const_int 1)
226 (match_operand:SI 1 "general_operand" "rmi")))]
227 ""
228 "btst %1.w,%0.b")
229
230 (define_insn ""
231 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "rm")
232 (const_int 1)
233 (match_operand:SI 1 "general_operand" "rmi")))]
234 ""
235 "btst %1.w,%0.w")
236
237 ;; The following two patterns are like the previous two
238 ;; except that they use the fact that bit-number operands (offset)
239 ;; are automatically masked to 3 or 5 bits when the base is a register.
240
241 (define_insn ""
242 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
243 (const_int 1)
244 (and:SI
245 (match_operand:SI 1 "general_operand" "rmi")
246 (const_int 7))))]
247 ""
248 "btst %1.w,%0.b")
249
250 (define_insn ""
251 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
252 (const_int 1)
253 (and:SI
254 (match_operand:SI 1 "general_operand" "rmi")
255 (const_int 31))))]
256 ""
257 "btst %1.w,%0.w")
258
259 ; More various size-patterns are allowed for btst, but not
260 ; included yet. M.Yuhara
261
262
263 (define_insn ""
264 [(set (cc0) (and:SI (sign_extend:SI
265 (sign_extend:HI
266 (match_operand:QI 0 "nonimmediate_operand" "rm")))
267 (match_operand:SI 1 "general_operand" "i")))]
268 "(GET_CODE (operands[1]) == CONST_INT
269 && (unsigned) INTVAL (operands[1]) < 0x100
270 && exact_log2 (INTVAL (operands[1])) >= 0)"
271 "*
272 {
273 register int log = exact_log2 (INTVAL (operands[1]));
274 operands[1] = GEN_INT (log);
275 return \"btst %1,%0.b\";
276 }")
277
278 ; I can add more patterns like above. But not yet. M.Yuhara
279
280
281 ; mtst is supported only by G/300.
282
283 (define_insn ""
284 [(set (cc0)
285 (and:SI (match_operand:SI 0 "general_operand" "%rmi")
286 (match_operand:SI 1 "general_operand" "rm")))]
287 "TARGET_G300"
288 "*
289 {
290 if (GET_CODE (operands[0]) == CONST_INT)
291 return \"mtst.w %0,%1\";
292 return \"mtst.w %1,%0\";
293 }")
294
295 (define_insn ""
296 [(set (cc0)
297 (and:HI (match_operand:HI 0 "general_operand" "%rmi")
298 (match_operand:HI 1 "general_operand" "rm")))]
299 "TARGET_G300"
300 "*
301 {
302 if (GET_CODE (operands[0]) == CONST_INT)
303 return \"mtst.h %0,%1\";
304 return \"mtst.h %1,%0\";
305 }")
306
307 (define_insn ""
308 [(set (cc0)
309 (and:QI (match_operand:QI 0 "general_operand" "%rmi")
310 (match_operand:QI 1 "general_operand" "rm")))]
311 "TARGET_G300"
312 "*
313 {
314 if (GET_CODE (operands[0]) == CONST_INT)
315 return \"mtst.b %0,%1\";
316 return \"mtst.b %1,%0\";
317 }")
318
319
320 \f
321 ;; move instructions
322
323 /* added by M.Yuhara */
324 ;; 1.35.04 89.08.28 modification start
325 ;; register_operand -> general_operand
326 ;; ashift -> mult
327
328 (define_insn ""
329 [(set (mem:SI (plus:SI
330 (match_operand:SI 0 "general_operand" "r")
331 (ashift:SI
332 (match_operand:SI 1 "general_operand" "r")
333 (const_int 2))))
334 (match_operand:SI 2 "general_operand" "rmi"))]
335 ""
336 "*
337 {
338 return \"mov.w %2,@(%0:b,%1*4)\";
339 }")
340
341 (define_insn ""
342 [(set (mem:SI (plus:SI
343 (ashift:SI
344 (match_operand:SI 0 "general_operand" "r")
345 (const_int 2))
346 (match_operand:SI 1 "general_operand" "r")))
347 (match_operand:SI 2 "general_operand" "rmi"))]
348 ""
349 "*
350 {
351 return \"mov.w %2,@(%1:b,%0*4)\";
352 }")
353
354
355 (define_insn ""
356 [(set (mem:SI (plus:SI
357 (match_operand:SI 0 "register_operand" "r")
358 (mult:SI
359 (match_operand:SI 1 "register_operand" "r")
360 (const_int 4))))
361 (match_operand:SI 2 "general_operand" "rmi"))]
362 ""
363 "*
364 {
365 return \"mov.w %2,@(%0:b,%1*4)\";
366 }")
367
368 (define_insn ""
369 [(set (mem:SI (plus:SI
370 (mult:SI
371 (match_operand:SI 0 "register_operand" "r")
372 (const_int 4))
373 (match_operand:SI 1 "register_operand" "r")))
374 (match_operand:SI 2 "general_operand" "rmi"))]
375 ""
376 "*
377 {
378 return \"mov.w %2,@(%1:b,%0*4)\";
379 }")
380
381
382 (define_insn ""
383 [(set (mem:SI (plus:SI
384 (match_operand:SI 0 "general_operand" "r")
385 (plus:SI
386 (match_operand:SI 1 "register_operand" "r")
387 (match_operand:SI 2 "register_operand" "i"))))
388 (match_operand:SI 3 "general_operand" "rmi"))]
389 ""
390 "*
391 {
392 return \"mov.w %3,@(%c2,%0,%1)\";
393 }")
394
395 (define_insn ""
396 [(set (mem:SI (plus:SI
397 (plus:SI
398 (match_operand:SI 0 "register_operand" "r")
399 (match_operand:SI 1 "register_operand" "r"))
400 (match_operand:SI 2 "general_operand" "i")))
401 (match_operand:SI 3 "general_operand" "rmi"))]
402 ""
403 "*
404 {
405 return \"mov.w %3,@(%c2,%0,%1)\";
406 }")
407
408
409 (define_insn ""
410 [(set (mem:SI (plus:SI
411 (match_operand:SI 0 "general_operand" "i")
412 (plus:SI
413 (match_operand:SI 1 "register_operand" "r")
414 (mult:SI
415 (match_operand:SI 2 "register_operand" "r")
416 (const_int 4)))))
417 (match_operand:SI 3 "general_operand" "rmi"))]
418 ""
419 "*
420 {
421 return \"mov.w %3,@(%1:b,%0,%2*4)\";
422 }")
423
424 ;; 89.08.28 1.35.04 modification end
425
426 ;; Should add "!" to op2 ??
427
428 ;; General move-address-to-operand should handle these.
429 ;; If that does not work, please figure out why.
430
431 ;(define_insn ""
432 ; [(set (match_operand:SI 0 "push_operand" "=m")
433 ; (plus:SI
434 ; (match_operand:SI 1 "immediate_operand" "i")
435 ; (match_operand:SI 2 "general_operand" "r")))]
436 ; ""
437 ; "mova.w @(%c1,%2),%-")
438
439 ;(define_insn ""
440 ; [(set (match_operand:SI 0 "push_operand" "=m")
441 ; (plus:SI
442 ; (match_operand:SI 1 "general_operand" "r")
443 ; (match_operand:SI 2 "immediate_operand" "i")))]
444 ; ""
445 ; "mova.w @(%c2,%1),%-")
446
447
448 (define_insn ""
449 [(set (match_operand:SI 0 "push_operand" "=m")
450 (minus:SI
451 (match_operand:SI 1 "general_operand" "r")
452 (match_operand:SI 2 "immediate_operand" "i")))]
453 ""
454 "mova.w @(%n2,%1),%-")
455
456
457
458 ;; General case of fullword move.
459
460 (define_insn "movsi"
461 [(set (match_operand:SI 0 "general_operand" "=rm")
462 (match_operand:SI 1 "general_operand" "rmi"))]
463 ""
464 "*
465 {
466 if (GET_CODE (operands[1]) == CONST_INT)
467 return mov_imm_word (INTVAL (operands[1]), operands[0]);
468 /* if (address_operand (operands[1], SImode))
469 return \"mova.w %1,%0\"; */
470 if (push_operand (operands[0], SImode))
471 return \"mov.w %1,%-\";
472 return \"mov.w %1,%0\";
473 }")
474
475 /* pushsi 89.08.10 for test M.Yuhara */
476 /*
477 (define_insn ""
478 [(set (match_operand:SI 0 "push_operand" "=m")
479 (match_operand:SI 1 "general_operand" "rmi"))]
480 ""
481 "*
482 {
483 if (GET_CODE (operands[1]) == CONST_INT)
484 return mov_imm_word (INTVAL (operands[1]), operands[0]);
485 if (push_operand (operands[0], SImode))
486 return \"mov.w %1,%-\";
487 return \"mov.w %1,%0\";
488 }")
489 */
490
491
492 (define_insn "movhi"
493 [(set (match_operand:HI 0 "general_operand" "=rm")
494 (match_operand:HI 1 "general_operand" "rmi"))]
495 ""
496 "*
497 {
498 if (push_operand (operands[0], SImode))
499 return \"mov.h %1,%-\";
500 return \"mov.h %1,%0\";
501 }")
502
503 ;; Is the operand constraint "+" necessary ????
504 ;; Should I check push_operand ????
505
506 (define_insn "movstricthi"
507 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+rm"))
508 (match_operand:HI 1 "general_operand" "rmi"))]
509 ""
510 "mov.h %1,%0");
511
512 (define_insn "movqi"
513 [(set (match_operand:QI 0 "general_operand" "=rm")
514 (match_operand:QI 1 "general_operand" "rmi"))]
515 ""
516 "*
517 {
518 if (GREG_P (operands[0]))
519 {
520 if (CONSTANT_P (operands[1]))
521 return \"mov:l %1,%0.w\";
522 else
523 return \"mov:l %1.b,%0.w\";
524 }
525 if (GREG_P (operands[1]))
526 return \"mov:s %1.w,%0.b\";
527 return \"mov.b %1,%0\";
528 }")
529
530 (define_insn "movstrictqi"
531 [(set (strict_low_part (match_operand:QI 0 "general_operand" "+rm"))
532 (match_operand:QI 1 "general_operand" "rmi"))]
533 ""
534 "mov.b %1,%0")
535
536
537 (define_insn "movsf"
538 [(set (match_operand:SF 0 "general_operand" "=f,mf,rm,fr")
539 (match_operand:SF 1 "general_operand" "mfF,f,rmF,fr"))]
540 ""
541 "*
542 {
543 switch (which_alternative)
544 {
545 case 0:
546 if (GET_CODE (operands[1]) == CONST_DOUBLE)
547 return output_move_const_single (operands);
548 return \"fmov.s %1,%0\";
549 case 1:
550 return \"fmov.s %1,%0\";
551 case 2:
552 if (GET_CODE (operands[1]) == CONST_DOUBLE)
553 return output_move_const_single (operands);
554 return \"mov.w %1,%0\";
555 case 3:
556 if (FPU_REG_P (operands[0]))
557 return \"mov.w %1,%-\\n\\tfmov.s %+,%0\";
558 return \"fmov.s %1,%-\\n\\tmov.w %+,%0\";
559 }
560 }")
561
562 (define_insn "movdf"
563 [(set (match_operand:DF 0 "general_operand" "=f,mf,rm,fr")
564 (match_operand:DF 1 "general_operand" "mfF,f,rmF,fr"))]
565 ""
566 "*
567 {
568 switch (which_alternative)
569 {
570 case 0:
571 if (GET_CODE (operands[1]) == CONST_DOUBLE)
572 return output_move_const_double (operands);
573 return \"fmov.d %1,%0\";
574 case 1:
575 return \"fmov.d %1,%0\";
576 case 2:
577 if (GET_CODE (operands[1]) == CONST_DOUBLE)
578 return output_move_const_double (operands);
579 return output_move_double (operands);
580 case 3:
581 if (FPU_REG_P (operands[0]))
582 {
583 rtx xoperands[2];
584 xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
585 output_asm_insn (\"mov.w %1,%-\", xoperands);
586 output_asm_insn (\"mov.w %1,%-\", operands);
587 return \"fmov.d %+,%0\";
588 }
589 else
590 {
591 output_asm_insn (\"fmov.d %f1,%-\", operands);
592 output_asm_insn (\"mov.w %+,%0\", operands);
593 operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
594 return \"mov.w %+,%0\";
595 }
596 }
597 }")
598
599
600 ;; movdi can apply to fp regs in some cases
601 ;; Must check again. you can use fsti/fldi, etc.
602 ;; FPU reg should be included ??
603 ;; 89.12.13 for test
604
605 (define_insn "movdi"
606 ;; Let's see if it really still needs to handle fp regs, and, if so, why.
607 [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro")
608 (match_operand:DI 1 "general_operand" "rF,m,roiF"))]
609 ""
610 "*
611 {
612 if (FPU_REG_P (operands[0]))
613 {
614 if (FPU_REG_P (operands[1]))
615 return \"fmov.d %1,%0\";
616 if (REG_P (operands[1]))
617 {
618 rtx xoperands[2];
619 xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
620 output_asm_insn (\"mov.w %1,%-\", xoperands);
621 output_asm_insn (\"mov.w %1,%-\", operands);
622 return \"fmov.d %+,%0\";
623 }
624 if (GET_CODE (operands[1]) == CONST_DOUBLE)
625 return output_move_const_double (operands);
626 return \"fmov.d %f1,%0\";
627 }
628 else if (FPU_REG_P (operands[1]))
629 {
630 if (REG_P (operands[0]))
631 {
632 output_asm_insn (\"fmov.d %f1,%-\;mov.w %+,%0\", operands);
633 operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
634 return \"mov.w %+,%0\";
635 }
636 else
637 return \"fmov.d %f1,%0\";
638 }
639 return output_move_double (operands);
640 }
641 ")
642
643
644 ;; The definition of this insn does not really explain what it does,
645 ;; but it should suffice
646 ;; that anything generated as this insn will be recognized as one
647 ;; and that it won't successfully combine with anything.
648
649 ;; This is dangerous when %0 and %1 overlapped !!!!!
650 ;; Ugly code...
651
652 (define_insn "movstrhi"
653 [(set (match_operand:BLK 0 "general_operand" "=m")
654 (match_operand:BLK 1 "general_operand" "m"))
655 (use (match_operand:HI 2 "general_operand" "rmi"))
656 (clobber (reg:SI 0))
657 (clobber (reg:SI 1))
658 (clobber (reg:SI 2))]
659 ""
660 "*
661 {
662 int op2const;
663 rtx tmpx;
664
665 if (CONSTANT_P (operands[1]))
666 {
667 fprintf (stderr, \"smov 1 const err \");
668 abort ();
669 }
670 else if (GET_CODE (operands[1]) == REG)
671 {
672 fprintf (stderr, \"smov 1 reg err \");
673 abort ();
674 }
675 else if (GET_CODE (operands[1]) == MEM)
676 {
677 tmpx = XEXP (operands[1], 0);
678 if (CONSTANT_ADDRESS_P (tmpx) || GREG_P (tmpx))
679 {
680 operands[1] = tmpx;
681 output_asm_insn (\"mov.w %1,r0\", operands);
682 }
683 else
684 {
685 output_asm_insn (\"mova %1,r0\", operands);
686 }
687 }
688 else
689 {
690 fprintf (stderr, \"smov 1 else err \");
691 abort ();
692 output_asm_insn (\"mova.w %p1,r0\", operands);
693 }
694
695 if (CONSTANT_P (operands[0]))
696 {
697 fprintf (stderr, \"smov 0 const err \");
698 abort ();
699 }
700 else if (GET_CODE (operands[0]) == REG)
701 {
702 fprintf (stderr, \"smov 0 reg err \");
703 abort ();
704 }
705 else if (GET_CODE (operands[0]) == MEM)
706 {
707 tmpx = XEXP (operands[0], 0);
708 if (CONSTANT_ADDRESS_P (tmpx) || GREG_P (tmpx))
709 {
710 operands[0] = tmpx;
711 output_asm_insn (\"mov.w %0,r1\", operands);
712 }
713 else
714 {
715 output_asm_insn (\"mova %0,r1\", operands);
716 }
717 }
718 else
719 {
720 fprintf (stderr, \"smov 0 else err \");
721 abort ();
722 }
723
724 if (GET_CODE (operands[2]) == CONST_INT)
725 {
726 op2const = INTVAL (operands[2]);
727 if (op2const % 4 != 0)
728 {
729 output_asm_insn (\"mov.w %2,r2\", operands);
730 return \"smov/n/f.b\";
731 }
732 op2const = op2const / 4;
733 if (op2const <= 4)
734 {
735 if (op2const == 0)
736 abort (0);
737 if (op2const == 1)
738 return \"mov.w @r0,@r1\";
739 output_asm_insn (\"mov.w @r0,@r1\", operands);
740 if (op2const == 2)
741 return \"mov.w @(4,r0),@(4,r1)\";
742 output_asm_insn (\"mov.w @(4,r0),@(4,r1)\", operands);
743 if (op2const == 3)
744 return \"mov.w @(8,r0),@(8,r1)\";
745 output_asm_insn (\"mov.w @(8,r0),@(8,r1)\", operands);
746 return \"mov.w @(12,r0),@(12,r1)\";
747 }
748
749 operands[2] = GEN_INT (op2const);
750 output_asm_insn (\"mov.w %2,r2\", operands);
751 return \"smov/n/f.w\";
752 }
753 else
754 {
755 fprintf (stderr, \"smov 0 else err \");
756 abort ();
757 output_asm_insn (\"mov %2.h,r2.w\", operands);
758 return \"smov/n/f.b\";
759 }
760
761 }")
762 \f
763 ;; M.Yuhara 89.08.24
764 ;; experiment on the built-in strcpy (__builtin_smov)
765 ;;
766 ;; len = 0 means unknown string length.
767 ;;
768 ;; mem:SI is dummy. Necessary so as not to be deleted by optimization.
769 ;; Use of BLKmode would be better...
770 ;;
771 ;;
772 (define_insn "smovsi"
773 [(set (mem:SI (match_operand:SI 0 "general_operand" "=rm"))
774 (mem:SI (match_operand:SI 1 "general_operand" "rm")))
775 (use (match_operand:SI 2 "general_operand" "i"))
776 (clobber (reg:SI 0))
777 (clobber (reg:SI 1))
778 (clobber (reg:SI 2))
779 (clobber (reg:SI 3))]
780 ""
781 "*
782 {
783 int len, wlen, blen, offset;
784 char tmpstr[128];
785 rtx xoperands[1];
786
787 len = INTVAL (operands[2]);
788 output_asm_insn (\"mov.w %1,r0\\t; begin built-in strcpy\", operands);
789 output_asm_insn (\"mov.w %0,r1\", operands);
790
791 if (len == 0)
792 {
793 output_asm_insn (\"mov:z.w #0,r2\", operands);
794 output_asm_insn (\"mov:z.w #0,r3\", operands);
795 return \"smov/eq/f.b\\t; end built-in strcpy\";
796 }
797
798 wlen = len / 4;
799 blen = len - wlen * 4;
800
801 if (wlen > 0)
802 {
803 if (len <= 40 && !TARGET_FORCE_SMOV)
804 {
805 output_asm_insn (\"mov.w @r0,@r1\", operands);
806 offset = 4;
807 while ( (blen = len - offset) > 0)
808 {
809 if (blen >= 4)
810 {
811 sprintf (tmpstr, \"mov.w @(%d,r0),@(%d,r1)\",
812 offset, offset);
813 output_asm_insn (tmpstr, operands);
814 offset += 4;
815 }
816 else if (blen >= 2)
817 {
818 sprintf (tmpstr, \"mov.h @(%d,r0),@(%d,r1)\",
819 offset, offset);
820 output_asm_insn (tmpstr, operands);
821 offset += 2;
822 }
823 else
824 {
825 sprintf (tmpstr, \"mov.b @(%d,r0),@(%d,r1)\",
826 offset, offset);
827 output_asm_insn (tmpstr, operands);
828 offset++;
829 }
830 }
831 return \"\\t\\t; end built-in strcpy\";
832 }
833 else
834 {
835 xoperands[0] = GEN_INT (wlen);
836 output_asm_insn (\"mov.w %0,r2\", xoperands);
837 output_asm_insn (\"smov/n/f.w\", operands);
838 }
839 }
840
841 if (blen >= 2)
842 {
843 output_asm_insn (\"mov.h @r0,@r1\", operands);
844 if (blen == 3)
845 output_asm_insn (\"mov.b @(2,r0),@(2,r1)\", operands);
846 }
847 else if (blen == 1)
848 {
849 output_asm_insn (\"mov.b @r0,@r1\", operands);
850 }
851
852 return \"\\t\\t; end built-in strcpy\";
853 }")
854 \f
855 ;; truncation instructions
856 (define_insn "truncsiqi2"
857 [(set (match_operand:QI 0 "general_operand" "=rm")
858 (truncate:QI
859 (match_operand:SI 1 "general_operand" "rmi")))]
860 ""
861 "mov %1.w,%0.b")
862 ; "*
863 ;{
864 ; if (GET_CODE (operands[0]) == REG)
865 ; return \"mov.w %1,%0\";
866 ; if (GET_CODE (operands[1]) == MEM)
867 ; operands[1] = adj_offsettable_operand (operands[1], 3);
868 ; return \"mov.b %1,%0\";
869 ;}")
870
871 (define_insn "trunchiqi2"
872 [(set (match_operand:QI 0 "general_operand" "=rm")
873 (truncate:QI
874 (match_operand:HI 1 "general_operand" "rmi")))]
875 ""
876 "mov %1.h,%0.b")
877 ; "*
878 ;{
879 ; if (GET_CODE (operands[0]) == REG)
880 ; return \"mov.h %1,%0\";
881 ; if (GET_CODE (operands[1]) == MEM)
882 ; operands[1] = adj_offsettable_operand (operands[1], 1);
883 ; return \"mov.b %1,%0\";
884 ;}")
885
886 (define_insn "truncsihi2"
887 [(set (match_operand:HI 0 "general_operand" "=rm")
888 (truncate:HI
889 (match_operand:SI 1 "general_operand" "rmi")))]
890 ""
891 "mov %1.w,%0.h")
892 ; "*
893 ;{
894 ; if (GET_CODE (operands[0]) == REG)
895 ; return \"mov.w %1,%0\";
896 ; if (GET_CODE (operands[1]) == MEM)
897 ; operands[1] = adj_offsettable_operand (operands[1], 2);
898 ; return \"mov.h %1,%0\";
899 ;}")
900 \f
901 ;; zero extension instructions
902 ;; define_expand (68k) -> define_insn (Gmicro)
903
904 (define_insn "zero_extendhisi2"
905 [(set (match_operand:SI 0 "general_operand" "=rm")
906 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
907 ""
908 "movu %1.h,%0.w")
909
910
911 (define_insn "zero_extendqihi2"
912 [(set (match_operand:HI 0 "general_operand" "=rm")
913 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
914 ""
915 "movu %1.b,%0.h")
916
917 (define_insn "zero_extendqisi2"
918 [(set (match_operand:SI 0 "general_operand" "=rm")
919 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
920 ""
921 "movu %1.b,%0.w")
922
923 \f
924 ;; sign extension instructions
925
926 (define_insn "extendhisi2"
927 [(set (match_operand:SI 0 "general_operand" "=rm")
928 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
929 ""
930 "mov %1.h,%0.w")
931
932
933 (define_insn "extendqihi2"
934 [(set (match_operand:HI 0 "general_operand" "=rm")
935 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
936 ""
937 "mov %1.b,%0.h")
938
939 (define_insn "extendqisi2"
940 [(set (match_operand:SI 0 "general_operand" "=rm")
941 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
942 ""
943 "mov %1.b,%0.w")
944
945
946 \f
947 ;; Conversions between float and double.
948
949 (define_insn "extendsfdf2"
950 [(set (match_operand:DF 0 "general_operand" "=*frm,f")
951 (float_extend:DF
952 (match_operand:SF 1 "general_operand" "f,rmF")))]
953 "TARGET_FPU"
954 "*
955 {
956 if (FPU_REG_P (operands[0]))
957 {
958 if (GET_CODE (operands[1]) == CONST_DOUBLE)
959 return output_move_const_double (operands);
960 if (GREG_P (operands[1]))
961 {
962 output_asm_insn (\"mov.w %1,%-\", operands);
963 return \"fmov %+.s,%0.d\";
964 }
965 return \"fmov %1.s,%0.d\";
966 }
967 else
968 {
969 if (GREG_P (operands[0]))
970 {
971 output_asm_insn (\"fmov %1.s,%-.d\", operands);
972 output_asm_insn (\"mov.w %+,%0\", operands);
973 operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
974 return \"mov.w %+,%0\";
975 }
976 return \"fmov %1.s,%0.d\";
977 }
978 }")
979
980
981 (define_insn "truncdfsf2"
982 [(set (match_operand:SF 0 "general_operand" "=rfm")
983 (float_truncate:SF
984 (match_operand:DF 1 "general_operand" "f")))]
985 "TARGET_FPU"
986 "*
987 {
988 if (GREG_P (operands[0]))
989 {
990 output_asm_insn (\"fmov %1.d,%-.s\", operands);
991 return \"mov.w %+,%0\";
992 }
993 return \"fmov %1.d,%0.s\";
994 }")
995 \f
996 ;; Conversion between fixed point and floating point.
997 ;; Note that among the fix-to-float insns
998 ;; the ones that start with SImode come first.
999 ;; That is so that an operand that is a CONST_INT
1000 ;; (and therefore lacks a specific machine mode).
1001 ;; will be recognized as SImode (which is always valid)
1002 ;; rather than as QImode or HImode.
1003
1004
1005 (define_insn "floatsisf2"
1006 [(set (match_operand:SF 0 "general_operand" "=f")
1007 (float:SF (match_operand:SI 1 "general_operand" "rmi")))]
1008 "TARGET_FPU"
1009 "fldi %1.w,%0.s")
1010
1011 (define_insn "floatsidf2"
1012 [(set (match_operand:DF 0 "general_operand" "=f")
1013 (float:DF (match_operand:SI 1 "general_operand" "rmi")))]
1014 "TARGET_FPU"
1015 "fldi %1.w,%0.d")
1016
1017 (define_insn "floathisf2"
1018 [(set (match_operand:SF 0 "general_operand" "=f")
1019 (float:SF (match_operand:HI 1 "general_operand" "rmi")))]
1020 "TARGET_FPU"
1021 "fldi %1.h,%0.s")
1022
1023 (define_insn "floathidf2"
1024 [(set (match_operand:DF 0 "general_operand" "=f")
1025 (float:DF (match_operand:HI 1 "general_operand" "rmi")))]
1026 "TARGET_FPU"
1027 "fldi %1.h,%0.d")
1028
1029 (define_insn "floatqisf2"
1030 [(set (match_operand:SF 0 "general_operand" "=f")
1031 (float:SF (match_operand:QI 1 "general_operand" "rmi")))]
1032 "TARGET_FPU"
1033 "fldi %1.b,%0.s")
1034
1035 (define_insn "floatqidf2"
1036 [(set (match_operand:DF 0 "general_operand" "=f")
1037 (float:DF (match_operand:QI 1 "general_operand" "rmi")))]
1038 "TARGET_FPU"
1039 "fldi %1.b,%0.d")
1040
1041 ;;; Convert a float to a float whose value is an integer.
1042 ;;; This is the first stage of converting it to an integer type.
1043 ;
1044 ;(define_insn "ftruncdf2"
1045 ; [(set (match_operand:DF 0 "general_operand" "=f")
1046 ; (fix:DF (match_operand:DF 1 "general_operand" "fFm")))]
1047 ; "TARGET_FPU"
1048 ; "*
1049 ;{
1050 ; return \"fintrz.d %f1,%0\";
1051 ;}")
1052 ;
1053 ;(define_insn "ftruncsf2"
1054 ; [(set (match_operand:SF 0 "general_operand" "=f")
1055 ; (fix:SF (match_operand:SF 1 "general_operand" "fFm")))]
1056 ; "TARGET_FPU"
1057 ; "*
1058 ;{
1059 ; return \"fintrz.s %f1,%0\";
1060 ;}")
1061
1062 ;; Convert a float to an integer.
1063
1064 (define_insn "fix_truncsfqi2"
1065 [(set (match_operand:QI 0 "general_operand" "=rm")
1066 (fix:QI (fix:SF (match_operand:SF 1 "general_operand" "f"))))]
1067 "TARGET_FPU"
1068 "fsti %1.s,%0.b")
1069
1070 (define_insn "fix_truncsfhi2"
1071 [(set (match_operand:HI 0 "general_operand" "=rm")
1072 (fix:HI (fix:SF (match_operand:SF 1 "general_operand" "f"))))]
1073 "TARGET_FPU"
1074 "fsti %1.s,%0.h")
1075
1076 (define_insn "fix_truncsfsi2"
1077 [(set (match_operand:SI 0 "general_operand" "=rm")
1078 (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "f"))))]
1079 "TARGET_FPU"
1080 "fsti %1.s,%0.w")
1081
1082 (define_insn "fix_truncdfqi2"
1083 [(set (match_operand:QI 0 "general_operand" "=rm")
1084 (fix:QI (fix:DF (match_operand:DF 1 "general_operand" "f"))))]
1085 "TARGET_FPU"
1086 "fsti %1.d,%0.b")
1087
1088 (define_insn "fix_truncdfhi2"
1089 [(set (match_operand:HI 0 "general_operand" "=rm")
1090 (fix:HI (fix:DF (match_operand:DF 1 "general_operand" "f"))))]
1091 "TARGET_FPU"
1092 "fsti %1.d,%0.h")
1093
1094 (define_insn "fix_truncdfsi2"
1095 [(set (match_operand:SI 0 "general_operand" "=rm")
1096 (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "f"))))]
1097 "TARGET_FPU"
1098 "fsti %1.d,%0.w")
1099
1100 \f
1101 ;;; Special add patterns
1102 ;;; 89.09.28
1103
1104 ;; This should be redundant; please find out why regular addsi3
1105 ;; fails to match this case.
1106
1107 ;(define_insn ""
1108 ; [(set (mem:SI (plus:SI
1109 ; (plus:SI (match_operand 0 "general_operand" "r")
1110 ; (match_operand 1 "general_operand" "r"))
1111 ; (match_operand 2 "general_operand" "i")))
1112 ; (plus:SI
1113 ; (mem:SI (plus:SI
1114 ; (plus:SI (match_dup 0)
1115 ; (match_dup 1))
1116 ; (match_dup 2)))
1117 ; (match_operand 3 "general_operand" "rmi")))]
1118 ; ""
1119 ; "add.w %3,@(%c2,%0,%1)")
1120
1121 \f
1122 ;; add instructions
1123
1124 ;; Note that the last two alternatives are near-duplicates
1125 ;; in order to handle insns generated by reload.
1126 ;; This is needed since they are not themselves reloaded,
1127 ;; so commutativity won't apply to them.
1128
1129 (define_insn "addsi3"
1130 [(set (match_operand:SI 0 "general_operand" "=rm,!r,!r")
1131 (plus:SI (match_operand:SI 1 "general_operand" "%0,r,ri")
1132 (match_operand:SI 2 "general_operand" "rmi,ri,r")))]
1133 ""
1134 "*
1135 {
1136 if (which_alternative == 0)
1137 {
1138 if (GET_CODE (operands[2]) == CONST_INT)
1139 {
1140 operands[1] = operands[2];
1141 return add_imm_word (INTVAL (operands[1]), operands[0], &operands[1]);
1142 }
1143 else
1144 return \"add.w %2,%0\";
1145 }
1146 else
1147 {
1148 if (GET_CODE (operands[1]) == REG
1149 && REGNO (operands[0]) == REGNO (operands[1]))
1150 return \"add.w %2,%0\";
1151 if (GET_CODE (operands[2]) == REG
1152 && REGNO (operands[0]) == REGNO (operands[2]))
1153 return \"add.w %1,%0\";
1154
1155 if (GET_CODE (operands[1]) == REG)
1156 {
1157 if (GET_CODE (operands[2]) == REG)
1158 return \"mova.w @(%1,%2),%0\";
1159 else
1160 return \"mova.w @(%c2,%1),%0\";
1161 }
1162 else
1163 return \"mova.w @(%c1,%2),%0\";
1164 }
1165 }")
1166
1167 (define_insn ""
1168 [(set (match_operand:SI 0 "general_operand" "=rm")
1169 (plus:SI (match_operand:SI 1 "general_operand" "0")
1170 (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rmi"))))]
1171 ""
1172 "*
1173 {
1174 if (CONSTANT_P (operands[2]))
1175 {
1176 operands[1] = operands[2];
1177 return add_imm_word (INTVAL (operands[1]), operands[0], &operands[1]);
1178 }
1179 else
1180 return \"add %2.h,%0.w\";
1181 }")
1182
1183 (define_insn "addhi3"
1184 [(set (match_operand:HI 0 "general_operand" "=rm")
1185 (plus:HI (match_operand:HI 1 "general_operand" "%0")
1186 (match_operand:HI 2 "general_operand" "rmi")))]
1187 ""
1188 "*
1189 {
1190 if (GET_CODE (operands[2]) == CONST_INT
1191 && INTVAL (operands[2]) < 0)
1192 return \"sub.h #%n2,%0\";
1193 if (GREG_P (operands[0]))
1194 {
1195 if (CONSTANT_P (operands[2]))
1196 return \"add:l %2,%0.w\";
1197 else
1198 return \"add:l %2.h,%0.w\";
1199 }
1200 return \"add.h %2,%0\";
1201 }")
1202
1203 (define_insn ""
1204 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+rm"))
1205 (plus:HI (match_dup 0)
1206 (match_operand:HI 1 "general_operand" "rmi")))]
1207 ""
1208 "add.h %1,%0")
1209
1210 (define_insn "addqi3"
1211 [(set (match_operand:QI 0 "general_operand" "=rm")
1212 (plus:QI (match_operand:QI 1 "general_operand" "%0")
1213 (match_operand:QI 2 "general_operand" "rmi")))]
1214 ""
1215 "*
1216 {
1217 if (GET_CODE (operands[2]) == CONST_INT
1218 && INTVAL (operands[2]) < 0)
1219 return \"sub.b #%n2,%0\";
1220 if (GREG_P (operands[0]))
1221 {
1222 if (CONSTANT_P (operands[2]))
1223 return \"add:l %2,%0.w\";
1224 else
1225 return \"add:l %2.b,%0.w\";
1226 }
1227 return \"add.b %2,%0\";
1228 }")
1229
1230 (define_insn ""
1231 [(set (strict_low_part (match_operand:QI 0 "general_operand" "+rm"))
1232 (plus:QI (match_dup 0)
1233 (match_operand:QI 1 "general_operand" "rmi")))]
1234 ""
1235 "add.b %1,%0")
1236
1237 (define_insn "adddf3"
1238 [(set (match_operand:DF 0 "general_operand" "=f")
1239 (plus:DF (match_operand:DF 1 "general_operand" "%0")
1240 (match_operand:DF 2 "general_operand" "fmG")))]
1241 "TARGET_FPU"
1242 "fadd.d %f2,%0")
1243
1244 (define_insn "addsf3"
1245 [(set (match_operand:SF 0 "general_operand" "=f")
1246 (plus:SF (match_operand:SF 1 "general_operand" "%0")
1247 (match_operand:SF 2 "general_operand" "fmG")))]
1248 "TARGET_FPU"
1249 "fadd.s %f2,%0")
1250 \f
1251 ;; subtract instructions
1252
1253 (define_insn "subsi3"
1254 [(set (match_operand:SI 0 "general_operand" "=rm,!r")
1255 (minus:SI (match_operand:SI 1 "general_operand" "0,r")
1256 (match_operand:SI 2 "general_operand" "rmi,i")))]
1257 ""
1258 "*
1259 {
1260 if (which_alternative == 0
1261 || (GET_CODE (operands[1]) == REG
1262 && REGNO (operands[0]) == REGNO (operands[1])))
1263 {
1264 if (GET_CODE (operands[2]) == CONST_INT)
1265 {
1266 operands[1] = operands[2];
1267 return sub_imm_word (INTVAL (operands[1]),
1268 operands[0], &operands[1]);
1269 }
1270 else
1271 return \"sub.w %2,%0\";
1272 }
1273 else
1274 return \"mova.w @(%n2,%1),%0\";
1275 }")
1276
1277 (define_insn ""
1278 [(set (match_operand:SI 0 "general_operand" "=rm")
1279 (minus:SI (match_operand:SI 1 "general_operand" "0")
1280 (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rmi"))))]
1281 ""
1282 "sub %2.h,%0.w")
1283
1284 (define_insn "subhi3"
1285 [(set (match_operand:HI 0 "general_operand" "=rm")
1286 (minus:HI (match_operand:HI 1 "general_operand" "0")
1287 (match_operand:HI 2 "general_operand" "rmi")))]
1288 ""
1289 "*
1290 {
1291 if (GET_CODE (operands[2]) == CONST_INT
1292 && INTVAL (operands[2]) < 0
1293 && INTVAL (operands[2]) != 0x8000)
1294 return \"add.h #%n2,%0\";
1295 return \"sub.h %2,%0\";
1296 }")
1297
1298 (define_insn ""
1299 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+rm"))
1300 (minus:HI (match_dup 0)
1301 (match_operand:HI 1 "general_operand" "rmi")))]
1302 ""
1303 "sub.h %1,%0")
1304
1305 (define_insn "subqi3"
1306 [(set (match_operand:QI 0 "general_operand" "=rm")
1307 (minus:QI (match_operand:QI 1 "general_operand" "0")
1308 (match_operand:QI 2 "general_operand" "rmi")))]
1309 ""
1310 "*
1311 {
1312 if (GET_CODE (operands[2]) == CONST_INT
1313 && INTVAL (operands[2]) < 0
1314 && INTVAL (operands[2]) != 0x80)
1315 return \"add.b #%n2,%0\";
1316 return \"sub.b %2,%0\";
1317 }")
1318
1319 (define_insn ""
1320 [(set (strict_low_part (match_operand:QI 0 "general_operand" "+rm"))
1321 (minus:QI (match_dup 0)
1322 (match_operand:QI 1 "general_operand" "rmi")))]
1323 ""
1324 "sub.b %1,%0")
1325
1326 (define_insn "subdf3"
1327 [(set (match_operand:DF 0 "general_operand" "=f")
1328 (minus:DF (match_operand:DF 1 "general_operand" "0")
1329 (match_operand:DF 2 "general_operand" "fmG")))]
1330 "TARGET_FPU"
1331 "fsub.d %f2,%0")
1332
1333 (define_insn "subsf3"
1334 [(set (match_operand:SF 0 "general_operand" "=f")
1335 (minus:SF (match_operand:SF 1 "general_operand" "0")
1336 (match_operand:SF 2 "general_operand" "fmG")))]
1337 "TARGET_FPU"
1338 "fsub.s %f2,%0")
1339
1340 \f
1341 ;; multiply instructions
1342
1343 (define_insn "mulqi3"
1344 [(set (match_operand:QI 0 "general_operand" "=rm")
1345 (mult:QI (match_operand:QI 1 "general_operand" "%0")
1346 (match_operand:QI 2 "general_operand" "rmi")))]
1347 ""
1348 "mul.b %2,%0")
1349
1350
1351 (define_insn "mulhi3"
1352 [(set (match_operand:HI 0 "general_operand" "=rm")
1353 (mult:HI (match_operand:HI 1 "general_operand" "%0")
1354 (match_operand:HI 2 "general_operand" "rmi")))]
1355 ""
1356 "mul.h %2,%0")
1357
1358 ;; define_insn "mulhisi3"
1359
1360 (define_insn "mulsi3"
1361 [(set (match_operand:SI 0 "general_operand" "=rm")
1362 (mult:SI (match_operand:SI 1 "general_operand" "%0")
1363 (match_operand:SI 2 "general_operand" "rmi")))]
1364 ""
1365 "mul.w %2,%0")
1366
1367 (define_insn "muldf3"
1368 [(set (match_operand:DF 0 "general_operand" "=f")
1369 (mult:DF (match_operand:DF 1 "general_operand" "%0")
1370 (match_operand:DF 2 "general_operand" "fmG")))]
1371 "TARGET_FPU"
1372 "fmul.d %f2,%0")
1373
1374 (define_insn "mulsf3"
1375 [(set (match_operand:SF 0 "general_operand" "=f")
1376 (mult:SF (match_operand:SF 1 "general_operand" "%0")
1377 (match_operand:SF 2 "general_operand" "fmG")))]
1378 "TARGET_FPU"
1379 "fmul.s %f2,%0")
1380
1381 \f
1382 ;; divide instructions
1383
1384 (define_insn "divqi3"
1385 [(set (match_operand:QI 0 "general_operand" "=rm")
1386 (div:QI (match_operand:QI 1 "general_operand" "0")
1387 (match_operand:QI 2 "general_operand" "rmi")))]
1388 ""
1389 "div.b %2,%0")
1390
1391 (define_insn "divhi3"
1392 [(set (match_operand:HI 0 "general_operand" "=rm")
1393 (div:HI (match_operand:HI 1 "general_operand" "0")
1394 (match_operand:HI 2 "general_operand" "rmi")))]
1395 ""
1396 "div.h %2,%0")
1397
1398 (define_insn "divhisi3"
1399 [(set (match_operand:HI 0 "general_operand" "=r")
1400 (div:HI (match_operand:SI 1 "general_operand" "0")
1401 (match_operand:HI 2 "general_operand" "rmi")))]
1402 ""
1403 "div %2.h,%0.w")
1404
1405 (define_insn "divsi3"
1406 [(set (match_operand:SI 0 "general_operand" "=rm")
1407 (div:SI (match_operand:SI 1 "general_operand" "0")
1408 (match_operand:SI 2 "general_operand" "rmi")))]
1409 ""
1410 "div.w %2,%0")
1411
1412 (define_insn "udivqi3"
1413 [(set (match_operand:QI 0 "general_operand" "=rm")
1414 (udiv:QI (match_operand:QI 1 "general_operand" "0")
1415 (match_operand:QI 2 "general_operand" "rmi")))]
1416 ""
1417 "divu.b %2,%0")
1418
1419 (define_insn "udivhi3"
1420 [(set (match_operand:HI 0 "general_operand" "=rm")
1421 (udiv:HI (match_operand:HI 1 "general_operand" "0")
1422 (match_operand:HI 2 "general_operand" "rmi")))]
1423 ""
1424 "divu.h %2,%0")
1425
1426 (define_insn "udivhisi3"
1427 [(set (match_operand:HI 0 "general_operand" "=r")
1428 (udiv:HI (match_operand:SI 1 "general_operand" "0")
1429 (match_operand:HI 2 "general_operand" "rmi")))]
1430 ""
1431 "divu %2.h,%0.w")
1432
1433 (define_insn "udivsi3"
1434 [(set (match_operand:SI 0 "general_operand" "=rm")
1435 (udiv:SI (match_operand:SI 1 "general_operand" "0")
1436 (match_operand:SI 2 "general_operand" "rmi")))]
1437 ""
1438 "divu.w %2,%0")
1439
1440 (define_insn "divdf3"
1441 [(set (match_operand:DF 0 "general_operand" "=f")
1442 (div:DF (match_operand:DF 1 "general_operand" "0")
1443 (match_operand:DF 2 "general_operand" "fmG")))]
1444 "TARGET_FPU"
1445 "fdiv.d %f2,%0")
1446
1447 (define_insn "divsf3"
1448 [(set (match_operand:SF 0 "general_operand" "=f")
1449 (div:SF (match_operand:SF 1 "general_operand" "0")
1450 (match_operand:SF 2 "general_operand" "fmG")))]
1451 "TARGET_FPU"
1452 "fdiv.s %f2,%0")
1453 \f
1454 ;; Remainder instructions.
1455
1456 (define_insn "modqi3"
1457 [(set (match_operand:QI 0 "general_operand" "=rm")
1458 (mod:QI (match_operand:QI 1 "general_operand" "0")
1459 (match_operand:QI 2 "general_operand" "rmi")))]
1460 ""
1461 "rem.b %2,%0")
1462
1463 (define_insn "modhisi3"
1464 [(set (match_operand:HI 0 "general_operand" "=r")
1465 (mod:HI (match_operand:SI 1 "general_operand" "0")
1466 (match_operand:HI 2 "general_operand" "rmi")))]
1467 ""
1468 "rem.h %2,%0")
1469
1470 (define_insn "umodqi3"
1471 [(set (match_operand:QI 0 "general_operand" "=rm")
1472 (umod:QI (match_operand:QI 1 "general_operand" "0")
1473 (match_operand:QI 2 "general_operand" "rmi")))]
1474 ""
1475 "remu.b %2,%0")
1476
1477 (define_insn "umodhi3"
1478 [(set (match_operand:HI 0 "general_operand" "=rm")
1479 (umod:HI (match_operand:HI 1 "general_operand" "0")
1480 (match_operand:HI 2 "general_operand" "rmi")))]
1481 ""
1482 "remu.h %2,%0")
1483
1484 (define_insn "umodhisi3"
1485 [(set (match_operand:HI 0 "general_operand" "=r")
1486 (umod:HI (match_operand:SI 1 "general_operand" "0")
1487 (match_operand:HI 2 "general_operand" "rmi")))]
1488 ""
1489 "remu %2.h,%0.w")
1490
1491 ;; define_insn "divmodsi4"
1492
1493 (define_insn "udivmodsi4"
1494 [(set (match_operand:SI 0 "general_operand" "=rm")
1495 (udiv:SI (match_operand:SI 1 "general_operand" "0")
1496 (match_operand:SI 2 "general_operand" "rmi")))
1497 (set (match_operand:SI 3 "general_operand" "=r")
1498 (umod:SI (match_dup 1) (match_dup 2)))]
1499 ""
1500 "mov.w #0,%3;divx.w %2,%0,%3")
1501 \f
1502 ;; logical-and instructions
1503
1504 (define_insn "andsi3"
1505 [(set (match_operand:SI 0 "general_operand" "=rm")
1506 (and:SI (match_operand:SI 1 "general_operand" "%0")
1507 (match_operand:SI 2 "general_operand" "rmi")))]
1508 ""
1509 "*
1510 {
1511 if (GET_CODE (operands[2]) == CONST_INT
1512 && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
1513 && (GREG_P (operands[0])
1514 || offsettable_memref_p (operands[0])))
1515
1516 {
1517 if (GET_CODE (operands[0]) != REG)
1518 operands[0] = adj_offsettable_operand (operands[0], 2);
1519 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1520 /* Do not delete a following tstl %0 insn; that would be incorrect. */
1521 CC_STATUS_INIT;
1522 return \"and.h %2,%0\";
1523 }
1524 return \"and.w %2,%0\";
1525 }")
1526
1527 (define_insn "andhi3"
1528 [(set (match_operand:HI 0 "general_operand" "=rm")
1529 (and:HI (match_operand:HI 1 "general_operand" "%0")
1530 (match_operand:HI 2 "general_operand" "rmi")))]
1531 ""
1532 "and.h %2,%0")
1533
1534 (define_insn "andqi3"
1535 [(set (match_operand:QI 0 "general_operand" "=rm")
1536 (and:QI (match_operand:QI 1 "general_operand" "%0")
1537 (match_operand:QI 2 "general_operand" "rmi")))]
1538 ""
1539 "and.b %2,%0")
1540
1541 (define_insn ""
1542 [(set (match_operand:SI 0 "general_operand" "=r")
1543 (and:SI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm"))
1544 (match_operand:SI 2 "general_operand" "0")))]
1545 ""
1546 "*
1547 {
1548 if (GET_CODE (operands[1]) == CONST_INT)
1549 return \"and %1,%0.w\";
1550 return \"and %1.h,%0.w\";
1551 }")
1552
1553
1554 (define_insn ""
1555 [(set (match_operand:SI 0 "general_operand" "=r")
1556 (and:SI (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm"))
1557 (match_operand:SI 2 "general_operand" "0")))]
1558 ""
1559 "*
1560 {
1561 if (GET_CODE (operands[1]) == CONST_INT)
1562 return \"and %1,%0.w\";
1563 return \"and %1.b,%0.w\";
1564 }")
1565 \f
1566 ;; inclusive-or instructions
1567
1568 (define_insn "iorsi3"
1569 [(set (match_operand:SI 0 "general_operand" "=rm")
1570 (ior:SI (match_operand:SI 1 "general_operand" "%0")
1571 (match_operand:SI 2 "general_operand" "rmi")))]
1572 ""
1573 "*
1574 {
1575 register int logval;
1576 if (GET_CODE (operands[2]) == CONST_INT
1577 && INTVAL (operands[2]) >> 16 == 0
1578 && (GREG_P (operands[0])
1579 || offsettable_memref_p (operands[0])))
1580 {
1581 if (GET_CODE (operands[0]) != REG)
1582 operands[0] = adj_offsettable_operand (operands[0], 2);
1583 /* Do not delete a following tstl %0 insn; that would be incorrect. */
1584 CC_STATUS_INIT;
1585 return \"or.h %2,%0\";
1586 }
1587 if (GET_CODE (operands[2]) == CONST_INT
1588 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
1589 && (GREG_P (operands[0])
1590 || offsettable_memref_p (operands[0])))
1591 {
1592 if (GREG_P (operands[0]))
1593 {
1594 if (logval < 7)
1595 {
1596 operands[1] = GEN_INT (7 - logval);
1597 return \"bset.b %1,%0\";
1598 }
1599 operands[1] = GEN_INT (31 - logval);
1600 return \"bset.w %1,%0\";
1601 }
1602 else
1603 {
1604 operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
1605 operands[1] = GEN_INT (7 - (logval % 8));
1606 }
1607 return \"bset.b %1,%0\";
1608 }
1609 return \"or.w %2,%0\";
1610 }")
1611
1612 (define_insn "iorhi3"
1613 [(set (match_operand:HI 0 "general_operand" "=rm")
1614 (ior:HI (match_operand:HI 1 "general_operand" "%0")
1615 (match_operand:HI 2 "general_operand" "rmi")))]
1616 ""
1617 "or.h %2,%0")
1618
1619 (define_insn "iorqi3"
1620 [(set (match_operand:QI 0 "general_operand" "=rm")
1621 (ior:QI (match_operand:QI 1 "general_operand" "%0")
1622 (match_operand:QI 2 "general_operand" "rmi")))]
1623 ""
1624 "or.b %2,%0")
1625 \f
1626 ;; xor instructions
1627
1628 (define_insn "xorsi3"
1629 [(set (match_operand:SI 0 "general_operand" "=rm")
1630 (xor:SI (match_operand:SI 1 "general_operand" "%0")
1631 (match_operand:SI 2 "general_operand" "rmi")))]
1632 ""
1633 "*
1634 {
1635 if (GET_CODE (operands[2]) == CONST_INT
1636 && INTVAL (operands[2]) >> 16 == 0
1637 && (offsettable_memref_p (operands[0]) || GREG_P (operands[0])))
1638 {
1639 if (! GREG_P (operands[0]))
1640 operands[0] = adj_offsettable_operand (operands[0], 2);
1641 /* Do not delete a following tstl %0 insn; that would be incorrect. */
1642 CC_STATUS_INIT;
1643 return \"xor.h %2,%0\";
1644 }
1645 return \"xor.w %2,%0\";
1646 }")
1647
1648 (define_insn "xorhi3"
1649 [(set (match_operand:HI 0 "general_operand" "=rm")
1650 (xor:HI (match_operand:HI 1 "general_operand" "%0")
1651 (match_operand:HI 2 "general_operand" "rmi")))]
1652 ""
1653 "xor.h %2,%0")
1654
1655 (define_insn "xorqi3"
1656 [(set (match_operand:QI 0 "general_operand" "=rm")
1657 (xor:QI (match_operand:QI 1 "general_operand" "%0")
1658 (match_operand:QI 2 "general_operand" "rmi")))]
1659 ""
1660 "xor.b %2,%0")
1661 \f
1662 ;; negation instructions
1663
1664 (define_insn "negsi2"
1665 [(set (match_operand:SI 0 "general_operand" "=rm")
1666 (neg:SI (match_operand:SI 1 "general_operand" "0")))]
1667 ""
1668 "neg.w %0")
1669
1670 (define_insn "neghi2"
1671 [(set (match_operand:HI 0 "general_operand" "=rm")
1672 (neg:HI (match_operand:HI 1 "general_operand" "0")))]
1673 ""
1674 "neg.h %0")
1675
1676 (define_insn "negqi2"
1677 [(set (match_operand:QI 0 "general_operand" "=rm")
1678 (neg:QI (match_operand:QI 1 "general_operand" "0")))]
1679 ""
1680 "neg.b %0")
1681
1682 (define_insn "negsf2"
1683 [(set (match_operand:SF 0 "general_operand" "=f")
1684 (neg:SF (match_operand:SF 1 "general_operand" "fmF")))]
1685 "TARGET_FPU"
1686 "fneg.s %f1,%0")
1687
1688
1689 (define_insn "negdf2"
1690 [(set (match_operand:DF 0 "general_operand" "=f")
1691 (neg:DF (match_operand:DF 1 "general_operand" "fmF")))]
1692 "TARGET_FPU"
1693 "fneg.d %f1,%0")
1694
1695 \f
1696 ;; Absolute value instructions
1697
1698 (define_insn "abssf2"
1699 [(set (match_operand:SF 0 "general_operand" "=f")
1700 (abs:SF (match_operand:SF 1 "general_operand" "fmF")))]
1701 "TARGET_FPU"
1702 "fabs.s %f1,%0")
1703
1704 (define_insn "absdf2"
1705 [(set (match_operand:DF 0 "general_operand" "=f")
1706 (abs:DF (match_operand:DF 1 "general_operand" "fmF")))]
1707 "TARGET_FPU"
1708 "fabs.d %f1,%0")
1709
1710 \f
1711 ;; one complement instructions
1712
1713 (define_insn "one_cmplsi2"
1714 [(set (match_operand:SI 0 "general_operand" "=rm")
1715 (not:SI (match_operand:SI 1 "general_operand" "0")))]
1716 ""
1717 "not.w %0")
1718
1719 (define_insn "one_cmplhi2"
1720 [(set (match_operand:HI 0 "general_operand" "=rm")
1721 (not:HI (match_operand:HI 1 "general_operand" "0")))]
1722 ""
1723 "not.h %0")
1724
1725 (define_insn "one_cmplqi2"
1726 [(set (match_operand:QI 0 "general_operand" "=rm")
1727 (not:QI (match_operand:QI 1 "general_operand" "0")))]
1728 ""
1729 "not.b %0")
1730 \f
1731 ;; Optimized special case of shifting.
1732 ;; Must precede the general case.
1733
1734 (define_insn ""
1735 [(set (match_operand:SI 0 "general_operand" "=r")
1736 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
1737 (const_int 24)))]
1738 "GET_CODE (XEXP (operands[1], 0)) != POST_INC
1739 && GET_CODE (XEXP (operands[1], 0)) != PRE_DEC"
1740 "mov:l %1.b,%0.w")
1741
1742 (define_insn ""
1743 [(set (match_operand:SI 0 "general_operand" "=r")
1744 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
1745 (const_int 24)))]
1746 "GET_CODE (XEXP (operands[1], 0)) != POST_INC
1747 && GET_CODE (XEXP (operands[1], 0)) != PRE_DEC"
1748 "movu %1.b,%0.w")
1749
1750 (define_insn ""
1751 [(set (cc0) (compare (match_operand:QI 0 "general_operand" "i")
1752 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
1753 (const_int 24))))]
1754 "(GET_CODE (operands[0]) == CONST_INT
1755 && (INTVAL (operands[0]) & ~0xff) == 0)"
1756 "*
1757 {
1758 cc_status.flags |= CC_REVERSED;
1759 if (my_signed_comp (insn))
1760 return \"cmp.b %0,%1\";
1761 return \"cmpu.b %0,%1\";
1762 }")
1763
1764 (define_insn ""
1765 [(set (cc0) (compare (lshiftrt:SI (match_operand:SI 0 "memory_operand" "m")
1766 (const_int 24))
1767 (match_operand:QI 1 "general_operand" "i")))]
1768 "(GET_CODE (operands[1]) == CONST_INT
1769 && (INTVAL (operands[1]) & ~0xff) == 0)"
1770 "*
1771 if (my_signed_comp (insn))
1772 return \"cmp.b %1,%0\";
1773 return \"cmpu.b %1,%0\";
1774 ")
1775
1776 (define_insn ""
1777 [(set (cc0) (compare (match_operand:QI 0 "general_operand" "i")
1778 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
1779 (const_int 24))))]
1780 "(GET_CODE (operands[0]) == CONST_INT
1781 && ((INTVAL (operands[0]) + 0x80) & ~0xff) == 0)"
1782 "*
1783 cc_status.flags |= CC_REVERSED;
1784 if (my_signed_comp (insn))
1785 return \"cmp.b %0,%1\";
1786 return \"cmpu.b %0,%1\";
1787 ")
1788
1789 (define_insn ""
1790 [(set (cc0) (compare (ashiftrt:SI (match_operand:SI 0 "memory_operand" "m")
1791 (const_int 24))
1792 (match_operand:QI 1 "general_operand" "i")))]
1793 "(GET_CODE (operands[1]) == CONST_INT
1794 && ((INTVAL (operands[1]) + 0x80) & ~0xff) == 0)"
1795 "*
1796 if (my_signed_comp (insn))
1797 return \"cmp.b %1,%0\";
1798 return \"cmpu.b %1,%0\";
1799 ")
1800 \f
1801 ;; arithmetic shift instructions
1802 ;; We don't need the shift memory by 1 bit instruction
1803
1804 (define_insn "ashlsi3"
1805 [(set (match_operand:SI 0 "general_operand" "=rm")
1806 (ashift:SI (match_operand:SI 1 "general_operand" "0")
1807 (match_operand:SI 2 "general_operand" "rmi")))]
1808 ""
1809 "sha.w %2,%0")
1810
1811 (define_insn "ashlhi3"
1812 [(set (match_operand:HI 0 "general_operand" "=rm")
1813 (ashift:HI (match_operand:HI 1 "general_operand" "0")
1814 (match_operand:HI 2 "general_operand" "rmi")))]
1815 ""
1816 "sha.h %2,%0")
1817
1818 (define_insn "ashlqi3"
1819 [(set (match_operand:QI 0 "general_operand" "=rm")
1820 (ashift:QI (match_operand:QI 1 "general_operand" "0")
1821 (match_operand:QI 2 "general_operand" "rmi")))]
1822 ""
1823 "sha.b %2,%0")
1824
1825 ;; Arithmetic right shift on the Gmicro works by negating the shift count
1826
1827 ;; ashiftrt -> ashift
1828 (define_expand "ashrsi3"
1829 [(set (match_operand:SI 0 "general_operand" "=rm")
1830 (ashift:SI (match_operand:SI 1 "general_operand" "0")
1831 (match_operand:SI 2 "general_operand" "rmi")))]
1832 ""
1833 "{ operands[2] = negate_rtx (SImode, operands[2]); }")
1834
1835 ;; ashiftrt -> ashift
1836 (define_expand "ashrhi3"
1837 [(set (match_operand:HI 0 "general_operand" "=rm")
1838 (ashift:HI (match_operand:HI 1 "general_operand" "0")
1839 (match_operand:HI 2 "general_operand" "rmi")))]
1840 ""
1841 " { operands[2] = negate_rtx (HImode, operands[2]); }")
1842
1843 ;; ashiftrt -> ashift
1844 (define_expand "ashrqi3"
1845 [(set (match_operand:QI 0 "general_operand" "=rm")
1846 (ashift:QI (match_operand:QI 1 "general_operand" "0")
1847 (match_operand:QI 2 "general_operand" "rmi")))]
1848 ""
1849 " { operands[2] = negate_rtx (QImode, operands[2]); }")
1850 \f
1851 ;; logical shift instructions
1852
1853 ;; Logical right shift on the gmicro works by negating the shift count,
1854 ;; then emitting a right shift with the shift count negated. This means
1855 ;; that all actual shift counts in the RTL will be positive. This
1856 ;; prevents converting shifts to ZERO_EXTRACTs with negative positions,
1857 ;; which isn't valid.
1858
1859 (define_expand "lshrsi3"
1860 [(set (match_operand:SI 0 "general_operand" "=g")
1861 (lshiftrt:SI (match_operand:SI 1 "general_operand" "g")
1862 (match_operand:SI 2 "general_operand" "g")))]
1863 ""
1864 "
1865 {
1866 if (GET_CODE (operands[2]) != CONST_INT)
1867 operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2]));
1868 }")
1869
1870 (define_insn ""
1871 [(set (match_operand:SI 0 "general_operand" "=rm")
1872 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1873 (match_operand:SI 2 "const_int_operand" "n")))]
1874 ""
1875 "shl.w %n2,%0")
1876
1877 (define_insn ""
1878 [(set (match_operand:SI 0 "general_operand" "=rm")
1879 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1880 (neg:SI (match_operand:SI 2 "general_operand" "rm"))))]
1881 ""
1882 "shl.w %2,%0")
1883
1884 (define_expand "lshrhi3"
1885 [(set (match_operand:HI 0 "general_operand" "=g")
1886 (lshiftrt:HI (match_operand:HI 1 "general_operand" "g")
1887 (match_operand:HI 2 "general_operand" "g")))]
1888 ""
1889 "
1890 {
1891 if (GET_CODE (operands[2]) != CONST_INT)
1892 operands[2] = gen_rtx (NEG, HImode, negate_rtx (HImode, operands[2]));
1893 }")
1894
1895 (define_insn ""
1896 [(set (match_operand:HI 0 "general_operand" "=rm")
1897 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1898 (match_operand:HI 2 "const_int_operand" "n")))]
1899 ""
1900 "shl.h %n2,%0")
1901
1902 (define_insn ""
1903 [(set (match_operand:HI 0 "general_operand" "=rm")
1904 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1905 (neg:HI (match_operand:HI 2 "general_operand" "rm"))))]
1906 ""
1907 "shl.h %2,%0")
1908
1909 (define_expand "lshrqi3"
1910 [(set (match_operand:QI 0 "general_operand" "=g")
1911 (lshiftrt:QI (match_operand:QI 1 "general_operand" "g")
1912 (match_operand:QI 2 "general_operand" "g")))]
1913 ""
1914 "
1915 {
1916 if (GET_CODE (operands[2]) != CONST_INT)
1917 operands[2] = gen_rtx (NEG, QImode, negate_rtx (QImode, operands[2]));
1918 }")
1919
1920 (define_insn ""
1921 [(set (match_operand:QI 0 "general_operand" "=rm")
1922 (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
1923 (match_operand:QI 2 "const_int_operand" "n")))]
1924 ""
1925 "shl.b %n2,%0")
1926
1927 (define_insn ""
1928 [(set (match_operand:QI 0 "general_operand" "=rm")
1929 (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
1930 (neg:QI (match_operand:QI 2 "general_operand" "rm"))))]
1931 ""
1932 "shl.b %2,%0")
1933 \f
1934 ;; rotate instructions
1935
1936 (define_insn "rotlsi3"
1937 [(set (match_operand:SI 0 "general_operand" "=rm")
1938 (rotate:SI (match_operand:SI 1 "general_operand" "0")
1939 (match_operand:SI 2 "general_operand" "rmi")))]
1940 ""
1941 "rol.w %2,%0")
1942
1943 (define_insn "rotlhi3"
1944 [(set (match_operand:HI 0 "general_operand" "=rm")
1945 (rotate:HI (match_operand:HI 1 "general_operand" "0")
1946 (match_operand:HI 2 "general_operand" "rmi")))]
1947 ""
1948 "rol.h %2,%0")
1949
1950 (define_insn "rotlqi3"
1951 [(set (match_operand:QI 0 "general_operand" "=rm")
1952 (rotate:QI (match_operand:QI 1 "general_operand" "0")
1953 (match_operand:QI 2 "general_operand" "rmi")))]
1954 ""
1955 "rol.b %2,%0")
1956
1957 (define_expand "rotrsi3"
1958 [(set (match_operand:SI 0 "general_operand" "=rm")
1959 (rotatert:SI (match_operand:SI 1 "general_operand" "0")
1960 (match_operand:SI 2 "general_operand" "rmi")))]
1961 ""
1962 " { operands[2] = negate_rtx (SImode, operands[2]); }")
1963
1964 (define_expand "rotrhi3"
1965 [(set (match_operand:HI 0 "general_operand" "=rm")
1966 (rotatert:HI (match_operand:HI 1 "general_operand" "0")
1967 (match_operand:HI 2 "general_operand" "rmi")))]
1968 ""
1969 " { operands[2] = negate_rtx (HImode, operands[2]); }")
1970
1971 (define_expand "rotrqi3"
1972 [(set (match_operand:QI 0 "general_operand" "=rm")
1973 (rotatert:QI (match_operand:QI 1 "general_operand" "0")
1974 (match_operand:QI 2 "general_operand" "rmi")))]
1975 ""
1976 " { operands[2] = negate_rtx (QImode, operands[2]); }")
1977 \f
1978 ;; Special cases of bit-field insns which we should
1979 ;; recognize in preference to the general case.
1980 ;; These handle aligned 8-bit and 16-bit fields,
1981 ;; which can usually be done with move instructions.
1982
1983 ;; Should I add mode_dependent_address_p ????
1984
1985 (define_insn ""
1986 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm")
1987 (match_operand:SI 1 "immediate_operand" "i")
1988 (match_operand:SI 2 "immediate_operand" "i"))
1989 (match_operand:SI 3 "general_operand" "rm"))]
1990 "TARGET_BITFIELD
1991 && GET_CODE (operands[1]) == CONST_INT
1992 && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
1993 && GET_CODE (operands[2]) == CONST_INT
1994 && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
1995 && (GET_CODE (operands[0]) != REG
1996 || ( INTVAL (operands[1]) + INTVAL (operands[2]) == 32))"
1997 "*
1998 {
1999 if (GET_CODE (operands[3]) == MEM)
2000 operands[3] = adj_offsettable_operand (operands[3],
2001 (32 - INTVAL (operands[1])) / 8);
2002
2003 if (GET_CODE (operands[0]) == REG)
2004 {
2005 if (INTVAL (operands[1]) == 8)
2006 return \"movu %3.b,%0.w\";
2007 return \"movu %3.h,%0.w\";
2008 }
2009 else
2010 {
2011 operands[0]
2012 = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
2013 if (INTVAL (operands[1]) == 8)
2014 return \"mov.b %3,%0\";
2015 return \"mov.h %3,%0\";
2016 }
2017 }")
2018
2019 (define_insn ""
2020 [(set (match_operand:SI 0 "general_operand" "=&r")
2021 (zero_extract:SI (match_operand:SI 1 "register_operand" "rm")
2022 (match_operand:SI 2 "immediate_operand" "i")
2023 (match_operand:SI 3 "immediate_operand" "i")))]
2024 "TARGET_BITFIELD
2025 && GET_CODE (operands[2]) == CONST_INT
2026 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
2027 && GET_CODE (operands[3]) == CONST_INT
2028 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0"
2029 "*
2030 {
2031 if (!REG_P (operands[1]))
2032 operands[1]
2033 = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
2034
2035 if (REG_P (operands[0]))
2036 {
2037 if (REG_P (operands[1]))
2038 {
2039 if (INTVAL (operands[2]) == 8)
2040 { /* width == 8 */
2041 switch (INTVAL (operands[3]))
2042 {
2043 case 0:
2044 return \"mov.w %1,%0;shl.w #-24,%0\";
2045 break;
2046 case 8:
2047 return \"mov.w %1,%0;shl.w #8,%0;shl.w #-24,%0\";
2048 break;
2049 case 16:
2050 return \"mov.w %1,%0;shl.w #16,%0;shl.w #-24,%0\";
2051 break;
2052 case 24:
2053 return \"movu %1.b,%0.w\";
2054 break;
2055 default:
2056 myabort (2);
2057 }
2058 }
2059 else
2060 {
2061 switch (INTVAL (operands[3]))
2062 {
2063 case 0:
2064 return \"mov.w %1,%0;shl.w #-16,%0\";
2065 break;
2066 case 16:
2067 return \"movu %1.h,%0.w\";
2068 break;
2069 default:
2070 myabort (3);
2071 }
2072 }
2073 }
2074 else
2075 {
2076 if (INTVAL (operands[2]) == 8)
2077 return \"movu %1.h,%0.w\";
2078 else
2079 return \"movu %1.b,%0.w\";
2080 }
2081 }
2082 else
2083 { /* op[0] == MEM */
2084 if (INTVAL (operands[2]) == 8)
2085 return \"movu %1.b,%0.w\";
2086 return \"movu %1.h,%0.w\";
2087 }
2088 }")
2089
2090 (define_insn ""
2091 [(set (match_operand:SI 0 "general_operand" "=r")
2092 (sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
2093 (match_operand:SI 2 "immediate_operand" "i")
2094 (match_operand:SI 3 "immediate_operand" "i")))]
2095 "TARGET_BITFIELD
2096 && GET_CODE (operands[2]) == CONST_INT
2097 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
2098 && GET_CODE (operands[3]) == CONST_INT
2099 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0"
2100 "*
2101 {
2102 if (!REG_P (operands[1]))
2103 operands[1]
2104 = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
2105
2106 if (REG_P (operands[0]))
2107 {
2108 if (REG_P (operands[1]))
2109 {
2110 if (INTVAL (operands[2]) == 8)
2111 { /* width == 8 */
2112 switch (INTVAL (operands[3]))
2113 {
2114 case 0:
2115 return \"mov.w %1,%0;sha.w #-24,%0\";
2116 break;
2117 case 8:
2118 return \"mov.w %1,%0;shl.w #8,%0;sha.w #-24,%0\";
2119 break;
2120 case 16:
2121 return \"mov.w %1,%0;shl.w #16,%0;sha.w #-24,%0\";
2122 break;
2123 case 24:
2124 return \"mov %1.b,%0.w\";
2125 break;
2126 default:
2127 myabort (4);
2128 }
2129 }
2130 else
2131 {
2132 switch (INTVAL (operands[3]))
2133 {
2134 case 0:
2135 return \"mov.w %1,%0;sha.w #-16,%0\";
2136 break;
2137 case 16:
2138 return \"mov %1.h,%0.w\";
2139 break;
2140 default:
2141 myabort (5);
2142 }
2143 }
2144 }
2145 else
2146 {
2147 if (INTVAL (operands[2]) == 8)
2148 return \"mov %1.h,%0.w\";
2149 else
2150 return \"mov %1.b,%0.w\";
2151 }
2152 }
2153 else
2154 { /* op[0] == MEM */
2155 if (INTVAL (operands[2]) == 8)
2156 return \"mov %1.b,%0.w\";
2157 return \"mov %1.h,%0.w\";
2158 }
2159 }")
2160 \f
2161 ;; Bit field instructions, general cases.
2162 ;; "o,d" constraint causes a nonoffsettable memref to match the "o"
2163 ;; so that its address is reloaded.
2164
2165 ;; extv dest:SI src(:QI/:SI) width:SI pos:SI
2166 ;; r.w m r.w/# rmi
2167 ;; %0 %1 %2 %3
2168
2169 (define_expand "extv"
2170 [(set (match_operand:SI 0 "general_operand" "")
2171 (sign_extract:SI (match_operand:SI 1 "general_operand" "")
2172 (match_operand:SI 2 "general_operand" "")
2173 (match_operand:SI 3 "general_operand" "")))]
2174 "TARGET_BITFIELD"
2175 "")
2176
2177 (define_insn ""
2178 [(set (match_operand:SI 0 "general_operand" "=r")
2179 (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
2180 (match_operand:SI 2 "general_operand" "ri")
2181 (match_operand:SI 3 "general_operand" "rmi")))]
2182 "TARGET_BITFIELD"
2183 "bfext %3,%2,%1,%0")
2184
2185
2186 (define_expand "extzv"
2187 [(set (match_operand:SI 0 "general_operand" "")
2188 (zero_extract:SI (match_operand:SI 1 "general_operand" "")
2189 (match_operand:SI 2 "general_operand" "")
2190 (match_operand:SI 3 "general_operand" "")))]
2191 "TARGET_BITFIELD"
2192 "")
2193
2194 (define_insn ""
2195 [(set (match_operand:SI 0 "general_operand" "=r")
2196 (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
2197 (match_operand:SI 2 "general_operand" "ri")
2198 (match_operand:SI 3 "general_operand" "rmi")))]
2199 "TARGET_BITFIELD"
2200 "bfextu %3,%2,%1,%0")
2201
2202 ;; There is no insn on the Gmicro to NOT/SET/CLR bitfield.
2203
2204
2205 ;; insv dest(BF):QI/SI width:SI pos:SI src:SI
2206 ;; m r.w rmi r.w/i
2207 ;; 0 1 2 3
2208
2209
2210 (define_expand "insv"
2211 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
2212 (match_operand:SI 1 "general_operand" "")
2213 (match_operand:SI 2 "general_operand" ""))
2214 (match_operand:SI 3 "general_operand" ""))]
2215 "TARGET_BITFIELD"
2216 "")
2217
2218 (define_insn ""
2219 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m,m")
2220 (match_operand:SI 1 "general_operand" "r,i")
2221 (match_operand:SI 2 "general_operand" "rmi,i"))
2222 (match_operand:SI 3 "general_operand" "ri,ri"))]
2223 "TARGET_BITFIELD"
2224 "bfinsu %3,%2,%1,%0")
2225
2226 ;;; bfins/bfinsu ????????
2227
2228 ;; == == == == == == == == == == == == ==
2229
2230 ;; Now recognize bit field insns that operate on registers
2231 ;; (or at least were intended to do so).
2232
2233 ;; On the Gmicro/300,
2234 ;; bitfield instructions are not applicable to registers ;-<
2235 ;; But I write the register cases, because without them the gcc
2236 ;; seems to use "and" instruction with some other instructions
2237 ;; instead of using a shift instruction.
2238 ;; It is because on many processors shift instructions are slower.
2239 ;; On the Gmicro/300 which has a barrel shifter,
2240 ;; it is faster to use a shift instruction.
2241 ;;
2242 ;; Restricts width and offset to be immediates.
2243 ;;
2244 (define_insn ""
2245 [(set (match_operand:SI 0 "general_operand" "=r")
2246 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
2247 (match_operand:SI 2 "immediate_operand" "i")
2248 (match_operand:SI 3 "immediate_operand" "i")))]
2249 "TARGET_BITFIELD"
2250 "*
2251 {
2252 if (REGNO (operands[0]) != REGNO (operands[1]))
2253 output_asm_insn (\"mov.w %1,%0\", operands);
2254 if (INTVAL (operands[3]) != 0)
2255 output_asm_insn (\"shl.w %3,%0\", operands);
2256 operands[2] = GEN_INT (-(32 - INTVAL (operands[2])));
2257 return \"sha.w %3,%0\";
2258 }")
2259
2260
2261 (define_insn ""
2262 [(set (match_operand:SI 0 "general_operand" "=r")
2263 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
2264 (match_operand:SI 2 "immediate_operand" "i")
2265 (match_operand:SI 3 "immediate_operand" "i")))]
2266 "TARGET_BITFIELD"
2267 "*
2268 {
2269 if (REGNO (operands[0]) != REGNO (operands[1]))
2270 output_asm_insn (\"mov.w %1,%0\", operands);
2271 if (INTVAL (operands[3]) != 0)
2272 output_asm_insn (\"shl.w %3,%0\", operands);
2273 operands[2] = GEN_INT (-(32 - INTVAL (operands[2])));
2274 return \"shl.w %3,%0\";
2275 }")
2276
2277
2278 ;; There are more descriptions for m68k, but not yet for the Gmicro.
2279 ;;
2280 \f
2281 ;; Basic conditional jump instructions.
2282
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 {
2293 OUTPUT_JUMP (\"beq %b0\", \"fbeq %b0\", \"beq %b0\");
2294 }")
2295
2296 (define_insn "bne"
2297 [(set (pc)
2298 (if_then_else (ne (cc0)
2299 (const_int 0))
2300 (label_ref (match_operand 0 "" ""))
2301 (pc)))]
2302 ""
2303 "*
2304 {
2305 OUTPUT_JUMP (\"bne %b0\", \"fbne %b0\", \"bne %b0\");
2306 }")
2307
2308 (define_insn "bgt"
2309 [(set (pc)
2310 (if_then_else (gt (cc0)
2311 (const_int 0))
2312 (label_ref (match_operand 0 "" ""))
2313 (pc)))]
2314 ""
2315 "*
2316 OUTPUT_JUMP (\"bgt %b0\", \"fbgt %b0\", 0);
2317 ")
2318
2319 (define_insn "bgtu"
2320 [(set (pc)
2321 (if_then_else (gtu (cc0)
2322 (const_int 0))
2323 (label_ref (match_operand 0 "" ""))
2324 (pc)))]
2325 ""
2326 "bgt %b0")
2327
2328 (define_insn "blt"
2329 [(set (pc)
2330 (if_then_else (lt (cc0)
2331 (const_int 0))
2332 (label_ref (match_operand 0 "" ""))
2333 (pc)))]
2334 ""
2335 "*
2336 OUTPUT_JUMP (\"blt %b0\", \"fblt %b0\", \"bms %b0\");
2337 ")
2338
2339 ;; bms ?????
2340 ;;
2341
2342 (define_insn "bltu"
2343 [(set (pc)
2344 (if_then_else (ltu (cc0)
2345 (const_int 0))
2346 (label_ref (match_operand 0 "" ""))
2347 (pc)))]
2348 ""
2349 "blt %b0")
2350
2351 (define_insn "bge"
2352 [(set (pc)
2353 (if_then_else (ge (cc0)
2354 (const_int 0))
2355 (label_ref (match_operand 0 "" ""))
2356 (pc)))]
2357 ""
2358 "*
2359 OUTPUT_JUMP (\"bge %b0\", \"fbge %b0\", \"bmc %b0\");
2360 ")
2361
2362 ;; bmc ??
2363
2364 (define_insn "bgeu"
2365 [(set (pc)
2366 (if_then_else (geu (cc0)
2367 (const_int 0))
2368 (label_ref (match_operand 0 "" ""))
2369 (pc)))]
2370 ""
2371 "bge %b0")
2372
2373 (define_insn "ble"
2374 [(set (pc)
2375 (if_then_else (le (cc0)
2376 (const_int 0))
2377 (label_ref (match_operand 0 "" ""))
2378 (pc)))]
2379 ""
2380 "ble %b0")
2381
2382 (define_insn "bleu"
2383 [(set (pc)
2384 (if_then_else (leu (cc0)
2385 (const_int 0))
2386 (label_ref (match_operand 0 "" ""))
2387 (pc)))]
2388 ""
2389 "ble %b0")
2390 \f
2391 ;; Negated conditional jump instructions.
2392
2393 (define_insn ""
2394 [(set (pc)
2395 (if_then_else (eq (cc0)
2396 (const_int 0))
2397 (pc)
2398 (label_ref (match_operand 0 "" ""))))]
2399 ""
2400 "*
2401 {
2402 OUTPUT_JUMP (\"bne %b0\", \"fbne %b0\", \"bne %b0\");
2403 }")
2404
2405 (define_insn ""
2406 [(set (pc)
2407 (if_then_else (ne (cc0)
2408 (const_int 0))
2409 (pc)
2410 (label_ref (match_operand 0 "" ""))))]
2411 ""
2412 "*
2413 {
2414 OUTPUT_JUMP (\"beq %b0\", \"fbeq %b0\", \"beq %b0\");
2415 }")
2416
2417 (define_insn ""
2418 [(set (pc)
2419 (if_then_else (gt (cc0)
2420 (const_int 0))
2421 (pc)
2422 (label_ref (match_operand 0 "" ""))))]
2423 ""
2424 "*
2425 OUTPUT_JUMP (\"ble %b0\", \"fbngt %b0\", 0);
2426 ")
2427 ;; fbngt ???
2428
2429 (define_insn ""
2430 [(set (pc)
2431 (if_then_else (gtu (cc0)
2432 (const_int 0))
2433 (pc)
2434 (label_ref (match_operand 0 "" ""))))]
2435 ""
2436 "ble %b0")
2437
2438 (define_insn ""
2439 [(set (pc)
2440 (if_then_else (lt (cc0)
2441 (const_int 0))
2442 (pc)
2443 (label_ref (match_operand 0 "" ""))))]
2444 ""
2445 "*
2446 OUTPUT_JUMP (\"bge %b0\", \"fbnlt %b0\", \"jbmc %b0\");
2447 ")
2448
2449 (define_insn ""
2450 [(set (pc)
2451 (if_then_else (ltu (cc0)
2452 (const_int 0))
2453 (pc)
2454 (label_ref (match_operand 0 "" ""))))]
2455 ""
2456 "blt %b0")
2457
2458 (define_insn ""
2459 [(set (pc)
2460 (if_then_else (ge (cc0)
2461 (const_int 0))
2462 (pc)
2463 (label_ref (match_operand 0 "" ""))))]
2464 ""
2465 "*
2466 OUTPUT_JUMP (\"blt %b0\", \"fbnge %b0\", \"jbms %b0\");
2467 ")
2468
2469 (define_insn ""
2470 [(set (pc)
2471 (if_then_else (geu (cc0)
2472 (const_int 0))
2473 (pc)
2474 (label_ref (match_operand 0 "" ""))))]
2475 ""
2476 "blt %b0")
2477 ;; ????
2478
2479 (define_insn ""
2480 [(set (pc)
2481 (if_then_else (le (cc0)
2482 (const_int 0))
2483 (pc)
2484 (label_ref (match_operand 0 "" ""))))]
2485 ""
2486 "*
2487 OUTPUT_JUMP (\"bgt %b0\", \"fbnle %b0\", 0);
2488 ")
2489
2490 (define_insn ""
2491 [(set (pc)
2492 (if_then_else (leu (cc0)
2493 (const_int 0))
2494 (pc)
2495 (label_ref (match_operand 0 "" ""))))]
2496 ""
2497 "bgt %b0")
2498 \f
2499 ;; Unconditional and other jump instructions
2500 (define_insn "jump"
2501 [(set (pc)
2502 (label_ref (match_operand 0 "" "")))]
2503 ""
2504 "bra %b0")
2505
2506 (define_insn "tablejump"
2507 [(set (pc)
2508 (plus:SI (pc) (match_operand:SI 0 "general_operand" "r")))
2509 (use (label_ref (match_operand 1 "" "")))]
2510 ""
2511 "jmp @(pc:b,4:4,%0)")
2512
2513 ;;
2514 ;; Should Add code for "ACB", "SCB". !!! ????
2515 ;; See m68k.h (dbra)
2516 ;;
2517
2518 ;; Call subroutine with no return value.
2519 (define_insn "call"
2520 [(call (match_operand:QI 0 "general_operand" "m")
2521 (match_operand:SI 1 "general_operand" "rmi"))]
2522 ;; Operand 1 not really used on the Gmicro.
2523
2524 ""
2525 "*
2526 {
2527 if (GET_CODE (operands[0]) == MEM
2528 && GET_CODE (XEXP (operands[0],0)) == SYMBOL_REF)
2529 return \"bsr %b0\";
2530 return \"jsr %0\";
2531 }")
2532
2533 ;; Call subroutine, returning value in operand 0
2534 ;; (which must be a hard register).
2535 (define_insn "call_value"
2536 [(set (match_operand 0 "" "=rf")
2537 (call (match_operand:QI 1 "general_operand" "m")
2538 (match_operand:SI 2 "general_operand" "rmi")))]
2539 ;; Operand 2 not really used on the Gmicro.
2540 ""
2541 "*
2542 {
2543 if (GET_CODE (operands[1]) == MEM
2544 && GET_CODE (XEXP (operands[1],0)) == SYMBOL_REF)
2545 return \"bsr %b1\";
2546 return \"jsr %1\";
2547 }")
2548
2549 ;; Call subroutine returning any type.
2550
2551 (define_expand "untyped_call"
2552 [(parallel [(call (match_operand 0 "" "")
2553 (const_int 0))
2554 (match_operand 1 "" "")
2555 (match_operand 2 "" "")])]
2556 ""
2557 "
2558 {
2559 int i;
2560
2561 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2562
2563 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2564 {
2565 rtx set = XVECEXP (operands[2], 0, i);
2566 emit_move_insn (SET_DEST (set), SET_SRC (set));
2567 }
2568
2569 /* The optimizer does not know that the call sets the function value
2570 registers we stored in the result block. We avoid problems by
2571 claiming that all hard registers are used and clobbered at this
2572 point. */
2573 emit_insn (gen_blockage ());
2574
2575 DONE;
2576 }")
2577
2578 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2579 ;; all of memory. This blocks insns from being moved across this point.
2580
2581 (define_insn "blockage"
2582 [(unspec_volatile [(const_int 0)] 0)]
2583 ""
2584 "")
2585
2586 (define_insn "nop"
2587 [(const_int 0)]
2588 ""
2589 "nop")
2590 \f
2591 ;; Turned off because the general move-an-address pattern handles it.
2592 ;;
2593 ;; Thus goes after the move instructions
2594 ;; because the move instructions are better (require no spilling)
2595 ;; when they can apply.
2596 ;; After add/sub now !!
2597
2598 ;(define_insn "pushasi"
2599 ; [(set (match_operand:SI 0 "push_operand" "=m")
2600 ; (match_operand:SI 1 "address_operand" "p"))]
2601 ; ""
2602 ; "*
2603 ;{
2604 ; if (GET_CODE (operands[1]) == CONST_INT)
2605 ; return push_imm_word (INTVAL (operands[1]), operands[0]);
2606 ; if (CONSTANT_P (operands[1]))
2607 ; return \"mov.w %1,%-\";
2608 ; if (GET_CODE (operands[1]) == REG)
2609 ; return \"mov.w %1,%-\";
2610 ; else if (GET_CODE (operands[1]) == MEM)
2611 ; {
2612 ; return \"mov.w %1,%-\";
2613 ; }
2614 ; else
2615 ; return \"mova.w %p1,%-\";
2616 ;}")
2617 \f
2618 ;; This should not be used unless the add/sub insns can't be.
2619
2620 /* mova.[whq] 89.08.11 for test M.Yuhara */
2621 ;(define_insn ""
2622 ; [(set (match_operand:SI 0 "general_operand" "=rm")
2623 ; (address (match_operand:SI 1 "address_operand" "p")))]
2624 ; ""
2625 ; "*
2626 ;{
2627 ; if (GET_CODE (operands[1]) == CONST_INT)
2628 ; return mov_imm_word (INTVAL (operands[1]), operands[0]);
2629 ; if (CONSTANT_P (operands[1]))
2630 ; return \"mov.w %1,%0\";
2631 ; if (GET_CODE (operands[1]) == REG)
2632 ; return \"mov.w %1,%0\";
2633 ; else if (GET_CODE (operands[1]) == MEM) {
2634 ; operands[1] = XEXP (operands[1],0);
2635 ; return \"mov.w %1,%0\";
2636 ; }
2637 ; else
2638 ; return \"mova.w %p1,%0\";
2639 ;}")
2640
2641
2642 (define_insn ""
2643 [(set (match_operand:SI 0 "general_operand" "=rm")
2644 (address (match_operand:HI 1 "address_operand" "")))]
2645 ""
2646 "*
2647 {
2648 if (GET_CODE (operands[1]) == CONST_INT)
2649 return mov_imm_word (INTVAL (operands[1]), operands[0]);
2650 if (CONSTANT_P (operands[1]))
2651 return \"mov.w %1,%0\";
2652 if (GET_CODE (operands[1]) == REG)
2653 return \"mov.w %1,%0\";
2654 else if (GET_CODE (operands[1]) == MEM)
2655 {
2656 operands[1] = XEXP (operands[1],0);
2657 return \"mov.w %1,%0\"; /* OK ? */
2658 }
2659 else
2660 return \"mova.w %p1,%0\";
2661 }")
2662
2663 ;(define_insn ""
2664 ; [(set (match_operand:SI 0 "general_operand" "=rm")
2665 ; (match_operand:QI 1 "address_operand" "p"))]
2666 ; ""
2667 ; "*
2668 ;{
2669 ; if (push_operand (operands[0], SImode))
2670 ; return \"mova %1,%-\";
2671 ; return \"mova %1,%0\";
2672 ;}")
2673
2674 ;(define_insn ""
2675 ; [(set (match_operand:SI 0 "general_operand" "=rm")
2676 ; (match_operand:QI 1 "address_operand" "p"))]
2677 ; ""
2678 ; "*
2679 ;{
2680 ; if (CONSTANT_P (operands[1]))
2681 ; return \"mov.w %1,%0\";
2682 ; else if (GET_CODE (operands[1]) == REG)
2683 ; return \"mov.w %1,%0\";
2684 ; else if (GET_CODE (operands[1]) == MEM)
2685 ; {
2686 ; operands[1] = XEXP (operands[1],0);
2687 ; return \"mov.w %1,%0 ; OK?\";
2688 ; }
2689 ; else if (GET_CODE (operands[0]) == REG
2690 ; && GET_CODE (operands[1]) == PLUS)
2691 ; {
2692 ; rtx xreg, xdisp;
2693 ;
2694 ; if (GET_CODE (XEXP (operands[1], 0)) == REG
2695 ; && REGNO (XEXP (operands[1], 0)) == REGNO (operands[0]))
2696 ; {
2697 ; xreg = XEXP (operands[1], 0);
2698 ; xdisp = XEXP (operands[1],1);
2699 ; }
2700 ; else
2701 ; {
2702 ; xreg = XEXP (operands[1], 1);
2703 ; xdisp = XEXP (operands[1],0);
2704 ; }
2705 ;
2706 ; if (GET_CODE (xreg) == REG
2707 ; && REGNO (xreg) == REGNO (operands[0])
2708 ; && (CONSTANT_P (xdisp) || GET_CODE (xdisp) == REG))
2709 ; {
2710 ; operands[1] = xdisp;
2711 ; if (CONSTANT_P (xdisp))
2712 ; return add_imm_word (INTVAL (xdisp), xreg, &operands[1]);
2713 ; else
2714 ; return \"add.w %1,%0\";
2715 ; }
2716 ; }
2717 ; return \"mova.w %p1,%0\";
2718 ;}")
2719 \f
2720 ;; This is the first machine-dependent peephole optimization.
2721 ;; It is useful when a floating value is returned from a function call
2722 ;; and then is moved into an FP register.
2723 ;; But it is mainly intended to test the support for these optimizations.
2724
2725 (define_peephole
2726 [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
2727 (set (match_operand:DF 0 "register_operand" "=f")
2728 (match_operand:DF 1 "register_operand" "r"))]
2729 "FPU_REG_P (operands[0]) && ! FPU_REG_P (operands[1])"
2730 "*
2731 {
2732 rtx xoperands[2];
2733 xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
2734 output_asm_insn (\"mov.w %1,@sp\", xoperands);
2735 output_asm_insn (\"mov.w %1,%-\", operands);
2736 return \"fmov.d %+,%0\";
2737 }
2738 ")