OSDN Git Service

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