OSDN Git Service

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