OSDN Git Service

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