OSDN Git Service

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