OSDN Git Service

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