(output_function_{pro,epi}logue): Use addq/subq when adjusting stack
[gcc.git] / gcc / config / m68k / m68k.c
1 /* Subroutines for insn-output.c for Motorola 68000 family.
2 Copyright (C) 1987, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 /* Some output-actions in m68k.md need these. */
23 #include <stdio.h>
24 #include "config.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "real.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
32 #include "output.h"
33 #include "insn-attr.h"
34
35 /* Needed for use_return_insn. */
36 #include "flags.h"
37
38 #ifdef SUPPORT_SUN_FPA
39
40 /* Index into this array by (register number >> 3) to find the
41 smallest class which contains that register. */
42 enum reg_class regno_reg_class[]
43 = { DATA_REGS, ADDR_REGS, FP_REGS,
44 LO_FPA_REGS, LO_FPA_REGS, FPA_REGS, FPA_REGS };
45
46 #endif /* defined SUPPORT_SUN_FPA */
47
48 /* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END,
49 if SGS_SWITCH_TABLE. */
50 int switch_table_difference_label_flag;
51
52 static rtx find_addr_reg ();
53 rtx legitimize_pic_address ();
54 \f
55
56 /* Alignment to use for loops and jumps */
57 /* Specify power of two alignment used for loops. */
58 char *m68k_align_loops_string;
59 /* Specify power of two alignment used for non-loop jumps. */
60 char *m68k_align_jumps_string;
61 /* Specify power of two alignment used for functions. */
62 char *m68k_align_funcs_string;
63
64 /* Specify power of two alignment used for loops. */
65 int m68k_align_loops;
66 /* Specify power of two alignment used for non-loop jumps. */
67 int m68k_align_jumps;
68 /* Specify power of two alignment used for functions. */
69 int m68k_align_funcs;
70
71
72 /* Sometimes certain combinations of command options do not make
73 sense on a particular target machine. You can define a macro
74 `OVERRIDE_OPTIONS' to take account of this. This macro, if
75 defined, is executed once just after all the command options have
76 been parsed.
77
78 Don't use this macro to turn on various extra optimizations for
79 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
80
81 void
82 override_options ()
83 {
84 int def_align;
85
86 def_align = 1;
87
88 /* Validate -malign-loops= value, or provide default */
89 if (m68k_align_loops_string)
90 {
91 m68k_align_loops = atoi (m68k_align_loops_string);
92 if (m68k_align_loops < 1 || m68k_align_loops > MAX_CODE_ALIGN)
93 fatal ("-malign-loops=%d is not between 1 and %d",
94 m68k_align_loops, MAX_CODE_ALIGN);
95 }
96 else
97 m68k_align_loops = def_align;
98
99 /* Validate -malign-jumps= value, or provide default */
100 if (m68k_align_jumps_string)
101 {
102 m68k_align_jumps = atoi (m68k_align_jumps_string);
103 if (m68k_align_jumps < 1 || m68k_align_jumps > MAX_CODE_ALIGN)
104 fatal ("-malign-jumps=%d is not between 1 and %d",
105 m68k_align_jumps, MAX_CODE_ALIGN);
106 }
107 else
108 m68k_align_jumps = def_align;
109
110 /* Validate -malign-functions= value, or provide default */
111 if (m68k_align_funcs_string)
112 {
113 m68k_align_funcs = atoi (m68k_align_funcs_string);
114 if (m68k_align_funcs < 1 || m68k_align_funcs > MAX_CODE_ALIGN)
115 fatal ("-malign-functions=%d is not between 1 and %d",
116 m68k_align_funcs, MAX_CODE_ALIGN);
117 }
118 else
119 m68k_align_funcs = def_align;
120 }
121 \f
122 /* Emit a (use pic_offset_table_rtx) if we used PIC relocation in the
123 function at any time during the compilation process. In the future
124 we should try and eliminate the USE if we can easily determine that
125 all PIC references were deleted from the current function. That would
126 save an address register */
127
128 void
129 finalize_pic ()
130 {
131 if (flag_pic && current_function_uses_pic_offset_table)
132 {
133 rtx insn = gen_rtx (USE, VOIDmode, pic_offset_table_rtx);
134 emit_insn_after (insn, get_insns ());
135 emit_insn (insn);
136 }
137 }
138
139 \f
140 /* This function generates the assembly code for function entry.
141 STREAM is a stdio stream to output the code to.
142 SIZE is an int: how many units of temporary storage to allocate.
143 Refer to the array `regs_ever_live' to determine which registers
144 to save; `regs_ever_live[I]' is nonzero if register number I
145 is ever used in the function. This function is responsible for
146 knowing which registers should not be saved even if used. */
147
148
149 /* Note that the order of the bit mask for fmovem is the opposite
150 of the order for movem! */
151
152
153 void
154 output_function_prologue (stream, size)
155 FILE *stream;
156 int size;
157 {
158 register int regno;
159 register int mask = 0;
160 int num_saved_regs = 0;
161 extern char call_used_regs[];
162 int fsize = (size + 3) & -4;
163
164
165 if (frame_pointer_needed)
166 {
167 if (fsize == 0 && TARGET_68040)
168 {
169 /* on the 68040, pea + move is faster than link.w 0 */
170 #ifdef MOTOROLA
171 asm_fprintf (stream, "\tpea (%s)\n\tmove.l %s,%s\n",
172 reg_names[FRAME_POINTER_REGNUM], reg_names[STACK_POINTER_REGNUM],
173 reg_names[FRAME_POINTER_REGNUM]);
174 #else
175 asm_fprintf (stream, "\tpea %s@\n\tmovel %s,%s\n",
176 reg_names[FRAME_POINTER_REGNUM], reg_names[STACK_POINTER_REGNUM],
177 reg_names[FRAME_POINTER_REGNUM]);
178 #endif
179 }
180 else if (fsize < 0x8000)
181 {
182 #ifdef MOTOROLA
183 asm_fprintf (stream, "\tlink.w %s,%0I%d\n",
184 reg_names[FRAME_POINTER_REGNUM], -fsize);
185 #else
186 asm_fprintf (stream, "\tlink %s,%0I%d\n",
187 reg_names[FRAME_POINTER_REGNUM], -fsize);
188 #endif
189 }
190 else if (TARGET_68020)
191 {
192 #ifdef MOTOROLA
193 asm_fprintf (stream, "\tlink.l %s,%0I%d\n",
194 reg_names[FRAME_POINTER_REGNUM], -fsize);
195 #else
196 asm_fprintf (stream, "\tlink %s,%0I%d\n",
197 reg_names[FRAME_POINTER_REGNUM], -fsize);
198 #endif
199 }
200 else
201 {
202 /* Adding negative number is faster on the 68040. */
203 #ifdef MOTOROLA
204 asm_fprintf (stream, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
205 reg_names[FRAME_POINTER_REGNUM], -fsize);
206 #else
207 asm_fprintf (stream, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
208 reg_names[FRAME_POINTER_REGNUM], -fsize);
209 #endif
210 }
211 }
212 else if (fsize)
213 {
214 if (fsize + 4 < 0x8000)
215 {
216 #ifdef NO_ADDSUB_Q
217 if (fsize + 4 <= 8)
218 {
219 if (!TARGET_5200)
220 {
221 /* asm_fprintf() cannot handle %. */
222 #ifdef MOTOROLA
223 asm_fprintf (stream, "\tsubq.w %OI%d,%Rsp\n", fsize + 4);
224 #else
225 asm_fprintf (stream, "\tsubqw %OI%d,%Rsp\n", fsize + 4);
226 #endif
227 }
228 else
229 {
230 #ifdef MOTOROLA
231 asm_fprintf (stream, "\tsubq.l %OI%d,%Rsp\n", fsize + 4);
232 #else
233 asm_fprintf (stream, "\tsubql %OI%d,%Rsp\n", fsize + 4);
234 #endif
235 }
236 }
237 else if (fsize + 4 <= 16 && TARGET_CPU32)
238 {
239 /* On the CPU32 it is faster to use two subqw instructions to
240 subtract a small integer (8 < N <= 16) to a register. */
241 /* asm_fprintf() cannot handle %. */
242 #ifdef MOTOROLA
243 asm_fprintf (stream, "\tsubq.w %OI8,%Rsp\n\tsubq.w %OI%d,%Rsp\n",
244 fsize + 4);
245 #else
246 asm_fprintf (stream, "\tsubqw %OI8,%Rsp\n\tsubqw %OI%d,%Rsp\n",
247 fsize + 4);
248 #endif
249 }
250 else
251 #endif /* NO_ADDSUB_Q */
252 if (TARGET_68040)
253 {
254 /* Adding negative number is faster on the 68040. */
255 /* asm_fprintf() cannot handle %. */
256 #ifdef MOTOROLA
257 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", - (fsize + 4));
258 #else
259 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", - (fsize + 4));
260 #endif
261 }
262 else
263 {
264 /* asm_fprintf() cannot handle %. */
265 #ifdef MOTOROLA
266 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", - (fsize + 4));
267 #else
268 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", - (fsize + 4));
269 #endif
270 }
271 }
272 else
273 {
274 /* asm_fprintf() cannot handle %. */
275 #ifdef MOTOROLA
276 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", - (fsize + 4));
277 #else
278 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", - (fsize + 4));
279 #endif
280 }
281 }
282 #ifdef SUPPORT_SUN_FPA
283 for (regno = 24; regno < 56; regno++)
284 if (regs_ever_live[regno] && ! call_used_regs[regno])
285 {
286 #ifdef MOTOROLA
287 asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
288 reg_names[regno]);
289 #else
290 asm_fprintf (stream, "\tfpmoved %s,%Rsp@-\n",
291 reg_names[regno]);
292 #endif
293 }
294 #endif
295 if (TARGET_68881)
296 {
297 for (regno = 16; regno < 24; regno++)
298 if (regs_ever_live[regno] && ! call_used_regs[regno])
299 mask |= 1 << (regno - 16);
300 if ((mask & 0xff) != 0)
301 {
302 #ifdef MOTOROLA
303 asm_fprintf (stream, "\tfmovm %0I0x%x,-(%Rsp)\n", mask & 0xff);
304 #else
305 asm_fprintf (stream, "\tfmovem %0I0x%x,%Rsp@-\n", mask & 0xff);
306 #endif
307 }
308 mask = 0;
309 }
310 for (regno = 0; regno < 16; regno++)
311 if (regs_ever_live[regno] && ! call_used_regs[regno])
312 {
313 mask |= 1 << (15 - regno);
314 num_saved_regs++;
315 }
316 if (frame_pointer_needed)
317 {
318 mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM));
319 num_saved_regs--;
320 }
321
322 #if NEED_PROBE
323 asm_fprintf (stream, "\ttstl %Rsp@(%d)\n", NEED_PROBE - num_saved_regs * 4);
324 #endif
325
326 if (num_saved_regs <= 2)
327 {
328 /* Store each separately in the same order moveml uses.
329 Using two movel instructions instead of a single moveml
330 is about 15% faster for the 68020 and 68030 at no expense
331 in code size */
332
333 int i;
334
335 /* Undo the work from above. */
336 for (i = 0; i< 16; i++)
337 if (mask & (1 << i))
338 asm_fprintf (stream,
339 #ifdef MOTOROLA
340 "\t%Omove.l %s,-(%Rsp)\n",
341 #else
342 "\tmovel %s,%Rsp@-\n",
343 #endif
344 reg_names[15 - i]);
345 }
346 else if (mask)
347 {
348 if (TARGET_5200)
349 {
350 /* The coldfire does not support the predecrement form of the
351 movml instruction, so we must adjust the stack pointer and
352 then use the plain address register indirect mode. We also
353 have to invert the register save mask to use the new mode.
354
355 FIXME: if num_saved_regs was calculated earlier, we could
356 combine the stack pointer adjustment with any adjustment
357 done when the initial stack frame is created. This would
358 save an instruction */
359
360 int newmask = 0;
361 int i;
362
363 for (i = 0; i < 16; i++)
364 if (mask & (1 << i))
365 newmask |= (1 << (15-i));
366
367 #ifdef MOTOROLA
368 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs*4);
369 asm_fprintf (stream, "\tmovm.l %0I0x%x,(%Rsp)\n", newmask);
370 #else
371 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs*4);
372 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@\n", newmask);
373 #endif
374 }
375 else
376 {
377 #ifdef MOTOROLA
378 asm_fprintf (stream, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask);
379 #else
380 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@-\n", mask);
381 #endif
382 }
383 }
384 if (flag_pic && current_function_uses_pic_offset_table)
385 {
386 #ifdef MOTOROLA
387 asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
388 reg_names[PIC_OFFSET_TABLE_REGNUM]);
389 #else
390 asm_fprintf (stream, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
391 reg_names[PIC_OFFSET_TABLE_REGNUM]);
392 asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",
393 reg_names[PIC_OFFSET_TABLE_REGNUM],
394 reg_names[PIC_OFFSET_TABLE_REGNUM]);
395 #endif
396 }
397 }
398 \f
399 /* Return true if this function's epilogue can be output as RTL. */
400
401 int
402 use_return_insn ()
403 {
404 int regno;
405
406 if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
407 return 0;
408
409 /* Copied from output_function_epilogue (). We should probably create a
410 separate layout routine to perform the common work. */
411
412 for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
413 if (regs_ever_live[regno] && ! call_used_regs[regno])
414 return 0;
415
416 return 1;
417 }
418
419 /* This function generates the assembly code for function exit,
420 on machines that need it. Args are same as for FUNCTION_PROLOGUE.
421
422 The function epilogue should not depend on the current stack pointer!
423 It should use the frame pointer only, if there is a frame pointer.
424 This is mandatory because of alloca; we also take advantage of it to
425 omit stack adjustments before returning. */
426
427 void
428 output_function_epilogue (stream, size)
429 FILE *stream;
430 int size;
431 {
432 register int regno;
433 register int mask, fmask;
434 register int nregs;
435 int offset, foffset, fpoffset;
436 extern char call_used_regs[];
437 int fsize = (size + 3) & -4;
438 int big = 0;
439 rtx insn = get_last_insn ();
440 int restore_from_sp = 0;
441
442 /* If the last insn was a BARRIER, we don't have to write any code. */
443 if (GET_CODE (insn) == NOTE)
444 insn = prev_nonnote_insn (insn);
445 if (insn && GET_CODE (insn) == BARRIER)
446 {
447 /* Output just a no-op so that debuggers don't get confused
448 about which function the pc is in at this address. */
449 asm_fprintf (stream, "\tnop\n");
450 return;
451 }
452
453 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
454 if (profile_block_flag == 2)
455 {
456 FUNCTION_BLOCK_PROFILER_EXIT (stream);
457 }
458 #endif
459
460 #ifdef FUNCTION_EXTRA_EPILOGUE
461 FUNCTION_EXTRA_EPILOGUE (stream, size);
462 #endif
463 nregs = 0; fmask = 0; fpoffset = 0;
464 #ifdef SUPPORT_SUN_FPA
465 for (regno = 24 ; regno < 56 ; regno++)
466 if (regs_ever_live[regno] && ! call_used_regs[regno])
467 nregs++;
468 fpoffset = nregs * 8;
469 #endif
470 nregs = 0;
471 if (TARGET_68881)
472 {
473 for (regno = 16; regno < 24; regno++)
474 if (regs_ever_live[regno] && ! call_used_regs[regno])
475 {
476 nregs++;
477 fmask |= 1 << (23 - regno);
478 }
479 }
480 foffset = fpoffset + nregs * 12;
481 nregs = 0; mask = 0;
482 if (frame_pointer_needed)
483 regs_ever_live[FRAME_POINTER_REGNUM] = 0;
484 for (regno = 0; regno < 16; regno++)
485 if (regs_ever_live[regno] && ! call_used_regs[regno])
486 {
487 nregs++;
488 mask |= 1 << regno;
489 }
490 offset = foffset + nregs * 4;
491 /* FIXME : leaf_function_p below is too strong.
492 What we really need to know there is if there could be pending
493 stack adjustment needed at that point. */
494 restore_from_sp = ! frame_pointer_needed
495 || (! current_function_calls_alloca && leaf_function_p ());
496 if (offset + fsize >= 0x8000
497 && ! restore_from_sp
498 && (mask || fmask || fpoffset))
499 {
500 #ifdef MOTOROLA
501 asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra1\n", -fsize);
502 #else
503 asm_fprintf (stream, "\tmovel %0I%d,%Ra1\n", -fsize);
504 #endif
505 fsize = 0, big = 1;
506 }
507 if (TARGET_5200 || nregs <= 2)
508 {
509 /* Restore each separately in the same order moveml does.
510 Using two movel instructions instead of a single moveml
511 is about 15% faster for the 68020 and 68030 at no expense
512 in code size. */
513
514 int i;
515
516 /* Undo the work from above. */
517 for (i = 0; i< 16; i++)
518 if (mask & (1 << i))
519 {
520 if (big)
521 {
522 #ifdef MOTOROLA
523 asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra1.l),%s\n",
524 offset + fsize,
525 reg_names[FRAME_POINTER_REGNUM],
526 reg_names[i]);
527 #else
528 asm_fprintf (stream, "\tmovel %s@(-%d,%Ra1:l),%s\n",
529 reg_names[FRAME_POINTER_REGNUM],
530 offset + fsize, reg_names[i]);
531 #endif
532 }
533 else if (restore_from_sp)
534 {
535 #ifdef MOTOROLA
536 asm_fprintf (stream, "\t%Omove.l (%Rsp)+,%s\n",
537 reg_names[i]);
538 #else
539 asm_fprintf (stream, "\tmovel %Rsp@+,%s\n",
540 reg_names[i]);
541 #endif
542 }
543 else
544 {
545 #ifdef MOTOROLA
546 asm_fprintf (stream, "\t%Omove.l -%d(%s),%s\n",
547 offset + fsize,
548 reg_names[FRAME_POINTER_REGNUM],
549 reg_names[i]);
550 #else
551 asm_fprintf (stream, "\tmovel %s@(-%d),%s\n",
552 reg_names[FRAME_POINTER_REGNUM],
553 offset + fsize, reg_names[i]);
554 #endif
555 }
556 offset = offset - 4;
557 }
558 }
559 else if (mask)
560 {
561 if (big)
562 {
563 #ifdef MOTOROLA
564 asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n",
565 offset + fsize,
566 reg_names[FRAME_POINTER_REGNUM],
567 mask);
568 #else
569 asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n",
570 reg_names[FRAME_POINTER_REGNUM],
571 offset + fsize, mask);
572 #endif
573 }
574 else if (restore_from_sp)
575 {
576 #ifdef MOTOROLA
577 asm_fprintf (stream, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask);
578 #else
579 asm_fprintf (stream, "\tmoveml %Rsp@+,%0I0x%x\n", mask);
580 #endif
581 }
582 else
583 {
584 #ifdef MOTOROLA
585 asm_fprintf (stream, "\tmovm.l -%d(%s),%0I0x%x\n",
586 offset + fsize,
587 reg_names[FRAME_POINTER_REGNUM],
588 mask);
589 #else
590 asm_fprintf (stream, "\tmoveml %s@(-%d),%0I0x%x\n",
591 reg_names[FRAME_POINTER_REGNUM],
592 offset + fsize, mask);
593 #endif
594 }
595 }
596 if (fmask)
597 {
598 if (big)
599 {
600 #ifdef MOTOROLA
601 asm_fprintf (stream, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n",
602 foffset + fsize,
603 reg_names[FRAME_POINTER_REGNUM],
604 fmask);
605 #else
606 asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n",
607 reg_names[FRAME_POINTER_REGNUM],
608 foffset + fsize, fmask);
609 #endif
610 }
611 else if (restore_from_sp)
612 {
613 #ifdef MOTOROLA
614 asm_fprintf (stream, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask);
615 #else
616 asm_fprintf (stream, "\tfmovem %Rsp@+,%0I0x%x\n", fmask);
617 #endif
618 }
619 else
620 {
621 #ifdef MOTOROLA
622 asm_fprintf (stream, "\tfmovm -%d(%s),%0I0x%x\n",
623 foffset + fsize,
624 reg_names[FRAME_POINTER_REGNUM],
625 fmask);
626 #else
627 asm_fprintf (stream, "\tfmovem %s@(-%d),%0I0x%x\n",
628 reg_names[FRAME_POINTER_REGNUM],
629 foffset + fsize, fmask);
630 #endif
631 }
632 }
633 if (fpoffset != 0)
634 for (regno = 55; regno >= 24; regno--)
635 if (regs_ever_live[regno] && ! call_used_regs[regno])
636 {
637 if (big)
638 {
639 #ifdef MOTOROLA
640 asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra1.l), %s\n",
641 fpoffset + fsize,
642 reg_names[FRAME_POINTER_REGNUM],
643 reg_names[regno]);
644 #else
645 asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra1:l), %s\n",
646 reg_names[FRAME_POINTER_REGNUM],
647 fpoffset + fsize, reg_names[regno]);
648 #endif
649 }
650 else if (restore_from_sp)
651 {
652 #ifdef MOTOROLA
653 asm_fprintf (stream, "\tfpmovd (%Rsp)+,%s\n",
654 reg_names[regno]);
655 #else
656 asm_fprintf (stream, "\tfpmoved %Rsp@+, %s\n",
657 reg_names[regno]);
658 #endif
659 }
660 else
661 {
662 #ifdef MOTOROLA
663 asm_fprintf (stream, "\tfpmovd -%d(%s), %s\n",
664 fpoffset + fsize,
665 reg_names[FRAME_POINTER_REGNUM],
666 reg_names[regno]);
667 #else
668 asm_fprintf (stream, "\tfpmoved %s@(-%d), %s\n",
669 reg_names[FRAME_POINTER_REGNUM],
670 fpoffset + fsize, reg_names[regno]);
671 #endif
672 }
673 fpoffset -= 8;
674 }
675 if (frame_pointer_needed)
676 fprintf (stream, "\tunlk %s\n",
677 reg_names[FRAME_POINTER_REGNUM]);
678 else if (fsize)
679 {
680 #ifdef NO_ADDSUB_Q
681 if (fsize + 4 <= 8)
682 {
683 if (!TARGET_5200)
684 {
685 #ifdef MOTOROLA
686 asm_fprintf (stream, "\taddq.w %OI%d,%Rsp\n", fsize + 4);
687 #else
688 asm_fprintf (stream, "\taddqw %OI%d,%Rsp\n", fsize + 4);
689 #endif
690 }
691 else
692 {
693 #ifdef MOTOROLA
694 asm_fprintf (stream, "\taddq.l %OI%d,%Rsp\n", fsize + 4);
695 #else
696 asm_fprintf (stream, "\taddql %OI%d,%Rsp\n", fsize + 4);
697 #endif
698 }
699 }
700 else if (fsize + 4 <= 16 && TARGET_CPU32)
701 {
702 /* On the CPU32 it is faster to use two addqw instructions to
703 add a small integer (8 < N <= 16) to a register. */
704 #ifdef MOTOROLA
705 asm_fprintf (stream, "\taddq.w %OI8,%Rsp\n\taddq.w %OI%d,%Rsp\n",
706 fsize + 4);
707 #else
708 asm_fprintf (stream, "\taddqw %OI8,%Rsp\n\taddqw %OI%d,%Rsp\n",
709 fsize + 4);
710 #endif
711 }
712 else
713 #endif /* NO_ADDSUB_Q */
714 if (fsize + 4 < 0x8000)
715 {
716 if (TARGET_68040)
717 {
718 /* asm_fprintf() cannot handle %. */
719 #ifdef MOTOROLA
720 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4);
721 #else
722 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", fsize + 4);
723 #endif
724 }
725 else
726 {
727 /* asm_fprintf() cannot handle %. */
728 #ifdef MOTOROLA
729 asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", fsize + 4);
730 #else
731 asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", fsize + 4);
732 #endif
733 }
734 }
735 else
736 {
737 /* asm_fprintf() cannot handle %. */
738 #ifdef MOTOROLA
739 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4);
740 #else
741 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4);
742 #endif
743 }
744 }
745 if (current_function_pops_args)
746 asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
747 else
748 fprintf (stream, "\trts\n");
749 }
750 \f
751 /* Similar to general_operand, but exclude stack_pointer_rtx. */
752
753 int
754 not_sp_operand (op, mode)
755 register rtx op;
756 enum machine_mode mode;
757 {
758 return op != stack_pointer_rtx && general_operand (op, mode);
759 }
760
761 /* Return TRUE if X is a valid comparison operator for the dbcc
762 instruction.
763
764 Note it rejects floating point comparison operators.
765 (In the future we could use Fdbcc).
766
767 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
768
769 int
770 valid_dbcc_comparison_p (x, mode)
771 rtx x;
772 enum machine_mode mode;
773 {
774 switch (GET_CODE (x))
775 {
776 case EQ: case NE: case GTU: case LTU:
777 case GEU: case LEU:
778 return 1;
779
780 /* Reject some when CC_NO_OVERFLOW is set. This may be over
781 conservative */
782 case GT: case LT: case GE: case LE:
783 return ! (cc_prev_status.flags & CC_NO_OVERFLOW);
784 default:
785 return 0;
786 }
787 }
788
789 /* Return non-zero if flags are currently in the 68881 flag register. */
790 int
791 flags_in_68881 ()
792 {
793 /* We could add support for these in the future */
794 return cc_status.flags & CC_IN_68881;
795 }
796
797 /* Output a dbCC; jCC sequence. Note we do not handle the
798 floating point version of this sequence (Fdbcc). We also
799 do not handle alternative conditions when CC_NO_OVERFLOW is
800 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
801 kick those out before we get here. */
802
803 output_dbcc_and_branch (operands)
804 rtx *operands;
805 {
806 switch (GET_CODE (operands[3]))
807 {
808 case EQ:
809 #ifdef MOTOROLA
810 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands);
811 #else
812 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands);
813 #endif
814 break;
815
816 case NE:
817 #ifdef MOTOROLA
818 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands);
819 #else
820 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands);
821 #endif
822 break;
823
824 case GT:
825 #ifdef MOTOROLA
826 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands);
827 #else
828 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands);
829 #endif
830 break;
831
832 case GTU:
833 #ifdef MOTOROLA
834 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands);
835 #else
836 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands);
837 #endif
838 break;
839
840 case LT:
841 #ifdef MOTOROLA
842 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands);
843 #else
844 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands);
845 #endif
846 break;
847
848 case LTU:
849 #ifdef MOTOROLA
850 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands);
851 #else
852 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands);
853 #endif
854 break;
855
856 case GE:
857 #ifdef MOTOROLA
858 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands);
859 #else
860 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands);
861 #endif
862 break;
863
864 case GEU:
865 #ifdef MOTOROLA
866 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands);
867 #else
868 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands);
869 #endif
870 break;
871
872 case LE:
873 #ifdef MOTOROLA
874 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands);
875 #else
876 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands);
877 #endif
878 break;
879
880 case LEU:
881 #ifdef MOTOROLA
882 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands);
883 #else
884 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands);
885 #endif
886 break;
887
888 default:
889 abort ();
890 }
891
892 /* If the decrement is to be done in SImode, then we have
893 to compensate for the fact that dbcc decrements in HImode. */
894 switch (GET_MODE (operands[0]))
895 {
896 case SImode:
897 #ifdef MOTOROLA
898 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands);
899 #else
900 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands);
901 #endif
902 break;
903
904 case HImode:
905 break;
906
907 default:
908 abort ();
909 }
910 }
911
912 char *
913 output_scc_di(op, operand1, operand2, dest)
914 rtx op;
915 rtx operand1;
916 rtx operand2;
917 rtx dest;
918 {
919 rtx loperands[7];
920 enum rtx_code op_code = GET_CODE (op);
921
922 /* The m68k cmp.l instruction requires operand1 to be a reg as used
923 below. Swap the operands and change the op if these requirements
924 are not fulfilled. */
925 if (GET_CODE (operand2) == REG && GET_CODE (operand1) != REG)
926 {
927 rtx tmp = operand1;
928
929 operand1 = operand2;
930 operand2 = tmp;
931 op_code = swap_condition (op_code);
932 }
933 loperands[0] = operand1;
934 if (GET_CODE (operand1) == REG)
935 loperands[1] = gen_rtx (REG, SImode, REGNO (operand1) + 1);
936 else
937 loperands[1] = adj_offsettable_operand (operand1, 4);
938 if (operand2 != const0_rtx)
939 {
940 loperands[2] = operand2;
941 if (GET_CODE (operand2) == REG)
942 loperands[3] = gen_rtx (REG, SImode, REGNO (operand2) + 1);
943 else
944 loperands[3] = adj_offsettable_operand (operand2, 4);
945 }
946 loperands[4] = gen_label_rtx();
947 if (operand2 != const0_rtx)
948 #ifdef MOTOROLA
949 #ifdef SGS_CMP_ORDER
950 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands);
951 #else
952 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands);
953 #endif
954 #else
955 #ifdef SGS_CMP_ORDER
956 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands);
957 #else
958 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands);
959 #endif
960 #endif
961 else
962 #ifdef MOTOROLA
963 output_asm_insn ("tst%.l %0\n\tjbne %l4\n\ttst%.l %1", loperands);
964 #else
965 output_asm_insn ("tst%.l %0\n\tjne %l4\n\ttst%.l %1", loperands);
966 #endif
967 loperands[5] = dest;
968
969 switch (op_code)
970 {
971 case EQ:
972 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
973 CODE_LABEL_NUMBER (loperands[4]));
974 output_asm_insn ("seq %5", loperands);
975 break;
976
977 case NE:
978 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
979 CODE_LABEL_NUMBER (loperands[4]));
980 output_asm_insn ("sne %5", loperands);
981 break;
982
983 case GT:
984 loperands[6] = gen_label_rtx();
985 #ifdef MOTOROLA
986 output_asm_insn ("shi %5\n\tjbra %l6", loperands);
987 #else
988 output_asm_insn ("shi %5\n\tjra %l6", loperands);
989 #endif
990 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
991 CODE_LABEL_NUMBER (loperands[4]));
992 output_asm_insn ("sgt %5", loperands);
993 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
994 CODE_LABEL_NUMBER (loperands[6]));
995 break;
996
997 case GTU:
998 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
999 CODE_LABEL_NUMBER (loperands[4]));
1000 output_asm_insn ("shi %5", loperands);
1001 break;
1002
1003 case LT:
1004 loperands[6] = gen_label_rtx();
1005 #ifdef MOTOROLA
1006 output_asm_insn ("scs %5\n\tjbra %l6", loperands);
1007 #else
1008 output_asm_insn ("scs %5\n\tjra %l6", loperands);
1009 #endif
1010 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1011 CODE_LABEL_NUMBER (loperands[4]));
1012 output_asm_insn ("slt %5", loperands);
1013 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1014 CODE_LABEL_NUMBER (loperands[6]));
1015 break;
1016
1017 case LTU:
1018 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1019 CODE_LABEL_NUMBER (loperands[4]));
1020 output_asm_insn ("scs %5", loperands);
1021 break;
1022
1023 case GE:
1024 loperands[6] = gen_label_rtx();
1025 #ifdef MOTOROLA
1026 output_asm_insn ("scc %5\n\tjbra %l6", loperands);
1027 #else
1028 output_asm_insn ("scc %5\n\tjra %l6", loperands);
1029 #endif
1030 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1031 CODE_LABEL_NUMBER (loperands[4]));
1032 output_asm_insn ("sge %5", loperands);
1033 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1034 CODE_LABEL_NUMBER (loperands[6]));
1035 break;
1036
1037 case GEU:
1038 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1039 CODE_LABEL_NUMBER (loperands[4]));
1040 output_asm_insn ("scc %5", loperands);
1041 break;
1042
1043 case LE:
1044 loperands[6] = gen_label_rtx();
1045 #ifdef MOTOROLA
1046 output_asm_insn ("sls %5\n\tjbra %l6", loperands);
1047 #else
1048 output_asm_insn ("sls %5\n\tjra %l6", loperands);
1049 #endif
1050 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1051 CODE_LABEL_NUMBER (loperands[4]));
1052 output_asm_insn ("sle %5", loperands);
1053 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1054 CODE_LABEL_NUMBER (loperands[6]));
1055 break;
1056
1057 case LEU:
1058 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1059 CODE_LABEL_NUMBER (loperands[4]));
1060 output_asm_insn ("sls %5", loperands);
1061 break;
1062
1063 default:
1064 abort ();
1065 }
1066 return "";
1067 }
1068
1069 char *
1070 output_btst (operands, countop, dataop, insn, signpos)
1071 rtx *operands;
1072 rtx countop, dataop;
1073 rtx insn;
1074 int signpos;
1075 {
1076 operands[0] = countop;
1077 operands[1] = dataop;
1078
1079 if (GET_CODE (countop) == CONST_INT)
1080 {
1081 register int count = INTVAL (countop);
1082 /* If COUNT is bigger than size of storage unit in use,
1083 advance to the containing unit of same size. */
1084 if (count > signpos)
1085 {
1086 int offset = (count & ~signpos) / 8;
1087 count = count & signpos;
1088 operands[1] = dataop = adj_offsettable_operand (dataop, offset);
1089 }
1090 if (count == signpos)
1091 cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
1092 else
1093 cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N;
1094
1095 /* These three statements used to use next_insns_test_no...
1096 but it appears that this should do the same job. */
1097 if (count == 31
1098 && next_insn_tests_no_inequality (insn))
1099 return "tst%.l %1";
1100 if (count == 15
1101 && next_insn_tests_no_inequality (insn))
1102 return "tst%.w %1";
1103 if (count == 7
1104 && next_insn_tests_no_inequality (insn))
1105 return "tst%.b %1";
1106
1107 cc_status.flags = CC_NOT_NEGATIVE;
1108 }
1109 return "btst %0,%1";
1110 }
1111 \f
1112 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1113 reference and a constant. */
1114
1115 int
1116 symbolic_operand (op, mode)
1117 register rtx op;
1118 enum machine_mode mode;
1119 {
1120 switch (GET_CODE (op))
1121 {
1122 case SYMBOL_REF:
1123 case LABEL_REF:
1124 return 1;
1125
1126 case CONST:
1127 op = XEXP (op, 0);
1128 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1129 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1130 && GET_CODE (XEXP (op, 1)) == CONST_INT);
1131
1132 #if 0 /* Deleted, with corresponding change in m68k.h,
1133 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
1134 case CONST_DOUBLE:
1135 return GET_MODE (op) == mode;
1136 #endif
1137
1138 default:
1139 return 0;
1140 }
1141 }
1142 \f
1143 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
1144
1145 int
1146 extend_operator(x, mode)
1147 rtx x;
1148 enum machine_mode mode;
1149 {
1150 if (mode != VOIDmode && GET_MODE(x) != mode)
1151 return 0;
1152 switch (GET_CODE(x))
1153 {
1154 case SIGN_EXTEND :
1155 case ZERO_EXTEND :
1156 return 1;
1157 default :
1158 return 0;
1159 }
1160 }
1161
1162 \f
1163 /* Legitimize PIC addresses. If the address is already
1164 position-independent, we return ORIG. Newly generated
1165 position-independent addresses go to REG. If we need more
1166 than one register, we lose.
1167
1168 An address is legitimized by making an indirect reference
1169 through the Global Offset Table with the name of the symbol
1170 used as an offset.
1171
1172 The assembler and linker are responsible for placing the
1173 address of the symbol in the GOT. The function prologue
1174 is responsible for initializing a5 to the starting address
1175 of the GOT.
1176
1177 The assembler is also responsible for translating a symbol name
1178 into a constant displacement from the start of the GOT.
1179
1180 A quick example may make things a little clearer:
1181
1182 When not generating PIC code to store the value 12345 into _foo
1183 we would generate the following code:
1184
1185 movel #12345, _foo
1186
1187 When generating PIC two transformations are made. First, the compiler
1188 loads the address of foo into a register. So the first transformation makes:
1189
1190 lea _foo, a0
1191 movel #12345, a0@
1192
1193 The code in movsi will intercept the lea instruction and call this
1194 routine which will transform the instructions into:
1195
1196 movel a5@(_foo:w), a0
1197 movel #12345, a0@
1198
1199
1200 That (in a nutshell) is how *all* symbol and label references are
1201 handled. */
1202
1203 rtx
1204 legitimize_pic_address (orig, mode, reg)
1205 rtx orig, reg;
1206 enum machine_mode mode;
1207 {
1208 rtx pic_ref = orig;
1209
1210 /* First handle a simple SYMBOL_REF or LABEL_REF */
1211 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1212 {
1213 if (reg == 0)
1214 abort ();
1215
1216 pic_ref = gen_rtx (MEM, Pmode,
1217 gen_rtx (PLUS, Pmode,
1218 pic_offset_table_rtx, orig));
1219 current_function_uses_pic_offset_table = 1;
1220 RTX_UNCHANGING_P (pic_ref) = 1;
1221 emit_move_insn (reg, pic_ref);
1222 return reg;
1223 }
1224 else if (GET_CODE (orig) == CONST)
1225 {
1226 rtx base, offset;
1227
1228 /* Make sure this is CONST has not already been legitimized */
1229 if (GET_CODE (XEXP (orig, 0)) == PLUS
1230 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1231 return orig;
1232
1233 if (reg == 0)
1234 abort ();
1235
1236 /* legitimize both operands of the PLUS */
1237 if (GET_CODE (XEXP (orig, 0)) == PLUS)
1238 {
1239 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1240 orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1241 base == reg ? 0 : reg);
1242 }
1243 else abort ();
1244
1245 if (GET_CODE (orig) == CONST_INT)
1246 return plus_constant_for_output (base, INTVAL (orig));
1247 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
1248 /* Likewise, should we set special REG_NOTEs here? */
1249 }
1250 return pic_ref;
1251 }
1252
1253 \f
1254 typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ } CONST_METHOD;
1255
1256 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
1257
1258 CONST_METHOD
1259 const_method (constant)
1260 rtx constant;
1261 {
1262 int i;
1263 unsigned u;
1264
1265 i = INTVAL (constant);
1266 if (USE_MOVQ (i))
1267 return MOVQ;
1268
1269 /* The Coldfire doesn't have byte or word operations. */
1270 /* FIXME: This may not be useful for the m68060 either */
1271 if (!TARGET_5200)
1272 {
1273 /* if -256 < N < 256 but N is not in range for a moveq
1274 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1275 if (USE_MOVQ (i ^ 0xff))
1276 return NOTB;
1277 /* Likewise, try with not.w */
1278 if (USE_MOVQ (i ^ 0xffff))
1279 return NOTW;
1280 /* This is the only value where neg.w is useful */
1281 if (i == -65408)
1282 return NEGW;
1283 /* Try also with swap */
1284 u = i;
1285 if (USE_MOVQ ((u >> 16) | (u << 16)))
1286 return SWAP;
1287 }
1288 /* Otherwise, use move.l */
1289 return MOVL;
1290 }
1291
1292 const_int_cost (constant)
1293 rtx constant;
1294 {
1295 switch (const_method (constant))
1296 {
1297 case MOVQ :
1298 /* Constants between -128 and 127 are cheap due to moveq */
1299 return 0;
1300 case NOTB :
1301 case NOTW :
1302 case NEGW :
1303 case SWAP :
1304 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
1305 return 1;
1306 case MOVL :
1307 return 2;
1308 default :
1309 abort ();
1310 }
1311 }
1312
1313 char *
1314 output_move_const_into_data_reg (operands)
1315 rtx *operands;
1316 {
1317 int i;
1318
1319 i = INTVAL (operands[1]);
1320 switch (const_method (operands[1]))
1321 {
1322 case MOVQ :
1323 #if defined (MOTOROLA) && !defined (CRDS)
1324 return "moveq%.l %1,%0";
1325 #else
1326 return "moveq %1,%0";
1327 #endif
1328 case NOTB :
1329 operands[1] = gen_rtx (CONST_INT, VOIDmode, i ^ 0xff);
1330 #if defined (MOTOROLA) && !defined (CRDS)
1331 return "moveq%.l %1,%0\n\tnot%.b %0";
1332 #else
1333 return "moveq %1,%0\n\tnot%.b %0";
1334 #endif
1335 case NOTW :
1336 operands[1] = gen_rtx (CONST_INT, VOIDmode, i ^ 0xffff);
1337 #if defined (MOTOROLA) && !defined (CRDS)
1338 return "moveq%.l %1,%0\n\tnot%.w %0";
1339 #else
1340 return "moveq %1,%0\n\tnot%.w %0";
1341 #endif
1342 case NEGW :
1343 #if defined (MOTOROLA) && !defined (CRDS)
1344 return "moveq%.l %#-128,%0\n\tneg%.w %0";
1345 #else
1346 return "moveq %#-128,%0\n\tneg%.w %0";
1347 #endif
1348 case SWAP :
1349 {
1350 unsigned u = i;
1351
1352 operands[1] = gen_rtx (CONST_INT, VOIDmode, (u << 16) | (u >> 16));
1353 #if defined (MOTOROLA) && !defined (CRDS)
1354 return "moveq%.l %1,%0\n\tswap %0";
1355 #else
1356 return "moveq %1,%0\n\tswap %0";
1357 #endif
1358 }
1359 case MOVL :
1360 return "move%.l %1,%0";
1361 default :
1362 abort ();
1363 }
1364 }
1365
1366 char *
1367 output_move_simode_const (operands)
1368 rtx *operands;
1369 {
1370 if (operands[1] == const0_rtx
1371 && (DATA_REG_P (operands[0])
1372 || GET_CODE (operands[0]) == MEM)
1373 /* clr insns on 68000 read before writing.
1374 This isn't so on the 68010, but we have no TARGET_68010. */
1375 && (TARGET_68020
1376 || !(GET_CODE (operands[0]) == MEM
1377 && MEM_VOLATILE_P (operands[0]))))
1378 return "clr%.l %0";
1379 else if (DATA_REG_P (operands[0]))
1380 return output_move_const_into_data_reg (operands);
1381 else if (ADDRESS_REG_P (operands[0])
1382 && INTVAL (operands[1]) < 0x8000
1383 && INTVAL (operands[1]) >= -0x8000)
1384 return "move%.w %1,%0";
1385 else if (GET_CODE (operands[0]) == MEM
1386 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1387 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1388 && INTVAL (operands[1]) < 0x8000
1389 && INTVAL (operands[1]) >= -0x8000)
1390 return "pea %a1";
1391 return "move%.l %1,%0";
1392 }
1393
1394 /* Return the best assembler insn template
1395 for moving operands[1] into operands[0] as a fullword. */
1396
1397 static char *
1398 singlemove_string (operands)
1399 rtx *operands;
1400 {
1401 #ifdef SUPPORT_SUN_FPA
1402 if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))
1403 return "fpmoves %1,%0";
1404 #endif
1405 if (GET_CODE (operands[1]) == CONST_INT)
1406 return output_move_simode_const (operands);
1407 return "move%.l %1,%0";
1408 }
1409
1410
1411 /* Output assembler code to perform a doubleword move insn
1412 with operands OPERANDS. */
1413
1414 char *
1415 output_move_double (operands)
1416 rtx *operands;
1417 {
1418 enum
1419 {
1420 REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP
1421 } optype0, optype1;
1422 rtx latehalf[2];
1423 rtx middlehalf[2];
1424 rtx xops[2];
1425 rtx addreg0 = 0, addreg1 = 0;
1426 int dest_overlapped_low = 0;
1427 int size = GET_MODE_SIZE (GET_MODE (operands[0]));
1428
1429 middlehalf[0] = 0;
1430 middlehalf[1] = 0;
1431
1432 /* First classify both operands. */
1433
1434 if (REG_P (operands[0]))
1435 optype0 = REGOP;
1436 else if (offsettable_memref_p (operands[0]))
1437 optype0 = OFFSOP;
1438 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1439 optype0 = POPOP;
1440 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1441 optype0 = PUSHOP;
1442 else if (GET_CODE (operands[0]) == MEM)
1443 optype0 = MEMOP;
1444 else
1445 optype0 = RNDOP;
1446
1447 if (REG_P (operands[1]))
1448 optype1 = REGOP;
1449 else if (CONSTANT_P (operands[1]))
1450 optype1 = CNSTOP;
1451 else if (offsettable_memref_p (operands[1]))
1452 optype1 = OFFSOP;
1453 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
1454 optype1 = POPOP;
1455 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1456 optype1 = PUSHOP;
1457 else if (GET_CODE (operands[1]) == MEM)
1458 optype1 = MEMOP;
1459 else
1460 optype1 = RNDOP;
1461
1462 /* Check for the cases that the operand constraints are not
1463 supposed to allow to happen. Abort if we get one,
1464 because generating code for these cases is painful. */
1465
1466 if (optype0 == RNDOP || optype1 == RNDOP)
1467 abort ();
1468
1469 /* If one operand is decrementing and one is incrementing
1470 decrement the former register explicitly
1471 and change that operand into ordinary indexing. */
1472
1473 if (optype0 == PUSHOP && optype1 == POPOP)
1474 {
1475 operands[0] = XEXP (XEXP (operands[0], 0), 0);
1476 if (size == 12)
1477 output_asm_insn ("sub%.l %#12,%0", operands);
1478 else
1479 output_asm_insn ("subq%.l %#8,%0", operands);
1480 if (GET_MODE (operands[1]) == XFmode)
1481 operands[0] = gen_rtx (MEM, XFmode, operands[0]);
1482 else if (GET_MODE (operands[0]) == DFmode)
1483 operands[0] = gen_rtx (MEM, DFmode, operands[0]);
1484 else
1485 operands[0] = gen_rtx (MEM, DImode, operands[0]);
1486 optype0 = OFFSOP;
1487 }
1488 if (optype0 == POPOP && optype1 == PUSHOP)
1489 {
1490 operands[1] = XEXP (XEXP (operands[1], 0), 0);
1491 if (size == 12)
1492 output_asm_insn ("sub%.l %#12,%1", operands);
1493 else
1494 output_asm_insn ("subq%.l %#8,%1", operands);
1495 if (GET_MODE (operands[1]) == XFmode)
1496 operands[1] = gen_rtx (MEM, XFmode, operands[1]);
1497 else if (GET_MODE (operands[1]) == DFmode)
1498 operands[1] = gen_rtx (MEM, DFmode, operands[1]);
1499 else
1500 operands[1] = gen_rtx (MEM, DImode, operands[1]);
1501 optype1 = OFFSOP;
1502 }
1503
1504 /* If an operand is an unoffsettable memory ref, find a register
1505 we can increment temporarily to make it refer to the second word. */
1506
1507 if (optype0 == MEMOP)
1508 addreg0 = find_addr_reg (XEXP (operands[0], 0));
1509
1510 if (optype1 == MEMOP)
1511 addreg1 = find_addr_reg (XEXP (operands[1], 0));
1512
1513 /* Ok, we can do one word at a time.
1514 Normally we do the low-numbered word first,
1515 but if either operand is autodecrementing then we
1516 do the high-numbered word first.
1517
1518 In either case, set up in LATEHALF the operands to use
1519 for the high-numbered word and in some cases alter the
1520 operands in OPERANDS to be suitable for the low-numbered word. */
1521
1522 if (size == 12)
1523 {
1524 if (optype0 == REGOP)
1525 {
1526 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2);
1527 middlehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1528 }
1529 else if (optype0 == OFFSOP)
1530 {
1531 middlehalf[0] = adj_offsettable_operand (operands[0], 4);
1532 latehalf[0] = adj_offsettable_operand (operands[0], size - 4);
1533 }
1534 else
1535 {
1536 middlehalf[0] = operands[0];
1537 latehalf[0] = operands[0];
1538 }
1539
1540 if (optype1 == REGOP)
1541 {
1542 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2);
1543 middlehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1544 }
1545 else if (optype1 == OFFSOP)
1546 {
1547 middlehalf[1] = adj_offsettable_operand (operands[1], 4);
1548 latehalf[1] = adj_offsettable_operand (operands[1], size - 4);
1549 }
1550 else if (optype1 == CNSTOP)
1551 {
1552 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1553 {
1554 REAL_VALUE_TYPE r;
1555 long l[3];
1556
1557 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1558 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
1559 operands[1] = GEN_INT (l[0]);
1560 middlehalf[1] = GEN_INT (l[1]);
1561 latehalf[1] = GEN_INT (l[2]);
1562 }
1563 else if (CONSTANT_P (operands[1]))
1564 {
1565 /* actually, no non-CONST_DOUBLE constant should ever
1566 appear here. */
1567 abort ();
1568 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
1569 latehalf[1] = constm1_rtx;
1570 else
1571 latehalf[1] = const0_rtx;
1572 }
1573 }
1574 else
1575 {
1576 middlehalf[1] = operands[1];
1577 latehalf[1] = operands[1];
1578 }
1579 }
1580 else
1581 /* size is not 12: */
1582 {
1583 if (optype0 == REGOP)
1584 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1585 else if (optype0 == OFFSOP)
1586 latehalf[0] = adj_offsettable_operand (operands[0], size - 4);
1587 else
1588 latehalf[0] = operands[0];
1589
1590 if (optype1 == REGOP)
1591 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1592 else if (optype1 == OFFSOP)
1593 latehalf[1] = adj_offsettable_operand (operands[1], size - 4);
1594 else if (optype1 == CNSTOP)
1595 split_double (operands[1], &operands[1], &latehalf[1]);
1596 else
1597 latehalf[1] = operands[1];
1598 }
1599
1600 /* If insn is effectively movd N(sp),-(sp) then we will do the
1601 high word first. We should use the adjusted operand 1 (which is N+4(sp))
1602 for the low word as well, to compensate for the first decrement of sp. */
1603 if (optype0 == PUSHOP
1604 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1605 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
1606 operands[1] = middlehalf[1] = latehalf[1];
1607
1608 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
1609 if the upper part of reg N does not appear in the MEM, arrange to
1610 emit the move late-half first. Otherwise, compute the MEM address
1611 into the upper part of N and use that as a pointer to the memory
1612 operand. */
1613 if (optype0 == REGOP
1614 && (optype1 == OFFSOP || optype1 == MEMOP))
1615 {
1616 rtx testlow = gen_rtx (REG, SImode, REGNO (operands[0]));
1617
1618 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
1619 && reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
1620 {
1621 /* If both halves of dest are used in the src memory address,
1622 compute the address into latehalf of dest.
1623 Note that this can't happen if the dest is two data regs. */
1624 compadr:
1625 xops[0] = latehalf[0];
1626 xops[1] = XEXP (operands[1], 0);
1627 output_asm_insn ("lea %a1,%0", xops);
1628 if( GET_MODE (operands[1]) == XFmode )
1629 {
1630 operands[1] = gen_rtx (MEM, XFmode, latehalf[0]);
1631 middlehalf[1] = adj_offsettable_operand (operands[1], size-8);
1632 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1633 }
1634 else
1635 {
1636 operands[1] = gen_rtx (MEM, DImode, latehalf[0]);
1637 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1638 }
1639 }
1640 else if (size == 12
1641 && reg_overlap_mentioned_p (middlehalf[0],
1642 XEXP (operands[1], 0)))
1643 {
1644 /* Check for two regs used by both source and dest.
1645 Note that this can't happen if the dest is all data regs.
1646 It can happen if the dest is d6, d7, a0.
1647 But in that case, latehalf is an addr reg, so
1648 the code at compadr does ok. */
1649
1650 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
1651 || reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
1652 goto compadr;
1653
1654 /* JRV says this can't happen: */
1655 if (addreg0 || addreg1)
1656 abort ();
1657
1658 /* Only the middle reg conflicts; simply put it last. */
1659 output_asm_insn (singlemove_string (operands), operands);
1660 output_asm_insn (singlemove_string (latehalf), latehalf);
1661 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1662 return "";
1663 }
1664 else if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0)))
1665 /* If the low half of dest is mentioned in the source memory
1666 address, the arrange to emit the move late half first. */
1667 dest_overlapped_low = 1;
1668 }
1669
1670 /* If one or both operands autodecrementing,
1671 do the two words, high-numbered first. */
1672
1673 /* Likewise, the first move would clobber the source of the second one,
1674 do them in the other order. This happens only for registers;
1675 such overlap can't happen in memory unless the user explicitly
1676 sets it up, and that is an undefined circumstance. */
1677
1678 if (optype0 == PUSHOP || optype1 == PUSHOP
1679 || (optype0 == REGOP && optype1 == REGOP
1680 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
1681 || REGNO (operands[0]) == REGNO (latehalf[1])))
1682 || dest_overlapped_low)
1683 {
1684 /* Make any unoffsettable addresses point at high-numbered word. */
1685 if (addreg0)
1686 {
1687 if (size == 12)
1688 output_asm_insn ("addq%.l %#8,%0", &addreg0);
1689 else
1690 output_asm_insn ("addq%.l %#4,%0", &addreg0);
1691 }
1692 if (addreg1)
1693 {
1694 if (size == 12)
1695 output_asm_insn ("addq%.l %#8,%0", &addreg1);
1696 else
1697 output_asm_insn ("addq%.l %#4,%0", &addreg1);
1698 }
1699
1700 /* Do that word. */
1701 output_asm_insn (singlemove_string (latehalf), latehalf);
1702
1703 /* Undo the adds we just did. */
1704 if (addreg0)
1705 output_asm_insn ("subq%.l %#4,%0", &addreg0);
1706 if (addreg1)
1707 output_asm_insn ("subq%.l %#4,%0", &addreg1);
1708
1709 if (size == 12)
1710 {
1711 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1712 if (addreg0)
1713 output_asm_insn ("subq%.l %#4,%0", &addreg0);
1714 if (addreg1)
1715 output_asm_insn ("subq%.l %#4,%0", &addreg1);
1716 }
1717
1718 /* Do low-numbered word. */
1719 return singlemove_string (operands);
1720 }
1721
1722 /* Normal case: do the two words, low-numbered first. */
1723
1724 output_asm_insn (singlemove_string (operands), operands);
1725
1726 /* Do the middle one of the three words for long double */
1727 if (size == 12)
1728 {
1729 if (addreg0)
1730 output_asm_insn ("addq%.l %#4,%0", &addreg0);
1731 if (addreg1)
1732 output_asm_insn ("addq%.l %#4,%0", &addreg1);
1733
1734 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1735 }
1736
1737 /* Make any unoffsettable addresses point at high-numbered word. */
1738 if (addreg0)
1739 output_asm_insn ("addq%.l %#4,%0", &addreg0);
1740 if (addreg1)
1741 output_asm_insn ("addq%.l %#4,%0", &addreg1);
1742
1743 /* Do that word. */
1744 output_asm_insn (singlemove_string (latehalf), latehalf);
1745
1746 /* Undo the adds we just did. */
1747 if (addreg0)
1748 {
1749 if (size == 12)
1750 output_asm_insn ("subq%.l %#8,%0", &addreg0);
1751 else
1752 output_asm_insn ("subq%.l %#4,%0", &addreg0);
1753 }
1754 if (addreg1)
1755 {
1756 if (size == 12)
1757 output_asm_insn ("subq%.l %#8,%0", &addreg1);
1758 else
1759 output_asm_insn ("subq%.l %#4,%0", &addreg1);
1760 }
1761
1762 return "";
1763 }
1764
1765 /* Return a REG that occurs in ADDR with coefficient 1.
1766 ADDR can be effectively incremented by incrementing REG. */
1767
1768 static rtx
1769 find_addr_reg (addr)
1770 rtx addr;
1771 {
1772 while (GET_CODE (addr) == PLUS)
1773 {
1774 if (GET_CODE (XEXP (addr, 0)) == REG)
1775 addr = XEXP (addr, 0);
1776 else if (GET_CODE (XEXP (addr, 1)) == REG)
1777 addr = XEXP (addr, 1);
1778 else if (CONSTANT_P (XEXP (addr, 0)))
1779 addr = XEXP (addr, 1);
1780 else if (CONSTANT_P (XEXP (addr, 1)))
1781 addr = XEXP (addr, 0);
1782 else
1783 abort ();
1784 }
1785 if (GET_CODE (addr) == REG)
1786 return addr;
1787 abort ();
1788 }
1789 \f
1790 /* Store in cc_status the expressions that the condition codes will
1791 describe after execution of an instruction whose pattern is EXP.
1792 Do not alter them if the instruction would not alter the cc's. */
1793
1794 /* On the 68000, all the insns to store in an address register fail to
1795 set the cc's. However, in some cases these instructions can make it
1796 possibly invalid to use the saved cc's. In those cases we clear out
1797 some or all of the saved cc's so they won't be used. */
1798
1799 notice_update_cc (exp, insn)
1800 rtx exp;
1801 rtx insn;
1802 {
1803 /* If the cc is being set from the fpa and the expression is not an
1804 explicit floating point test instruction (which has code to deal with
1805 this), reinit the CC. */
1806 if (((cc_status.value1 && FPA_REG_P (cc_status.value1))
1807 || (cc_status.value2 && FPA_REG_P (cc_status.value2)))
1808 && !(GET_CODE (exp) == PARALLEL
1809 && GET_CODE (XVECEXP (exp, 0, 0)) == SET
1810 && XEXP (XVECEXP (exp, 0, 0), 0) == cc0_rtx))
1811 {
1812 CC_STATUS_INIT;
1813 }
1814 else if (GET_CODE (exp) == SET)
1815 {
1816 if (GET_CODE (SET_SRC (exp)) == CALL)
1817 {
1818 CC_STATUS_INIT;
1819 }
1820 else if (ADDRESS_REG_P (SET_DEST (exp)))
1821 {
1822 if (cc_status.value1
1823 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1824 cc_status.value1 = 0;
1825 if (cc_status.value2
1826 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1827 cc_status.value2 = 0;
1828 }
1829 else if (!FP_REG_P (SET_DEST (exp))
1830 && SET_DEST (exp) != cc0_rtx
1831 && (FP_REG_P (SET_SRC (exp))
1832 || GET_CODE (SET_SRC (exp)) == FIX
1833 || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE
1834 || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND))
1835 {
1836 CC_STATUS_INIT;
1837 }
1838 /* A pair of move insns doesn't produce a useful overall cc. */
1839 else if (!FP_REG_P (SET_DEST (exp))
1840 && !FP_REG_P (SET_SRC (exp))
1841 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
1842 && (GET_CODE (SET_SRC (exp)) == REG
1843 || GET_CODE (SET_SRC (exp)) == MEM
1844 || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
1845 {
1846 CC_STATUS_INIT;
1847 }
1848 else if (GET_CODE (SET_SRC (exp)) == CALL)
1849 {
1850 CC_STATUS_INIT;
1851 }
1852 else if (XEXP (exp, 0) != pc_rtx)
1853 {
1854 cc_status.flags = 0;
1855 cc_status.value1 = XEXP (exp, 0);
1856 cc_status.value2 = XEXP (exp, 1);
1857 }
1858 }
1859 else if (GET_CODE (exp) == PARALLEL
1860 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1861 {
1862 if (ADDRESS_REG_P (XEXP (XVECEXP (exp, 0, 0), 0)))
1863 CC_STATUS_INIT;
1864 else if (XEXP (XVECEXP (exp, 0, 0), 0) != pc_rtx)
1865 {
1866 cc_status.flags = 0;
1867 cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
1868 cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1);
1869 }
1870 }
1871 else
1872 CC_STATUS_INIT;
1873 if (cc_status.value2 != 0
1874 && ADDRESS_REG_P (cc_status.value2)
1875 && GET_MODE (cc_status.value2) == QImode)
1876 CC_STATUS_INIT;
1877 if (cc_status.value2 != 0
1878 && !(cc_status.value1 && FPA_REG_P (cc_status.value1)))
1879 switch (GET_CODE (cc_status.value2))
1880 {
1881 case PLUS: case MINUS: case MULT:
1882 case DIV: case UDIV: case MOD: case UMOD: case NEG:
1883 #if 0 /* These instructions always clear the overflow bit */
1884 case ASHIFT: case ASHIFTRT: case LSHIFTRT:
1885 case ROTATE: case ROTATERT:
1886 #endif
1887 if (GET_MODE (cc_status.value2) != VOIDmode)
1888 cc_status.flags |= CC_NO_OVERFLOW;
1889 break;
1890 case ZERO_EXTEND:
1891 /* (SET r1 (ZERO_EXTEND r2)) on this machine
1892 ends with a move insn moving r2 in r2's mode.
1893 Thus, the cc's are set for r2.
1894 This can set N bit spuriously. */
1895 cc_status.flags |= CC_NOT_NEGATIVE;
1896 }
1897 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
1898 && cc_status.value2
1899 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
1900 cc_status.value2 = 0;
1901 if (((cc_status.value1 && FP_REG_P (cc_status.value1))
1902 || (cc_status.value2 && FP_REG_P (cc_status.value2)))
1903 && !((cc_status.value1 && FPA_REG_P (cc_status.value1))
1904 || (cc_status.value2 && FPA_REG_P (cc_status.value2))))
1905 cc_status.flags = CC_IN_68881;
1906 }
1907 \f
1908 char *
1909 output_move_const_double (operands)
1910 rtx *operands;
1911 {
1912 #ifdef SUPPORT_SUN_FPA
1913 if (TARGET_FPA && FPA_REG_P (operands[0]))
1914 {
1915 int code = standard_sun_fpa_constant_p (operands[1]);
1916
1917 if (code != 0)
1918 {
1919 static char buf[40];
1920
1921 sprintf (buf, "fpmove%%.d %%%%%d,%%0", code & 0x1ff);
1922 return buf;
1923 }
1924 return "fpmove%.d %1,%0";
1925 }
1926 else
1927 #endif
1928 {
1929 int code = standard_68881_constant_p (operands[1]);
1930
1931 if (code != 0)
1932 {
1933 static char buf[40];
1934
1935 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
1936 return buf;
1937 }
1938 return "fmove%.d %1,%0";
1939 }
1940 }
1941
1942 char *
1943 output_move_const_single (operands)
1944 rtx *operands;
1945 {
1946 #ifdef SUPPORT_SUN_FPA
1947 if (TARGET_FPA)
1948 {
1949 int code = standard_sun_fpa_constant_p (operands[1]);
1950
1951 if (code != 0)
1952 {
1953 static char buf[40];
1954
1955 sprintf (buf, "fpmove%%.s %%%%%d,%%0", code & 0x1ff);
1956 return buf;
1957 }
1958 return "fpmove%.s %1,%0";
1959 }
1960 else
1961 #endif /* defined SUPPORT_SUN_FPA */
1962 {
1963 int code = standard_68881_constant_p (operands[1]);
1964
1965 if (code != 0)
1966 {
1967 static char buf[40];
1968
1969 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
1970 return buf;
1971 }
1972 return "fmove%.s %f1,%0";
1973 }
1974 }
1975
1976 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
1977 from the "fmovecr" instruction.
1978 The value, anded with 0xff, gives the code to use in fmovecr
1979 to get the desired constant. */
1980
1981 /* This code has been fixed for cross-compilation. */
1982
1983 static int inited_68881_table = 0;
1984
1985 char *strings_68881[7] = {
1986 "0.0",
1987 "1.0",
1988 "10.0",
1989 "100.0",
1990 "10000.0",
1991 "1e8",
1992 "1e16"
1993 };
1994
1995 int codes_68881[7] = {
1996 0x0f,
1997 0x32,
1998 0x33,
1999 0x34,
2000 0x35,
2001 0x36,
2002 0x37
2003 };
2004
2005 REAL_VALUE_TYPE values_68881[7];
2006
2007 /* Set up values_68881 array by converting the decimal values
2008 strings_68881 to binary. */
2009
2010 void
2011 init_68881_table ()
2012 {
2013 int i;
2014 REAL_VALUE_TYPE r;
2015 enum machine_mode mode;
2016
2017 mode = SFmode;
2018 for (i = 0; i < 7; i++)
2019 {
2020 if (i == 6)
2021 mode = DFmode;
2022 r = REAL_VALUE_ATOF (strings_68881[i], mode);
2023 values_68881[i] = r;
2024 }
2025 inited_68881_table = 1;
2026 }
2027
2028 int
2029 standard_68881_constant_p (x)
2030 rtx x;
2031 {
2032 REAL_VALUE_TYPE r;
2033 int i;
2034 enum machine_mode mode;
2035
2036 #ifdef NO_ASM_FMOVECR
2037 return 0;
2038 #endif
2039
2040 /* fmovecr must be emulated on the 68040, so it shouldn't be used at all. */
2041 if (TARGET_68040)
2042 return 0;
2043
2044 #ifndef REAL_ARITHMETIC
2045 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2046 if (! flag_pretend_float)
2047 return 0;
2048 #endif
2049 #endif
2050
2051 if (! inited_68881_table)
2052 init_68881_table ();
2053
2054 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2055
2056 for (i = 0; i < 6; i++)
2057 {
2058 if (REAL_VALUES_EQUAL (r, values_68881[i]))
2059 return (codes_68881[i]);
2060 }
2061
2062 if (GET_MODE (x) == SFmode)
2063 return 0;
2064
2065 if (REAL_VALUES_EQUAL (r, values_68881[6]))
2066 return (codes_68881[6]);
2067
2068 /* larger powers of ten in the constants ram are not used
2069 because they are not equal to a `double' C constant. */
2070 return 0;
2071 }
2072
2073 /* If X is a floating-point constant, return the logarithm of X base 2,
2074 or 0 if X is not a power of 2. */
2075
2076 int
2077 floating_exact_log2 (x)
2078 rtx x;
2079 {
2080 REAL_VALUE_TYPE r, r1;
2081 int i;
2082
2083 #ifndef REAL_ARITHMETIC
2084 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2085 if (! flag_pretend_float)
2086 return 0;
2087 #endif
2088 #endif
2089
2090 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2091
2092 if (REAL_VALUES_LESS (r, dconst0))
2093 return 0;
2094
2095 r1 = dconst1;
2096 i = 0;
2097 while (REAL_VALUES_LESS (r1, r))
2098 {
2099 r1 = REAL_VALUE_LDEXP (dconst1, i);
2100 if (REAL_VALUES_EQUAL (r1, r))
2101 return i;
2102 i = i + 1;
2103 }
2104 return 0;
2105 }
2106 \f
2107 #ifdef SUPPORT_SUN_FPA
2108 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2109 from the Sun FPA's constant RAM.
2110 The value returned, anded with 0x1ff, gives the code to use in fpmove
2111 to get the desired constant. */
2112
2113 static int inited_FPA_table = 0;
2114
2115 char *strings_FPA[38] = {
2116 /* small rationals */
2117 "0.0",
2118 "1.0",
2119 "0.5",
2120 "-1.0",
2121 "2.0",
2122 "3.0",
2123 "4.0",
2124 "8.0",
2125 "0.25",
2126 "0.125",
2127 "10.0",
2128 "-0.5",
2129 /* Decimal equivalents of double precision values */
2130 "2.718281828459045091", /* D_E */
2131 "6.283185307179586477", /* 2 pi */
2132 "3.141592653589793116", /* D_PI */
2133 "1.570796326794896619", /* pi/2 */
2134 "1.414213562373095145", /* D_SQRT2 */
2135 "0.7071067811865475244", /* 1/sqrt(2) */
2136 "-1.570796326794896619", /* -pi/2 */
2137 "1.442695040888963387", /* D_LOG2ofE */
2138 "3.321928024887362182", /* D_LOG2of10 */
2139 "0.6931471805599452862", /* D_LOGEof2 */
2140 "2.302585092994045901", /* D_LOGEof10 */
2141 "0.3010299956639811980", /* D_LOG10of2 */
2142 "0.4342944819032518167", /* D_LOG10ofE */
2143 /* Decimal equivalents of single precision values */
2144 "2.718281745910644531", /* S_E */
2145 "6.283185307179586477", /* 2 pi */
2146 "3.141592741012573242", /* S_PI */
2147 "1.570796326794896619", /* pi/2 */
2148 "1.414213538169860840", /* S_SQRT2 */
2149 "0.7071067811865475244", /* 1/sqrt(2) */
2150 "-1.570796326794896619", /* -pi/2 */
2151 "1.442695021629333496", /* S_LOG2ofE */
2152 "3.321928024291992188", /* S_LOG2of10 */
2153 "0.6931471824645996094", /* S_LOGEof2 */
2154 "2.302585124969482442", /* S_LOGEof10 */
2155 "0.3010300099849700928", /* S_LOG10of2 */
2156 "0.4342944920063018799", /* S_LOG10ofE */
2157 };
2158
2159
2160 int codes_FPA[38] = {
2161 /* small rationals */
2162 0x200,
2163 0xe,
2164 0xf,
2165 0x10,
2166 0x11,
2167 0xb1,
2168 0x12,
2169 0x13,
2170 0x15,
2171 0x16,
2172 0x17,
2173 0x2e,
2174 /* double precision */
2175 0x8,
2176 0x9,
2177 0xa,
2178 0xb,
2179 0xc,
2180 0xd,
2181 0x27,
2182 0x28,
2183 0x29,
2184 0x2a,
2185 0x2b,
2186 0x2c,
2187 0x2d,
2188 /* single precision */
2189 0x8,
2190 0x9,
2191 0xa,
2192 0xb,
2193 0xc,
2194 0xd,
2195 0x27,
2196 0x28,
2197 0x29,
2198 0x2a,
2199 0x2b,
2200 0x2c,
2201 0x2d
2202 };
2203
2204 REAL_VALUE_TYPE values_FPA[38];
2205
2206 /* This code has been fixed for cross-compilation. */
2207
2208 void
2209 init_FPA_table ()
2210 {
2211 enum machine_mode mode;
2212 int i;
2213 REAL_VALUE_TYPE r;
2214
2215 mode = DFmode;
2216 for (i = 0; i < 38; i++)
2217 {
2218 if (i == 25)
2219 mode = SFmode;
2220 r = REAL_VALUE_ATOF (strings_FPA[i], mode);
2221 values_FPA[i] = r;
2222 }
2223 inited_FPA_table = 1;
2224 }
2225
2226
2227 int
2228 standard_sun_fpa_constant_p (x)
2229 rtx x;
2230 {
2231 REAL_VALUE_TYPE r;
2232 int i;
2233
2234 #ifndef REAL_ARITHMETIC
2235 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2236 if (! flag_pretend_float)
2237 return 0;
2238 #endif
2239 #endif
2240
2241 if (! inited_FPA_table)
2242 init_FPA_table ();
2243
2244 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2245
2246 for (i=0; i<12; i++)
2247 {
2248 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2249 return (codes_FPA[i]);
2250 }
2251
2252 if (GET_MODE (x) == SFmode)
2253 {
2254 for (i=25; i<38; i++)
2255 {
2256 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2257 return (codes_FPA[i]);
2258 }
2259 }
2260 else
2261 {
2262 for (i=12; i<25; i++)
2263 {
2264 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2265 return (codes_FPA[i]);
2266 }
2267 }
2268 return 0x0;
2269 }
2270 #endif /* define SUPPORT_SUN_FPA */
2271 \f
2272 /* A C compound statement to output to stdio stream STREAM the
2273 assembler syntax for an instruction operand X. X is an RTL
2274 expression.
2275
2276 CODE is a value that can be used to specify one of several ways
2277 of printing the operand. It is used when identical operands
2278 must be printed differently depending on the context. CODE
2279 comes from the `%' specification that was used to request
2280 printing of the operand. If the specification was just `%DIGIT'
2281 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2282 is the ASCII code for LTR.
2283
2284 If X is a register, this macro should print the register's name.
2285 The names can be found in an array `reg_names' whose type is
2286 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2287
2288 When the machine description has a specification `%PUNCT' (a `%'
2289 followed by a punctuation character), this macro is called with
2290 a null pointer for X and the punctuation character for CODE.
2291
2292 The m68k specific codes are:
2293
2294 '.' for dot needed in Motorola-style opcode names.
2295 '-' for an operand pushing on the stack:
2296 sp@-, -(sp) or -(%sp) depending on the style of syntax.
2297 '+' for an operand pushing on the stack:
2298 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2299 '@' for a reference to the top word on the stack:
2300 sp@, (sp) or (%sp) depending on the style of syntax.
2301 '#' for an immediate operand prefix (# in MIT and Motorola syntax
2302 but & in SGS syntax).
2303 '!' for the cc register (used in an `and to cc' insn).
2304 '$' for the letter `s' in an op code, but only on the 68040.
2305 '&' for the letter `d' in an op code, but only on the 68040.
2306 '/' for register prefix needed by longlong.h.
2307
2308 'b' for byte insn (no effect, on the Sun; this is for the ISI).
2309 'd' to force memory addressing to be absolute, not relative.
2310 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2311 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
2312 than directly). Second part of 'y' below.
2313 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2314 or print pair of registers as rx:ry.
2315 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
2316 CONST_DOUBLE's as SunFPA constant RAM registers if
2317 possible, so it should not be used except for the SunFPA.
2318
2319 */
2320
2321 void
2322 print_operand (file, op, letter)
2323 FILE *file; /* file to write to */
2324 rtx op; /* operand to print */
2325 int letter; /* %<letter> or 0 */
2326 {
2327 int i;
2328
2329 if (letter == '.')
2330 {
2331 #ifdef MOTOROLA
2332 asm_fprintf (file, ".");
2333 #endif
2334 }
2335 else if (letter == '#')
2336 {
2337 asm_fprintf (file, "%0I");
2338 }
2339 else if (letter == '-')
2340 {
2341 #ifdef MOTOROLA
2342 asm_fprintf (file, "-(%Rsp)");
2343 #else
2344 asm_fprintf (file, "%Rsp@-");
2345 #endif
2346 }
2347 else if (letter == '+')
2348 {
2349 #ifdef MOTOROLA
2350 asm_fprintf (file, "(%Rsp)+");
2351 #else
2352 asm_fprintf (file, "%Rsp@+");
2353 #endif
2354 }
2355 else if (letter == '@')
2356 {
2357 #ifdef MOTOROLA
2358 asm_fprintf (file, "(%Rsp)");
2359 #else
2360 asm_fprintf (file, "%Rsp@");
2361 #endif
2362 }
2363 else if (letter == '!')
2364 {
2365 asm_fprintf (file, "%Rfpcr");
2366 }
2367 else if (letter == '$')
2368 {
2369 if (TARGET_68040_ONLY)
2370 {
2371 fprintf (file, "s");
2372 }
2373 }
2374 else if (letter == '&')
2375 {
2376 if (TARGET_68040_ONLY)
2377 {
2378 fprintf (file, "d");
2379 }
2380 }
2381 else if (letter == '/')
2382 {
2383 asm_fprintf (file, "%R");
2384 }
2385 else if (GET_CODE (op) == REG)
2386 {
2387 #ifdef SUPPORT_SUN_FPA
2388 if (REGNO (op) < 16
2389 && (letter == 'y' || letter == 'x')
2390 && GET_MODE (op) == DFmode)
2391 {
2392 fprintf (file, "%s:%s", reg_names[REGNO (op)],
2393 reg_names[REGNO (op)+1]);
2394 }
2395 else
2396 #endif
2397 {
2398 if (letter == 'R')
2399 /* Print out the second register name of a register pair.
2400 I.e., R (6) => 7. */
2401 fputs (reg_names[REGNO (op) + 1], file);
2402 else
2403 fputs (reg_names[REGNO (op)], file);
2404 }
2405 }
2406 else if (GET_CODE (op) == MEM)
2407 {
2408 output_address (XEXP (op, 0));
2409 if (letter == 'd' && ! TARGET_68020
2410 && CONSTANT_ADDRESS_P (XEXP (op, 0))
2411 && !(GET_CODE (XEXP (op, 0)) == CONST_INT
2412 && INTVAL (XEXP (op, 0)) < 0x8000
2413 && INTVAL (XEXP (op, 0)) >= -0x8000))
2414 {
2415 #ifdef MOTOROLA
2416 fprintf (file, ".l");
2417 #else
2418 fprintf (file, ":l");
2419 #endif
2420 }
2421 }
2422 #ifdef SUPPORT_SUN_FPA
2423 else if ((letter == 'y' || letter == 'w')
2424 && GET_CODE (op) == CONST_DOUBLE
2425 && (i = standard_sun_fpa_constant_p (op)))
2426 {
2427 fprintf (file, "%%%d", i & 0x1ff);
2428 }
2429 #endif
2430 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
2431 {
2432 REAL_VALUE_TYPE r;
2433 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2434 ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
2435 }
2436 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
2437 {
2438 REAL_VALUE_TYPE r;
2439 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2440 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
2441 }
2442 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
2443 {
2444 REAL_VALUE_TYPE r;
2445 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2446 ASM_OUTPUT_DOUBLE_OPERAND (file, r);
2447 }
2448 else
2449 {
2450 asm_fprintf (file, "%0I"); output_addr_const (file, op);
2451 }
2452 }
2453
2454 \f
2455 /* A C compound statement to output to stdio stream STREAM the
2456 assembler syntax for an instruction operand that is a memory
2457 reference whose address is ADDR. ADDR is an RTL expression.
2458
2459 Note that this contains a kludge that knows that the only reason
2460 we have an address (plus (label_ref...) (reg...)) when not generating
2461 PIC code is in the insn before a tablejump, and we know that m68k.md
2462 generates a label LInnn: on such an insn.
2463
2464 It is possible for PIC to generate a (plus (label_ref...) (reg...))
2465 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2466
2467 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2468 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
2469 we want. This difference can be accommodated by using an assembler
2470 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2471 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
2472 macro. See m68k/sgs.h for an example; for versions without the bug.
2473 Some assemblers refuse all the above solutions. The workaround is to
2474 emit "K(pc,d0.l*2)" with K being a small constant known to give the
2475 right behaviour.
2476
2477 They also do not like things like "pea 1.w", so we simple leave off
2478 the .w on small constants.
2479
2480 This routine is responsible for distinguishing between -fpic and -fPIC
2481 style relocations in an address. When generating -fpic code the
2482 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
2483 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
2484
2485 #ifndef ASM_OUTPUT_CASE_FETCH
2486 #ifdef MOTOROLA
2487 #ifdef SGS
2488 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2489 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
2490 #else
2491 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2492 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2493 #endif
2494 #else
2495 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2496 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
2497 #endif
2498 #endif /* ASM_OUTPUT_CASE_FETCH */
2499
2500 void
2501 print_operand_address (file, addr)
2502 FILE *file;
2503 rtx addr;
2504 {
2505 register rtx reg1, reg2, breg, ireg;
2506 rtx offset;
2507
2508 switch (GET_CODE (addr))
2509 {
2510 case REG:
2511 #ifdef MOTOROLA
2512 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
2513 #else
2514 fprintf (file, "%s@", reg_names[REGNO (addr)]);
2515 #endif
2516 break;
2517 case PRE_DEC:
2518 #ifdef MOTOROLA
2519 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
2520 #else
2521 fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);
2522 #endif
2523 break;
2524 case POST_INC:
2525 #ifdef MOTOROLA
2526 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
2527 #else
2528 fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);
2529 #endif
2530 break;
2531 case PLUS:
2532 reg1 = reg2 = ireg = breg = offset = 0;
2533 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
2534 {
2535 offset = XEXP (addr, 0);
2536 addr = XEXP (addr, 1);
2537 }
2538 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
2539 {
2540 offset = XEXP (addr, 1);
2541 addr = XEXP (addr, 0);
2542 }
2543 if (GET_CODE (addr) != PLUS)
2544 {
2545 ;
2546 }
2547 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
2548 {
2549 reg1 = XEXP (addr, 0);
2550 addr = XEXP (addr, 1);
2551 }
2552 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
2553 {
2554 reg1 = XEXP (addr, 1);
2555 addr = XEXP (addr, 0);
2556 }
2557 else if (GET_CODE (XEXP (addr, 0)) == MULT)
2558 {
2559 reg1 = XEXP (addr, 0);
2560 addr = XEXP (addr, 1);
2561 }
2562 else if (GET_CODE (XEXP (addr, 1)) == MULT)
2563 {
2564 reg1 = XEXP (addr, 1);
2565 addr = XEXP (addr, 0);
2566 }
2567 else if (GET_CODE (XEXP (addr, 0)) == REG)
2568 {
2569 reg1 = XEXP (addr, 0);
2570 addr = XEXP (addr, 1);
2571 }
2572 else if (GET_CODE (XEXP (addr, 1)) == REG)
2573 {
2574 reg1 = XEXP (addr, 1);
2575 addr = XEXP (addr, 0);
2576 }
2577 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
2578 || GET_CODE (addr) == SIGN_EXTEND)
2579 {
2580 if (reg1 == 0)
2581 {
2582 reg1 = addr;
2583 }
2584 else
2585 {
2586 reg2 = addr;
2587 }
2588 addr = 0;
2589 }
2590 #if 0 /* for OLD_INDEXING */
2591 else if (GET_CODE (addr) == PLUS)
2592 {
2593 if (GET_CODE (XEXP (addr, 0)) == REG)
2594 {
2595 reg2 = XEXP (addr, 0);
2596 addr = XEXP (addr, 1);
2597 }
2598 else if (GET_CODE (XEXP (addr, 1)) == REG)
2599 {
2600 reg2 = XEXP (addr, 1);
2601 addr = XEXP (addr, 0);
2602 }
2603 }
2604 #endif
2605 if (offset != 0)
2606 {
2607 if (addr != 0)
2608 {
2609 abort ();
2610 }
2611 addr = offset;
2612 }
2613 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
2614 || GET_CODE (reg1) == MULT))
2615 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
2616 {
2617 breg = reg2;
2618 ireg = reg1;
2619 }
2620 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
2621 {
2622 breg = reg1;
2623 ireg = reg2;
2624 }
2625 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
2626 && ! (flag_pic && ireg == pic_offset_table_rtx))
2627 {
2628 int scale = 1;
2629 if (GET_CODE (ireg) == MULT)
2630 {
2631 scale = INTVAL (XEXP (ireg, 1));
2632 ireg = XEXP (ireg, 0);
2633 }
2634 if (GET_CODE (ireg) == SIGN_EXTEND)
2635 {
2636 ASM_OUTPUT_CASE_FETCH (file,
2637 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2638 reg_names[REGNO (XEXP (ireg, 0))]);
2639 fprintf (file, "w");
2640 }
2641 else
2642 {
2643 ASM_OUTPUT_CASE_FETCH (file,
2644 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2645 reg_names[REGNO (ireg)]);
2646 fprintf (file, "l");
2647 }
2648 if (scale != 1)
2649 {
2650 #ifdef MOTOROLA
2651 fprintf (file, "*%d", scale);
2652 #else
2653 fprintf (file, ":%d", scale);
2654 #endif
2655 }
2656 putc (')', file);
2657 break;
2658 }
2659 if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
2660 && ! (flag_pic && breg == pic_offset_table_rtx))
2661 {
2662 ASM_OUTPUT_CASE_FETCH (file,
2663 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2664 reg_names[REGNO (breg)]);
2665 fprintf (file, "l)");
2666 break;
2667 }
2668 if (ireg != 0 || breg != 0)
2669 {
2670 int scale = 1;
2671 if (breg == 0)
2672 {
2673 abort ();
2674 }
2675 if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)
2676 {
2677 abort ();
2678 }
2679 #ifdef MOTOROLA
2680 if (addr != 0)
2681 {
2682 output_addr_const (file, addr);
2683 if (flag_pic && (breg == pic_offset_table_rtx))
2684 fprintf (file, "@GOT");
2685 }
2686 fprintf (file, "(%s", reg_names[REGNO (breg)]);
2687 if (ireg != 0)
2688 {
2689 putc (',', file);
2690 }
2691 #else
2692 fprintf (file, "%s@(", reg_names[REGNO (breg)]);
2693 if (addr != 0)
2694 {
2695 output_addr_const (file, addr);
2696 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
2697 fprintf (file, ":w");
2698 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
2699 fprintf (file, ":l");
2700 }
2701 if (addr != 0 && ireg != 0)
2702 {
2703 putc (',', file);
2704 }
2705 #endif
2706 if (ireg != 0 && GET_CODE (ireg) == MULT)
2707 {
2708 scale = INTVAL (XEXP (ireg, 1));
2709 ireg = XEXP (ireg, 0);
2710 }
2711 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
2712 {
2713 #ifdef MOTOROLA
2714 fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);
2715 #else
2716 fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);
2717 #endif
2718 }
2719 else if (ireg != 0)
2720 {
2721 #ifdef MOTOROLA
2722 fprintf (file, "%s.l", reg_names[REGNO (ireg)]);
2723 #else
2724 fprintf (file, "%s:l", reg_names[REGNO (ireg)]);
2725 #endif
2726 }
2727 if (scale != 1)
2728 {
2729 #ifdef MOTOROLA
2730 fprintf (file, "*%d", scale);
2731 #else
2732 fprintf (file, ":%d", scale);
2733 #endif
2734 }
2735 putc (')', file);
2736 break;
2737 }
2738 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
2739 && ! (flag_pic && reg1 == pic_offset_table_rtx))
2740 {
2741 ASM_OUTPUT_CASE_FETCH (file,
2742 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2743 reg_names[REGNO (reg1)]);
2744 fprintf (file, "l)");
2745 break;
2746 }
2747 /* FALL-THROUGH (is this really what we want? */
2748 default:
2749 if (GET_CODE (addr) == CONST_INT
2750 && INTVAL (addr) < 0x8000
2751 && INTVAL (addr) >= -0x8000)
2752 {
2753 #ifdef MOTOROLA
2754 #ifdef SGS
2755 /* Many SGS assemblers croak on size specifiers for constants. */
2756 fprintf (file, "%d", INTVAL (addr));
2757 #else
2758 fprintf (file, "%d.w", INTVAL (addr));
2759 #endif
2760 #else
2761 fprintf (file, "%d:w", INTVAL (addr));
2762 #endif
2763 }
2764 else
2765 {
2766 output_addr_const (file, addr);
2767 }
2768 break;
2769 }
2770 }
2771 \f
2772 /* Check for cases where a clr insns can be omitted from code using
2773 strict_low_part sets. For example, the second clrl here is not needed:
2774 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
2775
2776 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
2777 insn we are checking for redundancy. TARGET is the register set by the
2778 clear insn. */
2779
2780 int
2781 strict_low_part_peephole_ok (mode, first_insn, target)
2782 enum machine_mode mode;
2783 rtx first_insn;
2784 rtx target;
2785 {
2786 rtx p;
2787
2788 p = prev_nonnote_insn (first_insn);
2789
2790 while (p)
2791 {
2792 /* If it isn't an insn, then give up. */
2793 if (GET_CODE (p) != INSN)
2794 return 0;
2795
2796 if (reg_set_p (target, p))
2797 {
2798 rtx set = single_set (p);
2799 rtx dest;
2800
2801 /* If it isn't an easy to recognize insn, then give up. */
2802 if (! set)
2803 return 0;
2804
2805 dest = SET_DEST (set);
2806
2807 /* If this sets the entire target register to zero, then our
2808 first_insn is redundant. */
2809 if (rtx_equal_p (dest, target)
2810 && SET_SRC (set) == const0_rtx)
2811 return 1;
2812 else if (GET_CODE (dest) == STRICT_LOW_PART
2813 && GET_CODE (XEXP (dest, 0)) == REG
2814 && REGNO (XEXP (dest, 0)) == REGNO (target)
2815 && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0)))
2816 <= GET_MODE_SIZE (mode)))
2817 /* This is a strict low part set which modifies less than
2818 we are using, so it is safe. */
2819 ;
2820 else
2821 return 0;
2822 }
2823
2824 p = prev_nonnote_insn (p);
2825
2826 }
2827
2828 return 0;
2829 }
2830
2831 /* Accept integer operands in the range 0..0xffffffff. We have to check the
2832 range carefully since this predicate is used in DImode contexts. Also, we
2833 need some extra crud to make it work when hosted on 64-bit machines. */
2834
2835 int
2836 const_uint32_operand (op, mode)
2837 rtx op;
2838 enum machine_mode mode;
2839 {
2840 #if HOST_BITS_PER_WIDE_INT > 32
2841 /* All allowed constants will fit a CONST_INT. */
2842 return (GET_CODE (op) == CONST_INT
2843 && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
2844 #else
2845 return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0)
2846 || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
2847 #endif
2848 }
2849
2850 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
2851 to check the range carefully since this predicate is used in DImode
2852 contexts. */
2853
2854 int
2855 const_sint32_operand (op, mode)
2856 rtx op;
2857 enum machine_mode mode;
2858 {
2859 /* All allowed constants will fit a CONST_INT. */
2860 return (GET_CODE (op) == CONST_INT
2861 && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
2862 }