mn10300.md (cmpsi): Tell reload to disregard the first alternative.
[gcc.git] / gcc / config / mn10300 / mn10300.md
1 ;; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
3 ;; Free Software Foundation, Inc.
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 "nonimmediate_operand" "=d*x*a,d*x,d*x*a,d*x*a,m")
61 (match_operand:QI 1 "general_operand" "0,I,d*xai,m,d*xa"))]
62 "TARGET_AM33
63 && (register_operand (operands[0], QImode)
64 || register_operand (operands[1], QImode))"
65 "*
66 {
67 switch (which_alternative)
68 {
69 case 0:
70 return \"nop\";
71 case 1:
72 return \"clr %0\";
73 case 2:
74 if (GET_CODE (operands[1]) == CONST_DOUBLE)
75 {
76 rtx xoperands[2];
77 xoperands[0] = operands[0];
78 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
79 output_asm_insn (\"mov %1,%0\", xoperands);
80 return \"\";
81 }
82
83 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
84 && GET_CODE (operands[1]) == CONST_INT)
85 {
86 HOST_WIDE_INT val = INTVAL (operands[1]);
87
88 if (((val & 0x80) && ! (val & 0xffffff00))
89 || ((val & 0x800000) && ! (val & 0xff000000)))
90 return \"movu %1,%0\";
91 }
92 return \"mov %1,%0\";
93 case 3:
94 case 4:
95 return \"movbu %1,%0\";
96 default:
97 abort ();
98 }
99 }"
100 [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
101
102 (define_insn ""
103 [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
104 (match_operand:QI 1 "general_operand" "0,I,dai,m,d"))]
105 "register_operand (operands[0], QImode)
106 || register_operand (operands[1], QImode)"
107 "*
108 {
109 switch (which_alternative)
110 {
111 case 0:
112 return \"nop\";
113 case 1:
114 return \"clr %0\";
115 case 2:
116 if (GET_CODE (operands[1]) == CONST_DOUBLE)
117 {
118 rtx xoperands[2];
119 xoperands[0] = operands[0];
120 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
121 output_asm_insn (\"mov %1,%0\", xoperands);
122 return \"\";
123 }
124
125 return \"mov %1,%0\";
126 case 3:
127 case 4:
128 return \"movbu %1,%0\";
129 default:
130 abort ();
131 }
132 }"
133 [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
134
135 ;; movhi
136
137 (define_expand "movhi"
138 [(set (match_operand:HI 0 "general_operand" "")
139 (match_operand:HI 1 "general_operand" ""))]
140 ""
141 "
142 {
143 /* One of the ops has to be in a register */
144 if (!register_operand (operand1, HImode)
145 && !register_operand (operand0, HImode))
146 operands[1] = copy_to_mode_reg (HImode, operand1);
147 }")
148
149 (define_insn ""
150 [(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a,d*x,d*x*a,d*x*a,m")
151 (match_operand:HI 1 "general_operand" "0,I,d*x*ai,m,d*x*a"))]
152 "TARGET_AM33
153 && (register_operand (operands[0], HImode)
154 || register_operand (operands[1], HImode))"
155 "*
156 {
157 switch (which_alternative)
158 {
159 case 0:
160 return \"nop\";
161 case 1:
162 return \"clr %0\";
163 case 2:
164 if (GET_CODE (operands[1]) == CONST_DOUBLE)
165 {
166 rtx xoperands[2];
167 xoperands[0] = operands[0];
168 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
169 output_asm_insn (\"mov %1,%0\", xoperands);
170 return \"\";
171 }
172
173 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
174 && GET_CODE (operands[1]) == CONST_INT)
175 {
176 HOST_WIDE_INT val = INTVAL (operands[1]);
177
178 if (((val & 0x80) && ! (val & 0xffffff00))
179 || ((val & 0x800000) && ! (val & 0xff000000)))
180 return \"movu %1,%0\";
181 }
182 return \"mov %1,%0\";
183 case 3:
184 case 4:
185 return \"movhu %1,%0\";
186 default:
187 abort ();
188 }
189 }"
190 [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
191
192 (define_insn ""
193 [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
194 (match_operand:HI 1 "general_operand" "0,I,dai,m,d"))]
195 "register_operand (operands[0], HImode)
196 || register_operand (operands[1], HImode)"
197 "*
198 {
199 switch (which_alternative)
200 {
201 case 0:
202 return \"nop\";
203 case 1:
204 return \"clr %0\";
205 case 2:
206 if (GET_CODE (operands[1]) == CONST_DOUBLE)
207 {
208 rtx xoperands[2];
209 xoperands[0] = operands[0];
210 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
211 output_asm_insn (\"mov %1,%0\", xoperands);
212 return \"\";
213 }
214 return \"mov %1,%0\";
215 case 3:
216 case 4:
217 return \"movhu %1,%0\";
218 default:
219 abort ();
220 }
221 }"
222 [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
223
224 ;; movsi and helpers
225
226 ;; We use this to handle addition of two values when one operand is the
227 ;; stack pointer and the other is a memory reference of some kind. Reload
228 ;; does not handle them correctly without this expander.
229 (define_expand "reload_insi"
230 [(set (match_operand:SI 0 "register_operand" "=a")
231 (match_operand:SI 1 "impossible_plus_operand" ""))
232 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
233 ""
234 "
235 {
236 if (XEXP (operands[1], 0) == stack_pointer_rtx)
237 {
238 if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
239 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
240 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
241 emit_move_insn (operands[2],
242 gen_rtx_ZERO_EXTEND
243 (GET_MODE (XEXP (operands[1], 1)),
244 SUBREG_REG (XEXP (operands[1], 1))));
245 else
246 emit_move_insn (operands[2], XEXP (operands[1], 1));
247 emit_move_insn (operands[0], XEXP (operands[1], 0));
248 }
249 else
250 {
251 if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
252 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
253 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
254 emit_move_insn (operands[2],
255 gen_rtx_ZERO_EXTEND
256 (GET_MODE (XEXP (operands[1], 0)),
257 SUBREG_REG (XEXP (operands[1], 0))));
258 else
259 emit_move_insn (operands[2], XEXP (operands[1], 0));
260 emit_move_insn (operands[0], XEXP (operands[1], 1));
261 }
262 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
263 DONE;
264 }")
265
266 (define_expand "movsi"
267 [(set (match_operand:SI 0 "general_operand" "")
268 (match_operand:SI 1 "general_operand" ""))]
269 ""
270 "
271 {
272 /* One of the ops has to be in a register */
273 if (!register_operand (operand1, SImode)
274 && !register_operand (operand0, SImode))
275 operands[1] = copy_to_mode_reg (SImode, operand1);
276 }")
277
278 (define_insn ""
279 [(set (match_operand:SI 0 "nonimmediate_operand"
280 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y")
281 (match_operand:SI 1 "general_operand"
282 "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,!*y,axR"))]
283 "register_operand (operands[0], SImode)
284 || register_operand (operands[1], SImode)"
285 "*
286 {
287 switch (which_alternative)
288 {
289 case 0:
290 case 1:
291 return \"nop\";
292 case 2:
293 return \"clr %0\";
294 case 3:
295 case 4:
296 case 5:
297 case 6:
298 case 7:
299 case 8:
300 case 9:
301 case 10:
302 case 11:
303 case 12:
304 case 13:
305 if (GET_CODE (operands[1]) == CONST_DOUBLE)
306 {
307 rtx xoperands[2];
308 xoperands[0] = operands[0];
309 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
310 output_asm_insn (\"mov %1,%0\", xoperands);
311 return \"\";
312 }
313
314 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
315 && GET_CODE (operands[1]) == CONST_INT)
316 {
317 HOST_WIDE_INT val = INTVAL (operands[1]);
318
319 if (((val & 0x80) && ! (val & 0xffffff00))
320 || ((val & 0x800000) && ! (val & 0xff000000)))
321 return \"movu %1,%0\";
322 }
323 return \"mov %1,%0\";
324 default:
325 abort ();
326 }
327 }"
328 [(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")])
329
330 (define_expand "movsf"
331 [(set (match_operand:SF 0 "general_operand" "")
332 (match_operand:SF 1 "general_operand" ""))]
333 ""
334 "
335 {
336 /* One of the ops has to be in a register */
337 if (!register_operand (operand1, SFmode)
338 && !register_operand (operand0, SFmode))
339 operands[1] = copy_to_mode_reg (SFmode, operand1);
340 }")
341
342 (define_insn ""
343 [(set (match_operand:SF 0 "nonimmediate_operand" "=dx,ax,dx,a,daxm,dax")
344 (match_operand:SF 1 "general_operand" "0,0,G,G,dax,daxFm"))]
345 "register_operand (operands[0], SFmode)
346 || register_operand (operands[1], SFmode)"
347 "*
348 {
349 switch (which_alternative)
350 {
351 case 0:
352 case 1:
353 return \"nop\";
354 case 2:
355 return \"clr %0\";
356 case 3:
357 case 4:
358 case 5:
359 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
360 && GET_CODE (operands[1]) == CONST_INT)
361 {
362 HOST_WIDE_INT val = INTVAL (operands[1]);
363
364 if (((val & 0x80) && ! (val & 0xffffff00))
365 || ((val & 0x800000) && ! (val & 0xff000000)))
366 return \"movu %1,%0\";
367 }
368 return \"mov %1,%0\";
369 default:
370 abort ();
371 }
372 }"
373 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")])
374
375 (define_expand "movdi"
376 [(set (match_operand:DI 0 "general_operand" "")
377 (match_operand:DI 1 "general_operand" ""))]
378 ""
379 "
380 {
381 /* One of the ops has to be in a register */
382 if (!register_operand (operand1, DImode)
383 && !register_operand (operand0, DImode))
384 operands[1] = copy_to_mode_reg (DImode, operand1);
385 }")
386
387 (define_insn ""
388 [(set (match_operand:DI 0 "nonimmediate_operand"
389 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
390 (match_operand:DI 1 "general_operand"
391 "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim"))]
392 "register_operand (operands[0], DImode)
393 || register_operand (operands[1], DImode)"
394 "*
395 {
396 long val[2];
397 REAL_VALUE_TYPE rv;
398
399 switch (which_alternative)
400 {
401 case 0:
402 case 1:
403 return \"nop\";
404
405 case 2:
406 return \"clr %L0\;clr %H0\";
407
408 case 3:
409 if (rtx_equal_p (operands[0], operands[1]))
410 return \"sub %L1,%L0\;mov %L0,%H0\";
411 else
412 return \"mov %1,%L0\;mov %L0,%H0\";
413 case 4:
414 case 5:
415 case 6:
416 case 7:
417 case 8:
418 case 9:
419 case 10:
420 case 11:
421 if (GET_CODE (operands[1]) == CONST_INT)
422 {
423 rtx low, high;
424 split_double (operands[1], &low, &high);
425 val[0] = INTVAL (low);
426 val[1] = INTVAL (high);
427 }
428 if (GET_CODE (operands[1]) == CONST_DOUBLE)
429 {
430 if (GET_MODE (operands[1]) == DFmode)
431 {
432 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
433 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
434 }
435 else if (GET_MODE (operands[1]) == VOIDmode
436 || GET_MODE (operands[1]) == DImode)
437 {
438 val[0] = CONST_DOUBLE_LOW (operands[1]);
439 val[1] = CONST_DOUBLE_HIGH (operands[1]);
440 }
441 }
442
443 if (GET_CODE (operands[1]) == MEM
444 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
445 {
446 rtx temp = operands[0];
447
448 while (GET_CODE (temp) == SUBREG)
449 temp = SUBREG_REG (temp);
450
451 if (GET_CODE (temp) != REG)
452 abort ();
453
454 if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
455 XEXP (operands[1], 0)))
456 return \"mov %H1,%H0\;mov %L1,%L0\";
457 else
458 return \"mov %L1,%L0\;mov %H1,%H0\";
459
460 }
461 else if (GET_CODE (operands[1]) == MEM
462 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
463 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
464 {
465 rtx xoperands[2];
466
467 xoperands[0] = operands[0];
468 xoperands[1] = XEXP (operands[1], 0);
469
470 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
471 xoperands);
472 return \"\";
473 }
474 else
475 {
476 if ((GET_CODE (operands[1]) == CONST_INT
477 || GET_CODE (operands[1]) == CONST_DOUBLE)
478 && val[0] == 0)
479 {
480 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
481 output_asm_insn (\"clr %L0\", operands);
482 else
483 output_asm_insn (\"mov %L1,%L0\", operands);
484 }
485 else if ((GET_CODE (operands[1]) == CONST_INT
486 || GET_CODE (operands[1]) == CONST_DOUBLE)
487 && (REGNO_REG_CLASS (true_regnum (operands[0]))
488 == EXTENDED_REGS)
489 && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
490 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
491 output_asm_insn (\"movu %1,%0\", operands);
492 else
493 output_asm_insn (\"mov %L1,%L0\", operands);
494
495 if ((GET_CODE (operands[1]) == CONST_INT
496 || GET_CODE (operands[1]) == CONST_DOUBLE)
497 && val[1] == 0)
498 {
499 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
500 output_asm_insn (\"clr %H0\", operands);
501 else
502 output_asm_insn (\"mov %H1,%H0\", operands);
503 }
504 else if ((GET_CODE (operands[1]) == CONST_INT
505 || GET_CODE (operands[1]) == CONST_DOUBLE)
506 && val[0] == val[1])
507 output_asm_insn (\"mov %L0,%H0\", operands);
508 else if ((GET_CODE (operands[1]) == CONST_INT
509 || GET_CODE (operands[1]) == CONST_DOUBLE)
510 && (REGNO_REG_CLASS (true_regnum (operands[0]))
511 == EXTENDED_REGS)
512 && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
513 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
514 output_asm_insn (\"movu %1,%0\", operands);
515 else
516 output_asm_insn (\"mov %H1,%H0\", operands);
517 return \"\";
518 }
519 default:
520 abort ();
521 }
522 }"
523 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
524
525 (define_expand "movdf"
526 [(set (match_operand:DF 0 "general_operand" "")
527 (match_operand:DF 1 "general_operand" ""))]
528 ""
529 "
530 {
531 /* One of the ops has to be in a register */
532 if (!register_operand (operand1, DFmode)
533 && !register_operand (operand0, DFmode))
534 operands[1] = copy_to_mode_reg (DFmode, operand1);
535 }")
536
537 (define_insn ""
538 [(set (match_operand:DF 0 "nonimmediate_operand"
539 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
540 (match_operand:DF 1 "general_operand"
541 "0,0,G,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
542 "register_operand (operands[0], DFmode)
543 || register_operand (operands[1], DFmode)"
544 "*
545 {
546 long val[2];
547 REAL_VALUE_TYPE rv;
548
549 switch (which_alternative)
550 {
551 case 0:
552 case 1:
553 return \"nop\";
554
555 case 2:
556 return \"clr %L0\;clr %H0\";
557
558 case 3:
559 if (rtx_equal_p (operands[0], operands[1]))
560 return \"sub %L1,%L0\;mov %L0,%H0\";
561 else
562 return \"mov %1,%L0\;mov %L0,%H0\";
563 case 4:
564 case 5:
565 case 6:
566 case 7:
567 case 8:
568 case 9:
569 case 10:
570 case 11:
571 if (GET_CODE (operands[1]) == CONST_INT)
572 {
573 rtx low, high;
574 split_double (operands[1], &low, &high);
575 val[0] = INTVAL (low);
576 val[1] = INTVAL (high);
577 }
578 if (GET_CODE (operands[1]) == CONST_DOUBLE)
579 {
580 if (GET_MODE (operands[1]) == DFmode)
581 {
582 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
583 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
584 }
585 else if (GET_MODE (operands[1]) == VOIDmode
586 || GET_MODE (operands[1]) == DImode)
587 {
588 val[0] = CONST_DOUBLE_LOW (operands[1]);
589 val[1] = CONST_DOUBLE_HIGH (operands[1]);
590 }
591 }
592
593 if (GET_CODE (operands[1]) == MEM
594 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
595 {
596 rtx temp = operands[0];
597
598 while (GET_CODE (temp) == SUBREG)
599 temp = SUBREG_REG (temp);
600
601 if (GET_CODE (temp) != REG)
602 abort ();
603
604 if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
605 XEXP (operands[1], 0)))
606 return \"mov %H1,%H0\;mov %L1,%L0\";
607 else
608 return \"mov %L1,%L0\;mov %H1,%H0\";
609
610 }
611 else if (GET_CODE (operands[1]) == MEM
612 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
613 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
614 {
615 rtx xoperands[2];
616
617 xoperands[0] = operands[0];
618 xoperands[1] = XEXP (operands[1], 0);
619
620 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
621 xoperands);
622 return \"\";
623 }
624 else
625 {
626 if ((GET_CODE (operands[1]) == CONST_INT
627 || GET_CODE (operands[1]) == CONST_DOUBLE)
628 && val[0] == 0)
629 {
630 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
631 output_asm_insn (\"clr %L0\", operands);
632 else
633 output_asm_insn (\"mov %L1,%L0\", operands);
634 }
635 else if ((GET_CODE (operands[1]) == CONST_INT
636 || GET_CODE (operands[1]) == CONST_DOUBLE)
637 && (REGNO_REG_CLASS (true_regnum (operands[0]))
638 == EXTENDED_REGS)
639 && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
640 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
641 output_asm_insn (\"movu %1,%0\", operands);
642 else
643 output_asm_insn (\"mov %L1,%L0\", operands);
644
645 if ((GET_CODE (operands[1]) == CONST_INT
646 || GET_CODE (operands[1]) == CONST_DOUBLE)
647 && val[1] == 0)
648 {
649 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
650 output_asm_insn (\"clr %H0\", operands);
651 else
652 output_asm_insn (\"mov %H1,%H0\", operands);
653 }
654 else if ((GET_CODE (operands[1]) == CONST_INT
655 || GET_CODE (operands[1]) == CONST_DOUBLE)
656 && val[0] == val[1])
657 output_asm_insn (\"mov %L0,%H0\", operands);
658 else if ((GET_CODE (operands[1]) == CONST_INT
659 || GET_CODE (operands[1]) == CONST_DOUBLE)
660 && (REGNO_REG_CLASS (true_regnum (operands[0]))
661 == EXTENDED_REGS)
662 && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
663 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
664 output_asm_insn (\"movu %1,%0\", operands);
665 else
666 output_asm_insn (\"mov %H1,%H0\", operands);
667 return \"\";
668 }
669 default:
670 abort ();
671 }
672 }"
673 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
674
675
676 \f
677 ;; ----------------------------------------------------------------------
678 ;; TEST INSTRUCTIONS
679 ;; ----------------------------------------------------------------------
680
681 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
682 ;; when we start trying to optimize this port.
683 (define_insn "tstsi"
684 [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
685 ""
686 "* return output_tst (operands[0], insn);"
687 [(set_attr "cc" "set_znv")])
688
689 (define_insn ""
690 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
691 "TARGET_AM33"
692 "* return output_tst (operands[0], insn);"
693 [(set_attr "cc" "set_znv")])
694
695 (define_insn ""
696 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
697 ""
698 "* return output_tst (operands[0], insn);"
699 [(set_attr "cc" "set_znv")])
700
701 (define_insn ""
702 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
703 "TARGET_AM33"
704 "* return output_tst (operands[0], insn);"
705 [(set_attr "cc" "set_znv")])
706
707 (define_insn ""
708 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
709 ""
710 "* return output_tst (operands[0], insn);"
711 [(set_attr "cc" "set_znv")])
712
713 ;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
714 ;; its operands hold equal values, but the operands of a cmp
715 ;; instruction must be distinct registers. In the case where we'd
716 ;; like to compare a register to itself, we can achieve this effect
717 ;; with a btst 0,d0 instead. (This will not alter the contents of d0
718 ;; but will have the proper effect on cc0. Using d0 is arbitrary; any
719 ;; data register would work.)
720
721 ;; Even though the first alternative would be preferrable if it can
722 ;; possibly match, reload must not be given the opportunity to attempt
723 ;; to use it. It assumes that such matches can only occur when one of
724 ;; the operands is used for input and the other for output. Since
725 ;; this is not the case, it abort()s. Indeed, such a reload cannot be
726 ;; possibly satisfied, so just mark the alternative with a `!', so
727 ;; that it is not considered by reload.
728
729 (define_insn "cmpsi"
730 [(set (cc0)
731 (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
732 (match_operand:SI 1 "nonmemory_operand" "*0,daxi")))]
733 ""
734 "@
735 btst 0,d0
736 cmp %1,%0"
737 [(set_attr "cc" "compare,compare")])
738 \f
739 ;; ----------------------------------------------------------------------
740 ;; ADD INSTRUCTIONS
741 ;; ----------------------------------------------------------------------
742
743 (define_expand "addsi3"
744 [(set (match_operand:SI 0 "register_operand" "")
745 (plus:SI (match_operand:SI 1 "register_operand" "")
746 (match_operand:SI 2 "nonmemory_operand" "")))]
747 ""
748 "")
749
750 (define_insn ""
751 [(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
752 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax")
753 (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))]
754 "TARGET_AM33"
755 "*
756 {
757 switch (which_alternative)
758 {
759 case 0:
760 case 1:
761 return \"inc %0\";
762 case 2:
763 case 3:
764 return \"inc4 %0\";
765 case 4:
766 case 5:
767 return \"add %2,%0\";
768 case 6:
769 {
770 enum reg_class src1_class, src2_class, dst_class;
771
772 src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
773 src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
774 dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
775
776 /* I'm not sure if this can happen or not. Might as well be prepared
777 and generate the best possible code if it does happen. */
778 if (true_regnum (operands[0]) == true_regnum (operands[1]))
779 return \"add %2,%0\";
780 if (true_regnum (operands[0]) == true_regnum (operands[2]))
781 return \"add %1,%0\";
782
783 /* Catch cases where no extended register was used. These should be
784 handled just like the mn10300. */
785 if (src1_class != EXTENDED_REGS
786 && src2_class != EXTENDED_REGS
787 && dst_class != EXTENDED_REGS)
788 {
789 /* We have to copy one of the sources into the destination, then
790 add the other source to the destination.
791
792 Carefully select which source to copy to the destination; a naive
793 implementation will waste a byte when the source classes are
794 different and the destination is an address register. Selecting
795 the lowest cost register copy will optimize this sequence. */
796 if (REGNO_REG_CLASS (true_regnum (operands[1]))
797 == REGNO_REG_CLASS (true_regnum (operands[0])))
798 return \"mov %1,%0\;add %2,%0\";
799 return \"mov %2,%0\;add %1,%0\";
800 }
801
802 /* At least one register is an extended register. */
803
804 /* The three operand add instruction on the am33 is a win iff the
805 output register is an extended register, or if both source
806 registers are extended registers. */
807 if (dst_class == EXTENDED_REGS
808 || src1_class == src2_class)
809 return \"add %2,%1,%0\";
810
811 /* It is better to copy one of the sources to the destination, then
812 perform a 2 address add. The destination in this case must be
813 an address or data register and one of the sources must be an
814 extended register and the remaining source must not be an extended
815 register.
816
817 The best code for this case is to copy the extended reg to the
818 destination, then emit a two address add. */
819 if (src1_class == EXTENDED_REGS)
820 return \"mov %1,%0\;add %2,%0\";
821 return \"mov %2,%0\;add %1,%0\";
822 }
823 default:
824 abort ();
825 }
826 }"
827 [(set_attr "cc" "set_zn,none_0hit,set_zn,none_0hit,set_zn,none_0hit,set_zn")])
828
829 (define_insn ""
830 [(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax")
831 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
832 (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
833 ""
834 "*
835 {
836 switch (which_alternative)
837 {
838 case 0:
839 case 1:
840 return \"inc %0\";
841 case 2:
842 return \"inc4 %0\";
843 case 3:
844 case 4:
845 return \"add %2,%0\";
846 case 5:
847 /* I'm not sure if this can happen or not. Might as well be prepared
848 and generate the best possible code if it does happen. */
849 if (true_regnum (operands[0]) == true_regnum (operands[1]))
850 return \"add %2,%0\";
851 if (true_regnum (operands[0]) == true_regnum (operands[2]))
852 return \"add %1,%0\";
853
854 /* We have to copy one of the sources into the destination, then add
855 the other source to the destination.
856
857 Carefully select which source to copy to the destination; a naive
858 implementation will waste a byte when the source classes are different
859 and the destination is an address register. Selecting the lowest
860 cost register copy will optimize this sequence. */
861 if (REGNO_REG_CLASS (true_regnum (operands[1]))
862 == REGNO_REG_CLASS (true_regnum (operands[0])))
863 return \"mov %1,%0\;add %2,%0\";
864 return \"mov %2,%0\;add %1,%0\";
865 default:
866 abort ();
867 }
868 }"
869 [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
870
871 ;; ----------------------------------------------------------------------
872 ;; SUBTRACT INSTRUCTIONS
873 ;; ----------------------------------------------------------------------
874
875 (define_expand "subsi3"
876 [(set (match_operand:SI 0 "register_operand" "")
877 (minus:SI (match_operand:SI 1 "register_operand" "")
878 (match_operand:SI 2 "nonmemory_operand" "")))]
879 ""
880 "")
881
882 (define_insn ""
883 [(set (match_operand:SI 0 "register_operand" "=dax,!dax")
884 (minus:SI (match_operand:SI 1 "register_operand" "0,dax")
885 (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
886 "TARGET_AM33"
887 "*
888 {
889 if (true_regnum (operands[0]) == true_regnum (operands[1]))
890 return \"sub %2,%0\";
891 else
892 {
893 enum reg_class src1_class, src2_class, dst_class;
894
895 src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
896 src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
897 dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
898
899 /* If no extended registers are used, then the best way to handle
900 this is to copy the first source operand into the destination
901 and emit a two address subtraction. */
902 if (src1_class != EXTENDED_REGS
903 && src2_class != EXTENDED_REGS
904 && dst_class != EXTENDED_REGS
905 && true_regnum (operands[0]) != true_regnum (operands[2]))
906 return \"mov %1,%0\;sub %2,%0\";
907 return \"sub %2,%1,%0\";
908 }
909 }"
910 [(set_attr "cc" "set_zn")])
911
912 (define_insn ""
913 [(set (match_operand:SI 0 "register_operand" "=dax")
914 (minus:SI (match_operand:SI 1 "register_operand" "0")
915 (match_operand:SI 2 "nonmemory_operand" "daxi")))]
916 ""
917 "sub %2,%0"
918 [(set_attr "cc" "set_zn")])
919
920 (define_expand "negsi2"
921 [(set (match_operand:SI 0 "register_operand" "")
922 (neg:SI (match_operand:SI 1 "register_operand" "")))]
923 ""
924 "
925 {
926 rtx target = gen_reg_rtx (SImode);
927
928 emit_move_insn (target, GEN_INT (0));
929 emit_insn (gen_subsi3 (target, target, operands[1]));
930 emit_move_insn (operands[0], target);
931 DONE;
932 }")
933
934 ;; ----------------------------------------------------------------------
935 ;; MULTIPLY INSTRUCTIONS
936 ;; ----------------------------------------------------------------------
937
938 (define_insn "mulsidi3"
939 [(set (match_operand:DI 0 "register_operand" "=dax")
940 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
941 (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
942 "TARGET_AM33"
943 "mul %1,%2,%H0,%L0"
944 [(set_attr "cc" "set_zn")])
945
946 (define_insn "umulsidi3"
947 [(set (match_operand:DI 0 "register_operand" "=dax")
948 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
949 (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
950 "TARGET_AM33"
951 "mulu %1,%2,%H0,%L0"
952 [(set_attr "cc" "set_zn")])
953
954 (define_expand "mulsi3"
955 [(set (match_operand:SI 0 "register_operand" "")
956 (mult:SI (match_operand:SI 1 "register_operand" "")
957 (match_operand:SI 2 "register_operand" "")))]
958 ""
959 "")
960
961 (define_insn ""
962 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
963 (mult:SI (match_operand:SI 1 "register_operand" "%0,0")
964 (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
965 "TARGET_AM33"
966 "*
967 {
968 if (TARGET_MULT_BUG)
969 return \"nop\;nop\;mul %2,%0\";
970 else
971 return \"mul %2,%0\";
972 }"
973 [(set_attr "cc" "set_zn")])
974
975 (define_insn ""
976 [(set (match_operand:SI 0 "register_operand" "=dx")
977 (mult:SI (match_operand:SI 1 "register_operand" "%0")
978 (match_operand:SI 2 "register_operand" "dx")))]
979 ""
980 "*
981 {
982 if (TARGET_MULT_BUG)
983 return \"nop\;nop\;mul %2,%0\";
984 else
985 return \"mul %2,%0\";
986 }"
987 [(set_attr "cc" "set_zn")])
988
989 (define_insn "udivmodsi4"
990 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
991 (udiv:SI (match_operand:SI 1 "general_operand" "0")
992 (match_operand:SI 2 "general_operand" "dx")))
993 (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
994 (umod:SI (match_dup 1) (match_dup 2)))]
995 ""
996 "*
997 {
998 output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
999
1000 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1001 return \"divu %2,%0\";
1002 else
1003 return \"divu %2,%0\;mov mdr,%3\";
1004 }"
1005 [(set_attr "cc" "set_zn")])
1006
1007 (define_insn "divmodsi4"
1008 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1009 (div:SI (match_operand:SI 1 "general_operand" "0")
1010 (match_operand:SI 2 "general_operand" "dx")))
1011 (set (match_operand:SI 3 "nonimmediate_operand" "=d")
1012 (mod:SI (match_dup 1) (match_dup 2)))]
1013 ""
1014 "*
1015 {
1016 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1017 return \"ext %0\;div %2,%0\";
1018 else
1019 return \"ext %0\;div %2,%0\;mov mdr,%3\";
1020 }"
1021 [(set_attr "cc" "set_zn")])
1022
1023 \f
1024 ;; ----------------------------------------------------------------------
1025 ;; AND INSTRUCTIONS
1026 ;; ----------------------------------------------------------------------
1027
1028 (define_expand "andsi3"
1029 [(set (match_operand:SI 0 "register_operand" "")
1030 (and:SI (match_operand:SI 1 "register_operand" "")
1031 (match_operand:SI 2 "nonmemory_operand" "")))]
1032 ""
1033 "")
1034
1035 (define_insn ""
1036 [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
1037 (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
1038 (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
1039 "TARGET_AM33"
1040 "*
1041 {
1042 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1043 return \"extbu %0\";
1044 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1045 return \"exthu %0\";
1046 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1047 return \"add %0,%0\;lsr 1,%0\";
1048 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1049 return \"asl2 %0\;lsr 2,%0\";
1050 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1051 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1052 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1053 return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1054 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1055 return \"lsr 1,%0\;add %0,%0\";
1056 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1057 return \"lsr 2,%0\;asl2 %0\";
1058 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1059 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1060 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1061 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1062 if (REG_P (operands[2]) && REG_P (operands[1])
1063 && true_regnum (operands[0]) != true_regnum (operands[1])
1064 && true_regnum (operands[0]) != true_regnum (operands[2])
1065 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1066 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1067 && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1068 return \"mov %1,%0\;and %2,%0\";
1069 if (REG_P (operands[2]) && REG_P (operands[1])
1070 && true_regnum (operands[0]) != true_regnum (operands[1])
1071 && true_regnum (operands[0]) != true_regnum (operands[2]))
1072 return \"and %1,%2,%0\";
1073 if (REG_P (operands[2]) && REG_P (operands[0])
1074 && true_regnum (operands[2]) == true_regnum (operands[0]))
1075 return \"and %1,%0\";
1076 return \"and %2,%0\";
1077 }"
1078 [(set_attr "cc" "none_0hit,set_znv,set_znv")])
1079
1080 (define_insn ""
1081 [(set (match_operand:SI 0 "register_operand" "=dx,dx")
1082 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1083 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
1084 ""
1085 "*
1086 {
1087 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1088 return \"extbu %0\";
1089 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1090 return \"exthu %0\";
1091 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1092 return \"add %0,%0\;lsr 1,%0\";
1093 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1094 return \"asl2 %0\;lsr 2,%0\";
1095 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1096 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1097 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1098 return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1099 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1100 return \"lsr 1,%0\;add %0,%0\";
1101 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1102 return \"lsr 2,%0\;asl2 %0\";
1103 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1104 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1105 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1106 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1107 return \"and %2,%0\";
1108 }"
1109 [(set_attr "cc" "none_0hit,set_znv")])
1110
1111 ;; ----------------------------------------------------------------------
1112 ;; OR INSTRUCTIONS
1113 ;; ----------------------------------------------------------------------
1114
1115 (define_expand "iorsi3"
1116 [(set (match_operand:SI 0 "register_operand" "")
1117 (ior:SI (match_operand:SI 1 "register_operand" "")
1118 (match_operand:SI 2 "nonmemory_operand" "")))]
1119 ""
1120 "")
1121
1122 (define_insn ""
1123 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1124 (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1125 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1126 "TARGET_AM33"
1127 "*
1128 {
1129 if (REG_P (operands[2]) && REG_P (operands[1])
1130 && true_regnum (operands[0]) != true_regnum (operands[1])
1131 && true_regnum (operands[0]) != true_regnum (operands[2])
1132 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1133 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1134 && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1135 return \"mov %1,%0\;or %2,%0\";
1136 if (REG_P (operands[2]) && REG_P (operands[1])
1137 && true_regnum (operands[0]) != true_regnum (operands[1])
1138 && true_regnum (operands[0]) != true_regnum (operands[2]))
1139 return \"or %1,%2,%0\";
1140 if (REG_P (operands[2]) && REG_P (operands[0])
1141 && true_regnum (operands[2]) == true_regnum (operands[0]))
1142 return \"or %1,%0\";
1143 return \"or %2,%0\";
1144 }"
1145 [(set_attr "cc" "set_znv")])
1146
1147 (define_insn ""
1148 [(set (match_operand:SI 0 "register_operand" "=dx")
1149 (ior:SI (match_operand:SI 1 "register_operand" "%0")
1150 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1151 ""
1152 "or %2,%0"
1153 [(set_attr "cc" "set_znv")])
1154
1155 ;; ----------------------------------------------------------------------
1156 ;; XOR INSTRUCTIONS
1157 ;; ----------------------------------------------------------------------
1158
1159 (define_expand "xorsi3"
1160 [(set (match_operand:SI 0 "register_operand" "")
1161 (xor:SI (match_operand:SI 1 "register_operand" "")
1162 (match_operand:SI 2 "nonmemory_operand" "")))]
1163 ""
1164 "")
1165
1166 (define_insn ""
1167 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1168 (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1169 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1170 "TARGET_AM33"
1171 "*
1172 {
1173 if (REG_P (operands[2]) && REG_P (operands[1])
1174 && true_regnum (operands[0]) != true_regnum (operands[1])
1175 && true_regnum (operands[0]) != true_regnum (operands[2])
1176 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1177 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1178 && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1179 return \"mov %1,%0\;xor %2,%0\";
1180 if (REG_P (operands[2]) && REG_P (operands[1])
1181 && true_regnum (operands[0]) != true_regnum (operands[1])
1182 && true_regnum (operands[0]) != true_regnum (operands[2]))
1183 return \"xor %1,%2,%0\";
1184 if (REG_P (operands[2]) && REG_P (operands[0])
1185 && true_regnum (operands[2]) == true_regnum (operands[0]))
1186 return \"xor %1,%0\";
1187 return \"xor %2,%0\";
1188 }"
1189 [(set_attr "cc" "set_znv")])
1190
1191 (define_insn ""
1192 [(set (match_operand:SI 0 "register_operand" "=dx")
1193 (xor:SI (match_operand:SI 1 "register_operand" "%0")
1194 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1195 ""
1196 "xor %2,%0"
1197 [(set_attr "cc" "set_znv")])
1198
1199 ;; ----------------------------------------------------------------------
1200 ;; NOT INSTRUCTIONS
1201 ;; ----------------------------------------------------------------------
1202
1203 (define_expand "one_cmplsi2"
1204 [(set (match_operand:SI 0 "register_operand" "")
1205 (not:SI (match_operand:SI 1 "register_operand" "")))]
1206 ""
1207 "")
1208
1209 (define_insn ""
1210 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1211 (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1212 "TARGET_AM33"
1213 "not %0"
1214 [(set_attr "cc" "set_znv")])
1215
1216 (define_insn ""
1217 [(set (match_operand:SI 0 "register_operand" "=dx")
1218 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1219 ""
1220 "not %0"
1221 [(set_attr "cc" "set_znv")])
1222 \f
1223 ;; -----------------------------------------------------------------
1224 ;; BIT FIELDS
1225 ;; -----------------------------------------------------------------
1226
1227
1228 ;; These set/clear memory in byte sized chunks.
1229 ;;
1230 ;; They are no smaller/faster than loading the value into a register
1231 ;; and storing the register, but they don't need a scratch register
1232 ;; which may allow for better code generation.
1233 (define_insn ""
1234 [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
1235 ""
1236 "@
1237 bclr 255,%A0
1238 clr %0"
1239 [(set_attr "cc" "clobber")])
1240
1241 (define_insn ""
1242 [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
1243 ""
1244 "@
1245 bset 255,%A0
1246 mov -1,%0"
1247 [(set_attr "cc" "clobber,none_0hit")])
1248
1249 (define_insn ""
1250 [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1251 (subreg:QI
1252 (and:SI (subreg:SI (match_dup 0) 0)
1253 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1254 ""
1255 "@
1256 bclr %N1,%A0
1257 and %1,%0"
1258 [(set_attr "cc" "clobber,set_znv")])
1259
1260 (define_insn ""
1261 [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1262 (subreg:QI
1263 (ior:SI (subreg:SI (match_dup 0) 0)
1264 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1265 ""
1266 "@
1267 bset %1,%A0
1268 or %1,%0"
1269 [(set_attr "cc" "clobber,set_znv")])
1270
1271 (define_insn ""
1272 [(set (cc0)
1273 (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1274 (match_operand 1 "const_int_operand" "")
1275 (match_operand 2 "const_int_operand" "")))]
1276 ""
1277 "*
1278 {
1279 int len = INTVAL (operands[1]);
1280 int bit = INTVAL (operands[2]);
1281 int mask = 0;
1282 rtx xoperands[2];
1283
1284 while (len > 0)
1285 {
1286 mask |= (1 << bit);
1287 bit++;
1288 len--;
1289 }
1290
1291 xoperands[0] = operands[0];
1292 xoperands[1] = GEN_INT (mask);
1293 output_asm_insn (\"btst %1,%0\", xoperands);
1294 return \"\";
1295 }"
1296 [(set_attr "cc" "clobber")])
1297
1298 (define_insn ""
1299 [(set (cc0)
1300 (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
1301 (match_operand 1 "const_int_operand" "")
1302 (match_operand 2 "const_int_operand" "")))]
1303 "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1304 "*
1305 {
1306 int len = INTVAL (operands[1]);
1307 int bit = INTVAL (operands[2]);
1308 int mask = 0;
1309 rtx xoperands[2];
1310
1311 while (len > 0)
1312 {
1313 mask |= (1 << bit);
1314 bit++;
1315 len--;
1316 }
1317
1318 /* If the source operand is not a reg (ie it is memory), then extract the
1319 bits from mask that we actually want to test. Note that the mask will
1320 never cross a byte boundary. */
1321 if (!REG_P (operands[0]))
1322 {
1323 if (mask & 0xff)
1324 mask = mask & 0xff;
1325 else if (mask & 0xff00)
1326 mask = (mask >> 8) & 0xff;
1327 else if (mask & 0xff0000)
1328 mask = (mask >> 16) & 0xff;
1329 else if (mask & 0xff000000)
1330 mask = (mask >> 24) & 0xff;
1331 }
1332
1333 xoperands[0] = operands[0];
1334 xoperands[1] = GEN_INT (mask);
1335 if (GET_CODE (operands[0]) == REG)
1336 output_asm_insn (\"btst %1,%0\", xoperands);
1337 else
1338 output_asm_insn (\"btst %1,%A0\", xoperands);
1339 return \"\";
1340 }"
1341 [(set_attr "cc" "clobber")])
1342
1343 (define_insn ""
1344 [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1345 (match_operand:SI 1 "const_int_operand" "")))]
1346 ""
1347 "btst %1,%0"
1348 [(set_attr "cc" "clobber")])
1349
1350 (define_insn ""
1351 [(set (cc0)
1352 (and:SI
1353 (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1354 (match_operand:SI 1 "const_8bit_operand" "")))]
1355 ""
1356 "@
1357 btst %1,%A0
1358 btst %1,%0"
1359 [(set_attr "cc" "clobber")])
1360
1361 \f
1362 ;; ----------------------------------------------------------------------
1363 ;; JUMP INSTRUCTIONS
1364 ;; ----------------------------------------------------------------------
1365
1366 ;; Conditional jump instructions
1367
1368 (define_expand "ble"
1369 [(set (pc)
1370 (if_then_else (le (cc0)
1371 (const_int 0))
1372 (label_ref (match_operand 0 "" ""))
1373 (pc)))]
1374 ""
1375 "")
1376
1377 (define_expand "bleu"
1378 [(set (pc)
1379 (if_then_else (leu (cc0)
1380 (const_int 0))
1381 (label_ref (match_operand 0 "" ""))
1382 (pc)))]
1383 ""
1384 "")
1385
1386 (define_expand "bge"
1387 [(set (pc)
1388 (if_then_else (ge (cc0)
1389 (const_int 0))
1390 (label_ref (match_operand 0 "" ""))
1391 (pc)))]
1392 ""
1393 "")
1394
1395 (define_expand "bgeu"
1396 [(set (pc)
1397 (if_then_else (geu (cc0)
1398 (const_int 0))
1399 (label_ref (match_operand 0 "" ""))
1400 (pc)))]
1401 ""
1402 "")
1403
1404 (define_expand "blt"
1405 [(set (pc)
1406 (if_then_else (lt (cc0)
1407 (const_int 0))
1408 (label_ref (match_operand 0 "" ""))
1409 (pc)))]
1410 ""
1411 "")
1412
1413 (define_expand "bltu"
1414 [(set (pc)
1415 (if_then_else (ltu (cc0)
1416 (const_int 0))
1417 (label_ref (match_operand 0 "" ""))
1418 (pc)))]
1419 ""
1420 "")
1421
1422 (define_expand "bgt"
1423 [(set (pc)
1424 (if_then_else (gt (cc0)
1425 (const_int 0))
1426 (label_ref (match_operand 0 "" ""))
1427 (pc)))]
1428 ""
1429 "")
1430
1431 (define_expand "bgtu"
1432 [(set (pc)
1433 (if_then_else (gtu (cc0)
1434 (const_int 0))
1435 (label_ref (match_operand 0 "" ""))
1436 (pc)))]
1437 ""
1438 "")
1439
1440 (define_expand "beq"
1441 [(set (pc)
1442 (if_then_else (eq (cc0)
1443 (const_int 0))
1444 (label_ref (match_operand 0 "" ""))
1445 (pc)))]
1446 ""
1447 "")
1448
1449 (define_expand "bne"
1450 [(set (pc)
1451 (if_then_else (ne (cc0)
1452 (const_int 0))
1453 (label_ref (match_operand 0 "" ""))
1454 (pc)))]
1455 ""
1456 "")
1457
1458 (define_insn ""
1459 [(set (pc)
1460 (if_then_else (match_operator 1 "comparison_operator"
1461 [(cc0) (const_int 0)])
1462 (label_ref (match_operand 0 "" ""))
1463 (pc)))]
1464 ""
1465 "*
1466 {
1467 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1468 && (GET_CODE (operands[1]) == GT
1469 || GET_CODE (operands[1]) == GE
1470 || GET_CODE (operands[1]) == LE
1471 || GET_CODE (operands[1]) == LT))
1472 return 0;
1473 return \"b%b1 %0\";
1474 }"
1475 [(set_attr "cc" "none")])
1476
1477 (define_insn ""
1478 [(set (pc)
1479 (if_then_else (match_operator 1 "comparison_operator"
1480 [(cc0) (const_int 0)])
1481 (pc)
1482 (label_ref (match_operand 0 "" ""))))]
1483 ""
1484 "*
1485 {
1486 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1487 && (GET_CODE (operands[1]) == GT
1488 || GET_CODE (operands[1]) == GE
1489 || GET_CODE (operands[1]) == LE
1490 || GET_CODE (operands[1]) == LT))
1491 return 0;
1492 return \"b%B1 %0\";
1493 }"
1494 [(set_attr "cc" "none")])
1495
1496 ;; Unconditional and other jump instructions.
1497
1498 (define_insn "jump"
1499 [(set (pc)
1500 (label_ref (match_operand 0 "" "")))]
1501 ""
1502 "jmp %l0"
1503 [(set_attr "cc" "none")])
1504
1505 (define_insn "indirect_jump"
1506 [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1507 ""
1508 "jmp (%0)"
1509 [(set_attr "cc" "none")])
1510
1511 (define_insn "tablejump"
1512 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1513 (use (label_ref (match_operand 1 "" "")))]
1514 ""
1515 "jmp (%0)"
1516 [(set_attr "cc" "none")])
1517
1518 ;; Call subroutine with no return value.
1519
1520 (define_expand "call"
1521 [(call (match_operand:QI 0 "general_operand" "")
1522 (match_operand:SI 1 "general_operand" ""))]
1523 ""
1524 "
1525 {
1526 if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
1527 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1528 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1529 DONE;
1530 }")
1531
1532 (define_insn "call_internal"
1533 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1534 (match_operand:SI 1 "general_operand" "g"))]
1535 ""
1536 "*
1537 {
1538 if (REG_P (operands[0]))
1539 return \"calls %C0\";
1540 else
1541 return \"call %C0,[],0\";
1542 }"
1543 [(set_attr "cc" "clobber")])
1544
1545 ;; Call subroutine, returning value in operand 0
1546 ;; (which must be a hard register).
1547
1548 (define_expand "call_value"
1549 [(set (match_operand 0 "" "")
1550 (call (match_operand:QI 1 "general_operand" "")
1551 (match_operand:SI 2 "general_operand" "")))]
1552 ""
1553 "
1554 {
1555 if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1556 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1557 emit_call_insn (gen_call_value_internal (operands[0],
1558 XEXP (operands[1], 0),
1559 operands[2]));
1560 DONE;
1561 }")
1562
1563 (define_insn "call_value_internal"
1564 [(set (match_operand 0 "" "=dax")
1565 (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1566 (match_operand:SI 2 "general_operand" "g")))]
1567 ""
1568 "*
1569 {
1570 if (REG_P (operands[1]))
1571 return \"calls %C1\";
1572 else
1573 return \"call %C1,[],0\";
1574 }"
1575 [(set_attr "cc" "clobber")])
1576
1577 (define_expand "untyped_call"
1578 [(parallel [(call (match_operand 0 "" "")
1579 (const_int 0))
1580 (match_operand 1 "" "")
1581 (match_operand 2 "" "")])]
1582 ""
1583 "
1584 {
1585 int i;
1586
1587 emit_call_insn (gen_call (operands[0], const0_rtx));
1588
1589 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1590 {
1591 rtx set = XVECEXP (operands[2], 0, i);
1592 emit_move_insn (SET_DEST (set), SET_SRC (set));
1593 }
1594 DONE;
1595 }")
1596
1597 (define_insn "nop"
1598 [(const_int 0)]
1599 ""
1600 "nop"
1601 [(set_attr "cc" "none")])
1602 \f
1603 ;; ----------------------------------------------------------------------
1604 ;; EXTEND INSTRUCTIONS
1605 ;; ----------------------------------------------------------------------
1606
1607 (define_expand "zero_extendqisi2"
1608 [(set (match_operand:SI 0 "general_operand" "")
1609 (zero_extend:SI
1610 (match_operand:QI 1 "general_operand" "")))]
1611 ""
1612 "")
1613
1614 (define_insn ""
1615 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1616 (zero_extend:SI
1617 (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1618 "TARGET_AM33"
1619 "@
1620 extbu %0
1621 mov %1,%0\;extbu %0
1622 movbu %1,%0
1623 extbu %0
1624 mov %1,%0\;extbu %0
1625 movbu %1,%0"
1626 [(set_attr "cc" "none_0hit")])
1627
1628 (define_insn ""
1629 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1630 (zero_extend:SI
1631 (match_operand:QI 1 "general_operand" "0,d,m")))]
1632 ""
1633 "@
1634 extbu %0
1635 mov %1,%0\;extbu %0
1636 movbu %1,%0"
1637 [(set_attr "cc" "none_0hit")])
1638
1639 (define_expand "zero_extendhisi2"
1640 [(set (match_operand:SI 0 "general_operand" "")
1641 (zero_extend:SI
1642 (match_operand:HI 1 "general_operand" "")))]
1643 ""
1644 "")
1645
1646 (define_insn ""
1647 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1648 (zero_extend:SI
1649 (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1650 "TARGET_AM33"
1651 "@
1652 exthu %0
1653 mov %1,%0\;exthu %0
1654 movhu %1,%0
1655 exthu %0
1656 mov %1,%0\;exthu %0
1657 movhu %1,%0"
1658 [(set_attr "cc" "none_0hit")])
1659
1660 (define_insn ""
1661 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1662 (zero_extend:SI
1663 (match_operand:HI 1 "general_operand" "0,dx,m")))]
1664 ""
1665 "@
1666 exthu %0
1667 mov %1,%0\;exthu %0
1668 movhu %1,%0"
1669 [(set_attr "cc" "none_0hit")])
1670
1671 ;;- sign extension instructions
1672
1673 (define_expand "extendqisi2"
1674 [(set (match_operand:SI 0 "general_operand" "")
1675 (sign_extend:SI
1676 (match_operand:QI 1 "general_operand" "")))]
1677 ""
1678 "")
1679
1680 (define_insn ""
1681 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1682 (sign_extend:SI
1683 (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1684 "TARGET_AM33"
1685 "@
1686 extb %0
1687 mov %1,%0\;extb %0
1688 extb %0
1689 mov %1,%0\;extb %0"
1690 [(set_attr "cc" "none_0hit")])
1691
1692 (define_insn ""
1693 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1694 (sign_extend:SI
1695 (match_operand:QI 1 "general_operand" "0,dx")))]
1696 ""
1697 "@
1698 extb %0
1699 mov %1,%0\;extb %0"
1700 [(set_attr "cc" "none_0hit")])
1701
1702 (define_expand "extendhisi2"
1703 [(set (match_operand:SI 0 "general_operand" "")
1704 (sign_extend:SI
1705 (match_operand:HI 1 "general_operand" "")))]
1706 ""
1707 "")
1708
1709 (define_insn ""
1710 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1711 (sign_extend:SI
1712 (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
1713 "TARGET_AM33"
1714 "@
1715 exth %0
1716 mov %1,%0\;exth %0
1717 exth %0
1718 mov %1,%0\;exth %0"
1719 [(set_attr "cc" "none_0hit")])
1720
1721 (define_insn ""
1722 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1723 (sign_extend:SI
1724 (match_operand:HI 1 "general_operand" "0,dx")))]
1725 ""
1726 "@
1727 exth %0
1728 mov %1,%0\;exth %0"
1729 [(set_attr "cc" "none_0hit")])
1730 \f
1731 ;; ----------------------------------------------------------------------
1732 ;; SHIFTS
1733 ;; ----------------------------------------------------------------------
1734
1735 (define_expand "ashlsi3"
1736 [(set (match_operand:SI 0 "register_operand" "")
1737 (ashift:SI
1738 (match_operand:SI 1 "register_operand" "")
1739 (match_operand:QI 2 "nonmemory_operand" "")))]
1740 ""
1741 "")
1742
1743 (define_insn ""
1744 [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
1745 (ashift:SI
1746 (match_operand:SI 1 "register_operand" "0,0,dax")
1747 (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
1748 "TARGET_AM33"
1749 "*
1750 {
1751 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
1752 return \"add %0,%0\";
1753
1754 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
1755 return \"asl2 %0\";
1756
1757 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
1758 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
1759 return \"asl2 %0\;add %0,%0\";
1760
1761 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
1762 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
1763 return \"asl2 %0\;asl2 %0\";
1764
1765 if (true_regnum (operands[1]) == true_regnum (operands[0]))
1766 return \"asl %S2,%0\";
1767
1768 if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1769 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1770 && true_regnum (operands[0]) != true_regnum (operands[2]))
1771 return \"mov %1,%0\;asl %S2,%0\";
1772 return \"asl %2,%1,%0\";
1773 }"
1774 [(set_attr "cc" "set_zn")])
1775
1776 (define_insn ""
1777 [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
1778 (ashift:SI
1779 (match_operand:SI 1 "register_operand" "0,0,0,0,0")
1780 (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
1781 ""
1782 "@
1783 add %0,%0
1784 asl2 %0
1785 asl2 %0\;add %0,%0
1786 asl2 %0\;asl2 %0
1787 asl %S2,%0"
1788 [(set_attr "cc" "set_zn")])
1789
1790 (define_expand "lshrsi3"
1791 [(set (match_operand:SI 0 "register_operand" "")
1792 (lshiftrt:SI
1793 (match_operand:SI 1 "register_operand" "")
1794 (match_operand:QI 2 "nonmemory_operand" "")))]
1795 ""
1796 "")
1797
1798 (define_insn ""
1799 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1800 (lshiftrt:SI
1801 (match_operand:SI 1 "register_operand" "0,dax")
1802 (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
1803 "TARGET_AM33"
1804 "*
1805 {
1806 if (true_regnum (operands[1]) == true_regnum (operands[0]))
1807 return \"lsr %S2,%0\";
1808
1809 if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1810 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1811 && true_regnum (operands[0]) != true_regnum (operands[2]))
1812 return \"mov %1,%0\;lsr %S2,%0\";
1813 return \"lsr %2,%1,%0\";
1814 }"
1815 [(set_attr "cc" "set_zn")])
1816
1817 (define_insn ""
1818 [(set (match_operand:SI 0 "register_operand" "=dx")
1819 (lshiftrt:SI
1820 (match_operand:SI 1 "register_operand" "0")
1821 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1822 ""
1823 "lsr %S2,%0"
1824 [(set_attr "cc" "set_zn")])
1825
1826 (define_expand "ashrsi3"
1827 [(set (match_operand:SI 0 "register_operand" "")
1828 (ashiftrt:SI
1829 (match_operand:SI 1 "register_operand" "")
1830 (match_operand:QI 2 "nonmemory_operand" "")))]
1831 ""
1832 "")
1833
1834 (define_insn ""
1835 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1836 (ashiftrt:SI
1837 (match_operand:SI 1 "register_operand" "0,dax")
1838 (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
1839 "TARGET_AM33"
1840 "*
1841 {
1842 if (true_regnum (operands[1]) == true_regnum (operands[0]))
1843 return \"asr %S2,%0\";
1844
1845 if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1846 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1847 && true_regnum (operands[0]) != true_regnum (operands[2]))
1848 return \"mov %1,%0\;asr %S2,%0\";
1849 return \"asr %2,%1,%0\";
1850 }"
1851 [(set_attr "cc" "set_zn")])
1852
1853 (define_insn ""
1854 [(set (match_operand:SI 0 "register_operand" "=dx")
1855 (ashiftrt:SI
1856 (match_operand:SI 1 "register_operand" "0")
1857 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1858 ""
1859 "asr %S2,%0"
1860 [(set_attr "cc" "set_zn")])
1861
1862 ;; ----------------------------------------------------------------------
1863 ;; FP INSTRUCTIONS
1864 ;; ----------------------------------------------------------------------
1865 ;;
1866 ;; The mn103 series does not have floating point instructions, but since
1867 ;; FP values are held in integer regs, we can clear the high bit easily
1868 ;; which gives us an efficient inline floating point absolute value.
1869 ;;
1870 ;; Similarly for negation of a FP value.
1871 ;;
1872
1873 (define_expand "absdf2"
1874 [(set (match_operand:DF 0 "register_operand" "")
1875 (abs:DF (match_operand:DF 1 "register_operand" "")))]
1876 ""
1877 "
1878 {
1879 rtx target, result, insns;
1880
1881 start_sequence ();
1882 target = operand_subword (operands[0], 1, 1, DFmode);
1883 result = expand_binop (SImode, and_optab,
1884 operand_subword_force (operands[1], 1, DFmode),
1885 GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
1886
1887 if (result == 0)
1888 abort ();
1889
1890 if (result != target)
1891 emit_move_insn (result, target);
1892
1893 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
1894 operand_subword_force (operands[1], 0, DFmode));
1895
1896 insns = get_insns ();
1897 end_sequence ();
1898
1899 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1900 DONE;
1901 }")
1902
1903 (define_expand "abssf2"
1904 [(set (match_operand:SF 0 "register_operand" "")
1905 (abs:SF (match_operand:SF 1 "register_operand" "")))]
1906 ""
1907 "
1908 {
1909 rtx result;
1910 rtx target;
1911
1912 target = operand_subword_force (operands[0], 0, SFmode);
1913 result = expand_binop (SImode, and_optab,
1914 operand_subword_force (operands[1], 0, SFmode),
1915 GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
1916 if (result == 0)
1917 abort ();
1918
1919 if (result != target)
1920 emit_move_insn (result, target);
1921
1922 /* Make a place for REG_EQUAL. */
1923 emit_move_insn (operands[0], operands[0]);
1924 DONE;
1925 }")
1926
1927
1928 (define_expand "negdf2"
1929 [(set (match_operand:DF 0 "register_operand" "")
1930 (neg:DF (match_operand:DF 1 "register_operand" "")))]
1931 ""
1932 "
1933 {
1934 rtx target, result, insns;
1935
1936 start_sequence ();
1937 target = operand_subword (operands[0], 1, 1, DFmode);
1938 result = expand_binop (SImode, xor_optab,
1939 operand_subword_force (operands[1], 1, DFmode),
1940 GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
1941
1942 if (result == 0)
1943 abort ();
1944
1945 if (result != target)
1946 emit_move_insn (result, target);
1947
1948 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
1949 operand_subword_force (operands[1], 0, DFmode));
1950
1951 insns = get_insns ();
1952 end_sequence ();
1953
1954 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1955 DONE;
1956 }")
1957
1958 (define_expand "negsf2"
1959 [(set (match_operand:SF 0 "register_operand" "")
1960 (neg:SF (match_operand:SF 1 "register_operand" "")))]
1961 ""
1962 "
1963 {
1964 rtx result;
1965 rtx target;
1966
1967 target = operand_subword_force (operands[0], 0, SFmode);
1968 result = expand_binop (SImode, xor_optab,
1969 operand_subword_force (operands[1], 0, SFmode),
1970 GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
1971 if (result == 0)
1972 abort ();
1973
1974 if (result != target)
1975 emit_move_insn (result, target);
1976
1977 /* Make a place for REG_EQUAL. */
1978 emit_move_insn (operands[0], operands[0]);
1979 DONE;
1980 }")
1981
1982
1983 ;; ----------------------------------------------------------------------
1984 ;; PROLOGUE/EPILOGUE
1985 ;; ----------------------------------------------------------------------
1986 (define_expand "prologue"
1987 [(const_int 0)]
1988 ""
1989 "expand_prologue (); DONE;")
1990
1991 (define_expand "epilogue"
1992 [(return)]
1993 ""
1994 "
1995 {
1996 expand_epilogue ();
1997 DONE;
1998 }")
1999
2000 (define_insn "return_internal"
2001 [(const_int 2)
2002 (return)]
2003 ""
2004 "rets"
2005 [(set_attr "cc" "clobber")])
2006
2007 ;; This insn restores the callee saved registers and does a return, it
2008 ;; can also deallocate stack space.
2009 (define_insn "return_internal_regs"
2010 [(const_int 0)
2011 (match_operand:SI 0 "const_int_operand" "i")
2012 (return)]
2013 ""
2014 "*
2015 {
2016 fputs (\"\\tret \", asm_out_file);
2017 mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2018 fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2019 return \"\";
2020 }"
2021 [(set_attr "cc" "clobber")])
2022
2023 ;; This instruction matches one generated by mn10300_gen_multiple_store()
2024 (define_insn "store_movm"
2025 [(match_parallel 0 "store_multiple_operation"
2026 [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
2027 ""
2028 "*
2029 {
2030 fputs (\"\\tmovm \", asm_out_file);
2031 mn10300_print_reg_list (asm_out_file,
2032 store_multiple_operation (operands[0], VOIDmode));
2033 fprintf (asm_out_file, \",(sp)\\n\");
2034 return \"\";
2035 }"
2036 [(set_attr "cc" "clobber")])
2037
2038 (define_insn "return"
2039 [(return)]
2040 "can_use_return_insn ()"
2041 "*
2042 {
2043 rtx next = next_active_insn (insn);
2044
2045 if (next
2046 && GET_CODE (next) == JUMP_INSN
2047 && GET_CODE (PATTERN (next)) == RETURN)
2048 return \"\";
2049 else
2050 return \"rets\";
2051 }"
2052 [(set_attr "cc" "clobber")])
2053
2054 ;; Try to combine consecutive updates of the stack pointer (or any
2055 ;; other register for that matter).
2056 (define_peephole
2057 [(set (match_operand:SI 0 "register_operand" "=dxay")
2058 (plus:SI (match_dup 0)
2059 (match_operand 1 "const_int_operand" "")))
2060 (set (match_dup 0)
2061 (plus:SI (match_dup 0)
2062 (match_operand 2 "const_int_operand" "")))]
2063 ""
2064 "*
2065 {
2066 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2067 return \"add %1,%0\";
2068 }"
2069 [(set_attr "cc" "clobber")])
2070
2071 ;;
2072 ;; We had patterns to check eq/ne, but the they don't work because
2073 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2074 ;;
2075 ;; The Z flag and C flag would be set, and we have no way to
2076 ;; check for the Z flag set and C flag clear.
2077 ;;
2078 ;; This will work on the mn10200 because we can check the ZX flag
2079 ;; if the comparison is in HImode.
2080 (define_peephole
2081 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2082 (set (pc) (if_then_else (ge (cc0) (const_int 0))
2083 (match_operand 1 "" "")
2084 (pc)))]
2085 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2086 "add %0,%0\;bcc %1"
2087 [(set_attr "cc" "clobber")])
2088
2089 (define_peephole
2090 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2091 (set (pc) (if_then_else (lt (cc0) (const_int 0))
2092 (match_operand 1 "" "")
2093 (pc)))]
2094 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2095 "add %0,%0\;bcs %1"
2096 [(set_attr "cc" "clobber")])
2097
2098 (define_peephole
2099 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2100 (set (pc) (if_then_else (ge (cc0) (const_int 0))
2101 (pc)
2102 (match_operand 1 "" "")))]
2103 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2104 "add %0,%0\;bcs %1"
2105 [(set_attr "cc" "clobber")])
2106
2107 (define_peephole
2108 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2109 (set (pc) (if_then_else (lt (cc0) (const_int 0))
2110 (pc)
2111 (match_operand 1 "" "")))]
2112 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2113 "add %0,%0\;bcc %1"
2114 [(set_attr "cc" "clobber")])
2115