OSDN Git Service

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