OSDN Git Service

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