OSDN Git Service

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