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