OSDN Git Service

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