OSDN Git Service

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