OSDN Git Service

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