OSDN Git Service

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