OSDN Git Service

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