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