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