OSDN Git Service

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