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