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