OSDN Git Service

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