]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/mn10300/mn10300.md
mn10300.c (REG_SAVE_BYTES): Only reserve space for registers which will be saved.
[thirdparty/gcc.git] / gcc / config / mn10300 / mn10300.md
1 ;; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3
4 ;; Contributed by Jeff Law (law@cygnus.com).
5
6 ;; This file is part of GNU CC.
7
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
22
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
25
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27
28 ;; Condition code settings.
29 ;; none - insn does not affect cc
30 ;; none_0hit - insn does not affect cc but it does modify operand 0
31 ;; This attribute is used to keep track of when operand 0 changes.
32 ;; See the description of NOTICE_UPDATE_CC for more info.
33 ;; set_znv - insn sets z,n,v to usable values; c is unusable.
34 ;; set_zn - insn sets z,n to usable values; v,c are unusable.
35 ;; compare - compare instruction
36 ;; invert -- like compare, but flags are inverted.
37 ;; clobber - value of cc is unknown
38 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber,invert"
39 (const_string "clobber"))
40 \f
41 ;; ----------------------------------------------------------------------
42 ;; MOVE INSTRUCTIONS
43 ;; ----------------------------------------------------------------------
44
45 ;; movqi
46
47 (define_expand "movqi"
48 [(set (match_operand:QI 0 "general_operand" "")
49 (match_operand:QI 1 "general_operand" ""))]
50 ""
51 "
52 {
53 /* One of the ops has to be in a register */
54 if (!register_operand (operand0, QImode)
55 && !register_operand (operand1, QImode))
56 operands[1] = copy_to_mode_reg (QImode, operand1);
57 }")
58
59 (define_insn ""
60 [(set (match_operand:QI 0 "general_operand" "=dx,*a,dx,*a,dx,*a,dx,*a,dx,m")
61 (match_operand:QI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dx"))]
62 "register_operand (operands[0], QImode)
63 || register_operand (operands[1], QImode)"
64 "*
65 {
66 switch (which_alternative)
67 {
68 case 0:
69 case 1:
70 return \"nop\";
71 case 2:
72 return \"clr %0\";
73 case 3:
74 case 4:
75 case 5:
76 case 6:
77 case 7:
78 if (GET_CODE (operands[1]) == CONST_DOUBLE)
79 {
80 rtx xoperands[2];
81 xoperands[0] = operands[0];
82 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
83 output_asm_insn (\"mov %1,%0\", xoperands);
84 return \"\";
85 }
86
87 return \"mov %1,%0\";
88 case 8:
89 case 9:
90 return \"movbu %1,%0\";
91 }
92 }"
93 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
94
95 ;; movhi
96
97 (define_expand "movhi"
98 [(set (match_operand:HI 0 "general_operand" "")
99 (match_operand:HI 1 "general_operand" ""))]
100 ""
101 "
102 {
103 /* One of the ops has to be in a register */
104 if (!register_operand (operand1, HImode)
105 && !register_operand (operand0, HImode))
106 operands[1] = copy_to_mode_reg (HImode, operand1);
107 }")
108
109 (define_insn ""
110 [(set (match_operand:HI 0 "general_operand" "=dx,*a,dx,*a,dx,*a,dx,*a,dx,m")
111 (match_operand:HI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dx"))]
112 "register_operand (operands[0], HImode)
113 || register_operand (operands[1], HImode)"
114 "*
115 {
116 switch (which_alternative)
117 {
118 case 0:
119 case 1:
120 return \"nop\";
121 case 2:
122 return \"clr %0\";
123 case 3:
124 case 4:
125 case 5:
126 case 6:
127 case 7:
128 if (GET_CODE (operands[1]) == CONST_DOUBLE)
129 {
130 rtx xoperands[2];
131 xoperands[0] = operands[0];
132 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
133 output_asm_insn (\"mov %1,%0\", xoperands);
134 return \"\";
135 }
136 return \"mov %1,%0\";
137 case 8:
138 case 9:
139 return \"movhu %1,%0\";
140 }
141 }"
142 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
143
144 ;; movsi and helpers
145
146 ;; We use this to handle addition of two values when one operand is the
147 ;; stack pointer and the other is a memory reference of some kind. Reload
148 ;; does not handle them correctly without this expander.
149 (define_expand "reload_insi"
150 [(set (match_operand:SI 0 "register_operand" "=a")
151 (match_operand:SI 1 "impossible_plus_operand" ""))
152 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
153 ""
154 "
155 {
156 if (XEXP (operands[1], 0) == stack_pointer_rtx)
157 {
158 emit_move_insn (operands[0], XEXP (operands[1], 0));
159 if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
160 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
161 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
162 emit_move_insn (operands[2],
163 gen_rtx (ZERO_EXTEND, GET_MODE (XEXP (operands[1], 1)),
164 SUBREG_REG (XEXP (operands[1], 1))));
165 else
166 emit_move_insn (operands[2], XEXP (operands[1], 1));
167 }
168 else
169 {
170 emit_move_insn (operands[0], XEXP (operands[1], 1));
171 if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
172 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
173 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
174 emit_move_insn (operands[2],
175 gen_rtx (ZERO_EXTEND, GET_MODE (XEXP (operands[1], 0)),
176 SUBREG_REG (XEXP (operands[1], 0))));
177 else
178 emit_move_insn (operands[2], XEXP (operands[1], 0));
179 }
180 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
181 DONE;
182 }")
183
184 (define_expand "movsi"
185 [(set (match_operand:SI 0 "general_operand" "")
186 (match_operand:SI 1 "general_operand" ""))]
187 ""
188 "
189 {
190 /* One of the ops has to be in a register */
191 if (!register_operand (operand1, SImode)
192 && !register_operand (operand0, SImode))
193 operands[1] = copy_to_mode_reg (SImode, operand1);
194 }")
195
196 (define_insn ""
197 [(set (match_operand:SI 0 "general_operand"
198 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,y")
199 (match_operand:SI 1 "general_operand"
200 "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,xy,axR"))]
201 "register_operand (operands[0], SImode)
202 || register_operand (operands[1], SImode)"
203 "*
204 {
205 switch (which_alternative)
206 {
207 case 0:
208 case 1:
209 return \"nop\";
210 case 2:
211 return \"clr %0\";
212 case 3:
213 case 4:
214 case 5:
215 case 6:
216 case 7:
217 case 8:
218 case 9:
219 case 10:
220 case 11:
221 case 12:
222 case 13:
223 if (GET_CODE (operands[1]) == CONST_DOUBLE)
224 {
225 rtx xoperands[2];
226 xoperands[0] = operands[0];
227 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
228 output_asm_insn (\"mov %1,%0\", xoperands);
229 return \"\";
230 }
231 return \"mov %1,%0\";
232 }
233 }"
234 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
235
236 (define_expand "movsf"
237 [(set (match_operand:SF 0 "general_operand" "")
238 (match_operand:SF 1 "general_operand" ""))]
239 ""
240 "
241 {
242 /* One of the ops has to be in a register */
243 if (!register_operand (operand1, SFmode)
244 && !register_operand (operand0, SFmode))
245 operands[1] = copy_to_mode_reg (SFmode, operand1);
246 }")
247
248 (define_insn ""
249 [(set (match_operand:SF 0 "general_operand" "=dx,ax,dx,a,daxm,dax")
250 (match_operand:SF 1 "general_operand" "0,0,G,G,dax,daxim"))]
251 "register_operand (operands[0], SFmode)
252 || register_operand (operands[1], SFmode)"
253 "*
254 {
255 switch (which_alternative)
256 {
257 case 0:
258 case 1:
259 return \"nop\";
260 case 2:
261 return \"clr %0\";
262 case 3:
263 case 4:
264 case 5:
265 return \"mov %1,%0\";
266 }
267 }"
268 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")])
269
270 (define_expand "movdi"
271 [(set (match_operand:DI 0 "general_operand" "")
272 (match_operand:DI 1 "general_operand" ""))]
273 ""
274 "
275 {
276 /* One of the ops has to be in a register */
277 if (!register_operand (operand1, DImode)
278 && !register_operand (operand0, DImode))
279 operands[1] = copy_to_mode_reg (DImode, operand1);
280 }")
281
282 (define_insn ""
283 [(set (match_operand:DI 0 "general_operand"
284 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
285 (match_operand:DI 1 "general_operand"
286 "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim"))]
287 "register_operand (operands[0], DImode)
288 || register_operand (operands[1], DImode)"
289 "*
290 {
291 long val[2];
292 REAL_VALUE_TYPE rv;
293
294 switch (which_alternative)
295 {
296 case 0:
297 case 1:
298 return \"nop\";
299
300 case 2:
301 return \"clr %L0\;clr %H0\";
302
303 case 3:
304 if (rtx_equal_p (operands[0], operands[1]))
305 return \"sub %L1,%L0\;mov %L0,%H0\";
306 else
307 return \"mov %1,%L0\;mov %L0,%H0\";
308 case 4:
309 case 5:
310 case 6:
311 case 7:
312 case 8:
313 case 9:
314 case 10:
315 case 11:
316 if (GET_CODE (operands[1]) == CONST_INT)
317 {
318 val[0] = INTVAL (operands[1]);
319 val[1] = val[0] < 0 ? -1 : 0;
320 }
321 if (GET_CODE (operands[1]) == CONST_DOUBLE)
322 {
323 if (GET_MODE (operands[1]) == DFmode)
324 {
325 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
326 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
327 }
328 else if (GET_MODE (operands[1]) == VOIDmode
329 || GET_MODE (operands[1]) == DImode)
330 {
331 val[0] = CONST_DOUBLE_LOW (operands[1]);
332 val[1] = CONST_DOUBLE_HIGH (operands[1]);
333 }
334 }
335
336 if (GET_CODE (operands[1]) == MEM
337 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
338 {
339 rtx temp = operands[0];
340
341 while (GET_CODE (temp) == SUBREG)
342 temp = SUBREG_REG (temp);
343
344 if (GET_CODE (temp) != REG)
345 abort ();
346
347 if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
348 XEXP (operands[1], 0)))
349 return \"mov %H1,%H0\;mov %L1,%L0\";
350 else
351 return \"mov %L1,%L0\;mov %H1,%H0\";
352
353 }
354 else if (GET_CODE (operands[1]) == MEM
355 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
356 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
357 {
358 rtx xoperands[2];
359
360 xoperands[0] = operands[0];
361 xoperands[1] = XEXP (operands[1], 0);
362
363 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
364 xoperands);
365 return \"\";
366 }
367 else
368 {
369 if ((GET_CODE (operands[1]) == CONST_INT
370 || GET_CODE (operands[1]) == CONST_DOUBLE)
371 && val[0] == 0)
372 {
373 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
374 output_asm_insn (\"clr %L0\", operands);
375 else
376 output_asm_insn (\"mov %L1,%L0\", operands);
377 }
378 else
379 output_asm_insn (\"mov %L1,%L0\", operands);
380
381 if ((GET_CODE (operands[1]) == CONST_INT
382 || GET_CODE (operands[1]) == CONST_DOUBLE)
383 && val[1] == 0)
384 {
385 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
386 output_asm_insn (\"clr %H0\", operands);
387 else
388 output_asm_insn (\"mov %H1,%H0\", operands);
389 }
390 else if ((GET_CODE (operands[1]) == CONST_INT
391 || GET_CODE (operands[1]) == CONST_DOUBLE)
392 && val[0] == val[1])
393 output_asm_insn (\"mov %L0,%H0\", operands);
394 else
395 output_asm_insn (\"mov %H1,%H0\", operands);
396 return \"\";
397 }
398 }
399 }"
400 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
401
402 (define_expand "movdf"
403 [(set (match_operand:DF 0 "general_operand" "")
404 (match_operand:DF 1 "general_operand" ""))]
405 ""
406 "
407 {
408 /* One of the ops has to be in a register */
409 if (!register_operand (operand1, DFmode)
410 && !register_operand (operand0, DFmode))
411 operands[1] = copy_to_mode_reg (DFmode, operand1);
412 }")
413
414 (define_insn ""
415 [(set (match_operand:DF 0 "general_operand"
416 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
417 (match_operand:DF 1 "general_operand"
418 "0,0,G,G,dx,ax,dx,ax,dxim,axim,dxim,axim"))]
419 "register_operand (operands[0], DFmode)
420 || register_operand (operands[1], DFmode)"
421 "*
422 {
423 long val[2];
424 REAL_VALUE_TYPE rv;
425
426 switch (which_alternative)
427 {
428 case 0:
429 case 1:
430 return \"nop\";
431
432 case 2:
433 return \"clr %L0\;clr %H0\";
434
435 case 3:
436 if (rtx_equal_p (operands[0], operands[1]))
437 return \"sub %L1,%L0\;mov %L0,%H0\";
438 else
439 return \"mov %1,%L0\;mov %L0,%H0\";
440 case 4:
441 case 5:
442 case 6:
443 case 7:
444 case 8:
445 case 9:
446 case 10:
447 case 11:
448 if (GET_CODE (operands[1]) == CONST_INT)
449 {
450 val[0] = INTVAL (operands[1]);
451 val[1] = val[0] < 0 ? -1 : 0;
452 }
453 if (GET_CODE (operands[1]) == CONST_DOUBLE)
454 {
455 if (GET_MODE (operands[1]) == DFmode)
456 {
457 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
458 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
459 }
460 else if (GET_MODE (operands[1]) == VOIDmode
461 || GET_MODE (operands[1]) == DImode)
462 {
463 val[0] = CONST_DOUBLE_LOW (operands[1]);
464 val[1] = CONST_DOUBLE_HIGH (operands[1]);
465 }
466 }
467
468 if (GET_CODE (operands[1]) == MEM
469 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
470 {
471 rtx temp = operands[0];
472
473 while (GET_CODE (temp) == SUBREG)
474 temp = SUBREG_REG (temp);
475
476 if (GET_CODE (temp) != REG)
477 abort ();
478
479 if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
480 XEXP (operands[1], 0)))
481 return \"mov %H1,%H0\;mov %L1,%L0\";
482 else
483 return \"mov %L1,%L0\;mov %H1,%H0\";
484
485 }
486 else if (GET_CODE (operands[1]) == MEM
487 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
488 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
489 {
490 rtx xoperands[2];
491
492 xoperands[0] = operands[0];
493 xoperands[1] = XEXP (operands[1], 0);
494
495 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
496 xoperands);
497 return \"\";
498 }
499 else
500 {
501 if ((GET_CODE (operands[1]) == CONST_INT
502 || GET_CODE (operands[1]) == CONST_DOUBLE)
503 && val[0] == 0)
504 {
505 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
506 output_asm_insn (\"clr %L0\", operands);
507 else
508 output_asm_insn (\"mov %L1,%L0\", operands);
509 }
510 else
511 output_asm_insn (\"mov %L1,%L0\", operands);
512
513 if ((GET_CODE (operands[1]) == CONST_INT
514 || GET_CODE (operands[1]) == CONST_DOUBLE)
515 && val[1] == 0)
516 {
517 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
518 output_asm_insn (\"clr %H0\", operands);
519 else
520 output_asm_insn (\"mov %H1,%H0\", operands);
521 }
522 else if ((GET_CODE (operands[1]) == CONST_INT
523 || GET_CODE (operands[1]) == CONST_DOUBLE)
524 && val[0] == val[1])
525 output_asm_insn (\"mov %L0,%H0\", operands);
526 else
527 output_asm_insn (\"mov %H1,%H0\", operands);
528 return \"\";
529 }
530 }
531 }"
532 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
533
534
535 \f
536 ;; ----------------------------------------------------------------------
537 ;; TEST INSTRUCTIONS
538 ;; ----------------------------------------------------------------------
539
540 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
541 ;; when we start trying to optimize this port.
542 (define_insn "tstsi"
543 [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
544 ""
545 "* return output_tst (operands[0], insn);"
546 [(set_attr "cc" "set_znv")])
547
548 (define_insn ""
549 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
550 ""
551 "* return output_tst (operands[0], insn);"
552 [(set_attr "cc" "set_znv")])
553
554 (define_insn ""
555 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
556 ""
557 "* return output_tst (operands[0], insn);"
558 [(set_attr "cc" "set_znv")])
559
560
561 (define_insn "cmpsi"
562 [(set (cc0)
563 (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
564 (match_operand:SI 1 "nonmemory_operand" "!*0,daxi")))]
565 ""
566 "@
567 add 0,%0
568 cmp %1,%0"
569 [(set_attr "cc" "invert,compare")])
570 \f
571 ;; ----------------------------------------------------------------------
572 ;; ADD INSTRUCTIONS
573 ;; ----------------------------------------------------------------------
574
575 (define_expand "addsi3"
576 [(set (match_operand:SI 0 "register_operand" "")
577 (plus:SI (match_operand:SI 1 "register_operand" "")
578 (match_operand:SI 2 "nonmemory_operand" "")))]
579 ""
580 "
581 {
582 /* We can't add a variable amount directly to the stack pointer;
583 so do so via a temporary register. */
584 if (operands[0] == stack_pointer_rtx
585 && GET_CODE (operands[1]) != CONST_INT
586 && GET_CODE (operands[2]) != CONST_INT)
587 {
588 rtx temp = gen_reg_rtx (SImode);
589 emit_move_insn (temp, gen_rtx (PLUS, SImode, operands[1], operands[2]));
590 emit_move_insn (operands[0], temp);
591 DONE;
592 }
593 }")
594
595 (define_insn ""
596 [(set (match_operand:SI 0 "register_operand" "=dx,ax,ax,dax,xy,!dax")
597 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
598 (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
599 ""
600 "*
601 {
602 switch (which_alternative)
603 {
604 case 0:
605 case 1:
606 return \"inc %0\";
607 case 2:
608 return \"inc4 %0\";
609 case 3:
610 case 4:
611 return \"add %2,%0\";
612 case 5:
613 /* I'm not sure if this can happen or not. Might as well be prepared
614 and generate the best possible code if it does happen. */
615 if (true_regnum (operands[0]) == true_regnum (operands[1]))
616 return \"add %2,%0\";
617 if (true_regnum (operands[0]) == true_regnum (operands[2]))
618 return \"add %1,%0\";
619
620 /* We have to copy one of the sources into the destination, then add
621 the other source to the destination.
622
623 Carefully select which source to copy to the destination; a naive
624 implementation will waste a byte when the source classes are different
625 and the destination is an address register. Selecting the lowest
626 cost register copy will optimize this sequence. */
627 if (REGNO_REG_CLASS (true_regnum (operands[1]))
628 == REGNO_REG_CLASS (true_regnum (operands[0])))
629 return \"mov %1,%0\;add %2,%0\";
630 return \"mov %2,%0\;add %1,%0\";
631 }
632 }"
633 [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
634
635 ;; ----------------------------------------------------------------------
636 ;; SUBTRACT INSTRUCTIONS
637 ;; ----------------------------------------------------------------------
638
639 (define_expand "subsi3"
640 [(set (match_operand:SI 0 "register_operand" "")
641 (minus:SI (match_operand:SI 1 "register_operand" "")
642 (match_operand:SI 2 "nonmemory_operand" "")))]
643 ""
644 "")
645
646 (define_insn ""
647 [(set (match_operand:SI 0 "register_operand" "=dax")
648 (minus:SI (match_operand:SI 1 "register_operand" "0")
649 (match_operand:SI 2 "nonmemory_operand" "daxi")))]
650 ""
651 "sub %2,%0"
652 [(set_attr "cc" "set_zn")])
653
654 (define_expand "negsi2"
655 [(set (match_operand:SI 0 "register_operand" "")
656 (neg:SI (match_operand:SI 1 "register_operand" "")))]
657 ""
658 "
659 {
660 rtx target = gen_reg_rtx (SImode);
661
662 emit_move_insn (target, GEN_INT (0));
663 emit_insn (gen_subsi3 (target, target, operands[1]));
664 emit_move_insn (operands[0], target);
665 DONE;
666 }")
667
668 ;; ----------------------------------------------------------------------
669 ;; MULTIPLY INSTRUCTIONS
670 ;; ----------------------------------------------------------------------
671
672 (define_expand "mulsi3"
673 [(set (match_operand:SI 0 "register_operand" "")
674 (mult:SI (match_operand:SI 1 "register_operand" "")
675 (match_operand:SI 2 "register_operand" "")))]
676 ""
677 "")
678
679 (define_insn ""
680 [(set (match_operand:SI 0 "register_operand" "=dx")
681 (mult:SI (match_operand:SI 1 "register_operand" "%0")
682 (match_operand:SI 2 "register_operand" "dx")))]
683 ""
684 "*
685 {
686 if (TARGET_MULT_BUG)
687 return \"nop\;nop\;mul %2,%0\";
688 else
689 return \"mul %2,%0\";
690 }"
691 [(set_attr "cc" "set_zn")])
692
693 (define_insn "udivmodsi4"
694 [(set (match_operand:SI 0 "general_operand" "=dx")
695 (udiv:SI (match_operand:SI 1 "general_operand" "0")
696 (match_operand:SI 2 "general_operand" "dx")))
697 (set (match_operand:SI 3 "general_operand" "=&d")
698 (umod:SI (match_dup 1) (match_dup 2)))]
699 ""
700 "*
701 {
702 output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
703
704 if (find_reg_note (insn, REG_UNUSED, operands[3]))
705 return \"divu %2,%0\";
706 else
707 return \"divu %2,%0\;mov mdr,%3\";
708 }"
709 [(set_attr "cc" "set_zn")])
710
711 (define_insn "divmodsi4"
712 [(set (match_operand:SI 0 "general_operand" "=dx")
713 (div:SI (match_operand:SI 1 "general_operand" "0")
714 (match_operand:SI 2 "general_operand" "dx")))
715 (set (match_operand:SI 3 "general_operand" "=d")
716 (mod:SI (match_dup 1) (match_dup 2)))]
717 ""
718 "*
719 {
720 if (find_reg_note (insn, REG_UNUSED, operands[3]))
721 return \"ext %0\;div %2,%0\";
722 else
723 return \"ext %0\;div %2,%0\;mov mdr,%3\";
724 }"
725 [(set_attr "cc" "set_zn")])
726
727 \f
728 ;; ----------------------------------------------------------------------
729 ;; AND INSTRUCTIONS
730 ;; ----------------------------------------------------------------------
731
732 (define_expand "andsi3"
733 [(set (match_operand:SI 0 "register_operand" "")
734 (and:SI (match_operand:SI 1 "register_operand" "")
735 (match_operand:SI 2 "nonmemory_operand" "")))]
736 ""
737 "")
738
739 (define_insn ""
740 [(set (match_operand:SI 0 "register_operand" "=dx,dx")
741 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
742 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
743 ""
744 "*
745 {
746 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
747 return \"extbu %0\";
748 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
749 return \"exthu %0\";
750 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
751 return \"add %0,%0\;lsr 1,%0\";
752 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
753 return \"asl2 %0\;lsr 2,%0\";
754 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
755 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
756 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
757 return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
758 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
759 return \"lsr 1,%0\;add %0,%0\";
760 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
761 return \"lsr 2,%0\;asl2 %0\";
762 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
763 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
764 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
765 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
766 return \"and %2,%0\";
767 }"
768 [(set_attr "cc" "none_0hit,set_znv")])
769
770 ;; ----------------------------------------------------------------------
771 ;; OR INSTRUCTIONS
772 ;; ----------------------------------------------------------------------
773
774 (define_expand "iorsi3"
775 [(set (match_operand:SI 0 "register_operand" "")
776 (ior:SI (match_operand:SI 1 "register_operand" "")
777 (match_operand:SI 2 "nonmemory_operand" "")))]
778 ""
779 "")
780
781 (define_insn ""
782 [(set (match_operand:SI 0 "register_operand" "=dx")
783 (ior:SI (match_operand:SI 1 "register_operand" "%0")
784 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
785 ""
786 "or %2,%0"
787 [(set_attr "cc" "set_znv")])
788
789 ;; ----------------------------------------------------------------------
790 ;; XOR INSTRUCTIONS
791 ;; ----------------------------------------------------------------------
792
793 (define_expand "xorsi3"
794 [(set (match_operand:SI 0 "register_operand" "")
795 (xor:SI (match_operand:SI 1 "register_operand" "")
796 (match_operand:SI 2 "nonmemory_operand" "")))]
797 ""
798 "")
799
800 (define_insn ""
801 [(set (match_operand:SI 0 "register_operand" "=dx")
802 (xor:SI (match_operand:SI 1 "register_operand" "%0")
803 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
804 ""
805 "xor %2,%0"
806 [(set_attr "cc" "set_znv")])
807
808 ;; ----------------------------------------------------------------------
809 ;; NOT INSTRUCTIONS
810 ;; ----------------------------------------------------------------------
811
812 (define_expand "one_cmplsi2"
813 [(set (match_operand:SI 0 "register_operand" "")
814 (not:SI (match_operand:SI 1 "register_operand" "")))]
815 ""
816 "")
817
818 (define_insn ""
819 [(set (match_operand:SI 0 "register_operand" "=dx")
820 (not:SI (match_operand:SI 1 "register_operand" "0")))]
821 ""
822 "not %0"
823 [(set_attr "cc" "set_znv")])
824 \f
825 ;; -----------------------------------------------------------------
826 ;; BIT FIELDS
827 ;; -----------------------------------------------------------------
828
829
830 ;; These set/clear memory in byte sized chunks.
831 ;;
832 ;; They are no smaller/faster than loading the value into a register
833 ;; and storing the register, but they don't need a scratch register
834 ;; which may allow for better code generation.
835 (define_insn ""
836 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))]
837 ""
838 "@
839 bclr 255,%A0
840 clr %0"
841 [(set_attr "cc" "clobber")])
842
843 (define_insn ""
844 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))]
845 ""
846 "@
847 bset 255,%A0
848 mov -1,%0"
849 [(set_attr "cc" "clobber,none_0hit")])
850
851 (define_insn ""
852 [(set (match_operand:QI 0 "general_operand" "=R,d")
853 (subreg:QI
854 (and:SI (subreg:SI (match_dup 0) 0)
855 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
856 ""
857 "@
858 bclr %N1,%A0
859 and %1,%0"
860 [(set_attr "cc" "clobber,set_znv")])
861
862 (define_insn ""
863 [(set (match_operand:QI 0 "general_operand" "=R,d")
864 (subreg:QI
865 (ior:SI (subreg:SI (match_dup 0) 0)
866 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
867 ""
868 "@
869 bset %1,%A0
870 or %1,%0"
871 [(set_attr "cc" "clobber,set_znv")])
872
873 (define_insn ""
874 [(set (cc0)
875 (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
876 (match_operand 1 "const_int_operand" "")
877 (match_operand 2 "const_int_operand" "")))]
878 ""
879 "*
880 {
881 int len = INTVAL (operands[1]);
882 int bit = INTVAL (operands[2]);
883 int mask = 0;
884 rtx xoperands[2];
885
886 while (len > 0)
887 {
888 mask |= (1 << bit);
889 bit++;
890 len--;
891 }
892
893 xoperands[0] = operands[0];
894 xoperands[1] = GEN_INT (mask);
895 output_asm_insn (\"btst %1,%0\", xoperands);
896 return \"\";
897 }"
898 [(set_attr "cc" "set_znv")])
899
900 (define_insn ""
901 [(set (cc0)
902 (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
903 (match_operand 1 "const_int_operand" "")
904 (match_operand 2 "const_int_operand" "")))]
905 "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
906 "*
907 {
908 int len = INTVAL (operands[1]);
909 int bit = INTVAL (operands[2]);
910 int mask = 0;
911 rtx xoperands[2];
912
913 while (len > 0)
914 {
915 mask |= (1 << bit);
916 bit++;
917 len--;
918 }
919
920 /* If the source operand is not a reg (ie it is memory), then extract the
921 bits from mask that we actually want to test. Note that the mask will
922 never cross a byte boundary. */
923 if (!REG_P (operands[0]))
924 {
925 if (mask & 0xff)
926 mask = mask & 0xff;
927 else if (mask & 0xff00)
928 mask = (mask >> 8) & 0xff;
929 else if (mask & 0xff0000)
930 mask = (mask >> 16) & 0xff;
931 else if (mask & 0xff000000)
932 mask = (mask >> 24) & 0xff;
933 }
934
935 xoperands[0] = operands[0];
936 xoperands[1] = GEN_INT (mask);
937 if (GET_CODE (operands[0]) == REG)
938 output_asm_insn (\"btst %1,%0\", xoperands);
939 else
940 output_asm_insn (\"btst %1,%A0\", xoperands);
941 return \"\";
942 }"
943 [(set_attr "cc" "set_znv")])
944
945 (define_insn ""
946 [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
947 (match_operand:SI 1 "const_int_operand" "")))]
948 ""
949 "btst %1,%0"
950 [(set_attr "cc" "set_znv")])
951
952 (define_insn ""
953 [(set (cc0)
954 (and:SI
955 (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
956 (match_operand:SI 1 "const_8bit_operand" "")))]
957 ""
958 "@
959 btst %1,%A0
960 btst %1,%0"
961 [(set_attr "cc" "set_znv")])
962
963 \f
964 ;; ----------------------------------------------------------------------
965 ;; JUMP INSTRUCTIONS
966 ;; ----------------------------------------------------------------------
967
968 ;; Conditional jump instructions
969
970 (define_expand "ble"
971 [(set (pc)
972 (if_then_else (le (cc0)
973 (const_int 0))
974 (label_ref (match_operand 0 "" ""))
975 (pc)))]
976 ""
977 "")
978
979 (define_expand "bleu"
980 [(set (pc)
981 (if_then_else (leu (cc0)
982 (const_int 0))
983 (label_ref (match_operand 0 "" ""))
984 (pc)))]
985 ""
986 "")
987
988 (define_expand "bge"
989 [(set (pc)
990 (if_then_else (ge (cc0)
991 (const_int 0))
992 (label_ref (match_operand 0 "" ""))
993 (pc)))]
994 ""
995 "")
996
997 (define_expand "bgeu"
998 [(set (pc)
999 (if_then_else (geu (cc0)
1000 (const_int 0))
1001 (label_ref (match_operand 0 "" ""))
1002 (pc)))]
1003 ""
1004 "")
1005
1006 (define_expand "blt"
1007 [(set (pc)
1008 (if_then_else (lt (cc0)
1009 (const_int 0))
1010 (label_ref (match_operand 0 "" ""))
1011 (pc)))]
1012 ""
1013 "")
1014
1015 (define_expand "bltu"
1016 [(set (pc)
1017 (if_then_else (ltu (cc0)
1018 (const_int 0))
1019 (label_ref (match_operand 0 "" ""))
1020 (pc)))]
1021 ""
1022 "")
1023
1024 (define_expand "bgt"
1025 [(set (pc)
1026 (if_then_else (gt (cc0)
1027 (const_int 0))
1028 (label_ref (match_operand 0 "" ""))
1029 (pc)))]
1030 ""
1031 "")
1032
1033 (define_expand "bgtu"
1034 [(set (pc)
1035 (if_then_else (gtu (cc0)
1036 (const_int 0))
1037 (label_ref (match_operand 0 "" ""))
1038 (pc)))]
1039 ""
1040 "")
1041
1042 (define_expand "beq"
1043 [(set (pc)
1044 (if_then_else (eq (cc0)
1045 (const_int 0))
1046 (label_ref (match_operand 0 "" ""))
1047 (pc)))]
1048 ""
1049 "")
1050
1051 (define_expand "bne"
1052 [(set (pc)
1053 (if_then_else (ne (cc0)
1054 (const_int 0))
1055 (label_ref (match_operand 0 "" ""))
1056 (pc)))]
1057 ""
1058 "")
1059
1060 (define_insn ""
1061 [(set (pc)
1062 (if_then_else (match_operator 1 "comparison_operator"
1063 [(cc0) (const_int 0)])
1064 (label_ref (match_operand 0 "" ""))
1065 (pc)))]
1066 ""
1067 "*
1068 {
1069 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1070 && (GET_CODE (operands[1]) == GT
1071 || GET_CODE (operands[1]) == GE
1072 || GET_CODE (operands[1]) == LE
1073 || GET_CODE (operands[1]) == LT))
1074 return 0;
1075 return \"b%b1 %0\";
1076 }"
1077 [(set_attr "cc" "none")])
1078
1079 (define_insn ""
1080 [(set (pc)
1081 (if_then_else (match_operator 1 "comparison_operator"
1082 [(cc0) (const_int 0)])
1083 (pc)
1084 (label_ref (match_operand 0 "" ""))))]
1085 ""
1086 "*
1087 {
1088 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1089 && (GET_CODE (operands[1]) == GT
1090 || GET_CODE (operands[1]) == GE
1091 || GET_CODE (operands[1]) == LE
1092 || GET_CODE (operands[1]) == LT))
1093 return 0;
1094 return \"b%B1 %0\";
1095 }"
1096 [(set_attr "cc" "none")])
1097
1098 ;; Unconditional and other jump instructions.
1099
1100 (define_insn "jump"
1101 [(set (pc)
1102 (label_ref (match_operand 0 "" "")))]
1103 ""
1104 "jmp %l0"
1105 [(set_attr "cc" "none")])
1106
1107 (define_insn "indirect_jump"
1108 [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1109 ""
1110 "jmp (%0)"
1111 [(set_attr "cc" "none")])
1112
1113 (define_insn "tablejump"
1114 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1115 (use (label_ref (match_operand 1 "" "")))]
1116 ""
1117 "jmp (%0)"
1118 [(set_attr "cc" "none")])
1119
1120 ;; Call subroutine with no return value.
1121
1122 (define_expand "call"
1123 [(call (match_operand:QI 0 "general_operand" "")
1124 (match_operand:SI 1 "general_operand" ""))]
1125 ""
1126 "
1127 {
1128 if (! call_address_operand (XEXP (operands[0], 0)))
1129 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1130 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1131 DONE;
1132 }")
1133
1134 (define_insn "call_internal"
1135 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1136 (match_operand:SI 1 "general_operand" "g"))]
1137 ""
1138 "*
1139 {
1140 if (REG_P (operands[0]))
1141 return \"calls %C0\";
1142 else
1143 return \"call %C0,[],0\";
1144 }"
1145 [(set_attr "cc" "clobber")])
1146
1147 ;; Call subroutine, returning value in operand 0
1148 ;; (which must be a hard register).
1149
1150 (define_expand "call_value"
1151 [(set (match_operand 0 "" "")
1152 (call (match_operand:QI 1 "general_operand" "")
1153 (match_operand:SI 2 "general_operand" "")))]
1154 ""
1155 "
1156 {
1157 if (! call_address_operand (XEXP (operands[1], 0)))
1158 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1159 emit_call_insn (gen_call_value_internal (operands[0],
1160 XEXP (operands[1], 0),
1161 operands[2]));
1162 DONE;
1163 }")
1164
1165 (define_insn "call_value_internal"
1166 [(set (match_operand 0 "" "=dax")
1167 (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1168 (match_operand:SI 2 "general_operand" "g")))]
1169 ""
1170 "*
1171 {
1172 if (REG_P (operands[1]))
1173 return \"calls %C1\";
1174 else
1175 return \"call %C1,[],0\";
1176 }"
1177 [(set_attr "cc" "clobber")])
1178
1179 (define_expand "untyped_call"
1180 [(parallel [(call (match_operand 0 "" "")
1181 (const_int 0))
1182 (match_operand 1 "" "")
1183 (match_operand 2 "" "")])]
1184 ""
1185 "
1186 {
1187 int i;
1188
1189 emit_call_insn (gen_call (operands[0], const0_rtx));
1190
1191 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1192 {
1193 rtx set = XVECEXP (operands[2], 0, i);
1194 emit_move_insn (SET_DEST (set), SET_SRC (set));
1195 }
1196 DONE;
1197 }")
1198
1199 (define_insn "nop"
1200 [(const_int 0)]
1201 ""
1202 "nop"
1203 [(set_attr "cc" "none")])
1204 \f
1205 ;; ----------------------------------------------------------------------
1206 ;; EXTEND INSTRUCTIONS
1207 ;; ----------------------------------------------------------------------
1208
1209 (define_expand "zero_extendqisi2"
1210 [(set (match_operand:SI 0 "general_operand" "")
1211 (zero_extend:SI
1212 (match_operand:QI 1 "general_operand" "")))]
1213 ""
1214 "")
1215
1216 (define_insn ""
1217 [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx")
1218 (zero_extend:SI
1219 (match_operand:QI 1 "general_operand" "0,d,m")))]
1220 ""
1221 "@
1222 extbu %0
1223 mov %1,%0\;extbu %0
1224 movbu %1,%0"
1225 [(set_attr "cc" "none_0hit")])
1226
1227 (define_expand "zero_extendhisi2"
1228 [(set (match_operand:SI 0 "general_operand" "")
1229 (zero_extend:SI
1230 (match_operand:HI 1 "general_operand" "")))]
1231 ""
1232 "")
1233
1234 (define_insn ""
1235 [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx")
1236 (zero_extend:SI
1237 (match_operand:HI 1 "general_operand" "0,dx,m")))]
1238 ""
1239 "@
1240 exthu %0
1241 mov %1,%0\;exthu %0
1242 movhu %1,%0"
1243 [(set_attr "cc" "none_0hit")])
1244
1245 ;;- sign extension instructions
1246
1247 (define_expand "extendqisi2"
1248 [(set (match_operand:SI 0 "general_operand" "")
1249 (sign_extend:SI
1250 (match_operand:QI 1 "general_operand" "")))]
1251 ""
1252 "")
1253
1254 (define_insn ""
1255 [(set (match_operand:SI 0 "general_operand" "=dx,dx")
1256 (sign_extend:SI
1257 (match_operand:QI 1 "general_operand" "0,dx")))]
1258 ""
1259 "@
1260 extb %0
1261 mov %1,%0\;extb %0"
1262 [(set_attr "cc" "none_0hit")])
1263
1264 (define_expand "extendhisi2"
1265 [(set (match_operand:SI 0 "general_operand" "")
1266 (sign_extend:SI
1267 (match_operand:HI 1 "general_operand" "")))]
1268 ""
1269 "")
1270
1271 (define_insn ""
1272 [(set (match_operand:SI 0 "general_operand" "=dx,dx")
1273 (sign_extend:SI
1274 (match_operand:HI 1 "general_operand" "0,dx")))]
1275 ""
1276 "@
1277 exth %0
1278 mov %1,%0\;exth %0"
1279 [(set_attr "cc" "none_0hit")])
1280 \f
1281 ;; ----------------------------------------------------------------------
1282 ;; SHIFTS
1283 ;; ----------------------------------------------------------------------
1284
1285 (define_expand "ashlsi3"
1286 [(set (match_operand:SI 0 "register_operand" "")
1287 (ashift:SI
1288 (match_operand:SI 1 "register_operand" "")
1289 (match_operand:QI 2 "nonmemory_operand" "")))]
1290 ""
1291 "")
1292
1293 (define_insn ""
1294 [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
1295 (ashift:SI
1296 (match_operand:SI 1 "register_operand" "0,0,0,0,0")
1297 (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
1298 ""
1299 "@
1300 add %0,%0
1301 asl2 %0
1302 asl2 %0\;add %0,%0
1303 asl2 %0\;asl2 %0
1304 asl %S2,%0"
1305 [(set_attr "cc" "set_zn")])
1306
1307 (define_expand "lshrsi3"
1308 [(set (match_operand:SI 0 "register_operand" "")
1309 (lshiftrt:SI
1310 (match_operand:SI 1 "register_operand" "")
1311 (match_operand:QI 2 "nonmemory_operand" "")))]
1312 ""
1313 "")
1314
1315 (define_insn ""
1316 [(set (match_operand:SI 0 "register_operand" "=dx")
1317 (lshiftrt:SI
1318 (match_operand:SI 1 "register_operand" "0")
1319 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1320 ""
1321 "lsr %S2,%0"
1322 [(set_attr "cc" "set_zn")])
1323
1324 (define_expand "ashrsi3"
1325 [(set (match_operand:SI 0 "register_operand" "")
1326 (ashiftrt:SI
1327 (match_operand:SI 1 "register_operand" "")
1328 (match_operand:QI 2 "nonmemory_operand" "")))]
1329 ""
1330 "")
1331
1332 (define_insn ""
1333 [(set (match_operand:SI 0 "register_operand" "=dx")
1334 (ashiftrt:SI
1335 (match_operand:SI 1 "register_operand" "0")
1336 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1337 ""
1338 "asr %S2,%0"
1339 [(set_attr "cc" "set_zn")])
1340
1341 ;; ----------------------------------------------------------------------
1342 ;; PROLOGUE/EPILOGUE
1343 ;; ----------------------------------------------------------------------
1344 (define_expand "prologue"
1345 [(const_int 0)]
1346 ""
1347 "expand_prologue (); DONE;")
1348
1349 (define_expand "epilogue"
1350 [(return)]
1351 ""
1352 "
1353 {
1354 expand_epilogue ();
1355 DONE;
1356 }")
1357
1358 (define_insn "return_internal"
1359 [(const_int 2)]
1360 ""
1361 "rets"
1362 [(set_attr "cc" "clobber")])
1363
1364 ;; This insn restores the callee saved registers and does a return, it
1365 ;; can also deallocate stack space.
1366 (define_insn "return_internal_regs"
1367 [(const_int 0)
1368 (match_operand:SI 0 "const_int_operand" "i")
1369 (return)]
1370 ""
1371 "*
1372 {
1373 int i, need_comma;
1374 int d2, d3, a2, a3;
1375
1376 need_comma = 0;
1377 fputs (\"\\tret [\", asm_out_file);
1378 if (regs_ever_live[2])
1379 {
1380 fputs (\"d2\", asm_out_file);
1381 need_comma = 1;
1382 }
1383 if (regs_ever_live[3])
1384 {
1385 if (need_comma)
1386 fputc (',', asm_out_file);
1387 fputs (\"d3\", asm_out_file);
1388 need_comma = 1;
1389 }
1390 if (regs_ever_live[6])
1391 {
1392 if (need_comma)
1393 fputc (',', asm_out_file);
1394 fputs (\"a2\", asm_out_file);
1395 need_comma = 1;
1396 }
1397 if (regs_ever_live[7])
1398 {
1399 if (need_comma)
1400 fputc (',', asm_out_file);
1401 fputs (\"a3\", asm_out_file);
1402 need_comma = 1;
1403 }
1404 fprintf (asm_out_file, \"],%d\\n\", INTVAL (operands[0]));
1405 return \"\";
1406 }"
1407 [(set_attr "cc" "clobber")])
1408
1409 (define_insn "store_movm"
1410 [(const_int 1)]
1411 ""
1412 "*
1413 {
1414 int i, need_comma;
1415 int d2, d3, a2, a3;
1416
1417 need_comma = 0;
1418 fputs (\"\\tmovm [\", asm_out_file);
1419 if (regs_ever_live[2])
1420 {
1421 fputs (\"d2\", asm_out_file);
1422 need_comma = 1;
1423 }
1424 if (regs_ever_live[3])
1425 {
1426 if (need_comma)
1427 fputc (',', asm_out_file);
1428 fputs (\"d3\", asm_out_file);
1429 need_comma = 1;
1430 }
1431 if (regs_ever_live[6])
1432 {
1433 if (need_comma)
1434 fputc (',', asm_out_file);
1435 fputs (\"a2\", asm_out_file);
1436 need_comma = 1;
1437 }
1438 if (regs_ever_live[7])
1439 {
1440 if (need_comma)
1441 fputc (',', asm_out_file);
1442 fputs (\"a3\", asm_out_file);
1443 need_comma = 1;
1444 }
1445 fputs (\"],(sp)\\n\", asm_out_file);
1446 return \"\";
1447 }"
1448 [(set_attr "cc" "clobber")])
1449
1450 (define_insn "return"
1451 [(return)]
1452 "can_use_return_insn ()"
1453 "*
1454 {
1455 rtx next = next_active_insn (insn);
1456
1457 if (next
1458 && GET_CODE (next) == JUMP_INSN
1459 && GET_CODE (PATTERN (next)) == RETURN)
1460 return \"\";
1461 else
1462 return \"rets\";
1463 }"
1464 [(set_attr "cc" "clobber")])
1465
1466 ;; Try to combine consecutive updates of the stack pointer (or any
1467 ;; other register for that matter).
1468 (define_peephole
1469 [(set (match_operand:SI 0 "register_operand" "=dxay")
1470 (plus:SI (match_dup 0)
1471 (match_operand 1 "const_int_operand" "")))
1472 (set (match_dup 0)
1473 (plus:SI (match_dup 0)
1474 (match_operand 2 "const_int_operand" "")))]
1475 ""
1476 "*
1477 {
1478 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
1479 return \"add %1,%0\";
1480 }"
1481 [(set_attr "cc" "clobber")])
1482
1483 ;;
1484 ;; We had patterns to check eq/ne, but the they don't work because
1485 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
1486 ;;
1487 ;; The Z flag and C flag would be set, and we have no way to
1488 ;; check for the Z flag set and C flag clear.
1489 ;;
1490 ;; This will work on the mn10200 because we can check the ZX flag
1491 ;; if the comparison is in HImode.
1492 (define_peephole
1493 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
1494 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1495 (match_operand 1 "" "")
1496 (pc)))]
1497 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1498 "add %0,%0\;bcc %1"
1499 [(set_attr "cc" "clobber")])
1500
1501 (define_peephole
1502 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
1503 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1504 (match_operand 1 "" "")
1505 (pc)))]
1506 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1507 "add %0,%0\;bcs %1"
1508 [(set_attr "cc" "clobber")])
1509
1510 (define_peephole
1511 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
1512 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1513 (pc)
1514 (match_operand 1 "" "")))]
1515 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1516 "add %0,%0\;bcs %1"
1517 [(set_attr "cc" "clobber")])
1518
1519 (define_peephole
1520 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
1521 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1522 (pc)
1523 (match_operand 1 "" "")))]
1524 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1525 "add %0,%0\;bcc %1"
1526 [(set_attr "cc" "clobber")])
1527