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