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