OSDN Git Service

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