OSDN Git Service

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