]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/mn10300/mn10300.md
mn10300.md (andsi3): Fix cut&pasto in 0xfffffffe constant.
[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")
1228 (cond
1229 [
1230 (eq (symbol_ref "which_alternative") (const_int 0)
1231 ) (const_string "none_0hit")
1232 (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1233 && (INTVAL (operands[2]) == 0x7fffffff
1234 || INTVAL (operands[2]) == 0x3fffffff
1235 || INTVAL (operands[2]) == 0x1fffffff
1236 || INTVAL (operands[2]) == 0x0fffffff
1237 || INTVAL (operands[2]) == 0xfffffffe
1238 || INTVAL (operands[2]) == 0xfffffffc
1239 || INTVAL (operands[2]) == 0xfffffff8
1240 || INTVAL (operands[2]) == 0xfffffff0)")
1241 (const_int 0)) (const_string "set_zn")
1242 ] (const_string "set_znv")))])
1243
1244 (define_insn ""
1245 [(set (match_operand:SI 0 "register_operand" "=dx,dx")
1246 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1247 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
1248 ""
1249 "*
1250 {
1251 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1252 return \"extbu %0\";
1253 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1254 return \"exthu %0\";
1255 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1256 return \"add %0,%0\;lsr 1,%0\";
1257 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1258 return \"asl2 %0\;lsr 2,%0\";
1259 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1260 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1261 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1262 return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1263 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1264 return \"lsr 1,%0\;add %0,%0\";
1265 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1266 return \"lsr 2,%0\;asl2 %0\";
1267 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1268 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1269 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1270 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1271 return \"and %2,%0\";
1272 }"
1273 [(set (attr "cc")
1274 (cond
1275 [
1276 (eq (symbol_ref "which_alternative") (const_int 0)
1277 ) (const_string "none_0hit")
1278 ;; Shifts don't set the V flag, but bitwise operations clear
1279 ;; it (which correctly reflects the absence of overflow in a
1280 ;; compare-with-zero that might follow). As for the
1281 ;; 0xfffffffe case, the add may overflow, so we can't use the
1282 ;; V flag.
1283 (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1284 && (INTVAL (operands[2]) == 0x7fffffff
1285 || INTVAL (operands[2]) == 0x3fffffff
1286 || INTVAL (operands[2]) == 0x1fffffff
1287 || INTVAL (operands[2]) == 0x0fffffff
1288 || INTVAL (operands[2]) == 0xfffffffe
1289 || INTVAL (operands[2]) == 0xfffffffc
1290 || INTVAL (operands[2]) == 0xfffffff8
1291 || INTVAL (operands[2]) == 0xfffffff0)")
1292 (const_int 0)) (const_string "set_zn")
1293 ] (const_string "set_znv")))])
1294
1295 ;; ----------------------------------------------------------------------
1296 ;; OR INSTRUCTIONS
1297 ;; ----------------------------------------------------------------------
1298
1299 (define_expand "iorsi3"
1300 [(set (match_operand:SI 0 "register_operand" "")
1301 (ior:SI (match_operand:SI 1 "register_operand" "")
1302 (match_operand:SI 2 "nonmemory_operand" "")))]
1303 ""
1304 "")
1305
1306 (define_insn ""
1307 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1308 (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1309 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1310 "TARGET_AM33"
1311 "*
1312 {
1313 if (REG_P (operands[2]) && REG_P (operands[1])
1314 && true_regnum (operands[0]) != true_regnum (operands[1])
1315 && true_regnum (operands[0]) != true_regnum (operands[2])
1316 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1317 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1318 && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1319 return \"mov %1,%0\;or %2,%0\";
1320 if (REG_P (operands[2]) && REG_P (operands[1])
1321 && true_regnum (operands[0]) != true_regnum (operands[1])
1322 && true_regnum (operands[0]) != true_regnum (operands[2]))
1323 return \"or %1,%2,%0\";
1324 if (REG_P (operands[2]) && REG_P (operands[0])
1325 && true_regnum (operands[2]) == true_regnum (operands[0]))
1326 return \"or %1,%0\";
1327 return \"or %2,%0\";
1328 }"
1329 [(set_attr "cc" "set_znv")])
1330
1331 (define_insn ""
1332 [(set (match_operand:SI 0 "register_operand" "=dx")
1333 (ior:SI (match_operand:SI 1 "register_operand" "%0")
1334 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1335 ""
1336 "or %2,%0"
1337 [(set_attr "cc" "set_znv")])
1338
1339 ;; ----------------------------------------------------------------------
1340 ;; XOR INSTRUCTIONS
1341 ;; ----------------------------------------------------------------------
1342
1343 (define_expand "xorsi3"
1344 [(set (match_operand:SI 0 "register_operand" "")
1345 (xor:SI (match_operand:SI 1 "register_operand" "")
1346 (match_operand:SI 2 "nonmemory_operand" "")))]
1347 ""
1348 "")
1349
1350 (define_insn ""
1351 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1352 (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1353 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1354 "TARGET_AM33"
1355 "*
1356 {
1357 if (REG_P (operands[2]) && REG_P (operands[1])
1358 && true_regnum (operands[0]) != true_regnum (operands[1])
1359 && true_regnum (operands[0]) != true_regnum (operands[2])
1360 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1361 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1362 && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1363 return \"mov %1,%0\;xor %2,%0\";
1364 if (REG_P (operands[2]) && REG_P (operands[1])
1365 && true_regnum (operands[0]) != true_regnum (operands[1])
1366 && true_regnum (operands[0]) != true_regnum (operands[2]))
1367 return \"xor %1,%2,%0\";
1368 if (REG_P (operands[2]) && REG_P (operands[0])
1369 && true_regnum (operands[2]) == true_regnum (operands[0]))
1370 return \"xor %1,%0\";
1371 return \"xor %2,%0\";
1372 }"
1373 [(set_attr "cc" "set_znv")])
1374
1375 (define_insn ""
1376 [(set (match_operand:SI 0 "register_operand" "=dx")
1377 (xor:SI (match_operand:SI 1 "register_operand" "%0")
1378 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1379 ""
1380 "xor %2,%0"
1381 [(set_attr "cc" "set_znv")])
1382
1383 ;; ----------------------------------------------------------------------
1384 ;; NOT INSTRUCTIONS
1385 ;; ----------------------------------------------------------------------
1386
1387 (define_expand "one_cmplsi2"
1388 [(set (match_operand:SI 0 "register_operand" "")
1389 (not:SI (match_operand:SI 1 "register_operand" "")))]
1390 ""
1391 "")
1392
1393 (define_insn ""
1394 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1395 (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1396 "TARGET_AM33"
1397 "not %0"
1398 [(set_attr "cc" "set_znv")])
1399
1400 (define_insn ""
1401 [(set (match_operand:SI 0 "register_operand" "=dx")
1402 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1403 ""
1404 "not %0"
1405 [(set_attr "cc" "set_znv")])
1406 \f
1407 ;; -----------------------------------------------------------------
1408 ;; BIT FIELDS
1409 ;; -----------------------------------------------------------------
1410
1411
1412 ;; These set/clear memory in byte sized chunks.
1413 ;;
1414 ;; They are no smaller/faster than loading the value into a register
1415 ;; and storing the register, but they don't need a scratch register
1416 ;; which may allow for better code generation.
1417 (define_insn ""
1418 [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
1419 ""
1420 "@
1421 bclr 255,%A0
1422 clr %0"
1423 [(set_attr "cc" "clobber")])
1424
1425 (define_insn ""
1426 [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
1427 ""
1428 "@
1429 bset 255,%A0
1430 mov -1,%0"
1431 [(set_attr "cc" "clobber,none_0hit")])
1432
1433 (define_insn ""
1434 [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1435 (subreg:QI
1436 (and:SI (subreg:SI (match_dup 0) 0)
1437 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1438 ""
1439 "@
1440 bclr %N1,%A0
1441 and %1,%0"
1442 [(set_attr "cc" "clobber,set_znv")])
1443
1444 (define_insn ""
1445 [(set (match_operand:QI 0 "memory_operand" "=R,T")
1446 (and:QI
1447 (match_dup 0)
1448 (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))]
1449 ""
1450 "@
1451 bclr %U1,%A0
1452 bclr %1,%0"
1453 [(set_attr "cc" "clobber,clobber")])
1454
1455 (define_insn ""
1456 [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1457 (subreg:QI
1458 (ior:SI (subreg:SI (match_dup 0) 0)
1459 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1460 ""
1461 "@
1462 bset %U1,%A0
1463 or %1,%0"
1464 [(set_attr "cc" "clobber,set_znv")])
1465
1466 (define_expand "iorqi3"
1467 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1468 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
1469 (match_operand:QI 2 "nonmemory_operand" "")))]
1470 ""
1471 "")
1472
1473 (define_insn ""
1474 [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,r")
1475 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1476 ;; This constraint should really be nonmemory_operand,
1477 ;; but making it general_operand, along with the
1478 ;; condition that not both input operands are MEMs, it
1479 ;; here helps combine do a better job.
1480 (match_operand:QI 2 "general_operand" "i,d,ir")))]
1481 "TARGET_AM33 &&
1482 (GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM)"
1483 "@
1484 bset %U2,%A0
1485 bset %2,%0
1486 or %2,%0"
1487 [(set_attr "cc" "clobber,clobber,set_znv")])
1488
1489 (define_insn ""
1490 [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
1491 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1492 ;; This constraint should really be nonmemory_operand,
1493 ;; but making it general_operand, along with the
1494 ;; condition that not both input operands are MEMs, it
1495 ;; here helps combine do a better job.
1496 (match_operand:QI 2 "general_operand" "i,d,id")))]
1497 "GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM"
1498 "@
1499 bset %U2,%A0
1500 bset %2,%0
1501 or %2,%0"
1502 [(set_attr "cc" "clobber,clobber,set_znv")])
1503
1504 (define_insn ""
1505 [(set (cc0)
1506 (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1507 (match_operand 1 "const_int_operand" "")
1508 (match_operand 2 "const_int_operand" "")))]
1509 ""
1510 "*
1511 {
1512 int len = INTVAL (operands[1]);
1513 int bit = INTVAL (operands[2]);
1514 int mask = 0;
1515 rtx xoperands[2];
1516
1517 while (len > 0)
1518 {
1519 mask |= (1 << bit);
1520 bit++;
1521 len--;
1522 }
1523
1524 xoperands[0] = operands[0];
1525 xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1526 output_asm_insn (\"btst %1,%0\", xoperands);
1527 return \"\";
1528 }"
1529 [(set_attr "cc" "clobber")])
1530
1531 (define_insn ""
1532 [(set (cc0)
1533 (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
1534 (match_operand 1 "const_int_operand" "")
1535 (match_operand 2 "const_int_operand" "")))]
1536 "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1537 "*
1538 {
1539 int len = INTVAL (operands[1]);
1540 int bit = INTVAL (operands[2]);
1541 int mask = 0;
1542 rtx xoperands[2];
1543
1544 while (len > 0)
1545 {
1546 mask |= (1 << bit);
1547 bit++;
1548 len--;
1549 }
1550
1551 /* If the source operand is not a reg (ie it is memory), then extract the
1552 bits from mask that we actually want to test. Note that the mask will
1553 never cross a byte boundary. */
1554 if (!REG_P (operands[0]))
1555 {
1556 if (mask & 0xff)
1557 mask = mask & 0xff;
1558 else if (mask & 0xff00)
1559 mask = (mask >> 8) & 0xff;
1560 else if (mask & 0xff0000)
1561 mask = (mask >> 16) & 0xff;
1562 else if (mask & 0xff000000)
1563 mask = (mask >> 24) & 0xff;
1564 }
1565
1566 xoperands[0] = operands[0];
1567 xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1568 if (GET_CODE (operands[0]) == REG)
1569 output_asm_insn (\"btst %1,%0\", xoperands);
1570 else
1571 output_asm_insn (\"btst %U1,%A0\", xoperands);
1572 return \"\";
1573 }"
1574 [(set_attr "cc" "clobber")])
1575
1576 (define_insn ""
1577 [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1578 (match_operand:SI 1 "const_int_operand" "")))]
1579 ""
1580 "btst %1,%0"
1581 [(set_attr "cc" "clobber")])
1582
1583 (define_insn ""
1584 [(set (cc0)
1585 (and:SI
1586 (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1587 (match_operand:SI 1 "const_8bit_operand" "")))]
1588 ""
1589 "@
1590 btst %U1,%A0
1591 btst %1,%0"
1592 [(set_attr "cc" "clobber")])
1593
1594 \f
1595 ;; ----------------------------------------------------------------------
1596 ;; JUMP INSTRUCTIONS
1597 ;; ----------------------------------------------------------------------
1598
1599 ;; Conditional jump instructions
1600
1601 (define_expand "ble"
1602 [(set (pc)
1603 (if_then_else (le (cc0)
1604 (const_int 0))
1605 (label_ref (match_operand 0 "" ""))
1606 (pc)))]
1607 ""
1608 "")
1609
1610 (define_expand "bleu"
1611 [(set (pc)
1612 (if_then_else (leu (cc0)
1613 (const_int 0))
1614 (label_ref (match_operand 0 "" ""))
1615 (pc)))]
1616 ""
1617 "")
1618
1619 (define_expand "bge"
1620 [(set (pc)
1621 (if_then_else (ge (cc0)
1622 (const_int 0))
1623 (label_ref (match_operand 0 "" ""))
1624 (pc)))]
1625 ""
1626 "")
1627
1628 (define_expand "bgeu"
1629 [(set (pc)
1630 (if_then_else (geu (cc0)
1631 (const_int 0))
1632 (label_ref (match_operand 0 "" ""))
1633 (pc)))]
1634 ""
1635 "")
1636
1637 (define_expand "blt"
1638 [(set (pc)
1639 (if_then_else (lt (cc0)
1640 (const_int 0))
1641 (label_ref (match_operand 0 "" ""))
1642 (pc)))]
1643 ""
1644 "")
1645
1646 (define_expand "bltu"
1647 [(set (pc)
1648 (if_then_else (ltu (cc0)
1649 (const_int 0))
1650 (label_ref (match_operand 0 "" ""))
1651 (pc)))]
1652 ""
1653 "")
1654
1655 (define_expand "bgt"
1656 [(set (pc)
1657 (if_then_else (gt (cc0)
1658 (const_int 0))
1659 (label_ref (match_operand 0 "" ""))
1660 (pc)))]
1661 ""
1662 "")
1663
1664 (define_expand "bgtu"
1665 [(set (pc)
1666 (if_then_else (gtu (cc0)
1667 (const_int 0))
1668 (label_ref (match_operand 0 "" ""))
1669 (pc)))]
1670 ""
1671 "")
1672
1673 (define_expand "beq"
1674 [(set (pc)
1675 (if_then_else (eq (cc0)
1676 (const_int 0))
1677 (label_ref (match_operand 0 "" ""))
1678 (pc)))]
1679 ""
1680 "")
1681
1682 (define_expand "bne"
1683 [(set (pc)
1684 (if_then_else (ne (cc0)
1685 (const_int 0))
1686 (label_ref (match_operand 0 "" ""))
1687 (pc)))]
1688 ""
1689 "")
1690
1691 (define_insn ""
1692 [(set (pc)
1693 (if_then_else (match_operator 1 "comparison_operator"
1694 [(cc0) (const_int 0)])
1695 (label_ref (match_operand 0 "" ""))
1696 (pc)))]
1697 ""
1698 "*
1699 {
1700 if (cc_status.mdep.fpCC)
1701 return \"fb%b1 %0\";
1702 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1703 && (GET_CODE (operands[1]) == GT
1704 || GET_CODE (operands[1]) == GE
1705 || GET_CODE (operands[1]) == LE
1706 || GET_CODE (operands[1]) == LT))
1707 return 0;
1708 return \"b%b1 %0\";
1709 }"
1710 [(set_attr "cc" "none")])
1711
1712 (define_insn ""
1713 [(set (pc)
1714 (if_then_else (match_operator 1 "comparison_operator"
1715 [(cc0) (const_int 0)])
1716 (pc)
1717 (label_ref (match_operand 0 "" ""))))]
1718 ""
1719 "*
1720 {
1721 if (cc_status.mdep.fpCC)
1722 return \"fb%B1 %0\";
1723 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1724 && (GET_CODE (operands[1]) == GT
1725 || GET_CODE (operands[1]) == GE
1726 || GET_CODE (operands[1]) == LE
1727 || GET_CODE (operands[1]) == LT))
1728 return 0;
1729 return \"b%B1 %0\";
1730 }"
1731 [(set_attr "cc" "none")])
1732
1733 ;; Unconditional and other jump instructions.
1734
1735 (define_insn "jump"
1736 [(set (pc)
1737 (label_ref (match_operand 0 "" "")))]
1738 ""
1739 "jmp %l0"
1740 [(set_attr "cc" "none")])
1741
1742 (define_insn "indirect_jump"
1743 [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1744 ""
1745 "jmp (%0)"
1746 [(set_attr "cc" "none")])
1747
1748 (define_expand "builtin_setjmp_receiver"
1749 [(match_operand 0 "" "")]
1750 "flag_pic"
1751 "
1752 {
1753 if (flag_pic)
1754 emit_insn (gen_GOTaddr2picreg ());
1755
1756 DONE;
1757 }")
1758
1759 (define_expand "casesi"
1760 [(match_operand:SI 0 "register_operand" "")
1761 (match_operand:SI 1 "immediate_operand" "")
1762 (match_operand:SI 2 "immediate_operand" "")
1763 (match_operand 3 "" "") (match_operand 4 "" "")]
1764 ""
1765 "
1766 {
1767 rtx table = gen_reg_rtx (SImode);
1768 rtx index = gen_reg_rtx (SImode);
1769 rtx addr = gen_reg_rtx (Pmode);
1770
1771 emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
1772 emit_move_insn (index, plus_constant (operands[0], - INTVAL (operands[1])));
1773 emit_insn (gen_cmpsi (index, operands[2]));
1774 emit_jump_insn (gen_bgtu (operands[4]));
1775 emit_move_insn (index, gen_rtx_ASHIFT (SImode, index, GEN_INT (2)));
1776 emit_move_insn (addr, gen_rtx_MEM (SImode,
1777 gen_rtx_PLUS (SImode, table, index)));
1778 if (flag_pic)
1779 emit_move_insn (addr, gen_rtx_PLUS (SImode, addr, table));
1780
1781 emit_jump_insn (gen_tablejump (addr, operands[3]));
1782 DONE;
1783 }")
1784
1785 (define_insn "tablejump"
1786 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1787 (use (label_ref (match_operand 1 "" "")))]
1788 ""
1789 "jmp (%0)"
1790 [(set_attr "cc" "none")])
1791
1792 ;; Call subroutine with no return value.
1793
1794 (define_expand "call"
1795 [(call (match_operand:QI 0 "general_operand" "")
1796 (match_operand:SI 1 "general_operand" ""))]
1797 ""
1798 "
1799 {
1800 if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
1801 {
1802 if (MN10300_GLOBAL_P (XEXP (operands[0], 0)))
1803 {
1804 /* The PLT code won't run on AM30, but then, there's no
1805 shared library support for AM30 either, so we just assume
1806 the linker is going to adjust all @PLT relocs to the
1807 actual symbols. */
1808 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1809 XEXP (operands[0], 0) = gen_sym2PLT (XEXP (operands[0], 0));
1810 }
1811 else
1812 XEXP (operands[0], 0) = gen_sym2PIC (XEXP (operands[0], 0));
1813 }
1814 if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
1815 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1816 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1817 DONE;
1818 }")
1819
1820 (define_insn "call_internal"
1821 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1822 (match_operand:SI 1 "general_operand" "g"))]
1823 ""
1824 "*
1825 {
1826 if (REG_P (operands[0]))
1827 return \"calls %C0\";
1828 else
1829 return \"call %C0,[],0\";
1830 }"
1831 [(set_attr "cc" "clobber")])
1832
1833 ;; Call subroutine, returning value in operand 0
1834 ;; (which must be a hard register).
1835
1836 (define_expand "call_value"
1837 [(set (match_operand 0 "" "")
1838 (call (match_operand:QI 1 "general_operand" "")
1839 (match_operand:SI 2 "general_operand" "")))]
1840 ""
1841 "
1842 {
1843 if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
1844 {
1845 if (MN10300_GLOBAL_P (XEXP (operands[1], 0)))
1846 {
1847 /* The PLT code won't run on AM30, but then, there's no
1848 shared library support for AM30 either, so we just assume
1849 the linker is going to adjust all @PLT relocs to the
1850 actual symbols. */
1851 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1852 XEXP (operands[1], 0) = gen_sym2PLT (XEXP (operands[1], 0));
1853 }
1854 else
1855 XEXP (operands[1], 0) = gen_sym2PIC (XEXP (operands[1], 0));
1856 }
1857 if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1858 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1859 emit_call_insn (gen_call_value_internal (operands[0],
1860 XEXP (operands[1], 0),
1861 operands[2]));
1862 DONE;
1863 }")
1864
1865 (define_insn "call_value_internal"
1866 [(set (match_operand 0 "" "=dax")
1867 (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1868 (match_operand:SI 2 "general_operand" "g")))]
1869 ""
1870 "*
1871 {
1872 if (REG_P (operands[1]))
1873 return \"calls %C1\";
1874 else
1875 return \"call %C1,[],0\";
1876 }"
1877 [(set_attr "cc" "clobber")])
1878
1879 (define_expand "untyped_call"
1880 [(parallel [(call (match_operand 0 "" "")
1881 (const_int 0))
1882 (match_operand 1 "" "")
1883 (match_operand 2 "" "")])]
1884 ""
1885 "
1886 {
1887 int i;
1888
1889 emit_call_insn (gen_call (operands[0], const0_rtx));
1890
1891 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1892 {
1893 rtx set = XVECEXP (operands[2], 0, i);
1894 emit_move_insn (SET_DEST (set), SET_SRC (set));
1895 }
1896 DONE;
1897 }")
1898
1899 (define_insn "nop"
1900 [(const_int 0)]
1901 ""
1902 "nop"
1903 [(set_attr "cc" "none")])
1904 \f
1905 ;; ----------------------------------------------------------------------
1906 ;; EXTEND INSTRUCTIONS
1907 ;; ----------------------------------------------------------------------
1908
1909 (define_expand "zero_extendqisi2"
1910 [(set (match_operand:SI 0 "general_operand" "")
1911 (zero_extend:SI
1912 (match_operand:QI 1 "general_operand" "")))]
1913 ""
1914 "")
1915
1916 (define_insn ""
1917 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1918 (zero_extend:SI
1919 (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1920 "TARGET_AM33"
1921 "@
1922 extbu %0
1923 mov %1,%0\;extbu %0
1924 movbu %1,%0
1925 extbu %0
1926 mov %1,%0\;extbu %0
1927 movbu %1,%0"
1928 [(set_attr "cc" "none_0hit")])
1929
1930 (define_insn ""
1931 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1932 (zero_extend:SI
1933 (match_operand:QI 1 "general_operand" "0,d,m")))]
1934 ""
1935 "@
1936 extbu %0
1937 mov %1,%0\;extbu %0
1938 movbu %1,%0"
1939 [(set_attr "cc" "none_0hit")])
1940
1941 (define_expand "zero_extendhisi2"
1942 [(set (match_operand:SI 0 "general_operand" "")
1943 (zero_extend:SI
1944 (match_operand:HI 1 "general_operand" "")))]
1945 ""
1946 "")
1947
1948 (define_insn ""
1949 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1950 (zero_extend:SI
1951 (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1952 "TARGET_AM33"
1953 "@
1954 exthu %0
1955 mov %1,%0\;exthu %0
1956 movhu %1,%0
1957 exthu %0
1958 mov %1,%0\;exthu %0
1959 movhu %1,%0"
1960 [(set_attr "cc" "none_0hit")])
1961
1962 (define_insn ""
1963 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1964 (zero_extend:SI
1965 (match_operand:HI 1 "general_operand" "0,dx,m")))]
1966 ""
1967 "@
1968 exthu %0
1969 mov %1,%0\;exthu %0
1970 movhu %1,%0"
1971 [(set_attr "cc" "none_0hit")])
1972
1973 ;;- sign extension instructions
1974
1975 (define_expand "extendqisi2"
1976 [(set (match_operand:SI 0 "general_operand" "")
1977 (sign_extend:SI
1978 (match_operand:QI 1 "general_operand" "")))]
1979 ""
1980 "")
1981
1982 (define_insn ""
1983 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1984 (sign_extend:SI
1985 (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1986 "TARGET_AM33"
1987 "@
1988 extb %0
1989 mov %1,%0\;extb %0
1990 extb %0
1991 mov %1,%0\;extb %0"
1992 [(set_attr "cc" "none_0hit")])
1993
1994 (define_insn ""
1995 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1996 (sign_extend:SI
1997 (match_operand:QI 1 "general_operand" "0,dx")))]
1998 ""
1999 "@
2000 extb %0
2001 mov %1,%0\;extb %0"
2002 [(set_attr "cc" "none_0hit")])
2003
2004 (define_expand "extendhisi2"
2005 [(set (match_operand:SI 0 "general_operand" "")
2006 (sign_extend:SI
2007 (match_operand:HI 1 "general_operand" "")))]
2008 ""
2009 "")
2010
2011 (define_insn ""
2012 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
2013 (sign_extend:SI
2014 (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
2015 "TARGET_AM33"
2016 "@
2017 exth %0
2018 mov %1,%0\;exth %0
2019 exth %0
2020 mov %1,%0\;exth %0"
2021 [(set_attr "cc" "none_0hit")])
2022
2023 (define_insn ""
2024 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
2025 (sign_extend:SI
2026 (match_operand:HI 1 "general_operand" "0,dx")))]
2027 ""
2028 "@
2029 exth %0
2030 mov %1,%0\;exth %0"
2031 [(set_attr "cc" "none_0hit")])
2032 \f
2033 ;; ----------------------------------------------------------------------
2034 ;; SHIFTS
2035 ;; ----------------------------------------------------------------------
2036
2037 (define_expand "ashlsi3"
2038 [(set (match_operand:SI 0 "register_operand" "")
2039 (ashift:SI
2040 (match_operand:SI 1 "register_operand" "")
2041 (match_operand:QI 2 "nonmemory_operand" "")))]
2042 ""
2043 "")
2044
2045 (define_insn ""
2046 [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
2047 (ashift:SI
2048 (match_operand:SI 1 "register_operand" "0,0,dax")
2049 (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
2050 "TARGET_AM33"
2051 "*
2052 {
2053 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
2054 return \"add %0,%0\";
2055
2056 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
2057 return \"asl2 %0\";
2058
2059 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
2060 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2061 return \"asl2 %0\;add %0,%0\";
2062
2063 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
2064 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2065 return \"asl2 %0\;asl2 %0\";
2066
2067 if (true_regnum (operands[1]) == true_regnum (operands[0]))
2068 return \"asl %S2,%0\";
2069
2070 if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2071 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2072 && true_regnum (operands[0]) != true_regnum (operands[2]))
2073 return \"mov %1,%0\;asl %S2,%0\";
2074 return \"asl %2,%1,%0\";
2075 }"
2076 [(set_attr "cc" "set_zn")])
2077
2078 (define_insn ""
2079 [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
2080 (ashift:SI
2081 (match_operand:SI 1 "register_operand" "0,0,0,0,0")
2082 (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
2083 ""
2084 "@
2085 add %0,%0
2086 asl2 %0
2087 asl2 %0\;add %0,%0
2088 asl2 %0\;asl2 %0
2089 asl %S2,%0"
2090 [(set_attr "cc" "set_zn")])
2091
2092 (define_expand "lshrsi3"
2093 [(set (match_operand:SI 0 "register_operand" "")
2094 (lshiftrt:SI
2095 (match_operand:SI 1 "register_operand" "")
2096 (match_operand:QI 2 "nonmemory_operand" "")))]
2097 ""
2098 "")
2099
2100 (define_insn ""
2101 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2102 (lshiftrt:SI
2103 (match_operand:SI 1 "register_operand" "0,dax")
2104 (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2105 "TARGET_AM33"
2106 "*
2107 {
2108 if (true_regnum (operands[1]) == true_regnum (operands[0]))
2109 return \"lsr %S2,%0\";
2110
2111 if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2112 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2113 && true_regnum (operands[0]) != true_regnum (operands[2]))
2114 return \"mov %1,%0\;lsr %S2,%0\";
2115 return \"lsr %2,%1,%0\";
2116 }"
2117 [(set_attr "cc" "set_zn")])
2118
2119 (define_insn ""
2120 [(set (match_operand:SI 0 "register_operand" "=dx")
2121 (lshiftrt:SI
2122 (match_operand:SI 1 "register_operand" "0")
2123 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2124 ""
2125 "lsr %S2,%0"
2126 [(set_attr "cc" "set_zn")])
2127
2128 (define_expand "ashrsi3"
2129 [(set (match_operand:SI 0 "register_operand" "")
2130 (ashiftrt:SI
2131 (match_operand:SI 1 "register_operand" "")
2132 (match_operand:QI 2 "nonmemory_operand" "")))]
2133 ""
2134 "")
2135
2136 (define_insn ""
2137 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2138 (ashiftrt:SI
2139 (match_operand:SI 1 "register_operand" "0,dax")
2140 (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2141 "TARGET_AM33"
2142 "*
2143 {
2144 if (true_regnum (operands[1]) == true_regnum (operands[0]))
2145 return \"asr %S2,%0\";
2146
2147 if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2148 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2149 && true_regnum (operands[0]) != true_regnum (operands[2]))
2150 return \"mov %1,%0\;asr %S2,%0\";
2151 return \"asr %2,%1,%0\";
2152 }"
2153 [(set_attr "cc" "set_zn")])
2154
2155 (define_insn ""
2156 [(set (match_operand:SI 0 "register_operand" "=dx")
2157 (ashiftrt:SI
2158 (match_operand:SI 1 "register_operand" "0")
2159 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2160 ""
2161 "asr %S2,%0"
2162 [(set_attr "cc" "set_zn")])
2163
2164 ;; ----------------------------------------------------------------------
2165 ;; FP INSTRUCTIONS
2166 ;; ----------------------------------------------------------------------
2167 ;;
2168 ;; The mn103 series does not have floating point instructions, but since
2169 ;; FP values are held in integer regs, we can clear the high bit easily
2170 ;; which gives us an efficient inline floating point absolute value.
2171 ;;
2172 ;; Similarly for negation of a FP value.
2173 ;;
2174
2175 (define_expand "absdf2"
2176 [(set (match_operand:DF 0 "register_operand" "")
2177 (abs:DF (match_operand:DF 1 "register_operand" "")))]
2178 ""
2179 "
2180 {
2181 rtx target, result, insns;
2182
2183 start_sequence ();
2184 target = operand_subword (operands[0], 1, 1, DFmode);
2185 result = expand_binop (SImode, and_optab,
2186 operand_subword_force (operands[1], 1, DFmode),
2187 GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2188
2189 if (result == 0)
2190 abort ();
2191
2192 if (result != target)
2193 emit_move_insn (result, target);
2194
2195 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2196 operand_subword_force (operands[1], 0, DFmode));
2197
2198 insns = get_insns ();
2199 end_sequence ();
2200
2201 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2202 DONE;
2203 }")
2204
2205 (define_expand "abssf2"
2206 [(set (match_operand:SF 0 "register_operand" "")
2207 (abs:SF (match_operand:SF 1 "register_operand" "")))]
2208 ""
2209 "
2210 {
2211 rtx result;
2212 rtx target;
2213
2214 if (TARGET_AM33_2)
2215 {
2216 emit_insn (gen_abssf2_am33_2 (operands[0], operands[1]));
2217 DONE;
2218 }
2219
2220 target = operand_subword_force (operands[0], 0, SFmode);
2221 result = expand_binop (SImode, and_optab,
2222 operand_subword_force (operands[1], 0, SFmode),
2223 GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2224 if (result == 0)
2225 abort ();
2226
2227 if (result != target)
2228 emit_move_insn (result, target);
2229
2230 /* Make a place for REG_EQUAL. */
2231 emit_move_insn (operands[0], operands[0]);
2232 DONE;
2233 }")
2234
2235
2236 (define_insn "abssf2_am33_2"
2237 [(set (match_operand:SF 0 "register_operand" "=f,f")
2238 (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2239 "TARGET_AM33_2"
2240 "@
2241 fabs %0
2242 fabs %1, %0"
2243 [(set_attr "cc" "none_0hit")])
2244
2245 (define_expand "negdf2"
2246 [(set (match_operand:DF 0 "register_operand" "")
2247 (neg:DF (match_operand:DF 1 "register_operand" "")))]
2248 ""
2249 "
2250 {
2251 rtx target, result, insns;
2252
2253 start_sequence ();
2254 target = operand_subword (operands[0], 1, 1, DFmode);
2255 result = expand_binop (SImode, xor_optab,
2256 operand_subword_force (operands[1], 1, DFmode),
2257 GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2258 target, 0, OPTAB_WIDEN);
2259
2260 if (result == 0)
2261 abort ();
2262
2263 if (result != target)
2264 emit_move_insn (result, target);
2265
2266 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2267 operand_subword_force (operands[1], 0, DFmode));
2268
2269 insns = get_insns ();
2270 end_sequence ();
2271
2272 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2273 DONE;
2274 }")
2275
2276 (define_expand "negsf2"
2277 [(set (match_operand:SF 0 "register_operand" "")
2278 (neg:SF (match_operand:SF 1 "register_operand" "")))]
2279 ""
2280 "
2281 {
2282 rtx result;
2283 rtx target;
2284
2285 if (TARGET_AM33_2)
2286 {
2287 emit_insn (gen_negsf2_am33_2 (operands[0], operands[1]));
2288 DONE;
2289 }
2290
2291 target = operand_subword_force (operands[0], 0, SFmode);
2292 result = expand_binop (SImode, xor_optab,
2293 operand_subword_force (operands[1], 0, SFmode),
2294 GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2295 target, 0, OPTAB_WIDEN);
2296 if (result == 0)
2297 abort ();
2298
2299 if (result != target)
2300 emit_move_insn (result, target);
2301
2302 /* Make a place for REG_EQUAL. */
2303 emit_move_insn (operands[0], operands[0]);
2304 DONE;
2305 }")
2306
2307 (define_insn "negsf2_am33_2"
2308 [(set (match_operand:SF 0 "register_operand" "=f,f")
2309 (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2310 "TARGET_AM33_2"
2311 "@
2312 fneg %0
2313 fneg %1, %0"
2314 [(set_attr "cc" "none_0hit")])
2315
2316 (define_expand "sqrtsf2"
2317 [(set (match_operand:SF 0 "register_operand" "")
2318 (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
2319 "TARGET_AM33_2 && flag_unsafe_math_optimizations"
2320 "
2321 {
2322 rtx scratch = gen_reg_rtx (SFmode);
2323 emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
2324 emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
2325 scratch));
2326 DONE;
2327 }")
2328
2329 (define_insn "rsqrtsf2"
2330 [(set (match_operand:SF 0 "register_operand" "=f,f")
2331 (div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
2332 (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
2333 "TARGET_AM33_2"
2334 "@
2335 frsqrt %0
2336 frsqrt %1, %0"
2337 [(set_attr "cc" "none_0hit")])
2338
2339 (define_insn "addsf3"
2340 [(set (match_operand:SF 0 "register_operand" "=f,f")
2341 (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
2342 (match_operand:SF 2 "general_operand" "f,?fF")))]
2343 "TARGET_AM33_2"
2344 "@
2345 fadd %2, %0
2346 fadd %2, %1, %0"
2347 [(set_attr "cc" "none_0hit")])
2348
2349 (define_insn "subsf3"
2350 [(set (match_operand:SF 0 "register_operand" "=f,f")
2351 (minus:SF (match_operand:SF 1 "register_operand" "0,f")
2352 (match_operand:SF 2 "general_operand" "f,?fF")))]
2353 "TARGET_AM33_2"
2354 "@
2355 fsub %2, %0
2356 fsub %2, %1, %0"
2357 [(set_attr "cc" "none_0hit")])
2358
2359 (define_insn "mulsf3"
2360 [(set (match_operand:SF 0 "register_operand" "=f,f")
2361 (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
2362 (match_operand:SF 2 "general_operand" "f,?fF")))]
2363 "TARGET_AM33_2"
2364 "@
2365 fmul %2, %0
2366 fmul %2, %1, %0"
2367 [(set_attr "cc" "none_0hit")])
2368
2369 (define_insn "divsf3"
2370 [(set (match_operand:SF 0 "register_operand" "=f,f")
2371 (div:SF (match_operand:SF 1 "register_operand" "0,f")
2372 (match_operand:SF 2 "general_operand" "f,?fF")))]
2373 "TARGET_AM33_2"
2374 "@
2375 fdiv %2, %0
2376 fdiv %2, %1, %0"
2377 [(set_attr "cc" "none_0hit")])
2378
2379 (define_insn "fmaddsf4"
2380 [(set (match_operand:SF 0 "register_operand" "=A")
2381 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2382 (match_operand:SF 2 "register_operand" "f"))
2383 (match_operand:SF 3 "register_operand" "f")))]
2384 "TARGET_AM33_2"
2385 "fmadd %1, %2, %3, %0"
2386 [(set_attr "cc" "none_0hit")])
2387
2388 (define_insn "fmsubsf4"
2389 [(set (match_operand:SF 0 "register_operand" "=A")
2390 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2391 (match_operand:SF 2 "register_operand" "f"))
2392 (match_operand:SF 3 "register_operand" "f")))]
2393 "TARGET_AM33_2"
2394 "fmsub %1, %2, %3, %0"
2395 [(set_attr "cc" "none_0hit")])
2396
2397 (define_insn "fnmaddsf4"
2398 [(set (match_operand:SF 0 "register_operand" "=A")
2399 (minus:SF (match_operand:SF 3 "register_operand" "f")
2400 (mult:SF (match_operand:SF 1 "register_operand" "%f")
2401 (match_operand:SF 2 "register_operand" "f"))))]
2402 "TARGET_AM33_2"
2403 "fnmadd %1, %2, %3, %0"
2404 [(set_attr "cc" "none_0hit")])
2405
2406 (define_insn "fnmsubsf4"
2407 [(set (match_operand:SF 0 "register_operand" "=A")
2408 (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2409 (match_operand:SF 2 "register_operand" "f")))
2410 (match_operand:SF 3 "register_operand" "f")))]
2411 "TARGET_AM33_2"
2412 "fnmsub %1, %2, %3, %0"
2413 [(set_attr "cc" "none_0hit")])
2414
2415
2416 ;; ----------------------------------------------------------------------
2417 ;; PROLOGUE/EPILOGUE
2418 ;; ----------------------------------------------------------------------
2419 (define_expand "prologue"
2420 [(const_int 0)]
2421 ""
2422 "expand_prologue (); DONE;")
2423
2424 (define_expand "epilogue"
2425 [(return)]
2426 ""
2427 "
2428 {
2429 expand_epilogue ();
2430 DONE;
2431 }")
2432
2433 (define_insn "return_internal"
2434 [(const_int 2)
2435 (return)]
2436 ""
2437 "rets"
2438 [(set_attr "cc" "clobber")])
2439
2440 ;; This insn restores the callee saved registers and does a return, it
2441 ;; can also deallocate stack space.
2442 (define_insn "return_internal_regs"
2443 [(const_int 0)
2444 (match_operand:SI 0 "const_int_operand" "i")
2445 (return)]
2446 ""
2447 "*
2448 {
2449 fputs (\"\\tret \", asm_out_file);
2450 mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2451 fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2452 return \"\";
2453 }"
2454 [(set_attr "cc" "clobber")])
2455
2456 ;; This instruction matches one generated by mn10300_gen_multiple_store()
2457 (define_insn "store_movm"
2458 [(match_parallel 0 "store_multiple_operation"
2459 [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
2460 ""
2461 "*
2462 {
2463 fputs (\"\\tmovm \", asm_out_file);
2464 mn10300_print_reg_list (asm_out_file,
2465 store_multiple_operation (operands[0], VOIDmode));
2466 fprintf (asm_out_file, \",(sp)\\n\");
2467 return \"\";
2468 }"
2469 [(set_attr "cc" "clobber")])
2470
2471 (define_insn "return"
2472 [(return)]
2473 "can_use_return_insn ()"
2474 "*
2475 {
2476 rtx next = next_active_insn (insn);
2477
2478 if (next
2479 && GET_CODE (next) == JUMP_INSN
2480 && GET_CODE (PATTERN (next)) == RETURN)
2481 return \"\";
2482 else
2483 return \"rets\";
2484 }"
2485 [(set_attr "cc" "clobber")])
2486
2487 ;; Try to combine consecutive updates of the stack pointer (or any
2488 ;; other register for that matter).
2489 (define_peephole
2490 [(set (match_operand:SI 0 "register_operand" "=dxay")
2491 (plus:SI (match_dup 0)
2492 (match_operand 1 "const_int_operand" "")))
2493 (set (match_dup 0)
2494 (plus:SI (match_dup 0)
2495 (match_operand 2 "const_int_operand" "")))]
2496 ""
2497 "*
2498 {
2499 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2500 return \"add %1,%0\";
2501 }"
2502 [(set_attr "cc" "clobber")])
2503
2504 ;;
2505 ;; We had patterns to check eq/ne, but the they don't work because
2506 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2507 ;;
2508 ;; The Z flag and C flag would be set, and we have no way to
2509 ;; check for the Z flag set and C flag clear.
2510 ;;
2511 ;; This will work on the mn10200 because we can check the ZX flag
2512 ;; if the comparison is in HImode.
2513 (define_peephole
2514 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2515 (set (pc) (if_then_else (ge (cc0) (const_int 0))
2516 (match_operand 1 "" "")
2517 (pc)))]
2518 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2519 "add %0,%0\;bcc %1"
2520 [(set_attr "cc" "clobber")])
2521
2522 (define_peephole
2523 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2524 (set (pc) (if_then_else (lt (cc0) (const_int 0))
2525 (match_operand 1 "" "")
2526 (pc)))]
2527 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2528 "add %0,%0\;bcs %1"
2529 [(set_attr "cc" "clobber")])
2530
2531 (define_peephole
2532 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2533 (set (pc) (if_then_else (ge (cc0) (const_int 0))
2534 (pc)
2535 (match_operand 1 "" "")))]
2536 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2537 "add %0,%0\;bcs %1"
2538 [(set_attr "cc" "clobber")])
2539
2540 (define_peephole
2541 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2542 (set (pc) (if_then_else (lt (cc0) (const_int 0))
2543 (pc)
2544 (match_operand 1 "" "")))]
2545 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2546 "add %0,%0\;bcc %1"
2547 [(set_attr "cc" "clobber")])
2548
2549 (define_expand "int_label"
2550 [(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
2551 "" "")
2552
2553 (define_expand "GOTaddr2picreg"
2554 [(match_dup 0)]
2555 "" "
2556 {
2557 /* It would be nice to be able to have int_label keep track of the
2558 counter and all, but if we add C code to it, we'll get an insn
2559 back, and we just want the pattern. */
2560 operands[0] = gen_int_label (GEN_INT (mn10300_unspec_int_label_counter++));
2561 if (TARGET_AM33)
2562 emit_insn (gen_am33_loadPC (operands[0]));
2563 else
2564 emit_insn (gen_mn10300_loadPC (operands[0]));
2565 emit_insn (gen_add_GOT_to_pic_reg (operands[0]));
2566 DONE;
2567 }
2568 ")
2569
2570 (define_insn "am33_loadPC"
2571 [(parallel
2572 [(set (reg:SI PIC_REG) (pc))
2573 (use (match_operand 0 "" ""))])]
2574 "TARGET_AM33"
2575 "%0:\;mov pc,a2")
2576
2577
2578 (define_insn_and_split "mn10300_loadPC"
2579 [(parallel
2580 [(set (reg:SI PIC_REG) (pc))
2581 (use (match_operand 0 "" ""))])]
2582 ""
2583 "#"
2584 "reload_completed"
2585 [(match_operand 0 "" "")]
2586 "
2587 {
2588 rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
2589 int need_stack_space = (get_frame_size () == 0
2590 && current_function_outgoing_args_size == 0);
2591
2592 if (need_stack_space)
2593 emit_move_insn (sp_reg, plus_constant (sp_reg, -4));
2594
2595 emit_insn (gen_call_next_insn (operands[0]));
2596
2597 if (need_stack_space)
2598 emit_insn (gen_pop_pic_reg ());
2599 else
2600 emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
2601
2602 DONE;
2603 }")
2604
2605 (define_insn "call_next_insn"
2606 [(parallel
2607 [(set (mem:SI (reg:SI SP_REG)) (pc))
2608 (use (match_operand 0 "" ""))])]
2609 "reload_completed"
2610 "calls %0\;%0:")
2611
2612 (define_expand "add_GOT_to_pic_reg"
2613 [(set (reg:SI PIC_REG)
2614 (plus:SI
2615 (reg:SI PIC_REG)
2616 (const
2617 (unspec [(minus:SI
2618 (match_dup 1)
2619 (const (minus:SI
2620 (const (match_operand:SI 0 "" ""))
2621 (pc))))
2622 ] UNSPEC_PIC))))]
2623 ""
2624 "
2625 {
2626 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2627 }")
2628
2629 (define_expand "symGOT2reg"
2630 [(match_operand:SI 0 "" "")
2631 (match_operand:SI 1 "" "")]
2632 ""
2633 "
2634 {
2635 rtx insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1]));
2636
2637 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
2638
2639 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
2640 REG_NOTES (insn));
2641
2642 DONE;
2643 }")
2644
2645 (define_expand "symGOT2reg_i"
2646 [(set (match_operand:SI 0 "" "")
2647 (mem:SI (plus:SI (reg:SI PIC_REG)
2648 (const (unspec [(match_operand:SI 1 "" "")]
2649 UNSPEC_GOT)))))]
2650 ""
2651 "")
2652
2653 (define_expand "symGOTOFF2reg"
2654 [(match_operand:SI 0 "" "") (match_operand:SI 1 "" "")]
2655 ""
2656 "
2657 {
2658 rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1]));
2659
2660 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
2661 REG_NOTES (insn));
2662
2663 DONE;
2664 }")
2665
2666 (define_expand "symGOTOFF2reg_i"
2667 [(set (match_operand:SI 0 "" "")
2668 (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
2669 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI PIC_REG)))]
2670 ""
2671 "")
2672
2673 (define_expand "sym2PIC"
2674 [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC)]
2675 "" "")
2676
2677 (define_expand "sym2PLT"
2678 [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT)]
2679 "" "")