OSDN Git Service

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