OSDN Git Service

cd8a2b7a2dc7fb47c566e0278b64aba60d337614
[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 #if defined (MOTOROLA)
1608       return "moveq%.l %1,%0";
1609 #else
1610       return "moveq %1,%0";
1611 #endif
1612     case NOTB :
1613       operands[1] = GEN_INT (i ^ 0xff);
1614 #if defined (MOTOROLA)
1615       return "moveq%.l %1,%0\n\tnot%.b %0";
1616 #else
1617       return "moveq %1,%0\n\tnot%.b %0";
1618 #endif   
1619     case NOTW :
1620       operands[1] = GEN_INT (i ^ 0xffff);
1621 #if defined (MOTOROLA)
1622       return "moveq%.l %1,%0\n\tnot%.w %0";
1623 #else
1624       return "moveq %1,%0\n\tnot%.w %0";
1625 #endif   
1626     case NEGW :
1627 #if defined (MOTOROLA)
1628       return "moveq%.l %#-128,%0\n\tneg%.w %0";
1629 #else
1630       return "moveq %#-128,%0\n\tneg%.w %0";
1631 #endif   
1632     case SWAP :
1633       {
1634         unsigned u = i;
1635
1636         operands[1] = GEN_INT ((u << 16) | (u >> 16));
1637 #if defined (MOTOROLA)
1638         return "moveq%.l %1,%0\n\tswap %0";
1639 #else
1640         return "moveq %1,%0\n\tswap %0";
1641 #endif   
1642       }
1643     case MOVL :
1644         return "move%.l %1,%0";
1645     default :
1646         abort ();
1647     }
1648 }
1649
1650 const char *
1651 output_move_simode_const (operands)
1652      rtx *operands;
1653 {
1654   if (operands[1] == const0_rtx
1655       && (DATA_REG_P (operands[0])
1656           || GET_CODE (operands[0]) == MEM)
1657       /* clr insns on 68000 read before writing.
1658          This isn't so on the 68010, but we have no TARGET_68010.  */
1659       && ((TARGET_68020 || TARGET_5200)
1660           || !(GET_CODE (operands[0]) == MEM
1661                && MEM_VOLATILE_P (operands[0]))))
1662     return "clr%.l %0";
1663   else if (operands[1] == const0_rtx
1664            && ADDRESS_REG_P (operands[0]))
1665     return "sub%.l %0,%0";
1666   else if (DATA_REG_P (operands[0]))
1667     return output_move_const_into_data_reg (operands);
1668   else if (ADDRESS_REG_P (operands[0])
1669            && INTVAL (operands[1]) < 0x8000
1670            && INTVAL (operands[1]) >= -0x8000)
1671     return "move%.w %1,%0";
1672   else if (GET_CODE (operands[0]) == MEM
1673       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1674       && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1675            && INTVAL (operands[1]) < 0x8000
1676            && INTVAL (operands[1]) >= -0x8000)
1677     return "pea %a1";
1678   return "move%.l %1,%0";
1679 }
1680
1681 const char *
1682 output_move_simode (operands)
1683      rtx *operands;
1684 {
1685   if (GET_CODE (operands[1]) == CONST_INT)
1686     return output_move_simode_const (operands);
1687   else if ((GET_CODE (operands[1]) == SYMBOL_REF
1688             || GET_CODE (operands[1]) == CONST)
1689            && push_operand (operands[0], SImode))
1690     return "pea %a1";
1691   else if ((GET_CODE (operands[1]) == SYMBOL_REF
1692             || GET_CODE (operands[1]) == CONST)
1693            && ADDRESS_REG_P (operands[0]))
1694     return "lea %a1,%0";
1695   return "move%.l %1,%0";
1696 }
1697
1698 const char *
1699 output_move_himode (operands)
1700      rtx *operands;
1701 {
1702  if (GET_CODE (operands[1]) == CONST_INT)
1703     {
1704       if (operands[1] == const0_rtx
1705           && (DATA_REG_P (operands[0])
1706               || GET_CODE (operands[0]) == MEM)
1707           /* clr insns on 68000 read before writing.
1708              This isn't so on the 68010, but we have no TARGET_68010.  */
1709           && ((TARGET_68020 || TARGET_5200)
1710               || !(GET_CODE (operands[0]) == MEM
1711                    && MEM_VOLATILE_P (operands[0]))))
1712         return "clr%.w %0";
1713       else if (operands[1] == const0_rtx
1714                && ADDRESS_REG_P (operands[0]))
1715         return "sub%.l %0,%0";
1716       else if (DATA_REG_P (operands[0])
1717                && INTVAL (operands[1]) < 128
1718                && INTVAL (operands[1]) >= -128)
1719         {
1720 #if defined(MOTOROLA)
1721           return "moveq%.l %1,%0";
1722 #else
1723           return "moveq %1,%0";
1724 #endif
1725         }
1726       else if (INTVAL (operands[1]) < 0x8000
1727                && INTVAL (operands[1]) >= -0x8000)
1728         return "move%.w %1,%0";
1729     }
1730   else if (CONSTANT_P (operands[1]))
1731     return "move%.l %1,%0";
1732 #ifndef SGS_NO_LI
1733   /* Recognize the insn before a tablejump, one that refers
1734      to a table of offsets.  Such an insn will need to refer
1735      to a label on the insn.  So output one.  Use the label-number
1736      of the table of offsets to generate this label.  This code,
1737      and similar code below, assumes that there will be at most one
1738      reference to each table.  */
1739   if (GET_CODE (operands[1]) == MEM
1740       && GET_CODE (XEXP (operands[1], 0)) == PLUS
1741       && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF
1742       && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS)
1743     {
1744       rtx labelref = XEXP (XEXP (operands[1], 0), 1);
1745 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
1746 #ifdef SGS
1747       asm_fprintf (asm_out_file, "\tset %LLI%d,.+2\n",
1748                    CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1749 #else /* not SGS */
1750       asm_fprintf (asm_out_file, "\t.set %LLI%d,.+2\n",
1751                    CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1752 #endif /* not SGS */
1753 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
1754       (*targetm.asm_out.internal_label) (asm_out_file, "LI",
1755                                  CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1756 #ifdef SGS_SWITCH_TABLES
1757       /* Set flag saying we need to define the symbol
1758          LD%n (with value L%n-LI%n) at the end of the switch table.  */
1759       switch_table_difference_label_flag = 1;
1760 #endif /* SGS_SWITCH_TABLES */
1761 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
1762     }
1763 #endif /* SGS_NO_LI */
1764   return "move%.w %1,%0";
1765 }
1766
1767 const char *
1768 output_move_qimode (operands)
1769      rtx *operands;
1770 {
1771   rtx xoperands[4];
1772
1773   /* This is probably useless, since it loses for pushing a struct
1774      of several bytes a byte at a time.  */
1775   /* 68k family always modifies the stack pointer by at least 2, even for
1776      byte pushes.  The 5200 (coldfire) does not do this.  */
1777   if (GET_CODE (operands[0]) == MEM
1778       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1779       && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx
1780       && ! ADDRESS_REG_P (operands[1])
1781       && ! TARGET_5200)
1782     {
1783       xoperands[1] = operands[1];
1784       xoperands[2]
1785         = gen_rtx_MEM (QImode,
1786                        gen_rtx_PLUS (VOIDmode, stack_pointer_rtx, const1_rtx));
1787       /* Just pushing a byte puts it in the high byte of the halfword.  */
1788       /* We must put it in the low-order, high-numbered byte.  */
1789       if (!reg_mentioned_p (stack_pointer_rtx, operands[1]))
1790         {
1791           xoperands[3] = stack_pointer_rtx;
1792 #ifndef NO_ADDSUB_Q
1793           output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
1794 #else
1795           output_asm_insn ("sub%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
1796 #endif
1797         }
1798       else
1799         output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands);
1800       return "";
1801     }
1802
1803   /* clr and st insns on 68000 read before writing.
1804      This isn't so on the 68010, but we have no TARGET_68010.  */
1805   if (!ADDRESS_REG_P (operands[0])
1806       && ((TARGET_68020 || TARGET_5200)
1807           || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1808     {
1809       if (operands[1] == const0_rtx)
1810         return "clr%.b %0";
1811       if ((!TARGET_5200 || DATA_REG_P (operands[0]))
1812           && GET_CODE (operands[1]) == CONST_INT
1813           && (INTVAL (operands[1]) & 255) == 255)
1814         {
1815           CC_STATUS_INIT;
1816           return "st %0";
1817         }
1818     }
1819   if (GET_CODE (operands[1]) == CONST_INT
1820       && DATA_REG_P (operands[0])
1821       && INTVAL (operands[1]) < 128
1822       && INTVAL (operands[1]) >= -128)
1823     {
1824 #if defined(MOTOROLA)
1825       return "moveq%.l %1,%0";
1826 #else
1827       return "moveq %1,%0";
1828 #endif
1829     }
1830   if (operands[1] == const0_rtx && ADDRESS_REG_P (operands[0]))
1831     return "sub%.l %0,%0";
1832   if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
1833     return "move%.l %1,%0";
1834   /* 68k family (including the 5200 coldfire) does not support byte moves to
1835      from address registers.  */
1836   if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
1837     return "move%.w %1,%0";
1838   return "move%.b %1,%0";
1839 }
1840
1841 const char *
1842 output_move_stricthi (operands)
1843      rtx *operands;
1844 {
1845   if (operands[1] == const0_rtx
1846       /* clr insns on 68000 read before writing.
1847          This isn't so on the 68010, but we have no TARGET_68010.  */
1848       && ((TARGET_68020 || TARGET_5200)
1849           || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1850     return "clr%.w %0";
1851   return "move%.w %1,%0";
1852 }
1853
1854 const char *
1855 output_move_strictqi (operands)
1856      rtx *operands;
1857 {
1858   if (operands[1] == const0_rtx
1859       /* clr insns on 68000 read before writing.
1860          This isn't so on the 68010, but we have no TARGET_68010.  */
1861       && ((TARGET_68020 || TARGET_5200)
1862           || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1863     return "clr%.b %0";
1864   return "move%.b %1,%0";
1865 }
1866
1867 /* Return the best assembler insn template
1868    for moving operands[1] into operands[0] as a fullword.  */
1869
1870 static const char *
1871 singlemove_string (operands)
1872      rtx *operands;
1873 {
1874   if (GET_CODE (operands[1]) == CONST_INT)
1875     return output_move_simode_const (operands);
1876   return "move%.l %1,%0";
1877 }
1878
1879
1880 /* Output assembler code to perform a doubleword move insn
1881    with operands OPERANDS.  */
1882
1883 const char *
1884 output_move_double (operands)
1885      rtx *operands;
1886 {
1887   enum
1888     {
1889       REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP
1890     } optype0, optype1;
1891   rtx latehalf[2];
1892   rtx middlehalf[2];
1893   rtx xops[2];
1894   rtx addreg0 = 0, addreg1 = 0;
1895   int dest_overlapped_low = 0;
1896   int size = GET_MODE_SIZE (GET_MODE (operands[0]));
1897
1898   middlehalf[0] = 0;
1899   middlehalf[1] = 0;
1900
1901   /* First classify both operands.  */
1902
1903   if (REG_P (operands[0]))
1904     optype0 = REGOP;
1905   else if (offsettable_memref_p (operands[0]))
1906     optype0 = OFFSOP;
1907   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1908     optype0 = POPOP;
1909   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1910     optype0 = PUSHOP;
1911   else if (GET_CODE (operands[0]) == MEM)
1912     optype0 = MEMOP;
1913   else
1914     optype0 = RNDOP;
1915
1916   if (REG_P (operands[1]))
1917     optype1 = REGOP;
1918   else if (CONSTANT_P (operands[1]))
1919     optype1 = CNSTOP;
1920   else if (offsettable_memref_p (operands[1]))
1921     optype1 = OFFSOP;
1922   else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
1923     optype1 = POPOP;
1924   else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1925     optype1 = PUSHOP;
1926   else if (GET_CODE (operands[1]) == MEM)
1927     optype1 = MEMOP;
1928   else
1929     optype1 = RNDOP;
1930
1931   /* Check for the cases that the operand constraints are not
1932      supposed to allow to happen.  Abort if we get one,
1933      because generating code for these cases is painful.  */
1934
1935   if (optype0 == RNDOP || optype1 == RNDOP)
1936     abort ();
1937
1938   /* If one operand is decrementing and one is incrementing
1939      decrement the former register explicitly
1940      and change that operand into ordinary indexing.  */
1941
1942   if (optype0 == PUSHOP && optype1 == POPOP)
1943     {
1944       operands[0] = XEXP (XEXP (operands[0], 0), 0);
1945       if (size == 12)
1946         output_asm_insn ("sub%.l %#12,%0", operands);
1947       else
1948         output_asm_insn ("subq%.l %#8,%0", operands);
1949       if (GET_MODE (operands[1]) == XFmode)
1950         operands[0] = gen_rtx_MEM (XFmode, operands[0]);
1951       else if (GET_MODE (operands[0]) == DFmode)
1952         operands[0] = gen_rtx_MEM (DFmode, operands[0]);
1953       else
1954         operands[0] = gen_rtx_MEM (DImode, operands[0]);
1955       optype0 = OFFSOP;
1956     }
1957   if (optype0 == POPOP && optype1 == PUSHOP)
1958     {
1959       operands[1] = XEXP (XEXP (operands[1], 0), 0);
1960       if (size == 12)
1961         output_asm_insn ("sub%.l %#12,%1", operands);
1962       else
1963         output_asm_insn ("subq%.l %#8,%1", operands);
1964       if (GET_MODE (operands[1]) == XFmode)
1965         operands[1] = gen_rtx_MEM (XFmode, operands[1]);
1966       else if (GET_MODE (operands[1]) == DFmode)
1967         operands[1] = gen_rtx_MEM (DFmode, operands[1]);
1968       else
1969         operands[1] = gen_rtx_MEM (DImode, operands[1]);
1970       optype1 = OFFSOP;
1971     }
1972
1973   /* If an operand is an unoffsettable memory ref, find a register
1974      we can increment temporarily to make it refer to the second word.  */
1975
1976   if (optype0 == MEMOP)
1977     addreg0 = find_addr_reg (XEXP (operands[0], 0));
1978
1979   if (optype1 == MEMOP)
1980     addreg1 = find_addr_reg (XEXP (operands[1], 0));
1981
1982   /* Ok, we can do one word at a time.
1983      Normally we do the low-numbered word first,
1984      but if either operand is autodecrementing then we
1985      do the high-numbered word first.
1986
1987      In either case, set up in LATEHALF the operands to use
1988      for the high-numbered word and in some cases alter the
1989      operands in OPERANDS to be suitable for the low-numbered word.  */
1990
1991   if (size == 12)
1992     {
1993       if (optype0 == REGOP)
1994         {
1995           latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
1996           middlehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1997         }
1998       else if (optype0 == OFFSOP)
1999         {
2000           middlehalf[0] = adjust_address (operands[0], SImode, 4);
2001           latehalf[0] = adjust_address (operands[0], SImode, size - 4);
2002         }
2003       else
2004         {
2005           middlehalf[0] = operands[0];
2006           latehalf[0] = operands[0];
2007         }
2008
2009       if (optype1 == REGOP)
2010         {
2011           latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
2012           middlehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2013         }
2014       else if (optype1 == OFFSOP)
2015         {
2016           middlehalf[1] = adjust_address (operands[1], SImode, 4);
2017           latehalf[1] = adjust_address (operands[1], SImode, size - 4);
2018         }
2019       else if (optype1 == CNSTOP)
2020         {
2021           if (GET_CODE (operands[1]) == CONST_DOUBLE)
2022             {
2023               REAL_VALUE_TYPE r;
2024               long l[3];
2025
2026               REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2027               REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
2028               operands[1] = GEN_INT (l[0]);
2029               middlehalf[1] = GEN_INT (l[1]);
2030               latehalf[1] = GEN_INT (l[2]);
2031             }
2032           else if (CONSTANT_P (operands[1]))
2033             {
2034               /* actually, no non-CONST_DOUBLE constant should ever
2035                  appear here.  */
2036               abort ();
2037               if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
2038                 latehalf[1] = constm1_rtx;
2039               else
2040                 latehalf[1] = const0_rtx;
2041             }
2042         }
2043       else
2044         {
2045           middlehalf[1] = operands[1];
2046           latehalf[1] = operands[1];
2047         }
2048     }
2049   else
2050     /* size is not 12: */
2051     {
2052       if (optype0 == REGOP)
2053         latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2054       else if (optype0 == OFFSOP)
2055         latehalf[0] = adjust_address (operands[0], SImode, size - 4);
2056       else
2057         latehalf[0] = operands[0];
2058
2059       if (optype1 == REGOP)
2060         latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2061       else if (optype1 == OFFSOP)
2062         latehalf[1] = adjust_address (operands[1], SImode, size - 4);
2063       else if (optype1 == CNSTOP)
2064         split_double (operands[1], &operands[1], &latehalf[1]);
2065       else
2066         latehalf[1] = operands[1];
2067     }
2068
2069   /* If insn is effectively movd N(sp),-(sp) then we will do the
2070      high word first.  We should use the adjusted operand 1 (which is N+4(sp))
2071      for the low word as well, to compensate for the first decrement of sp.  */
2072   if (optype0 == PUSHOP
2073       && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
2074       && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
2075     operands[1] = middlehalf[1] = latehalf[1];
2076
2077   /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
2078      if the upper part of reg N does not appear in the MEM, arrange to
2079      emit the move late-half first.  Otherwise, compute the MEM address
2080      into the upper part of N and use that as a pointer to the memory
2081      operand.  */
2082   if (optype0 == REGOP
2083       && (optype1 == OFFSOP || optype1 == MEMOP))
2084     {
2085       rtx testlow = gen_rtx_REG (SImode, REGNO (operands[0]));
2086
2087       if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
2088           && reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2089         {
2090           /* If both halves of dest are used in the src memory address,
2091              compute the address into latehalf of dest.
2092              Note that this can't happen if the dest is two data regs.  */
2093 compadr:
2094           xops[0] = latehalf[0];
2095           xops[1] = XEXP (operands[1], 0);
2096           output_asm_insn ("lea %a1,%0", xops);
2097           if (GET_MODE (operands[1]) == XFmode )
2098             {
2099               operands[1] = gen_rtx_MEM (XFmode, latehalf[0]);
2100               middlehalf[1] = adjust_address (operands[1], DImode, size - 8);
2101               latehalf[1] = adjust_address (operands[1], DImode, size - 4);
2102             }
2103           else
2104             {
2105               operands[1] = gen_rtx_MEM (DImode, latehalf[0]);
2106               latehalf[1] = adjust_address (operands[1], DImode, size - 4);
2107             }
2108         }
2109       else if (size == 12
2110                && reg_overlap_mentioned_p (middlehalf[0],
2111                                            XEXP (operands[1], 0)))
2112         {
2113           /* Check for two regs used by both source and dest.
2114              Note that this can't happen if the dest is all data regs.
2115              It can happen if the dest is d6, d7, a0.
2116              But in that case, latehalf is an addr reg, so
2117              the code at compadr does ok.  */
2118
2119           if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
2120               || reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2121             goto compadr;
2122
2123           /* JRV says this can't happen: */
2124           if (addreg0 || addreg1)
2125             abort ();
2126
2127           /* Only the middle reg conflicts; simply put it last.  */
2128           output_asm_insn (singlemove_string (operands), operands);
2129           output_asm_insn (singlemove_string (latehalf), latehalf);
2130           output_asm_insn (singlemove_string (middlehalf), middlehalf);
2131           return "";
2132         }
2133       else if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0)))
2134         /* If the low half of dest is mentioned in the source memory
2135            address, the arrange to emit the move late half first.  */
2136         dest_overlapped_low = 1;
2137     }
2138
2139   /* If one or both operands autodecrementing,
2140      do the two words, high-numbered first.  */
2141
2142   /* Likewise,  the first move would clobber the source of the second one,
2143      do them in the other order.  This happens only for registers;
2144      such overlap can't happen in memory unless the user explicitly
2145      sets it up, and that is an undefined circumstance.  */
2146
2147   if (optype0 == PUSHOP || optype1 == PUSHOP
2148       || (optype0 == REGOP && optype1 == REGOP
2149           && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
2150               || REGNO (operands[0]) == REGNO (latehalf[1])))
2151       || dest_overlapped_low)
2152     {
2153       /* Make any unoffsettable addresses point at high-numbered word.  */
2154       if (addreg0)
2155         {
2156           if (size == 12)
2157             output_asm_insn ("addq%.l %#8,%0", &addreg0);
2158           else
2159             output_asm_insn ("addq%.l %#4,%0", &addreg0);
2160         }
2161       if (addreg1)
2162         {
2163           if (size == 12)
2164             output_asm_insn ("addq%.l %#8,%0", &addreg1);
2165           else
2166             output_asm_insn ("addq%.l %#4,%0", &addreg1);
2167         }
2168
2169       /* Do that word.  */
2170       output_asm_insn (singlemove_string (latehalf), latehalf);
2171
2172       /* Undo the adds we just did.  */
2173       if (addreg0)
2174         output_asm_insn ("subq%.l %#4,%0", &addreg0);
2175       if (addreg1)
2176         output_asm_insn ("subq%.l %#4,%0", &addreg1);
2177
2178       if (size == 12)
2179         {
2180           output_asm_insn (singlemove_string (middlehalf), middlehalf);
2181           if (addreg0)
2182             output_asm_insn ("subq%.l %#4,%0", &addreg0);
2183           if (addreg1)
2184             output_asm_insn ("subq%.l %#4,%0", &addreg1);
2185         }
2186
2187       /* Do low-numbered word.  */
2188       return singlemove_string (operands);
2189     }
2190
2191   /* Normal case: do the two words, low-numbered first.  */
2192
2193   output_asm_insn (singlemove_string (operands), operands);
2194
2195   /* Do the middle one of the three words for long double */
2196   if (size == 12)
2197     {
2198       if (addreg0)
2199         output_asm_insn ("addq%.l %#4,%0", &addreg0);
2200       if (addreg1)
2201         output_asm_insn ("addq%.l %#4,%0", &addreg1);
2202
2203       output_asm_insn (singlemove_string (middlehalf), middlehalf);
2204     }
2205
2206   /* Make any unoffsettable addresses point at high-numbered word.  */
2207   if (addreg0)
2208     output_asm_insn ("addq%.l %#4,%0", &addreg0);
2209   if (addreg1)
2210     output_asm_insn ("addq%.l %#4,%0", &addreg1);
2211
2212   /* Do that word.  */
2213   output_asm_insn (singlemove_string (latehalf), latehalf);
2214
2215   /* Undo the adds we just did.  */
2216   if (addreg0)
2217     {
2218       if (size == 12)
2219         output_asm_insn ("subq%.l %#8,%0", &addreg0);
2220       else
2221         output_asm_insn ("subq%.l %#4,%0", &addreg0);
2222     }
2223   if (addreg1)
2224     {
2225       if (size == 12)
2226         output_asm_insn ("subq%.l %#8,%0", &addreg1);
2227       else
2228         output_asm_insn ("subq%.l %#4,%0", &addreg1);
2229     }
2230
2231   return "";
2232 }
2233
2234 /* Return a REG that occurs in ADDR with coefficient 1.
2235    ADDR can be effectively incremented by incrementing REG.  */
2236
2237 static rtx
2238 find_addr_reg (addr)
2239      rtx addr;
2240 {
2241   while (GET_CODE (addr) == PLUS)
2242     {
2243       if (GET_CODE (XEXP (addr, 0)) == REG)
2244         addr = XEXP (addr, 0);
2245       else if (GET_CODE (XEXP (addr, 1)) == REG)
2246         addr = XEXP (addr, 1);
2247       else if (CONSTANT_P (XEXP (addr, 0)))
2248         addr = XEXP (addr, 1);
2249       else if (CONSTANT_P (XEXP (addr, 1)))
2250         addr = XEXP (addr, 0);
2251       else
2252         abort ();
2253     }
2254   if (GET_CODE (addr) == REG)
2255     return addr;
2256   abort ();
2257 }
2258
2259 /* Output assembler code to perform a 32 bit 3 operand add.  */
2260
2261 const char *
2262 output_addsi3 (operands)
2263      rtx *operands;
2264 {
2265   if (! operands_match_p (operands[0], operands[1]))
2266     {
2267       if (!ADDRESS_REG_P (operands[1]))
2268         {
2269           rtx tmp = operands[1];
2270
2271           operands[1] = operands[2];
2272           operands[2] = tmp;
2273         }
2274
2275       /* These insns can result from reloads to access
2276          stack slots over 64k from the frame pointer.  */
2277       if (GET_CODE (operands[2]) == CONST_INT
2278           && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
2279         return "move%.l %2,%0\n\tadd%.l %1,%0";
2280 #ifdef SGS
2281       if (GET_CODE (operands[2]) == REG)
2282         return "lea 0(%1,%2.l),%0";
2283       else
2284         return "lea %c2(%1),%0";
2285 #else /* not SGS */
2286 #ifdef MOTOROLA
2287       if (GET_CODE (operands[2]) == REG)
2288         return "lea (%1,%2.l),%0";
2289       else
2290         return "lea (%c2,%1),%0";
2291 #else /* not MOTOROLA (MIT syntax) */
2292       if (GET_CODE (operands[2]) == REG)
2293         return "lea %1@(0,%2:l),%0";
2294       else
2295         return "lea %1@(%c2),%0";
2296 #endif /* not MOTOROLA */
2297 #endif /* not SGS */
2298     }
2299   if (GET_CODE (operands[2]) == CONST_INT)
2300     {
2301 #ifndef NO_ADDSUB_Q
2302       if (INTVAL (operands[2]) > 0
2303           && INTVAL (operands[2]) <= 8)
2304         return "addq%.l %2,%0";
2305       if (INTVAL (operands[2]) < 0
2306           && INTVAL (operands[2]) >= -8)
2307         {
2308           operands[2] = GEN_INT (- INTVAL (operands[2]));
2309           return "subq%.l %2,%0";
2310         }
2311       /* On the CPU32 it is faster to use two addql instructions to
2312          add a small integer (8 < N <= 16) to a register.
2313          Likewise for subql.  */
2314       if (TARGET_CPU32 && REG_P (operands[0]))
2315         {
2316           if (INTVAL (operands[2]) > 8
2317               && INTVAL (operands[2]) <= 16)
2318             {
2319               operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
2320               return "addq%.l %#8,%0\n\taddq%.l %2,%0";
2321             }
2322           if (INTVAL (operands[2]) < -8
2323               && INTVAL (operands[2]) >= -16)
2324             {
2325               operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
2326               return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
2327             }
2328         }
2329 #endif
2330       if (ADDRESS_REG_P (operands[0])
2331           && INTVAL (operands[2]) >= -0x8000
2332           && INTVAL (operands[2]) < 0x8000)
2333         {
2334           if (TARGET_68040)
2335             return "add%.w %2,%0";
2336           else
2337 #ifdef MOTOROLA  
2338             return "lea (%c2,%0),%0";
2339 #else
2340             return "lea %0@(%c2),%0";
2341 #endif
2342         }
2343     }
2344   return "add%.l %2,%0";
2345 }
2346 \f
2347 /* Store in cc_status the expressions that the condition codes will
2348    describe after execution of an instruction whose pattern is EXP.
2349    Do not alter them if the instruction would not alter the cc's.  */
2350
2351 /* On the 68000, all the insns to store in an address register fail to
2352    set the cc's.  However, in some cases these instructions can make it
2353    possibly invalid to use the saved cc's.  In those cases we clear out
2354    some or all of the saved cc's so they won't be used.  */
2355
2356 void
2357 notice_update_cc (exp, insn)
2358      rtx exp;
2359      rtx insn;
2360 {
2361   if (GET_CODE (exp) == SET)
2362     {
2363       if (GET_CODE (SET_SRC (exp)) == CALL)
2364         {
2365           CC_STATUS_INIT; 
2366         }
2367       else if (ADDRESS_REG_P (SET_DEST (exp)))
2368         {
2369           if (cc_status.value1 && modified_in_p (cc_status.value1, insn))
2370             cc_status.value1 = 0;
2371           if (cc_status.value2 && modified_in_p (cc_status.value2, insn))
2372             cc_status.value2 = 0; 
2373         }
2374       else if (!FP_REG_P (SET_DEST (exp))
2375                && SET_DEST (exp) != cc0_rtx
2376                && (FP_REG_P (SET_SRC (exp))
2377                    || GET_CODE (SET_SRC (exp)) == FIX
2378                    || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE
2379                    || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND))
2380         {
2381           CC_STATUS_INIT; 
2382         }
2383       /* A pair of move insns doesn't produce a useful overall cc.  */
2384       else if (!FP_REG_P (SET_DEST (exp))
2385                && !FP_REG_P (SET_SRC (exp))
2386                && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
2387                && (GET_CODE (SET_SRC (exp)) == REG
2388                    || GET_CODE (SET_SRC (exp)) == MEM
2389                    || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
2390         {
2391           CC_STATUS_INIT; 
2392         }
2393       else if (GET_CODE (SET_SRC (exp)) == CALL)
2394         {
2395           CC_STATUS_INIT; 
2396         }
2397       else if (XEXP (exp, 0) != pc_rtx)
2398         {
2399           cc_status.flags = 0;
2400           cc_status.value1 = XEXP (exp, 0);
2401           cc_status.value2 = XEXP (exp, 1);
2402         }
2403     }
2404   else if (GET_CODE (exp) == PARALLEL
2405            && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2406     {
2407       if (ADDRESS_REG_P (XEXP (XVECEXP (exp, 0, 0), 0)))
2408         CC_STATUS_INIT;
2409       else if (XEXP (XVECEXP (exp, 0, 0), 0) != pc_rtx)
2410         {
2411           cc_status.flags = 0;
2412           cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
2413           cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1);
2414         }
2415     }
2416   else
2417     CC_STATUS_INIT;
2418   if (cc_status.value2 != 0
2419       && ADDRESS_REG_P (cc_status.value2)
2420       && GET_MODE (cc_status.value2) == QImode)
2421     CC_STATUS_INIT;
2422   if (cc_status.value2 != 0)
2423     switch (GET_CODE (cc_status.value2))
2424       {
2425       case PLUS: case MINUS: case MULT:
2426       case DIV: case UDIV: case MOD: case UMOD: case NEG:
2427 #if 0 /* These instructions always clear the overflow bit */
2428       case ASHIFT: case ASHIFTRT: case LSHIFTRT:
2429       case ROTATE: case ROTATERT:
2430 #endif
2431         if (GET_MODE (cc_status.value2) != VOIDmode)
2432           cc_status.flags |= CC_NO_OVERFLOW;
2433         break;
2434       case ZERO_EXTEND:
2435         /* (SET r1 (ZERO_EXTEND r2)) on this machine
2436            ends with a move insn moving r2 in r2's mode.
2437            Thus, the cc's are set for r2.
2438            This can set N bit spuriously.  */
2439         cc_status.flags |= CC_NOT_NEGATIVE; 
2440
2441       default:
2442         break;
2443       }
2444   if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
2445       && cc_status.value2
2446       && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
2447     cc_status.value2 = 0;
2448   if (((cc_status.value1 && FP_REG_P (cc_status.value1))
2449        || (cc_status.value2 && FP_REG_P (cc_status.value2))))
2450     cc_status.flags = CC_IN_68881;
2451 }
2452 \f
2453 const char *
2454 output_move_const_double (operands)
2455      rtx *operands;
2456 {
2457   int code = standard_68881_constant_p (operands[1]);
2458
2459   if (code != 0)
2460     {
2461       static char buf[40];
2462
2463       sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
2464       return buf;
2465     }
2466   return "fmove%.d %1,%0";
2467 }
2468
2469 const char *
2470 output_move_const_single (operands)
2471      rtx *operands;
2472 {
2473   int code = standard_68881_constant_p (operands[1]);
2474
2475   if (code != 0)
2476     {
2477       static char buf[40];
2478
2479       sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
2480       return buf;
2481     }
2482   return "fmove%.s %f1,%0";
2483 }
2484
2485 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2486    from the "fmovecr" instruction.
2487    The value, anded with 0xff, gives the code to use in fmovecr
2488    to get the desired constant.  */
2489
2490 /* This code has been fixed for cross-compilation.  */
2491   
2492 static int inited_68881_table = 0;
2493
2494 static const char *const strings_68881[7] = {
2495   "0.0",
2496   "1.0",
2497   "10.0",
2498   "100.0",
2499   "10000.0",
2500   "1e8",
2501   "1e16"
2502   };
2503
2504 static const int codes_68881[7] = {
2505   0x0f,
2506   0x32,
2507   0x33,
2508   0x34,
2509   0x35,
2510   0x36,
2511   0x37
2512   };
2513
2514 REAL_VALUE_TYPE values_68881[7];
2515
2516 /* Set up values_68881 array by converting the decimal values
2517    strings_68881 to binary.  */
2518
2519 void
2520 init_68881_table ()
2521 {
2522   int i;
2523   REAL_VALUE_TYPE r;
2524   enum machine_mode mode;
2525
2526   mode = SFmode;
2527   for (i = 0; i < 7; i++)
2528     {
2529       if (i == 6)
2530         mode = DFmode;
2531       r = REAL_VALUE_ATOF (strings_68881[i], mode);
2532       values_68881[i] = r;
2533     }
2534   inited_68881_table = 1;
2535 }
2536
2537 int
2538 standard_68881_constant_p (x)
2539      rtx x;
2540 {
2541   REAL_VALUE_TYPE r;
2542   int i;
2543
2544 #ifdef NO_ASM_FMOVECR
2545   return 0;
2546 #endif
2547
2548   /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2549      used at all on those chips.  */
2550   if (TARGET_68040 || TARGET_68060)
2551     return 0;
2552
2553   if (! inited_68881_table)
2554     init_68881_table ();
2555
2556   REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2557
2558   /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2559      is rejected.  */
2560   for (i = 0; i < 6; i++)
2561     {
2562       if (REAL_VALUES_IDENTICAL (r, values_68881[i]))
2563         return (codes_68881[i]);
2564     }
2565   
2566   if (GET_MODE (x) == SFmode)
2567     return 0;
2568
2569   if (REAL_VALUES_EQUAL (r, values_68881[6]))
2570     return (codes_68881[6]);
2571
2572   /* larger powers of ten in the constants ram are not used
2573      because they are not equal to a `double' C constant.  */
2574   return 0;
2575 }
2576
2577 /* If X is a floating-point constant, return the logarithm of X base 2,
2578    or 0 if X is not a power of 2.  */
2579
2580 int
2581 floating_exact_log2 (x)
2582      rtx x;
2583 {
2584   REAL_VALUE_TYPE r, r1;
2585   int exp;
2586
2587   REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2588
2589   if (REAL_VALUES_LESS (r, dconst1))
2590     return 0;
2591
2592   exp = real_exponent (&r);
2593   real_2expN (&r1, exp);
2594   if (REAL_VALUES_EQUAL (r1, r))
2595     return exp;
2596
2597   return 0;
2598 }
2599 \f
2600 /* A C compound statement to output to stdio stream STREAM the
2601    assembler syntax for an instruction operand X.  X is an RTL
2602    expression.
2603
2604    CODE is a value that can be used to specify one of several ways
2605    of printing the operand.  It is used when identical operands
2606    must be printed differently depending on the context.  CODE
2607    comes from the `%' specification that was used to request
2608    printing of the operand.  If the specification was just `%DIGIT'
2609    then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2610    is the ASCII code for LTR.
2611
2612    If X is a register, this macro should print the register's name.
2613    The names can be found in an array `reg_names' whose type is
2614    `char *[]'.  `reg_names' is initialized from `REGISTER_NAMES'.
2615
2616    When the machine description has a specification `%PUNCT' (a `%'
2617    followed by a punctuation character), this macro is called with
2618    a null pointer for X and the punctuation character for CODE.
2619
2620    The m68k specific codes are:
2621
2622    '.' for dot needed in Motorola-style opcode names.
2623    '-' for an operand pushing on the stack:
2624        sp@-, -(sp) or -(%sp) depending on the style of syntax.
2625    '+' for an operand pushing on the stack:
2626        sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2627    '@' for a reference to the top word on the stack:
2628        sp@, (sp) or (%sp) depending on the style of syntax.
2629    '#' for an immediate operand prefix (# in MIT and Motorola syntax
2630        but & in SGS syntax).
2631    '!' for the cc register (used in an `and to cc' insn).
2632    '$' for the letter `s' in an op code, but only on the 68040.
2633    '&' for the letter `d' in an op code, but only on the 68040.
2634    '/' for register prefix needed by longlong.h.
2635
2636    'b' for byte insn (no effect, on the Sun; this is for the ISI).
2637    'd' to force memory addressing to be absolute, not relative.
2638    'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2639    'o' for operands to go directly to output_operand_address (bypassing
2640        print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
2641    'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2642        or print pair of registers as rx:ry.
2643
2644    */
2645
2646 void
2647 print_operand (file, op, letter)
2648      FILE *file;                /* file to write to */
2649      rtx op;                    /* operand to print */
2650      int letter;                /* %<letter> or 0 */
2651 {
2652   if (letter == '.')
2653     {
2654 #if defined (MOTOROLA)
2655       fprintf (file, ".");
2656 #endif
2657     }
2658   else if (letter == '#')
2659     {
2660       asm_fprintf (file, "%I");
2661     }
2662   else if (letter == '-')
2663     {
2664 #ifdef MOTOROLA
2665       asm_fprintf (file, "-(%Rsp)");
2666 #else
2667       asm_fprintf (file, "%Rsp@-");
2668 #endif
2669     }
2670   else if (letter == '+')
2671     {
2672 #ifdef MOTOROLA
2673       asm_fprintf (file, "(%Rsp)+");
2674 #else
2675       asm_fprintf (file, "%Rsp@+");
2676 #endif
2677     }
2678   else if (letter == '@')
2679     {
2680 #ifdef MOTOROLA
2681       asm_fprintf (file, "(%Rsp)");
2682 #else
2683       asm_fprintf (file, "%Rsp@");
2684 #endif
2685     }
2686   else if (letter == '!')
2687     {
2688       asm_fprintf (file, "%Rfpcr");
2689     }
2690   else if (letter == '$')
2691     {
2692       if (TARGET_68040_ONLY)
2693         {
2694           fprintf (file, "s");
2695         }
2696     }
2697   else if (letter == '&')
2698     {
2699       if (TARGET_68040_ONLY)
2700         {
2701           fprintf (file, "d");
2702         }
2703     }
2704   else if (letter == '/')
2705     {
2706       asm_fprintf (file, "%R");
2707     }
2708   else if (letter == 'o')
2709     {
2710       /* This is only for direct addresses with TARGET_PCREL */
2711       if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
2712           || !TARGET_PCREL) 
2713         abort ();
2714       output_addr_const (file, XEXP (op, 0));
2715     }
2716   else if (GET_CODE (op) == REG)
2717     {
2718       if (letter == 'R')
2719         /* Print out the second register name of a register pair.
2720            I.e., R (6) => 7.  */
2721         fputs (reg_names[REGNO (op) + 1], file);
2722       else
2723         fputs (reg_names[REGNO (op)], file);
2724     }
2725   else if (GET_CODE (op) == MEM)
2726     {
2727       output_address (XEXP (op, 0));
2728       if (letter == 'd' && ! TARGET_68020
2729           && CONSTANT_ADDRESS_P (XEXP (op, 0))
2730           && !(GET_CODE (XEXP (op, 0)) == CONST_INT
2731                && INTVAL (XEXP (op, 0)) < 0x8000
2732                && INTVAL (XEXP (op, 0)) >= -0x8000))
2733         {
2734 #ifdef MOTOROLA
2735           fprintf (file, ".l");
2736 #else
2737           fprintf (file, ":l");
2738 #endif
2739         }
2740     }
2741   else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
2742     {
2743       REAL_VALUE_TYPE r;
2744       REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2745       ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
2746     }
2747   else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
2748     {
2749       REAL_VALUE_TYPE r;
2750       REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2751       ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
2752     }
2753   else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
2754     {
2755       REAL_VALUE_TYPE r;
2756       REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2757       ASM_OUTPUT_DOUBLE_OPERAND (file, r);
2758     }
2759   else
2760     {
2761       /* Use `print_operand_address' instead of `output_addr_const'
2762          to ensure that we print relevant PIC stuff.  */
2763       asm_fprintf (file, "%I");
2764       if (TARGET_PCREL
2765           && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
2766         print_operand_address (file, op);
2767       else
2768         output_addr_const (file, op);
2769     }
2770 }
2771
2772 \f
2773 /* A C compound statement to output to stdio stream STREAM the
2774    assembler syntax for an instruction operand that is a memory
2775    reference whose address is ADDR.  ADDR is an RTL expression.
2776
2777    Note that this contains a kludge that knows that the only reason
2778    we have an address (plus (label_ref...) (reg...)) when not generating
2779    PIC code is in the insn before a tablejump, and we know that m68k.md
2780    generates a label LInnn: on such an insn.
2781
2782    It is possible for PIC to generate a (plus (label_ref...) (reg...))
2783    and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2784
2785    Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2786    fails to assemble.  Luckily "Lnnn(pc,d0.l*2)" produces the results
2787    we want.  This difference can be accommodated by using an assembler
2788    define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2789    string, as necessary.  This is accomplished via the ASM_OUTPUT_CASE_END
2790    macro.  See m68k/sgs.h for an example; for versions without the bug.
2791    Some assemblers refuse all the above solutions.  The workaround is to
2792    emit "K(pc,d0.l*2)" with K being a small constant known to give the
2793    right behavior.
2794
2795    They also do not like things like "pea 1.w", so we simple leave off
2796    the .w on small constants. 
2797
2798    This routine is responsible for distinguishing between -fpic and -fPIC 
2799    style relocations in an address.  When generating -fpic code the
2800    offset is output in word mode (eg movel a5@(_foo:w), a0).  When generating
2801    -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
2802
2803 #ifndef ASM_OUTPUT_CASE_FETCH
2804 #ifdef MOTOROLA
2805 #ifdef SGS
2806 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2807         asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
2808 #else
2809 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2810         asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2811 #endif
2812 #else
2813 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2814         asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
2815 #endif
2816 #endif /* ASM_OUTPUT_CASE_FETCH */
2817
2818 void
2819 print_operand_address (file, addr)
2820      FILE *file;
2821      rtx addr;
2822 {
2823   register rtx reg1, reg2, breg, ireg;
2824   rtx offset;
2825
2826   switch (GET_CODE (addr))
2827     {
2828       case REG:
2829 #ifdef MOTOROLA
2830         fprintf (file, "(%s)", reg_names[REGNO (addr)]);
2831 #else
2832         fprintf (file, "%s@", reg_names[REGNO (addr)]);
2833 #endif
2834         break;
2835       case PRE_DEC:
2836 #ifdef MOTOROLA
2837         fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
2838 #else
2839         fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);
2840 #endif
2841         break;
2842       case POST_INC:
2843 #ifdef MOTOROLA
2844         fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
2845 #else
2846         fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);
2847 #endif
2848         break;
2849       case PLUS:
2850         reg1 = reg2 = ireg = breg = offset = 0;
2851         if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
2852           {
2853             offset = XEXP (addr, 0);
2854             addr = XEXP (addr, 1);
2855           }
2856         else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
2857           {
2858             offset = XEXP (addr, 1);
2859             addr = XEXP (addr, 0);
2860           }
2861         if (GET_CODE (addr) != PLUS)
2862           {
2863             ;
2864           }
2865         else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
2866           {
2867             reg1 = XEXP (addr, 0);
2868             addr = XEXP (addr, 1);
2869           }
2870         else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
2871           {
2872             reg1 = XEXP (addr, 1);
2873             addr = XEXP (addr, 0);
2874           }
2875         else if (GET_CODE (XEXP (addr, 0)) == MULT)
2876           {
2877             reg1 = XEXP (addr, 0);
2878             addr = XEXP (addr, 1);
2879           }
2880         else if (GET_CODE (XEXP (addr, 1)) == MULT)
2881           {
2882             reg1 = XEXP (addr, 1);
2883             addr = XEXP (addr, 0);
2884           }
2885         else if (GET_CODE (XEXP (addr, 0)) == REG)
2886           {
2887             reg1 = XEXP (addr, 0);
2888             addr = XEXP (addr, 1);
2889           }
2890         else if (GET_CODE (XEXP (addr, 1)) == REG)
2891           {
2892             reg1 = XEXP (addr, 1);
2893             addr = XEXP (addr, 0);
2894           }
2895         if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
2896             || GET_CODE (addr) == SIGN_EXTEND)
2897           {
2898             if (reg1 == 0)
2899               {
2900                 reg1 = addr;
2901               }
2902             else
2903               {
2904                 reg2 = addr;
2905               }
2906             addr = 0;
2907           }
2908 #if 0   /* for OLD_INDEXING */
2909         else if (GET_CODE (addr) == PLUS)
2910           {
2911             if (GET_CODE (XEXP (addr, 0)) == REG)
2912               {
2913                 reg2 = XEXP (addr, 0);
2914                 addr = XEXP (addr, 1);
2915               }
2916             else if (GET_CODE (XEXP (addr, 1)) == REG)
2917               {
2918                 reg2 = XEXP (addr, 1);
2919                 addr = XEXP (addr, 0);
2920               }
2921           }
2922 #endif
2923         if (offset != 0)
2924           {
2925             if (addr != 0)
2926               {
2927                 abort ();
2928               }
2929             addr = offset;
2930           }
2931         if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
2932                       || GET_CODE (reg1) == MULT))
2933             || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
2934           {
2935             breg = reg2;
2936             ireg = reg1;
2937           }
2938         else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
2939           {
2940             breg = reg1;
2941             ireg = reg2;
2942           }
2943         if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
2944             && ! (flag_pic && ireg == pic_offset_table_rtx))
2945           {
2946             int scale = 1;
2947             if (GET_CODE (ireg) == MULT)
2948               {
2949                 scale = INTVAL (XEXP (ireg, 1));
2950                 ireg = XEXP (ireg, 0);
2951               }
2952             if (GET_CODE (ireg) == SIGN_EXTEND)
2953               {
2954                 ASM_OUTPUT_CASE_FETCH (file,
2955                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
2956                              reg_names[REGNO (XEXP (ireg, 0))]);
2957                 fprintf (file, "w");
2958               }
2959             else
2960               {
2961                 ASM_OUTPUT_CASE_FETCH (file,
2962                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
2963                              reg_names[REGNO (ireg)]);
2964                 fprintf (file, "l");
2965               }
2966             if (scale != 1)
2967               {
2968 #ifdef MOTOROLA
2969                 fprintf (file, "*%d", scale);
2970 #else
2971                 fprintf (file, ":%d", scale);
2972 #endif
2973               }
2974             putc (')', file);
2975             break;
2976           }
2977         if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
2978             && ! (flag_pic && breg == pic_offset_table_rtx))
2979           {
2980             ASM_OUTPUT_CASE_FETCH (file,
2981                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
2982                          reg_names[REGNO (breg)]);
2983             fprintf (file, "l)");
2984             break;
2985           }
2986         if (ireg != 0 || breg != 0)
2987           {
2988             int scale = 1;
2989             if (breg == 0)
2990               {
2991                 abort ();
2992               }
2993             if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)
2994               {
2995                 abort ();
2996               }
2997 #ifdef MOTOROLA
2998             if (addr != 0)
2999               {
3000                 output_addr_const (file, addr);
3001                 if (flag_pic && (breg == pic_offset_table_rtx))
3002                   {
3003                     fprintf (file, "@GOT");
3004                     if (flag_pic == 1)
3005                       fprintf (file, ".w");
3006                   }
3007               }
3008             fprintf (file, "(%s", reg_names[REGNO (breg)]);
3009             if (ireg != 0)
3010               {
3011                 putc (',', file);
3012               }
3013 #else
3014             fprintf (file, "%s@(", reg_names[REGNO (breg)]);
3015             if (addr != 0)
3016               {
3017                 output_addr_const (file, addr);
3018                 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
3019                   fprintf (file, ":w");
3020                 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
3021                   fprintf (file, ":l");
3022               }
3023             if (addr != 0 && ireg != 0)
3024               {
3025                 putc (',', file);
3026               }
3027 #endif
3028             if (ireg != 0 && GET_CODE (ireg) == MULT)
3029               {
3030                 scale = INTVAL (XEXP (ireg, 1));
3031                 ireg = XEXP (ireg, 0);
3032               }
3033             if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
3034               {
3035 #ifdef MOTOROLA
3036                 fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);
3037 #else
3038                 fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);
3039 #endif
3040               }
3041             else if (ireg != 0)
3042               {
3043 #ifdef MOTOROLA
3044                 fprintf (file, "%s.l", reg_names[REGNO (ireg)]);
3045 #else
3046                 fprintf (file, "%s:l", reg_names[REGNO (ireg)]);
3047 #endif
3048               }
3049             if (scale != 1)
3050               {
3051 #ifdef MOTOROLA
3052                 fprintf (file, "*%d", scale);
3053 #else
3054                 fprintf (file, ":%d", scale);
3055 #endif
3056               }
3057             putc (')', file);
3058             break;
3059           }
3060         else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
3061                  && ! (flag_pic && reg1 == pic_offset_table_rtx))       
3062           {
3063             ASM_OUTPUT_CASE_FETCH (file,
3064                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
3065                          reg_names[REGNO (reg1)]);
3066             fprintf (file, "l)");
3067             break;
3068           }
3069         /* FALL-THROUGH (is this really what we want?)  */
3070       default:
3071         if (GET_CODE (addr) == CONST_INT
3072             && INTVAL (addr) < 0x8000
3073             && INTVAL (addr) >= -0x8000)
3074           {
3075 #ifdef MOTOROLA
3076 #ifdef SGS
3077             /* Many SGS assemblers croak on size specifiers for constants.  */
3078             fprintf (file, "%d", (int) INTVAL (addr));
3079 #else
3080             fprintf (file, "%d.w", (int) INTVAL (addr));
3081 #endif
3082 #else
3083             fprintf (file, "%d:w", (int) INTVAL (addr));
3084 #endif
3085           }
3086         else if (GET_CODE (addr) == CONST_INT)
3087           {
3088             fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
3089           }
3090         else if (TARGET_PCREL)
3091           {
3092             fputc ('(', file);
3093             output_addr_const (file, addr);
3094             if (flag_pic == 1)
3095               asm_fprintf (file, ":w,%Rpc)");
3096             else
3097               asm_fprintf (file, ":l,%Rpc)");
3098           }
3099         else
3100           {
3101             /* Special case for SYMBOL_REF if the symbol name ends in
3102                `.<letter>', this can be mistaken as a size suffix.  Put
3103                the name in parentheses.  */
3104             if (GET_CODE (addr) == SYMBOL_REF
3105                 && strlen (XSTR (addr, 0)) > 2
3106                 && XSTR (addr, 0)[strlen (XSTR (addr, 0)) - 2] == '.')
3107               {
3108                 putc ('(', file);
3109                 output_addr_const (file, addr);
3110                 putc (')', file);
3111               }
3112             else
3113               output_addr_const (file, addr);
3114           }
3115         break;
3116     }
3117 }
3118 \f
3119 /* Check for cases where a clr insns can be omitted from code using
3120    strict_low_part sets.  For example, the second clrl here is not needed:
3121    clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3122
3123    MODE is the mode of this STRICT_LOW_PART set.  FIRST_INSN is the clear
3124    insn we are checking for redundancy.  TARGET is the register set by the
3125    clear insn.  */
3126
3127 int
3128 strict_low_part_peephole_ok (mode, first_insn, target)
3129      enum machine_mode mode;
3130      rtx first_insn;
3131      rtx target;
3132 {
3133   rtx p;
3134
3135   p = prev_nonnote_insn (first_insn);
3136
3137   while (p)
3138     {
3139       /* If it isn't an insn, then give up.  */
3140       if (GET_CODE (p) != INSN)
3141         return 0;
3142
3143       if (reg_set_p (target, p))
3144         {
3145           rtx set = single_set (p);
3146           rtx dest;
3147
3148           /* If it isn't an easy to recognize insn, then give up.  */
3149           if (! set)
3150             return 0;
3151
3152           dest = SET_DEST (set);
3153
3154           /* If this sets the entire target register to zero, then our
3155              first_insn is redundant.  */
3156           if (rtx_equal_p (dest, target)
3157               && SET_SRC (set) == const0_rtx)
3158             return 1;
3159           else if (GET_CODE (dest) == STRICT_LOW_PART
3160                    && GET_CODE (XEXP (dest, 0)) == REG
3161                    && REGNO (XEXP (dest, 0)) == REGNO (target)
3162                    && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0)))
3163                        <= GET_MODE_SIZE (mode)))
3164             /* This is a strict low part set which modifies less than
3165                we are using, so it is safe.  */
3166             ;
3167           else
3168             return 0;
3169         }
3170
3171       p = prev_nonnote_insn (p);
3172
3173     }
3174
3175   return 0;
3176 }
3177
3178 /* Accept integer operands in the range 0..0xffffffff.  We have to check the
3179    range carefully since this predicate is used in DImode contexts.  Also, we
3180    need some extra crud to make it work when hosted on 64-bit machines.  */
3181
3182 int
3183 const_uint32_operand (op, mode)
3184      rtx op;
3185      enum machine_mode mode;
3186 {
3187   /* It doesn't make sense to ask this question with a mode that is
3188      not larger than 32 bits.  */
3189   if (GET_MODE_BITSIZE (mode) <= 32)
3190     abort ();
3191
3192 #if HOST_BITS_PER_WIDE_INT > 32
3193   /* All allowed constants will fit a CONST_INT.  */
3194   return (GET_CODE (op) == CONST_INT
3195           && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
3196 #else
3197   return (GET_CODE (op) == CONST_INT
3198           || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
3199 #endif
3200 }
3201
3202 /* Accept integer operands in the range -0x80000000..0x7fffffff.  We have
3203    to check the range carefully since this predicate is used in DImode
3204    contexts.  */
3205
3206 int
3207 const_sint32_operand (op, mode)
3208      rtx op;
3209      enum machine_mode mode;
3210 {
3211   /* It doesn't make sense to ask this question with a mode that is
3212      not larger than 32 bits.  */
3213   if (GET_MODE_BITSIZE (mode) <= 32)
3214     abort ();
3215
3216   /* All allowed constants will fit a CONST_INT.  */
3217   return (GET_CODE (op) == CONST_INT
3218           && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
3219 }
3220
3221 /* Operand predicates for implementing asymmetric pc-relative addressing
3222    on m68k.  The m68k supports pc-relative addressing (mode 7, register 2)
3223    when used as a source operand, but not as a destination operand.
3224
3225    We model this by restricting the meaning of the basic predicates
3226    (general_operand, memory_operand, etc) to forbid the use of this
3227    addressing mode, and then define the following predicates that permit
3228    this addressing mode.  These predicates can then be used for the
3229    source operands of the appropriate instructions.
3230
3231    n.b.  While it is theoretically possible to change all machine patterns
3232    to use this addressing more where permitted by the architecture,
3233    it has only been implemented for "common" cases: SImode, HImode, and
3234    QImode operands, and only for the principle operations that would
3235    require this addressing mode: data movement and simple integer operations.
3236
3237    In parallel with these new predicates, two new constraint letters
3238    were defined: 'S' and 'T'.  'S' is the -mpcrel analog of 'm'.
3239    'T' replaces 's' in the non-pcrel case.  It is a no-op in the pcrel case.
3240    In the pcrel case 's' is only valid in combination with 'a' registers.
3241    See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3242    of how these constraints are used.
3243
3244    The use of these predicates is strictly optional, though patterns that
3245    don't will cause an extra reload register to be allocated where one
3246    was not necessary:
3247
3248         lea (abc:w,%pc),%a0     ; need to reload address
3249         moveq &1,%d1            ; since write to pc-relative space
3250         movel %d1,%a0@          ; is not allowed
3251         ...
3252         lea (abc:w,%pc),%a1     ; no need to reload address here
3253         movel %a1@,%d0          ; since "movel (abc:w,%pc),%d0" is ok
3254
3255    For more info, consult tiemann@cygnus.com.
3256
3257
3258    All of the ugliness with predicates and constraints is due to the
3259    simple fact that the m68k does not allow a pc-relative addressing
3260    mode as a destination.  gcc does not distinguish between source and
3261    destination addresses.  Hence, if we claim that pc-relative address
3262    modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3263    end up with invalid code.  To get around this problem, we left
3264    pc-relative modes as invalid addresses, and then added special
3265    predicates and constraints to accept them.
3266
3267    A cleaner way to handle this is to modify gcc to distinguish
3268    between source and destination addresses.  We can then say that
3269    pc-relative is a valid source address but not a valid destination
3270    address, and hopefully avoid a lot of the predicate and constraint
3271    hackery.  Unfortunately, this would be a pretty big change.  It would
3272    be a useful change for a number of ports, but there aren't any current
3273    plans to undertake this.
3274
3275    ***************************************************************************/
3276
3277
3278 /* Special case of a general operand that's used as a source operand.
3279    Use this to permit reads from PC-relative memory when -mpcrel
3280    is specified.  */
3281
3282 int
3283 general_src_operand (op, mode)
3284      rtx op;
3285      enum machine_mode mode;
3286 {
3287   if (TARGET_PCREL
3288       && 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 general_operand (op, mode);
3294 }
3295
3296 /* Special case of a nonimmediate operand that's used as a source.
3297    Use this to permit reads from PC-relative memory when -mpcrel
3298    is specified.  */
3299
3300 int
3301 nonimmediate_src_operand (op, mode)
3302      rtx op;
3303      enum machine_mode mode;
3304 {
3305   if (TARGET_PCREL && GET_CODE (op) == MEM
3306       && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3307           || GET_CODE (XEXP (op, 0)) == LABEL_REF
3308           || GET_CODE (XEXP (op, 0)) == CONST))
3309     return 1;
3310   return nonimmediate_operand (op, mode);
3311 }
3312
3313 /* Special case of a memory operand that's used as a source.
3314    Use this to permit reads from PC-relative memory when -mpcrel
3315    is specified.  */
3316
3317 int
3318 memory_src_operand (op, mode)
3319      rtx op;
3320      enum machine_mode mode;
3321 {
3322   if (TARGET_PCREL && GET_CODE (op) == MEM
3323       && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3324           || GET_CODE (XEXP (op, 0)) == LABEL_REF
3325           || GET_CODE (XEXP (op, 0)) == CONST))
3326     return 1;
3327   return memory_operand (op, mode);
3328 }
3329
3330 /* Predicate that accepts only a pc-relative address.  This is needed
3331    because pc-relative addresses don't satisfy the predicate
3332    "general_src_operand".  */
3333
3334 int
3335 pcrel_address (op, mode)
3336      rtx op;
3337      enum machine_mode mode ATTRIBUTE_UNUSED;
3338 {
3339   return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF
3340           || GET_CODE (op) == CONST);
3341 }
3342
3343 const char *
3344 output_andsi3 (operands)
3345      rtx *operands;
3346 {
3347   int logval;
3348   if (GET_CODE (operands[2]) == CONST_INT
3349       && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
3350       && (DATA_REG_P (operands[0])
3351           || offsettable_memref_p (operands[0]))
3352       && !TARGET_5200)
3353     {
3354       if (GET_CODE (operands[0]) != REG)
3355         operands[0] = adjust_address (operands[0], HImode, 2);
3356       operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
3357       /* Do not delete a following tstl %0 insn; that would be incorrect.  */
3358       CC_STATUS_INIT;
3359       if (operands[2] == const0_rtx)
3360         return "clr%.w %0";
3361       return "and%.w %2,%0";
3362     }
3363   if (GET_CODE (operands[2]) == CONST_INT
3364       && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
3365       && (DATA_REG_P (operands[0])
3366           || offsettable_memref_p (operands[0])))
3367     {
3368       if (DATA_REG_P (operands[0]))
3369         {
3370           operands[1] = GEN_INT (logval);
3371         }
3372       else
3373         {
3374           operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3375           operands[1] = GEN_INT (logval % 8);
3376         }
3377       /* This does not set condition codes in a standard way.  */
3378       CC_STATUS_INIT;
3379       return "bclr %1,%0";
3380     }
3381   return "and%.l %2,%0";
3382 }
3383
3384 const char *
3385 output_iorsi3 (operands)
3386      rtx *operands;
3387 {
3388   register int logval;
3389   if (GET_CODE (operands[2]) == CONST_INT
3390       && INTVAL (operands[2]) >> 16 == 0
3391       && (DATA_REG_P (operands[0])
3392           || offsettable_memref_p (operands[0]))
3393       && !TARGET_5200)
3394     {
3395       if (GET_CODE (operands[0]) != REG)
3396         operands[0] = adjust_address (operands[0], HImode, 2);
3397       /* Do not delete a following tstl %0 insn; that would be incorrect.  */
3398       CC_STATUS_INIT;
3399       if (INTVAL (operands[2]) == 0xffff)
3400         return "mov%.w %2,%0";
3401       return "or%.w %2,%0";
3402     }
3403   if (GET_CODE (operands[2]) == CONST_INT
3404       && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3405       && (DATA_REG_P (operands[0])
3406           || offsettable_memref_p (operands[0])))
3407     {
3408       if (DATA_REG_P (operands[0]))
3409         operands[1] = GEN_INT (logval);
3410       else
3411         {
3412           operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3413           operands[1] = GEN_INT (logval % 8);
3414         }
3415       CC_STATUS_INIT;
3416       return "bset %1,%0";
3417     }
3418   return "or%.l %2,%0";
3419 }
3420
3421 const char *
3422 output_xorsi3 (operands)
3423      rtx *operands;
3424 {
3425   register int logval;
3426   if (GET_CODE (operands[2]) == CONST_INT
3427       && INTVAL (operands[2]) >> 16 == 0
3428       && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))
3429       && !TARGET_5200)
3430     {
3431       if (! DATA_REG_P (operands[0]))
3432         operands[0] = adjust_address (operands[0], HImode, 2);
3433       /* Do not delete a following tstl %0 insn; that would be incorrect.  */
3434       CC_STATUS_INIT;
3435       if (INTVAL (operands[2]) == 0xffff)
3436         return "not%.w %0";
3437       return "eor%.w %2,%0";
3438     }
3439   if (GET_CODE (operands[2]) == CONST_INT
3440       && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3441       && (DATA_REG_P (operands[0])
3442           || offsettable_memref_p (operands[0])))
3443     {
3444       if (DATA_REG_P (operands[0]))
3445         operands[1] = GEN_INT (logval);
3446       else
3447         {
3448           operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3449           operands[1] = GEN_INT (logval % 8);
3450         }
3451       CC_STATUS_INIT;
3452       return "bchg %1,%0";
3453     }
3454   return "eor%.l %2,%0";
3455 }
3456
3457 /* Output assembly to switch to section NAME with attribute FLAGS.  */
3458
3459 static void
3460 m68k_coff_asm_named_section (name, flags)
3461      const char *name;
3462      unsigned int flags;
3463 {
3464   char flagchar;
3465
3466   if (flags & SECTION_WRITE)
3467     flagchar = 'd';
3468   else
3469     flagchar = 'x';
3470
3471   fprintf (asm_out_file, "\t.section\t%s,\"%c\"\n", name, flagchar);
3472 }
3473
3474 #ifdef CTOR_LIST_BEGIN
3475 static void
3476 m68k_svr3_asm_out_constructor (symbol, priority)
3477      rtx symbol;
3478      int priority ATTRIBUTE_UNUSED;
3479 {
3480   rtx xop[2];
3481
3482   xop[1] = symbol;
3483   xop[0] = gen_rtx_MEM (SImode, gen_rtx_PRE_DEC (SImode, stack_pointer_rtx));
3484
3485   init_section ();
3486   output_asm_insn (output_move_simode (xop), xop);
3487 }
3488 #endif
3489
3490 #ifdef HPUX_ASM
3491 static void
3492 m68k_hp320_internal_label (stream, prefix, labelno)
3493      FILE *stream;
3494      const char *prefix;
3495      unsigned long labelno;
3496 {
3497   if (prefix[0] == 'L' && prefix[1] == 'I')
3498     fprintf(stream, "\tset %s%ld,.+2\n", prefix, labelno);
3499   else
3500     fprintf (stream, "%s%ld:\n", prefix, labelno);
3501 }
3502
3503 static void
3504 m68k_hp320_file_start ()
3505 {
3506   /* version 1: 68010.
3507              2: 68020 without FPU.
3508              3: 68020 with FPU.  */
3509   fprintf (asm_out_file, "\tversion %d\n",
3510            TARGET_68020 ? (TARGET_68881 ? 3 : 2) : 1);
3511 }
3512 #endif
3513
3514 static void
3515 m68k_output_mi_thunk (file, thunk, delta, vcall_offset, function)
3516      FILE *file;
3517      tree thunk ATTRIBUTE_UNUSED;
3518      HOST_WIDE_INT delta;
3519      HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
3520      tree function;
3521 {
3522   rtx xops[1];
3523   const char *fmt;
3524
3525   if (delta > 0 && delta <= 8)
3526 #ifdef MOTOROLA
3527     asm_fprintf (file, "\taddq.l %I%d,4(%Rsp)\n", (int) delta);
3528 #else
3529     asm_fprintf (file, "\taddql %I%d,%Rsp@(4)\n", (int) delta);
3530 #endif
3531   else if (delta < 0 && delta >= -8)
3532 #ifdef MOTOROLA
3533     asm_fprintf (file, "\tsubq.l %I%d,4(%Rsp)\n", (int) -delta);
3534 #else
3535     asm_fprintf (file, "\tsubql %I%d,%Rsp@(4)\n", (int) -delta);
3536 #endif
3537   else
3538 #ifdef MOTOROLA
3539     asm_fprintf (file, "\tadd.l %I%wd,4(%Rsp)\n", delta);
3540 #else
3541     asm_fprintf (file, "\taddl %I%wd,%Rsp@(4)\n", delta);
3542 #endif
3543
3544   xops[0] = DECL_RTL (function);
3545
3546   /* Logic taken from call patterns in m68k.md.  */
3547   if (flag_pic)
3548     {
3549       if (TARGET_PCREL)
3550         fmt = "bra.l %o0";
3551       else
3552         {
3553 #ifdef MOTOROLA
3554 #ifdef HPUX_ASM
3555           fmt = "bra.l %0";
3556 #else
3557 #ifdef USE_GAS
3558           fmt = "bra.l %0@PLTPC";
3559 #else
3560           fmt = "bra %0@PLTPC";
3561 #endif
3562 #endif
3563 #else
3564 #ifdef USE_GAS
3565           fmt = "bra.l %0";
3566 #else
3567           fmt = "jra %0,a1";
3568 #endif
3569 #endif
3570         }
3571     }
3572   else
3573     {
3574 #if defined (MOTOROLA) && !defined (USE_GAS)
3575       fmt = "jmp %0";
3576 #else
3577       fmt = "jra %0";
3578 #endif
3579     }
3580
3581   output_asm_insn (fmt, xops);
3582 }