OSDN Git Service

e304a655962bebc6c5450425df73b2ce809fe593
[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 : 13)
1511 #define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : 5)
1512 #define DIVW_COST (TARGET_68020 ? 27 : 12)
1513
1514     case PLUS:
1515       /* An lea costs about three times as much as a simple add.  */
1516       if (GET_MODE (x) == SImode
1517           && GET_CODE (XEXP (x, 1)) == REG
1518           && GET_CODE (XEXP (x, 0)) == MULT
1519           && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
1520           && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1521           && (INTVAL (XEXP (XEXP (x, 0), 1)) == 2
1522               || INTVAL (XEXP (XEXP (x, 0), 1)) == 4
1523               || INTVAL (XEXP (XEXP (x, 0), 1)) == 8))
1524         *total = COSTS_N_INSNS (3);      /* lea an@(dx:l:i),am */
1525       return false;
1526
1527     case ASHIFT:
1528     case ASHIFTRT:
1529     case LSHIFTRT:
1530       if (TARGET_68060)
1531         {
1532           *total = COSTS_N_INSNS(1);
1533           return true;
1534         }
1535       if (! TARGET_68020)
1536         {
1537           if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1538             {
1539               if (INTVAL (XEXP (x, 1)) < 16)
1540                 *total = COSTS_N_INSNS (2) + INTVAL (XEXP (x, 1)) / 2;
1541               else
1542                 /* We're using clrw + swap for these cases.  */
1543                 *total = COSTS_N_INSNS (4) + (INTVAL (XEXP (x, 1)) - 16) / 2;
1544             }
1545           else
1546             *total = COSTS_N_INSNS (10); /* worst case */
1547           return true;
1548         }
1549       /* A shift by a big integer takes an extra instruction.  */
1550       if (GET_CODE (XEXP (x, 1)) == CONST_INT
1551           && (INTVAL (XEXP (x, 1)) == 16))
1552         {
1553           *total = COSTS_N_INSNS (2);    /* clrw;swap */
1554           return true;
1555         }
1556       if (GET_CODE (XEXP (x, 1)) == CONST_INT
1557           && !(INTVAL (XEXP (x, 1)) > 0
1558                && INTVAL (XEXP (x, 1)) <= 8))
1559         {
1560           *total = COSTS_N_INSNS (3);    /* lsr #i,dn */
1561           return true;
1562         }
1563       return false;
1564
1565     case MULT:
1566       if ((GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
1567            || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
1568           && GET_MODE (x) == SImode)
1569         *total = COSTS_N_INSNS (MULW_COST);
1570       else if (GET_MODE (x) == QImode || GET_MODE (x) == HImode)
1571         *total = COSTS_N_INSNS (MULW_COST);
1572       else
1573         *total = COSTS_N_INSNS (MULL_COST);
1574       return true;
1575
1576     case DIV:
1577     case UDIV:
1578     case MOD:
1579     case UMOD:
1580       if (GET_MODE (x) == QImode || GET_MODE (x) == HImode)
1581         *total = COSTS_N_INSNS (DIVW_COST);     /* div.w */
1582       else
1583         *total = COSTS_N_INSNS (43);            /* div.l */
1584       return true;
1585
1586     default:
1587       return false;
1588     }
1589 }
1590
1591 const char *
1592 output_move_const_into_data_reg (operands)
1593      rtx *operands;
1594 {
1595   int i;
1596
1597   i = INTVAL (operands[1]);
1598   switch (const_method (operands[1]))
1599     {
1600     case MOVQ :
1601       return "moveq %1,%0";
1602     case NOTB :
1603       operands[1] = GEN_INT (i ^ 0xff);
1604       return "moveq %1,%0\n\tnot%.b %0";
1605     case NOTW :
1606       operands[1] = GEN_INT (i ^ 0xffff);
1607       return "moveq %1,%0\n\tnot%.w %0";
1608     case NEGW :
1609       return "moveq %#-128,%0\n\tneg%.w %0";
1610     case SWAP :
1611       {
1612         unsigned u = i;
1613
1614         operands[1] = GEN_INT ((u << 16) | (u >> 16));
1615         return "moveq %1,%0\n\tswap %0";
1616       }
1617     case MOVL :
1618         return "move%.l %1,%0";
1619     default :
1620         abort ();
1621     }
1622 }
1623
1624 const char *
1625 output_move_simode_const (operands)
1626      rtx *operands;
1627 {
1628   if (operands[1] == const0_rtx
1629       && (DATA_REG_P (operands[0])
1630           || GET_CODE (operands[0]) == MEM)
1631       /* clr insns on 68000 read before writing.
1632          This isn't so on the 68010, but we have no TARGET_68010.  */
1633       && ((TARGET_68020 || TARGET_COLDFIRE)
1634           || !(GET_CODE (operands[0]) == MEM
1635                && MEM_VOLATILE_P (operands[0]))))
1636     return "clr%.l %0";
1637   else if (operands[1] == const0_rtx
1638            && ADDRESS_REG_P (operands[0]))
1639     return "sub%.l %0,%0";
1640   else if (DATA_REG_P (operands[0]))
1641     return output_move_const_into_data_reg (operands);
1642   else if (ADDRESS_REG_P (operands[0])
1643            && INTVAL (operands[1]) < 0x8000
1644            && INTVAL (operands[1]) >= -0x8000)
1645     return "move%.w %1,%0";
1646   else if (GET_CODE (operands[0]) == MEM
1647       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1648       && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1649            && INTVAL (operands[1]) < 0x8000
1650            && INTVAL (operands[1]) >= -0x8000)
1651     return "pea %a1";
1652   return "move%.l %1,%0";
1653 }
1654
1655 const char *
1656 output_move_simode (operands)
1657      rtx *operands;
1658 {
1659   if (GET_CODE (operands[1]) == CONST_INT)
1660     return output_move_simode_const (operands);
1661   else if ((GET_CODE (operands[1]) == SYMBOL_REF
1662             || GET_CODE (operands[1]) == CONST)
1663            && push_operand (operands[0], SImode))
1664     return "pea %a1";
1665   else if ((GET_CODE (operands[1]) == SYMBOL_REF
1666             || GET_CODE (operands[1]) == CONST)
1667            && ADDRESS_REG_P (operands[0]))
1668     return "lea %a1,%0";
1669   return "move%.l %1,%0";
1670 }
1671
1672 const char *
1673 output_move_himode (operands)
1674      rtx *operands;
1675 {
1676  if (GET_CODE (operands[1]) == CONST_INT)
1677     {
1678       if (operands[1] == const0_rtx
1679           && (DATA_REG_P (operands[0])
1680               || GET_CODE (operands[0]) == MEM)
1681           /* clr insns on 68000 read before writing.
1682              This isn't so on the 68010, but we have no TARGET_68010.  */
1683           && ((TARGET_68020 || TARGET_COLDFIRE)
1684               || !(GET_CODE (operands[0]) == MEM
1685                    && MEM_VOLATILE_P (operands[0]))))
1686         return "clr%.w %0";
1687       else if (operands[1] == const0_rtx
1688                && ADDRESS_REG_P (operands[0]))
1689         return "sub%.l %0,%0";
1690       else if (DATA_REG_P (operands[0])
1691                && INTVAL (operands[1]) < 128
1692                && INTVAL (operands[1]) >= -128)
1693         {
1694           return "moveq %1,%0";
1695         }
1696       else if (INTVAL (operands[1]) < 0x8000
1697                && INTVAL (operands[1]) >= -0x8000)
1698         return "move%.w %1,%0";
1699     }
1700   else if (CONSTANT_P (operands[1]))
1701     return "move%.l %1,%0";
1702   /* Recognize the insn before a tablejump, one that refers
1703      to a table of offsets.  Such an insn will need to refer
1704      to a label on the insn.  So output one.  Use the label-number
1705      of the table of offsets to generate this label.  This code,
1706      and similar code below, assumes that there will be at most one
1707      reference to each table.  */
1708   if (GET_CODE (operands[1]) == MEM
1709       && GET_CODE (XEXP (operands[1], 0)) == PLUS
1710       && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF
1711       && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS)
1712     {
1713       rtx labelref = XEXP (XEXP (operands[1], 0), 1);
1714 #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
1715 #ifdef SGS
1716       asm_fprintf (asm_out_file, "\tset %LLI%d,.+2\n",
1717                    CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1718 #else /* not SGS */
1719       asm_fprintf (asm_out_file, "\t.set %LLI%d,.+2\n",
1720                    CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1721 #endif /* not SGS */
1722 #else /* SGS_SWITCH_TABLES or not MOTOROLA */
1723       (*targetm.asm_out.internal_label) (asm_out_file, "LI",
1724                                  CODE_LABEL_NUMBER (XEXP (labelref, 0)));
1725 #ifdef SGS_SWITCH_TABLES
1726       /* Set flag saying we need to define the symbol
1727          LD%n (with value L%n-LI%n) at the end of the switch table.  */
1728       switch_table_difference_label_flag = 1;
1729 #endif /* SGS_SWITCH_TABLES */
1730 #endif /* SGS_SWITCH_TABLES or not MOTOROLA */
1731     }
1732   return "move%.w %1,%0";
1733 }
1734
1735 const char *
1736 output_move_qimode (operands)
1737      rtx *operands;
1738 {
1739   rtx xoperands[4];
1740
1741   /* This is probably useless, since it loses for pushing a struct
1742      of several bytes a byte at a time.  */
1743   /* 68k family always modifies the stack pointer by at least 2, even for
1744      byte pushes.  The 5200 (coldfire) does not do this.  */
1745   if (GET_CODE (operands[0]) == MEM
1746       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1747       && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx
1748       && ! ADDRESS_REG_P (operands[1])
1749       && ! TARGET_COLDFIRE)
1750     {
1751       xoperands[1] = operands[1];
1752       xoperands[2]
1753         = gen_rtx_MEM (QImode,
1754                        gen_rtx_PLUS (VOIDmode, stack_pointer_rtx, const1_rtx));
1755       /* Just pushing a byte puts it in the high byte of the halfword.  */
1756       /* We must put it in the low-order, high-numbered byte.  */
1757       if (!reg_mentioned_p (stack_pointer_rtx, operands[1]))
1758         {
1759           xoperands[3] = stack_pointer_rtx;
1760           output_asm_insn ("subq%.l %#2,%3\n\tmove%.b %1,%2", xoperands);
1761         }
1762       else
1763         output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands);
1764       return "";
1765     }
1766
1767   /* clr and st insns on 68000 read before writing.
1768      This isn't so on the 68010, but we have no TARGET_68010.  */
1769   if (!ADDRESS_REG_P (operands[0])
1770       && ((TARGET_68020 || TARGET_COLDFIRE)
1771           || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1772     {
1773       if (operands[1] == const0_rtx)
1774         return "clr%.b %0";
1775       if ((!TARGET_COLDFIRE || DATA_REG_P (operands[0]))
1776           && GET_CODE (operands[1]) == CONST_INT
1777           && (INTVAL (operands[1]) & 255) == 255)
1778         {
1779           CC_STATUS_INIT;
1780           return "st %0";
1781         }
1782     }
1783   if (GET_CODE (operands[1]) == CONST_INT
1784       && DATA_REG_P (operands[0])
1785       && INTVAL (operands[1]) < 128
1786       && INTVAL (operands[1]) >= -128)
1787     {
1788       return "moveq %1,%0";
1789     }
1790   if (operands[1] == const0_rtx && ADDRESS_REG_P (operands[0]))
1791     return "sub%.l %0,%0";
1792   if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
1793     return "move%.l %1,%0";
1794   /* 68k family (including the 5200 coldfire) does not support byte moves to
1795      from address registers.  */
1796   if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
1797     return "move%.w %1,%0";
1798   return "move%.b %1,%0";
1799 }
1800
1801 const char *
1802 output_move_stricthi (operands)
1803      rtx *operands;
1804 {
1805   if (operands[1] == const0_rtx
1806       /* clr insns on 68000 read before writing.
1807          This isn't so on the 68010, but we have no TARGET_68010.  */
1808       && ((TARGET_68020 || TARGET_COLDFIRE)
1809           || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1810     return "clr%.w %0";
1811   return "move%.w %1,%0";
1812 }
1813
1814 const char *
1815 output_move_strictqi (operands)
1816      rtx *operands;
1817 {
1818   if (operands[1] == const0_rtx
1819       /* clr insns on 68000 read before writing.
1820          This isn't so on the 68010, but we have no TARGET_68010.  */
1821       && ((TARGET_68020 || TARGET_COLDFIRE)
1822           || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1823     return "clr%.b %0";
1824   return "move%.b %1,%0";
1825 }
1826
1827 /* Return the best assembler insn template
1828    for moving operands[1] into operands[0] as a fullword.  */
1829
1830 static const char *
1831 singlemove_string (operands)
1832      rtx *operands;
1833 {
1834   if (GET_CODE (operands[1]) == CONST_INT)
1835     return output_move_simode_const (operands);
1836   return "move%.l %1,%0";
1837 }
1838
1839
1840 /* Output assembler code to perform a doubleword move insn
1841    with operands OPERANDS.  */
1842
1843 const char *
1844 output_move_double (operands)
1845      rtx *operands;
1846 {
1847   enum
1848     {
1849       REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP
1850     } optype0, optype1;
1851   rtx latehalf[2];
1852   rtx middlehalf[2];
1853   rtx xops[2];
1854   rtx addreg0 = 0, addreg1 = 0;
1855   int dest_overlapped_low = 0;
1856   int size = GET_MODE_SIZE (GET_MODE (operands[0]));
1857
1858   middlehalf[0] = 0;
1859   middlehalf[1] = 0;
1860
1861   /* First classify both operands.  */
1862
1863   if (REG_P (operands[0]))
1864     optype0 = REGOP;
1865   else if (offsettable_memref_p (operands[0]))
1866     optype0 = OFFSOP;
1867   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1868     optype0 = POPOP;
1869   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1870     optype0 = PUSHOP;
1871   else if (GET_CODE (operands[0]) == MEM)
1872     optype0 = MEMOP;
1873   else
1874     optype0 = RNDOP;
1875
1876   if (REG_P (operands[1]))
1877     optype1 = REGOP;
1878   else if (CONSTANT_P (operands[1]))
1879     optype1 = CNSTOP;
1880   else if (offsettable_memref_p (operands[1]))
1881     optype1 = OFFSOP;
1882   else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
1883     optype1 = POPOP;
1884   else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1885     optype1 = PUSHOP;
1886   else if (GET_CODE (operands[1]) == MEM)
1887     optype1 = MEMOP;
1888   else
1889     optype1 = RNDOP;
1890
1891   /* Check for the cases that the operand constraints are not
1892      supposed to allow to happen.  Abort if we get one,
1893      because generating code for these cases is painful.  */
1894
1895   if (optype0 == RNDOP || optype1 == RNDOP)
1896     abort ();
1897
1898   /* If one operand is decrementing and one is incrementing
1899      decrement the former register explicitly
1900      and change that operand into ordinary indexing.  */
1901
1902   if (optype0 == PUSHOP && optype1 == POPOP)
1903     {
1904       operands[0] = XEXP (XEXP (operands[0], 0), 0);
1905       if (size == 12)
1906         output_asm_insn ("sub%.l %#12,%0", operands);
1907       else
1908         output_asm_insn ("subq%.l %#8,%0", operands);
1909       if (GET_MODE (operands[1]) == XFmode)
1910         operands[0] = gen_rtx_MEM (XFmode, operands[0]);
1911       else if (GET_MODE (operands[0]) == DFmode)
1912         operands[0] = gen_rtx_MEM (DFmode, operands[0]);
1913       else
1914         operands[0] = gen_rtx_MEM (DImode, operands[0]);
1915       optype0 = OFFSOP;
1916     }
1917   if (optype0 == POPOP && optype1 == PUSHOP)
1918     {
1919       operands[1] = XEXP (XEXP (operands[1], 0), 0);
1920       if (size == 12)
1921         output_asm_insn ("sub%.l %#12,%1", operands);
1922       else
1923         output_asm_insn ("subq%.l %#8,%1", operands);
1924       if (GET_MODE (operands[1]) == XFmode)
1925         operands[1] = gen_rtx_MEM (XFmode, operands[1]);
1926       else if (GET_MODE (operands[1]) == DFmode)
1927         operands[1] = gen_rtx_MEM (DFmode, operands[1]);
1928       else
1929         operands[1] = gen_rtx_MEM (DImode, operands[1]);
1930       optype1 = OFFSOP;
1931     }
1932
1933   /* If an operand is an unoffsettable memory ref, find a register
1934      we can increment temporarily to make it refer to the second word.  */
1935
1936   if (optype0 == MEMOP)
1937     addreg0 = find_addr_reg (XEXP (operands[0], 0));
1938
1939   if (optype1 == MEMOP)
1940     addreg1 = find_addr_reg (XEXP (operands[1], 0));
1941
1942   /* Ok, we can do one word at a time.
1943      Normally we do the low-numbered word first,
1944      but if either operand is autodecrementing then we
1945      do the high-numbered word first.
1946
1947      In either case, set up in LATEHALF the operands to use
1948      for the high-numbered word and in some cases alter the
1949      operands in OPERANDS to be suitable for the low-numbered word.  */
1950
1951   if (size == 12)
1952     {
1953       if (optype0 == REGOP)
1954         {
1955           latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
1956           middlehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1957         }
1958       else if (optype0 == OFFSOP)
1959         {
1960           middlehalf[0] = adjust_address (operands[0], SImode, 4);
1961           latehalf[0] = adjust_address (operands[0], SImode, size - 4);
1962         }
1963       else
1964         {
1965           middlehalf[0] = operands[0];
1966           latehalf[0] = operands[0];
1967         }
1968
1969       if (optype1 == REGOP)
1970         {
1971           latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1972           middlehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1973         }
1974       else if (optype1 == OFFSOP)
1975         {
1976           middlehalf[1] = adjust_address (operands[1], SImode, 4);
1977           latehalf[1] = adjust_address (operands[1], SImode, size - 4);
1978         }
1979       else if (optype1 == CNSTOP)
1980         {
1981           if (GET_CODE (operands[1]) == CONST_DOUBLE)
1982             {
1983               REAL_VALUE_TYPE r;
1984               long l[3];
1985
1986               REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1987               REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
1988               operands[1] = GEN_INT (l[0]);
1989               middlehalf[1] = GEN_INT (l[1]);
1990               latehalf[1] = GEN_INT (l[2]);
1991             }
1992           else if (CONSTANT_P (operands[1]))
1993             {
1994               /* actually, no non-CONST_DOUBLE constant should ever
1995                  appear here.  */
1996               abort ();
1997               if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
1998                 latehalf[1] = constm1_rtx;
1999               else
2000                 latehalf[1] = const0_rtx;
2001             }
2002         }
2003       else
2004         {
2005           middlehalf[1] = operands[1];
2006           latehalf[1] = operands[1];
2007         }
2008     }
2009   else
2010     /* size is not 12: */
2011     {
2012       if (optype0 == REGOP)
2013         latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2014       else if (optype0 == OFFSOP)
2015         latehalf[0] = adjust_address (operands[0], SImode, size - 4);
2016       else
2017         latehalf[0] = operands[0];
2018
2019       if (optype1 == REGOP)
2020         latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2021       else if (optype1 == OFFSOP)
2022         latehalf[1] = adjust_address (operands[1], SImode, size - 4);
2023       else if (optype1 == CNSTOP)
2024         split_double (operands[1], &operands[1], &latehalf[1]);
2025       else
2026         latehalf[1] = operands[1];
2027     }
2028
2029   /* If insn is effectively movd N(sp),-(sp) then we will do the
2030      high word first.  We should use the adjusted operand 1 (which is N+4(sp))
2031      for the low word as well, to compensate for the first decrement of sp.  */
2032   if (optype0 == PUSHOP
2033       && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
2034       && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
2035     operands[1] = middlehalf[1] = latehalf[1];
2036
2037   /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
2038      if the upper part of reg N does not appear in the MEM, arrange to
2039      emit the move late-half first.  Otherwise, compute the MEM address
2040      into the upper part of N and use that as a pointer to the memory
2041      operand.  */
2042   if (optype0 == REGOP
2043       && (optype1 == OFFSOP || optype1 == MEMOP))
2044     {
2045       rtx testlow = gen_rtx_REG (SImode, REGNO (operands[0]));
2046
2047       if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
2048           && reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2049         {
2050           /* If both halves of dest are used in the src memory address,
2051              compute the address into latehalf of dest.
2052              Note that this can't happen if the dest is two data regs.  */
2053 compadr:
2054           xops[0] = latehalf[0];
2055           xops[1] = XEXP (operands[1], 0);
2056           output_asm_insn ("lea %a1,%0", xops);
2057           if (GET_MODE (operands[1]) == XFmode )
2058             {
2059               operands[1] = gen_rtx_MEM (XFmode, latehalf[0]);
2060               middlehalf[1] = adjust_address (operands[1], DImode, size - 8);
2061               latehalf[1] = adjust_address (operands[1], DImode, size - 4);
2062             }
2063           else
2064             {
2065               operands[1] = gen_rtx_MEM (DImode, latehalf[0]);
2066               latehalf[1] = adjust_address (operands[1], DImode, size - 4);
2067             }
2068         }
2069       else if (size == 12
2070                && reg_overlap_mentioned_p (middlehalf[0],
2071                                            XEXP (operands[1], 0)))
2072         {
2073           /* Check for two regs used by both source and dest.
2074              Note that this can't happen if the dest is all data regs.
2075              It can happen if the dest is d6, d7, a0.
2076              But in that case, latehalf is an addr reg, so
2077              the code at compadr does ok.  */
2078
2079           if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
2080               || reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
2081             goto compadr;
2082
2083           /* JRV says this can't happen: */
2084           if (addreg0 || addreg1)
2085             abort ();
2086
2087           /* Only the middle reg conflicts; simply put it last.  */
2088           output_asm_insn (singlemove_string (operands), operands);
2089           output_asm_insn (singlemove_string (latehalf), latehalf);
2090           output_asm_insn (singlemove_string (middlehalf), middlehalf);
2091           return "";
2092         }
2093       else if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0)))
2094         /* If the low half of dest is mentioned in the source memory
2095            address, the arrange to emit the move late half first.  */
2096         dest_overlapped_low = 1;
2097     }
2098
2099   /* If one or both operands autodecrementing,
2100      do the two words, high-numbered first.  */
2101
2102   /* Likewise,  the first move would clobber the source of the second one,
2103      do them in the other order.  This happens only for registers;
2104      such overlap can't happen in memory unless the user explicitly
2105      sets it up, and that is an undefined circumstance.  */
2106
2107   if (optype0 == PUSHOP || optype1 == PUSHOP
2108       || (optype0 == REGOP && optype1 == REGOP
2109           && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
2110               || REGNO (operands[0]) == REGNO (latehalf[1])))
2111       || dest_overlapped_low)
2112     {
2113       /* Make any unoffsettable addresses point at high-numbered word.  */
2114       if (addreg0)
2115         {
2116           if (size == 12)
2117             output_asm_insn ("addq%.l %#8,%0", &addreg0);
2118           else
2119             output_asm_insn ("addq%.l %#4,%0", &addreg0);
2120         }
2121       if (addreg1)
2122         {
2123           if (size == 12)
2124             output_asm_insn ("addq%.l %#8,%0", &addreg1);
2125           else
2126             output_asm_insn ("addq%.l %#4,%0", &addreg1);
2127         }
2128
2129       /* Do that word.  */
2130       output_asm_insn (singlemove_string (latehalf), latehalf);
2131
2132       /* Undo the adds we just did.  */
2133       if (addreg0)
2134         output_asm_insn ("subq%.l %#4,%0", &addreg0);
2135       if (addreg1)
2136         output_asm_insn ("subq%.l %#4,%0", &addreg1);
2137
2138       if (size == 12)
2139         {
2140           output_asm_insn (singlemove_string (middlehalf), middlehalf);
2141           if (addreg0)
2142             output_asm_insn ("subq%.l %#4,%0", &addreg0);
2143           if (addreg1)
2144             output_asm_insn ("subq%.l %#4,%0", &addreg1);
2145         }
2146
2147       /* Do low-numbered word.  */
2148       return singlemove_string (operands);
2149     }
2150
2151   /* Normal case: do the two words, low-numbered first.  */
2152
2153   output_asm_insn (singlemove_string (operands), operands);
2154
2155   /* Do the middle one of the three words for long double */
2156   if (size == 12)
2157     {
2158       if (addreg0)
2159         output_asm_insn ("addq%.l %#4,%0", &addreg0);
2160       if (addreg1)
2161         output_asm_insn ("addq%.l %#4,%0", &addreg1);
2162
2163       output_asm_insn (singlemove_string (middlehalf), middlehalf);
2164     }
2165
2166   /* Make any unoffsettable addresses point at high-numbered word.  */
2167   if (addreg0)
2168     output_asm_insn ("addq%.l %#4,%0", &addreg0);
2169   if (addreg1)
2170     output_asm_insn ("addq%.l %#4,%0", &addreg1);
2171
2172   /* Do that word.  */
2173   output_asm_insn (singlemove_string (latehalf), latehalf);
2174
2175   /* Undo the adds we just did.  */
2176   if (addreg0)
2177     {
2178       if (size == 12)
2179         output_asm_insn ("subq%.l %#8,%0", &addreg0);
2180       else
2181         output_asm_insn ("subq%.l %#4,%0", &addreg0);
2182     }
2183   if (addreg1)
2184     {
2185       if (size == 12)
2186         output_asm_insn ("subq%.l %#8,%0", &addreg1);
2187       else
2188         output_asm_insn ("subq%.l %#4,%0", &addreg1);
2189     }
2190
2191   return "";
2192 }
2193
2194 /* Return a REG that occurs in ADDR with coefficient 1.
2195    ADDR can be effectively incremented by incrementing REG.  */
2196
2197 static rtx
2198 find_addr_reg (addr)
2199      rtx addr;
2200 {
2201   while (GET_CODE (addr) == PLUS)
2202     {
2203       if (GET_CODE (XEXP (addr, 0)) == REG)
2204         addr = XEXP (addr, 0);
2205       else if (GET_CODE (XEXP (addr, 1)) == REG)
2206         addr = XEXP (addr, 1);
2207       else if (CONSTANT_P (XEXP (addr, 0)))
2208         addr = XEXP (addr, 1);
2209       else if (CONSTANT_P (XEXP (addr, 1)))
2210         addr = XEXP (addr, 0);
2211       else
2212         abort ();
2213     }
2214   if (GET_CODE (addr) == REG)
2215     return addr;
2216   abort ();
2217 }
2218
2219 /* Output assembler code to perform a 32 bit 3 operand add.  */
2220
2221 const char *
2222 output_addsi3 (operands)
2223      rtx *operands;
2224 {
2225   if (! operands_match_p (operands[0], operands[1]))
2226     {
2227       if (!ADDRESS_REG_P (operands[1]))
2228         {
2229           rtx tmp = operands[1];
2230
2231           operands[1] = operands[2];
2232           operands[2] = tmp;
2233         }
2234
2235       /* These insns can result from reloads to access
2236          stack slots over 64k from the frame pointer.  */
2237       if (GET_CODE (operands[2]) == CONST_INT
2238           && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
2239         return "move%.l %2,%0\n\tadd%.l %1,%0";
2240 #ifdef SGS
2241       if (GET_CODE (operands[2]) == REG)
2242         return "lea 0(%1,%2.l),%0";
2243       else
2244         return "lea %c2(%1),%0";
2245 #else /* not SGS */
2246 #ifdef MOTOROLA
2247       if (GET_CODE (operands[2]) == REG)
2248         return "lea (%1,%2.l),%0";
2249       else
2250         return "lea (%c2,%1),%0";
2251 #else /* not MOTOROLA (MIT syntax) */
2252       if (GET_CODE (operands[2]) == REG)
2253         return "lea %1@(0,%2:l),%0";
2254       else
2255         return "lea %1@(%c2),%0";
2256 #endif /* not MOTOROLA */
2257 #endif /* not SGS */
2258     }
2259   if (GET_CODE (operands[2]) == CONST_INT)
2260     {
2261       if (INTVAL (operands[2]) > 0
2262           && INTVAL (operands[2]) <= 8)
2263         return "addq%.l %2,%0";
2264       if (INTVAL (operands[2]) < 0
2265           && INTVAL (operands[2]) >= -8)
2266         {
2267           operands[2] = GEN_INT (- INTVAL (operands[2]));
2268           return "subq%.l %2,%0";
2269         }
2270       /* On the CPU32 it is faster to use two addql instructions to
2271          add a small integer (8 < N <= 16) to a register.
2272          Likewise for subql.  */
2273       if (TARGET_CPU32 && REG_P (operands[0]))
2274         {
2275           if (INTVAL (operands[2]) > 8
2276               && INTVAL (operands[2]) <= 16)
2277             {
2278               operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
2279               return "addq%.l %#8,%0\n\taddq%.l %2,%0";
2280             }
2281           if (INTVAL (operands[2]) < -8
2282               && INTVAL (operands[2]) >= -16)
2283             {
2284               operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
2285               return "subq%.l %#8,%0\n\tsubq%.l %2,%0";
2286             }
2287         }
2288       if (ADDRESS_REG_P (operands[0])
2289           && INTVAL (operands[2]) >= -0x8000
2290           && INTVAL (operands[2]) < 0x8000)
2291         {
2292           if (TARGET_68040)
2293             return "add%.w %2,%0";
2294           else
2295 #ifdef MOTOROLA  
2296             return "lea (%c2,%0),%0";
2297 #else
2298             return "lea %0@(%c2),%0";
2299 #endif
2300         }
2301     }
2302   return "add%.l %2,%0";
2303 }
2304 \f
2305 /* Store in cc_status the expressions that the condition codes will
2306    describe after execution of an instruction whose pattern is EXP.
2307    Do not alter them if the instruction would not alter the cc's.  */
2308
2309 /* On the 68000, all the insns to store in an address register fail to
2310    set the cc's.  However, in some cases these instructions can make it
2311    possibly invalid to use the saved cc's.  In those cases we clear out
2312    some or all of the saved cc's so they won't be used.  */
2313
2314 void
2315 notice_update_cc (exp, insn)
2316      rtx exp;
2317      rtx insn;
2318 {
2319   if (GET_CODE (exp) == SET)
2320     {
2321       if (GET_CODE (SET_SRC (exp)) == CALL)
2322         {
2323           CC_STATUS_INIT; 
2324         }
2325       else if (ADDRESS_REG_P (SET_DEST (exp)))
2326         {
2327           if (cc_status.value1 && modified_in_p (cc_status.value1, insn))
2328             cc_status.value1 = 0;
2329           if (cc_status.value2 && modified_in_p (cc_status.value2, insn))
2330             cc_status.value2 = 0; 
2331         }
2332       else if (!FP_REG_P (SET_DEST (exp))
2333                && SET_DEST (exp) != cc0_rtx
2334                && (FP_REG_P (SET_SRC (exp))
2335                    || GET_CODE (SET_SRC (exp)) == FIX
2336                    || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE
2337                    || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND))
2338         {
2339           CC_STATUS_INIT; 
2340         }
2341       /* A pair of move insns doesn't produce a useful overall cc.  */
2342       else if (!FP_REG_P (SET_DEST (exp))
2343                && !FP_REG_P (SET_SRC (exp))
2344                && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
2345                && (GET_CODE (SET_SRC (exp)) == REG
2346                    || GET_CODE (SET_SRC (exp)) == MEM
2347                    || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
2348         {
2349           CC_STATUS_INIT; 
2350         }
2351       else if (GET_CODE (SET_SRC (exp)) == CALL)
2352         {
2353           CC_STATUS_INIT; 
2354         }
2355       else if (XEXP (exp, 0) != pc_rtx)
2356         {
2357           cc_status.flags = 0;
2358           cc_status.value1 = XEXP (exp, 0);
2359           cc_status.value2 = XEXP (exp, 1);
2360         }
2361     }
2362   else if (GET_CODE (exp) == PARALLEL
2363            && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2364     {
2365       if (ADDRESS_REG_P (XEXP (XVECEXP (exp, 0, 0), 0)))
2366         CC_STATUS_INIT;
2367       else if (XEXP (XVECEXP (exp, 0, 0), 0) != pc_rtx)
2368         {
2369           cc_status.flags = 0;
2370           cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
2371           cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1);
2372         }
2373     }
2374   else
2375     CC_STATUS_INIT;
2376   if (cc_status.value2 != 0
2377       && ADDRESS_REG_P (cc_status.value2)
2378       && GET_MODE (cc_status.value2) == QImode)
2379     CC_STATUS_INIT;
2380   if (cc_status.value2 != 0)
2381     switch (GET_CODE (cc_status.value2))
2382       {
2383       case PLUS: case MINUS: case MULT:
2384       case DIV: case UDIV: case MOD: case UMOD: case NEG:
2385 #if 0 /* These instructions always clear the overflow bit */
2386       case ASHIFT: case ASHIFTRT: case LSHIFTRT:
2387       case ROTATE: case ROTATERT:
2388 #endif
2389         if (GET_MODE (cc_status.value2) != VOIDmode)
2390           cc_status.flags |= CC_NO_OVERFLOW;
2391         break;
2392       case ZERO_EXTEND:
2393         /* (SET r1 (ZERO_EXTEND r2)) on this machine
2394            ends with a move insn moving r2 in r2's mode.
2395            Thus, the cc's are set for r2.
2396            This can set N bit spuriously.  */
2397         cc_status.flags |= CC_NOT_NEGATIVE; 
2398
2399       default:
2400         break;
2401       }
2402   if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
2403       && cc_status.value2
2404       && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
2405     cc_status.value2 = 0;
2406   if (((cc_status.value1 && FP_REG_P (cc_status.value1))
2407        || (cc_status.value2 && FP_REG_P (cc_status.value2))))
2408     cc_status.flags = CC_IN_68881;
2409 }
2410 \f
2411 const char *
2412 output_move_const_double (operands)
2413      rtx *operands;
2414 {
2415   int code = standard_68881_constant_p (operands[1]);
2416
2417   if (code != 0)
2418     {
2419       static char buf[40];
2420
2421       sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
2422       return buf;
2423     }
2424   return "fmove%.d %1,%0";
2425 }
2426
2427 const char *
2428 output_move_const_single (operands)
2429      rtx *operands;
2430 {
2431   int code = standard_68881_constant_p (operands[1]);
2432
2433   if (code != 0)
2434     {
2435       static char buf[40];
2436
2437       sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
2438       return buf;
2439     }
2440   return "fmove%.s %f1,%0";
2441 }
2442
2443 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2444    from the "fmovecr" instruction.
2445    The value, anded with 0xff, gives the code to use in fmovecr
2446    to get the desired constant.  */
2447
2448 /* This code has been fixed for cross-compilation.  */
2449   
2450 static int inited_68881_table = 0;
2451
2452 static const char *const strings_68881[7] = {
2453   "0.0",
2454   "1.0",
2455   "10.0",
2456   "100.0",
2457   "10000.0",
2458   "1e8",
2459   "1e16"
2460   };
2461
2462 static const int codes_68881[7] = {
2463   0x0f,
2464   0x32,
2465   0x33,
2466   0x34,
2467   0x35,
2468   0x36,
2469   0x37
2470   };
2471
2472 REAL_VALUE_TYPE values_68881[7];
2473
2474 /* Set up values_68881 array by converting the decimal values
2475    strings_68881 to binary.  */
2476
2477 void
2478 init_68881_table ()
2479 {
2480   int i;
2481   REAL_VALUE_TYPE r;
2482   enum machine_mode mode;
2483
2484   mode = SFmode;
2485   for (i = 0; i < 7; i++)
2486     {
2487       if (i == 6)
2488         mode = DFmode;
2489       r = REAL_VALUE_ATOF (strings_68881[i], mode);
2490       values_68881[i] = r;
2491     }
2492   inited_68881_table = 1;
2493 }
2494
2495 int
2496 standard_68881_constant_p (x)
2497      rtx x;
2498 {
2499   REAL_VALUE_TYPE r;
2500   int i;
2501
2502   /* fmovecr must be emulated on the 68040 and 68060, so it shouldn't be
2503      used at all on those chips.  */
2504   if (TARGET_68040 || TARGET_68060)
2505     return 0;
2506
2507   if (! inited_68881_table)
2508     init_68881_table ();
2509
2510   REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2511
2512   /* Use REAL_VALUES_IDENTICAL instead of REAL_VALUES_EQUAL so that -0.0
2513      is rejected.  */
2514   for (i = 0; i < 6; i++)
2515     {
2516       if (REAL_VALUES_IDENTICAL (r, values_68881[i]))
2517         return (codes_68881[i]);
2518     }
2519   
2520   if (GET_MODE (x) == SFmode)
2521     return 0;
2522
2523   if (REAL_VALUES_EQUAL (r, values_68881[6]))
2524     return (codes_68881[6]);
2525
2526   /* larger powers of ten in the constants ram are not used
2527      because they are not equal to a `double' C constant.  */
2528   return 0;
2529 }
2530
2531 /* If X is a floating-point constant, return the logarithm of X base 2,
2532    or 0 if X is not a power of 2.  */
2533
2534 int
2535 floating_exact_log2 (x)
2536      rtx x;
2537 {
2538   REAL_VALUE_TYPE r, r1;
2539   int exp;
2540
2541   REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2542
2543   if (REAL_VALUES_LESS (r, dconst1))
2544     return 0;
2545
2546   exp = real_exponent (&r);
2547   real_2expN (&r1, exp);
2548   if (REAL_VALUES_EQUAL (r1, r))
2549     return exp;
2550
2551   return 0;
2552 }
2553 \f
2554 /* A C compound statement to output to stdio stream STREAM the
2555    assembler syntax for an instruction operand X.  X is an RTL
2556    expression.
2557
2558    CODE is a value that can be used to specify one of several ways
2559    of printing the operand.  It is used when identical operands
2560    must be printed differently depending on the context.  CODE
2561    comes from the `%' specification that was used to request
2562    printing of the operand.  If the specification was just `%DIGIT'
2563    then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2564    is the ASCII code for LTR.
2565
2566    If X is a register, this macro should print the register's name.
2567    The names can be found in an array `reg_names' whose type is
2568    `char *[]'.  `reg_names' is initialized from `REGISTER_NAMES'.
2569
2570    When the machine description has a specification `%PUNCT' (a `%'
2571    followed by a punctuation character), this macro is called with
2572    a null pointer for X and the punctuation character for CODE.
2573
2574    The m68k specific codes are:
2575
2576    '.' for dot needed in Motorola-style opcode names.
2577    '-' for an operand pushing on the stack:
2578        sp@-, -(sp) or -(%sp) depending on the style of syntax.
2579    '+' for an operand pushing on the stack:
2580        sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2581    '@' for a reference to the top word on the stack:
2582        sp@, (sp) or (%sp) depending on the style of syntax.
2583    '#' for an immediate operand prefix (# in MIT and Motorola syntax
2584        but & in SGS syntax).
2585    '!' for the cc register (used in an `and to cc' insn).
2586    '$' for the letter `s' in an op code, but only on the 68040.
2587    '&' for the letter `d' in an op code, but only on the 68040.
2588    '/' for register prefix needed by longlong.h.
2589
2590    'b' for byte insn (no effect, on the Sun; this is for the ISI).
2591    'd' to force memory addressing to be absolute, not relative.
2592    'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2593    'o' for operands to go directly to output_operand_address (bypassing
2594        print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
2595    'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2596        or print pair of registers as rx:ry.
2597
2598    */
2599
2600 void
2601 print_operand (file, op, letter)
2602      FILE *file;                /* file to write to */
2603      rtx op;                    /* operand to print */
2604      int letter;                /* %<letter> or 0 */
2605 {
2606   if (letter == '.')
2607     {
2608 #if defined (MOTOROLA)
2609       fprintf (file, ".");
2610 #endif
2611     }
2612   else if (letter == '#')
2613     {
2614       asm_fprintf (file, "%I");
2615     }
2616   else if (letter == '-')
2617     {
2618 #ifdef MOTOROLA
2619       asm_fprintf (file, "-(%Rsp)");
2620 #else
2621       asm_fprintf (file, "%Rsp@-");
2622 #endif
2623     }
2624   else if (letter == '+')
2625     {
2626 #ifdef MOTOROLA
2627       asm_fprintf (file, "(%Rsp)+");
2628 #else
2629       asm_fprintf (file, "%Rsp@+");
2630 #endif
2631     }
2632   else if (letter == '@')
2633     {
2634 #ifdef MOTOROLA
2635       asm_fprintf (file, "(%Rsp)");
2636 #else
2637       asm_fprintf (file, "%Rsp@");
2638 #endif
2639     }
2640   else if (letter == '!')
2641     {
2642       asm_fprintf (file, "%Rfpcr");
2643     }
2644   else if (letter == '$')
2645     {
2646       if (TARGET_68040_ONLY)
2647         {
2648           fprintf (file, "s");
2649         }
2650     }
2651   else if (letter == '&')
2652     {
2653       if (TARGET_68040_ONLY)
2654         {
2655           fprintf (file, "d");
2656         }
2657     }
2658   else if (letter == '/')
2659     {
2660       asm_fprintf (file, "%R");
2661     }
2662   else if (letter == 'o')
2663     {
2664       /* This is only for direct addresses with TARGET_PCREL */
2665       if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
2666           || !TARGET_PCREL) 
2667         abort ();
2668       output_addr_const (file, XEXP (op, 0));
2669     }
2670   else if (GET_CODE (op) == REG)
2671     {
2672       if (letter == 'R')
2673         /* Print out the second register name of a register pair.
2674            I.e., R (6) => 7.  */
2675         fputs (reg_names[REGNO (op) + 1], file);
2676       else
2677         fputs (reg_names[REGNO (op)], file);
2678     }
2679   else if (GET_CODE (op) == MEM)
2680     {
2681       output_address (XEXP (op, 0));
2682       if (letter == 'd' && ! TARGET_68020
2683           && CONSTANT_ADDRESS_P (XEXP (op, 0))
2684           && !(GET_CODE (XEXP (op, 0)) == CONST_INT
2685                && INTVAL (XEXP (op, 0)) < 0x8000
2686                && INTVAL (XEXP (op, 0)) >= -0x8000))
2687         {
2688 #ifdef MOTOROLA
2689           fprintf (file, ".l");
2690 #else
2691           fprintf (file, ":l");
2692 #endif
2693         }
2694     }
2695   else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
2696     {
2697       REAL_VALUE_TYPE r;
2698       REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2699       ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
2700     }
2701   else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
2702     {
2703       REAL_VALUE_TYPE r;
2704       REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2705       ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
2706     }
2707   else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
2708     {
2709       REAL_VALUE_TYPE r;
2710       REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2711       ASM_OUTPUT_DOUBLE_OPERAND (file, r);
2712     }
2713   else
2714     {
2715       /* Use `print_operand_address' instead of `output_addr_const'
2716          to ensure that we print relevant PIC stuff.  */
2717       asm_fprintf (file, "%I");
2718       if (TARGET_PCREL
2719           && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
2720         print_operand_address (file, op);
2721       else
2722         output_addr_const (file, op);
2723     }
2724 }
2725
2726 \f
2727 /* A C compound statement to output to stdio stream STREAM the
2728    assembler syntax for an instruction operand that is a memory
2729    reference whose address is ADDR.  ADDR is an RTL expression.
2730
2731    Note that this contains a kludge that knows that the only reason
2732    we have an address (plus (label_ref...) (reg...)) when not generating
2733    PIC code is in the insn before a tablejump, and we know that m68k.md
2734    generates a label LInnn: on such an insn.
2735
2736    It is possible for PIC to generate a (plus (label_ref...) (reg...))
2737    and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2738
2739    Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2740    fails to assemble.  Luckily "Lnnn(pc,d0.l*2)" produces the results
2741    we want.  This difference can be accommodated by using an assembler
2742    define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2743    string, as necessary.  This is accomplished via the ASM_OUTPUT_CASE_END
2744    macro.  See m68k/sgs.h for an example; for versions without the bug.
2745    Some assemblers refuse all the above solutions.  The workaround is to
2746    emit "K(pc,d0.l*2)" with K being a small constant known to give the
2747    right behavior.
2748
2749    They also do not like things like "pea 1.w", so we simple leave off
2750    the .w on small constants. 
2751
2752    This routine is responsible for distinguishing between -fpic and -fPIC 
2753    style relocations in an address.  When generating -fpic code the
2754    offset is output in word mode (eg movel a5@(_foo:w), a0).  When generating
2755    -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
2756
2757 #ifndef ASM_OUTPUT_CASE_FETCH
2758 #ifdef MOTOROLA
2759 #ifdef SGS
2760 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2761         asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
2762 #else
2763 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2764         asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2765 #endif
2766 #else
2767 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2768         asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
2769 #endif
2770 #endif /* ASM_OUTPUT_CASE_FETCH */
2771
2772 void
2773 print_operand_address (file, addr)
2774      FILE *file;
2775      rtx addr;
2776 {
2777   register rtx reg1, reg2, breg, ireg;
2778   rtx offset;
2779
2780   switch (GET_CODE (addr))
2781     {
2782       case REG:
2783 #ifdef MOTOROLA
2784         fprintf (file, "(%s)", reg_names[REGNO (addr)]);
2785 #else
2786         fprintf (file, "%s@", reg_names[REGNO (addr)]);
2787 #endif
2788         break;
2789       case PRE_DEC:
2790 #ifdef MOTOROLA
2791         fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
2792 #else
2793         fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);
2794 #endif
2795         break;
2796       case POST_INC:
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 PLUS:
2804         reg1 = reg2 = ireg = breg = offset = 0;
2805         if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
2806           {
2807             offset = XEXP (addr, 0);
2808             addr = XEXP (addr, 1);
2809           }
2810         else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
2811           {
2812             offset = XEXP (addr, 1);
2813             addr = XEXP (addr, 0);
2814           }
2815         if (GET_CODE (addr) != PLUS)
2816           {
2817             ;
2818           }
2819         else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
2820           {
2821             reg1 = XEXP (addr, 0);
2822             addr = XEXP (addr, 1);
2823           }
2824         else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
2825           {
2826             reg1 = XEXP (addr, 1);
2827             addr = XEXP (addr, 0);
2828           }
2829         else if (GET_CODE (XEXP (addr, 0)) == MULT)
2830           {
2831             reg1 = XEXP (addr, 0);
2832             addr = XEXP (addr, 1);
2833           }
2834         else if (GET_CODE (XEXP (addr, 1)) == MULT)
2835           {
2836             reg1 = XEXP (addr, 1);
2837             addr = XEXP (addr, 0);
2838           }
2839         else if (GET_CODE (XEXP (addr, 0)) == REG)
2840           {
2841             reg1 = XEXP (addr, 0);
2842             addr = XEXP (addr, 1);
2843           }
2844         else if (GET_CODE (XEXP (addr, 1)) == REG)
2845           {
2846             reg1 = XEXP (addr, 1);
2847             addr = XEXP (addr, 0);
2848           }
2849         if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
2850             || GET_CODE (addr) == SIGN_EXTEND)
2851           {
2852             if (reg1 == 0)
2853               {
2854                 reg1 = addr;
2855               }
2856             else
2857               {
2858                 reg2 = addr;
2859               }
2860             addr = 0;
2861           }
2862 #if 0   /* for OLD_INDEXING */
2863         else if (GET_CODE (addr) == PLUS)
2864           {
2865             if (GET_CODE (XEXP (addr, 0)) == REG)
2866               {
2867                 reg2 = XEXP (addr, 0);
2868                 addr = XEXP (addr, 1);
2869               }
2870             else if (GET_CODE (XEXP (addr, 1)) == REG)
2871               {
2872                 reg2 = XEXP (addr, 1);
2873                 addr = XEXP (addr, 0);
2874               }
2875           }
2876 #endif
2877         if (offset != 0)
2878           {
2879             if (addr != 0)
2880               {
2881                 abort ();
2882               }
2883             addr = offset;
2884           }
2885         if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
2886                       || GET_CODE (reg1) == MULT))
2887             || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
2888           {
2889             breg = reg2;
2890             ireg = reg1;
2891           }
2892         else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
2893           {
2894             breg = reg1;
2895             ireg = reg2;
2896           }
2897         if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
2898             && ! (flag_pic && ireg == pic_offset_table_rtx))
2899           {
2900             int scale = 1;
2901             if (GET_CODE (ireg) == MULT)
2902               {
2903                 scale = INTVAL (XEXP (ireg, 1));
2904                 ireg = XEXP (ireg, 0);
2905               }
2906             if (GET_CODE (ireg) == SIGN_EXTEND)
2907               {
2908                 ASM_OUTPUT_CASE_FETCH (file,
2909                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
2910                              reg_names[REGNO (XEXP (ireg, 0))]);
2911                 fprintf (file, "w");
2912               }
2913             else
2914               {
2915                 ASM_OUTPUT_CASE_FETCH (file,
2916                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
2917                              reg_names[REGNO (ireg)]);
2918                 fprintf (file, "l");
2919               }
2920             if (scale != 1)
2921               {
2922 #ifdef MOTOROLA
2923                 fprintf (file, "*%d", scale);
2924 #else
2925                 fprintf (file, ":%d", scale);
2926 #endif
2927               }
2928             putc (')', file);
2929             break;
2930           }
2931         if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
2932             && ! (flag_pic && breg == pic_offset_table_rtx))
2933           {
2934             ASM_OUTPUT_CASE_FETCH (file,
2935                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
2936                          reg_names[REGNO (breg)]);
2937             fprintf (file, "l)");
2938             break;
2939           }
2940         if (ireg != 0 || breg != 0)
2941           {
2942             int scale = 1;
2943             if (breg == 0)
2944               {
2945                 abort ();
2946               }
2947             if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)
2948               {
2949                 abort ();
2950               }
2951 #ifdef MOTOROLA
2952             if (addr != 0)
2953               {
2954                 output_addr_const (file, addr);
2955                 if (flag_pic && (breg == pic_offset_table_rtx))
2956                   {
2957                     fprintf (file, "@GOT");
2958                     if (flag_pic == 1)
2959                       fprintf (file, ".w");
2960                   }
2961               }
2962             fprintf (file, "(%s", reg_names[REGNO (breg)]);
2963             if (ireg != 0)
2964               {
2965                 putc (',', file);
2966               }
2967 #else
2968             fprintf (file, "%s@(", reg_names[REGNO (breg)]);
2969             if (addr != 0)
2970               {
2971                 output_addr_const (file, addr);
2972                 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
2973                   fprintf (file, ":w");
2974                 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
2975                   fprintf (file, ":l");
2976               }
2977             if (addr != 0 && ireg != 0)
2978               {
2979                 putc (',', file);
2980               }
2981 #endif
2982             if (ireg != 0 && GET_CODE (ireg) == MULT)
2983               {
2984                 scale = INTVAL (XEXP (ireg, 1));
2985                 ireg = XEXP (ireg, 0);
2986               }
2987             if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
2988               {
2989 #ifdef MOTOROLA
2990                 fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);
2991 #else
2992                 fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);
2993 #endif
2994               }
2995             else if (ireg != 0)
2996               {
2997 #ifdef MOTOROLA
2998                 fprintf (file, "%s.l", reg_names[REGNO (ireg)]);
2999 #else
3000                 fprintf (file, "%s:l", reg_names[REGNO (ireg)]);
3001 #endif
3002               }
3003             if (scale != 1)
3004               {
3005 #ifdef MOTOROLA
3006                 fprintf (file, "*%d", scale);
3007 #else
3008                 fprintf (file, ":%d", scale);
3009 #endif
3010               }
3011             putc (')', file);
3012             break;
3013           }
3014         else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
3015                  && ! (flag_pic && reg1 == pic_offset_table_rtx))       
3016           {
3017             ASM_OUTPUT_CASE_FETCH (file,
3018                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
3019                          reg_names[REGNO (reg1)]);
3020             fprintf (file, "l)");
3021             break;
3022           }
3023         /* FALL-THROUGH (is this really what we want?)  */
3024       default:
3025         if (GET_CODE (addr) == CONST_INT
3026             && INTVAL (addr) < 0x8000
3027             && INTVAL (addr) >= -0x8000)
3028           {
3029 #ifdef MOTOROLA
3030 #ifdef SGS
3031             /* Many SGS assemblers croak on size specifiers for constants.  */
3032             fprintf (file, "%d", (int) INTVAL (addr));
3033 #else
3034             fprintf (file, "%d.w", (int) INTVAL (addr));
3035 #endif
3036 #else
3037             fprintf (file, "%d:w", (int) INTVAL (addr));
3038 #endif
3039           }
3040         else if (GET_CODE (addr) == CONST_INT)
3041           {
3042             fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
3043           }
3044         else if (TARGET_PCREL)
3045           {
3046             fputc ('(', file);
3047             output_addr_const (file, addr);
3048             if (flag_pic == 1)
3049               asm_fprintf (file, ":w,%Rpc)");
3050             else
3051               asm_fprintf (file, ":l,%Rpc)");
3052           }
3053         else
3054           {
3055             /* Special case for SYMBOL_REF if the symbol name ends in
3056                `.<letter>', this can be mistaken as a size suffix.  Put
3057                the name in parentheses.  */
3058             if (GET_CODE (addr) == SYMBOL_REF
3059                 && strlen (XSTR (addr, 0)) > 2
3060                 && XSTR (addr, 0)[strlen (XSTR (addr, 0)) - 2] == '.')
3061               {
3062                 putc ('(', file);
3063                 output_addr_const (file, addr);
3064                 putc (')', file);
3065               }
3066             else
3067               output_addr_const (file, addr);
3068           }
3069         break;
3070     }
3071 }
3072 \f
3073 /* Check for cases where a clr insns can be omitted from code using
3074    strict_low_part sets.  For example, the second clrl here is not needed:
3075    clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3076
3077    MODE is the mode of this STRICT_LOW_PART set.  FIRST_INSN is the clear
3078    insn we are checking for redundancy.  TARGET is the register set by the
3079    clear insn.  */
3080
3081 int
3082 strict_low_part_peephole_ok (mode, first_insn, target)
3083      enum machine_mode mode;
3084      rtx first_insn;
3085      rtx target;
3086 {
3087   rtx p;
3088
3089   p = prev_nonnote_insn (first_insn);
3090
3091   while (p)
3092     {
3093       /* If it isn't an insn, then give up.  */
3094       if (GET_CODE (p) != INSN)
3095         return 0;
3096
3097       if (reg_set_p (target, p))
3098         {
3099           rtx set = single_set (p);
3100           rtx dest;
3101
3102           /* If it isn't an easy to recognize insn, then give up.  */
3103           if (! set)
3104             return 0;
3105
3106           dest = SET_DEST (set);
3107
3108           /* If this sets the entire target register to zero, then our
3109              first_insn is redundant.  */
3110           if (rtx_equal_p (dest, target)
3111               && SET_SRC (set) == const0_rtx)
3112             return 1;
3113           else if (GET_CODE (dest) == STRICT_LOW_PART
3114                    && GET_CODE (XEXP (dest, 0)) == REG
3115                    && REGNO (XEXP (dest, 0)) == REGNO (target)
3116                    && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0)))
3117                        <= GET_MODE_SIZE (mode)))
3118             /* This is a strict low part set which modifies less than
3119                we are using, so it is safe.  */
3120             ;
3121           else
3122             return 0;
3123         }
3124
3125       p = prev_nonnote_insn (p);
3126
3127     }
3128
3129   return 0;
3130 }
3131
3132 /* Accept integer operands in the range 0..0xffffffff.  We have to check the
3133    range carefully since this predicate is used in DImode contexts.  Also, we
3134    need some extra crud to make it work when hosted on 64-bit machines.  */
3135
3136 int
3137 const_uint32_operand (op, mode)
3138      rtx op;
3139      enum machine_mode mode;
3140 {
3141   /* It doesn't make sense to ask this question with a mode that is
3142      not larger than 32 bits.  */
3143   if (GET_MODE_BITSIZE (mode) <= 32)
3144     abort ();
3145
3146 #if HOST_BITS_PER_WIDE_INT > 32
3147   /* All allowed constants will fit a CONST_INT.  */
3148   return (GET_CODE (op) == CONST_INT
3149           && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
3150 #else
3151   return (GET_CODE (op) == CONST_INT
3152           || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
3153 #endif
3154 }
3155
3156 /* Accept integer operands in the range -0x80000000..0x7fffffff.  We have
3157    to check the range carefully since this predicate is used in DImode
3158    contexts.  */
3159
3160 int
3161 const_sint32_operand (op, mode)
3162      rtx op;
3163      enum machine_mode mode;
3164 {
3165   /* It doesn't make sense to ask this question with a mode that is
3166      not larger than 32 bits.  */
3167   if (GET_MODE_BITSIZE (mode) <= 32)
3168     abort ();
3169
3170   /* All allowed constants will fit a CONST_INT.  */
3171   return (GET_CODE (op) == CONST_INT
3172           && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
3173 }
3174
3175 /* Operand predicates for implementing asymmetric pc-relative addressing
3176    on m68k.  The m68k supports pc-relative addressing (mode 7, register 2)
3177    when used as a source operand, but not as a destination operand.
3178
3179    We model this by restricting the meaning of the basic predicates
3180    (general_operand, memory_operand, etc) to forbid the use of this
3181    addressing mode, and then define the following predicates that permit
3182    this addressing mode.  These predicates can then be used for the
3183    source operands of the appropriate instructions.
3184
3185    n.b.  While it is theoretically possible to change all machine patterns
3186    to use this addressing more where permitted by the architecture,
3187    it has only been implemented for "common" cases: SImode, HImode, and
3188    QImode operands, and only for the principle operations that would
3189    require this addressing mode: data movement and simple integer operations.
3190
3191    In parallel with these new predicates, two new constraint letters
3192    were defined: 'S' and 'T'.  'S' is the -mpcrel analog of 'm'.
3193    'T' replaces 's' in the non-pcrel case.  It is a no-op in the pcrel case.
3194    In the pcrel case 's' is only valid in combination with 'a' registers.
3195    See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
3196    of how these constraints are used.
3197
3198    The use of these predicates is strictly optional, though patterns that
3199    don't will cause an extra reload register to be allocated where one
3200    was not necessary:
3201
3202         lea (abc:w,%pc),%a0     ; need to reload address
3203         moveq &1,%d1            ; since write to pc-relative space
3204         movel %d1,%a0@          ; is not allowed
3205         ...
3206         lea (abc:w,%pc),%a1     ; no need to reload address here
3207         movel %a1@,%d0          ; since "movel (abc:w,%pc),%d0" is ok
3208
3209    For more info, consult tiemann@cygnus.com.
3210
3211
3212    All of the ugliness with predicates and constraints is due to the
3213    simple fact that the m68k does not allow a pc-relative addressing
3214    mode as a destination.  gcc does not distinguish between source and
3215    destination addresses.  Hence, if we claim that pc-relative address
3216    modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
3217    end up with invalid code.  To get around this problem, we left
3218    pc-relative modes as invalid addresses, and then added special
3219    predicates and constraints to accept them.
3220
3221    A cleaner way to handle this is to modify gcc to distinguish
3222    between source and destination addresses.  We can then say that
3223    pc-relative is a valid source address but not a valid destination
3224    address, and hopefully avoid a lot of the predicate and constraint
3225    hackery.  Unfortunately, this would be a pretty big change.  It would
3226    be a useful change for a number of ports, but there aren't any current
3227    plans to undertake this.
3228
3229    ***************************************************************************/
3230
3231
3232 /* Special case of a general operand that's used as a source operand.
3233    Use this to permit reads from PC-relative memory when -mpcrel
3234    is specified.  */
3235
3236 int
3237 general_src_operand (op, mode)
3238      rtx op;
3239      enum machine_mode mode;
3240 {
3241   if (TARGET_PCREL
3242       && GET_CODE (op) == MEM
3243       && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3244           || GET_CODE (XEXP (op, 0)) == LABEL_REF
3245           || GET_CODE (XEXP (op, 0)) == CONST))
3246     return 1;
3247   return general_operand (op, mode);
3248 }
3249
3250 /* Special case of a nonimmediate operand that's used as a source.
3251    Use this to permit reads from PC-relative memory when -mpcrel
3252    is specified.  */
3253
3254 int
3255 nonimmediate_src_operand (op, mode)
3256      rtx op;
3257      enum machine_mode mode;
3258 {
3259   if (TARGET_PCREL && GET_CODE (op) == MEM
3260       && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3261           || GET_CODE (XEXP (op, 0)) == LABEL_REF
3262           || GET_CODE (XEXP (op, 0)) == CONST))
3263     return 1;
3264   return nonimmediate_operand (op, mode);
3265 }
3266
3267 /* Special case of a memory operand that's used as a source.
3268    Use this to permit reads from PC-relative memory when -mpcrel
3269    is specified.  */
3270
3271 int
3272 memory_src_operand (op, mode)
3273      rtx op;
3274      enum machine_mode mode;
3275 {
3276   if (TARGET_PCREL && GET_CODE (op) == MEM
3277       && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3278           || GET_CODE (XEXP (op, 0)) == LABEL_REF
3279           || GET_CODE (XEXP (op, 0)) == CONST))
3280     return 1;
3281   return memory_operand (op, mode);
3282 }
3283
3284 /* Predicate that accepts only a pc-relative address.  This is needed
3285    because pc-relative addresses don't satisfy the predicate
3286    "general_src_operand".  */
3287
3288 int
3289 pcrel_address (op, mode)
3290      rtx op;
3291      enum machine_mode mode ATTRIBUTE_UNUSED;
3292 {
3293   return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF
3294           || GET_CODE (op) == CONST);
3295 }
3296
3297 const char *
3298 output_andsi3 (operands)
3299      rtx *operands;
3300 {
3301   int logval;
3302   if (GET_CODE (operands[2]) == CONST_INT
3303       && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
3304       && (DATA_REG_P (operands[0])
3305           || offsettable_memref_p (operands[0]))
3306       && !TARGET_COLDFIRE)
3307     {
3308       if (GET_CODE (operands[0]) != REG)
3309         operands[0] = adjust_address (operands[0], HImode, 2);
3310       operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
3311       /* Do not delete a following tstl %0 insn; that would be incorrect.  */
3312       CC_STATUS_INIT;
3313       if (operands[2] == const0_rtx)
3314         return "clr%.w %0";
3315       return "and%.w %2,%0";
3316     }
3317   if (GET_CODE (operands[2]) == CONST_INT
3318       && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
3319       && (DATA_REG_P (operands[0])
3320           || offsettable_memref_p (operands[0])))
3321     {
3322       if (DATA_REG_P (operands[0]))
3323         {
3324           operands[1] = GEN_INT (logval);
3325         }
3326       else
3327         {
3328           operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3329           operands[1] = GEN_INT (logval % 8);
3330         }
3331       /* This does not set condition codes in a standard way.  */
3332       CC_STATUS_INIT;
3333       return "bclr %1,%0";
3334     }
3335   return "and%.l %2,%0";
3336 }
3337
3338 const char *
3339 output_iorsi3 (operands)
3340      rtx *operands;
3341 {
3342   register int logval;
3343   if (GET_CODE (operands[2]) == CONST_INT
3344       && INTVAL (operands[2]) >> 16 == 0
3345       && (DATA_REG_P (operands[0])
3346           || offsettable_memref_p (operands[0]))
3347       && !TARGET_COLDFIRE)
3348     {
3349       if (GET_CODE (operands[0]) != REG)
3350         operands[0] = adjust_address (operands[0], HImode, 2);
3351       /* Do not delete a following tstl %0 insn; that would be incorrect.  */
3352       CC_STATUS_INIT;
3353       if (INTVAL (operands[2]) == 0xffff)
3354         return "mov%.w %2,%0";
3355       return "or%.w %2,%0";
3356     }
3357   if (GET_CODE (operands[2]) == CONST_INT
3358       && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3359       && (DATA_REG_P (operands[0])
3360           || offsettable_memref_p (operands[0])))
3361     {
3362       if (DATA_REG_P (operands[0]))
3363         operands[1] = GEN_INT (logval);
3364       else
3365         {
3366           operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3367           operands[1] = GEN_INT (logval % 8);
3368         }
3369       CC_STATUS_INIT;
3370       return "bset %1,%0";
3371     }
3372   return "or%.l %2,%0";
3373 }
3374
3375 const char *
3376 output_xorsi3 (operands)
3377      rtx *operands;
3378 {
3379   register int logval;
3380   if (GET_CODE (operands[2]) == CONST_INT
3381       && INTVAL (operands[2]) >> 16 == 0
3382       && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))
3383       && !TARGET_COLDFIRE)
3384     {
3385       if (! DATA_REG_P (operands[0]))
3386         operands[0] = adjust_address (operands[0], HImode, 2);
3387       /* Do not delete a following tstl %0 insn; that would be incorrect.  */
3388       CC_STATUS_INIT;
3389       if (INTVAL (operands[2]) == 0xffff)
3390         return "not%.w %0";
3391       return "eor%.w %2,%0";
3392     }
3393   if (GET_CODE (operands[2]) == CONST_INT
3394       && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3395       && (DATA_REG_P (operands[0])
3396           || offsettable_memref_p (operands[0])))
3397     {
3398       if (DATA_REG_P (operands[0]))
3399         operands[1] = GEN_INT (logval);
3400       else
3401         {
3402           operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
3403           operands[1] = GEN_INT (logval % 8);
3404         }
3405       CC_STATUS_INIT;
3406       return "bchg %1,%0";
3407     }
3408   return "eor%.l %2,%0";
3409 }
3410
3411 /* Output assembly to switch to section NAME with attribute FLAGS.  */
3412
3413 static void
3414 m68k_coff_asm_named_section (name, flags)
3415      const char *name;
3416      unsigned int flags;
3417 {
3418   char flagchar;
3419
3420   if (flags & SECTION_WRITE)
3421     flagchar = 'd';
3422   else
3423     flagchar = 'x';
3424
3425   fprintf (asm_out_file, "\t.section\t%s,\"%c\"\n", name, flagchar);
3426 }
3427
3428 #ifdef CTOR_LIST_BEGIN
3429 static void
3430 m68k_svr3_asm_out_constructor (symbol, priority)
3431      rtx symbol;
3432      int priority ATTRIBUTE_UNUSED;
3433 {
3434   rtx xop[2];
3435
3436   xop[1] = symbol;
3437   xop[0] = gen_rtx_MEM (SImode, gen_rtx_PRE_DEC (SImode, stack_pointer_rtx));
3438
3439   init_section ();
3440   output_asm_insn (output_move_simode (xop), xop);
3441 }
3442 #endif
3443
3444 #ifdef HPUX_ASM
3445 static void
3446 m68k_hp320_internal_label (stream, prefix, labelno)
3447      FILE *stream;
3448      const char *prefix;
3449      unsigned long labelno;
3450 {
3451   if (prefix[0] == 'L' && prefix[1] == 'I')
3452     fprintf(stream, "\tset %s%ld,.+2\n", prefix, labelno);
3453   else
3454     fprintf (stream, "%s%ld:\n", prefix, labelno);
3455 }
3456
3457 static void
3458 m68k_hp320_file_start ()
3459 {
3460   /* version 1: 68010.
3461              2: 68020 without FPU.
3462              3: 68020 with FPU.  */
3463   fprintf (asm_out_file, "\tversion %d\n",
3464            TARGET_68020 ? (TARGET_68881 ? 3 : 2) : 1);
3465 }
3466 #endif
3467
3468 static void
3469 m68k_output_mi_thunk (file, thunk, delta, vcall_offset, function)
3470      FILE *file;
3471      tree thunk ATTRIBUTE_UNUSED;
3472      HOST_WIDE_INT delta;
3473      HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
3474      tree function;
3475 {
3476   rtx xops[1];
3477   const char *fmt;
3478
3479   if (delta > 0 && delta <= 8)
3480 #ifdef MOTOROLA
3481     asm_fprintf (file, "\taddq.l %I%d,4(%Rsp)\n", (int) delta);
3482 #else
3483     asm_fprintf (file, "\taddql %I%d,%Rsp@(4)\n", (int) delta);
3484 #endif
3485   else if (delta < 0 && delta >= -8)
3486 #ifdef MOTOROLA
3487     asm_fprintf (file, "\tsubq.l %I%d,4(%Rsp)\n", (int) -delta);
3488 #else
3489     asm_fprintf (file, "\tsubql %I%d,%Rsp@(4)\n", (int) -delta);
3490 #endif
3491   else
3492 #ifdef MOTOROLA
3493     asm_fprintf (file, "\tadd.l %I%wd,4(%Rsp)\n", delta);
3494 #else
3495     asm_fprintf (file, "\taddl %I%wd,%Rsp@(4)\n", delta);
3496 #endif
3497
3498   xops[0] = DECL_RTL (function);
3499
3500   /* Logic taken from call patterns in m68k.md.  */
3501   if (flag_pic)
3502     {
3503       if (TARGET_PCREL)
3504         fmt = "bra.l %o0";
3505       else
3506         {
3507 #ifdef MOTOROLA
3508 #ifdef HPUX_ASM
3509           fmt = "bra.l %0";
3510 #else
3511 #ifdef USE_GAS
3512           fmt = "bra.l %0@PLTPC";
3513 #else
3514           fmt = "bra %0@PLTPC";
3515 #endif
3516 #endif
3517 #else
3518 #ifdef USE_GAS
3519           fmt = "bra.l %0";
3520 #else
3521           fmt = "jra %0,a1";
3522 #endif
3523 #endif
3524         }
3525     }
3526   else
3527     {
3528 #if defined (MOTOROLA) && !defined (USE_GAS)
3529       fmt = "jmp %0";
3530 #else
3531       fmt = "jra %0";
3532 #endif
3533     }
3534
3535   output_asm_insn (fmt, xops);
3536 }