OSDN Git Service

(output_function_prologue): Make a probe instruction if NEED_PROBE if nonzero.
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / m68k.c
1 /* Subroutines for insn-output.c for Motorola 68000 family.
2    Copyright (C) 1987 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20
21 /* Some output-actions in m68k.md need these.  */
22 #include <stdio.h>
23 #include "config.h"
24 #include "rtl.h"
25 #include "regs.h"
26 #include "hard-reg-set.h"
27 #include "real.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "insn-flags.h"
31 #include "output.h"
32 #include "insn-attr.h"
33
34 /* Needed for use_return_insn.  */
35 #include "flags.h"
36
37 #ifdef SUPPORT_SUN_FPA
38
39 /* Index into this array by (register number >> 3) to find the
40    smallest class which contains that register.  */
41 enum reg_class regno_reg_class[]
42   = { DATA_REGS, ADDR_REGS, FP_REGS,
43       LO_FPA_REGS, LO_FPA_REGS, FPA_REGS, FPA_REGS };
44
45 #endif /* defined SUPPORT_SUN_FPA */
46
47 /* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END,
48    if SGS_SWITCH_TABLE.  */
49 int switch_table_difference_label_flag;
50
51 static rtx find_addr_reg ();
52 rtx legitimize_pic_address ();
53 \f
54
55 /* Emit a (use pic_offset_table_rtx) if we used PIC relocation in the 
56    function at any time during the compilation process.  In the future 
57    we should try and eliminate the USE if we can easily determine that 
58    all PIC references were deleted from the current function.  That would 
59    save an address register */
60    
61 finalize_pic ()
62 {
63   if (flag_pic && current_function_uses_pic_offset_table)
64     emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));
65 }
66
67 \f
68 /* This function generates the assembly code for function entry.
69    STREAM is a stdio stream to output the code to.
70    SIZE is an int: how many units of temporary storage to allocate.
71    Refer to the array `regs_ever_live' to determine which registers
72    to save; `regs_ever_live[I]' is nonzero if register number I
73    is ever used in the function.  This function is responsible for
74    knowing which registers should not be saved even if used.  */
75
76
77 /* Note that the order of the bit mask for fmovem is the opposite
78    of the order for movem!  */
79
80
81 void
82 output_function_prologue (stream, size)
83      FILE *stream;
84      int size;
85 {
86   register int regno;
87   register int mask = 0;
88   int num_saved_regs = 0;
89   extern char call_used_regs[];
90   int fsize = (size + 3) & -4;
91   
92
93   if (frame_pointer_needed)
94     {
95       /* Adding negative number is faster on the 68040.  */
96       if (fsize < 0x8000 && !TARGET_68040)
97         {
98 #ifdef MOTOROLA
99           asm_fprintf (stream, "\tlink.w %s,%0I%d\n",
100                        reg_names[FRAME_POINTER_REGNUM], -fsize);
101 #else
102           asm_fprintf (stream, "\tlink %s,%0I%d\n",
103                        reg_names[FRAME_POINTER_REGNUM], -fsize);
104 #endif
105         }
106       else if (TARGET_68020)
107         {
108 #ifdef MOTOROLA
109           asm_fprintf (stream, "\tlink.l %s,%0I%d\n",
110                        reg_names[FRAME_POINTER_REGNUM], -fsize);
111 #else
112           asm_fprintf (stream, "\tlink %s,%0I%d\n",
113                        reg_names[FRAME_POINTER_REGNUM], -fsize);
114 #endif
115         }
116       else
117         {
118 #ifdef MOTOROLA
119           asm_fprintf (stream, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
120                        reg_names[FRAME_POINTER_REGNUM], -fsize);
121 #else
122           asm_fprintf (stream, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
123                        reg_names[FRAME_POINTER_REGNUM], -fsize);
124 #endif
125         }
126     }
127   else if (fsize)
128     {
129       /* Adding negative number is faster on the 68040.  */
130       if (fsize + 4 < 0x8000)
131         {
132 #ifdef MOTOROLA
133           asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", - (fsize + 4));
134 #else
135           asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", - (fsize + 4));
136 #endif
137         }
138       else
139         {
140 #ifdef MOTOROLA
141           asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", - (fsize + 4));
142 #else
143           asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", - (fsize + 4));
144 #endif
145         }
146     }
147 #ifdef SUPPORT_SUN_FPA
148   for (regno = 24; regno < 56; regno++)
149     if (regs_ever_live[regno] && ! call_used_regs[regno])
150       {
151 #ifdef MOTOROLA
152         asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
153                      reg_names[regno]);
154 #else
155         asm_fprintf (stream, "\tfpmoved %s,%Rsp@-\n",
156                      reg_names[regno]);
157 #endif
158       }
159 #endif
160   for (regno = 16; regno < 24; regno++)
161     if (regs_ever_live[regno] && ! call_used_regs[regno])
162        mask |= 1 << (regno - 16);
163   if ((mask & 0xff) != 0)
164     {
165 #ifdef MOTOROLA
166       asm_fprintf (stream, "\tfmovm %0I0x%x,-(%Rsp)\n", mask & 0xff);
167 #else
168       asm_fprintf (stream, "\tfmovem %0I0x%x,%Rsp@-\n", mask & 0xff);
169 #endif
170     }
171   mask = 0;
172   for (regno = 0; regno < 16; regno++)
173     if (regs_ever_live[regno] && ! call_used_regs[regno])
174       {
175         mask |= 1 << (15 - regno);
176         num_saved_regs++;
177       }
178   if (frame_pointer_needed)
179     {
180       mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM));
181       num_saved_regs--;
182     }
183
184 #if NEED_PROBE
185   fprintf (stream, "\ttstl sp@(%d)\n", NEED_PROBE - num_saved_regs * 4);
186 #endif
187
188   if (num_saved_regs <= 2)
189     {
190       /* Store each separately in the same order moveml uses.
191          Using two movel instructions instead of a single moveml
192          is about 15% faster for the 68020 and 68030 at no expense
193          in code size */
194
195       int i;
196
197       /* Undo the work from above. */
198       for (i = 0; i< 16; i++)
199         if (mask & (1 << i))
200           asm_fprintf (stream,
201 #ifdef MOTOROLA
202                        "\t%Omove.l %s,-(%Rsp)\n",
203 #else
204                        "\tmovel %s,%Rsp@-\n",
205 #endif
206                        reg_names[15 - i]);
207     }
208   else if (mask)
209     {
210 #ifdef MOTOROLA
211       asm_fprintf (stream, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask);
212 #else
213       asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@-\n", mask);
214 #endif
215     }
216   if (flag_pic && current_function_uses_pic_offset_table)
217     {
218 #ifdef MOTOROLA
219       asm_fprintf (stream, "\t%Omove.l %0I__GLOBAL_OFFSET_TABLE_, %s\n",
220                    reg_names[PIC_OFFSET_TABLE_REGNUM]);
221       asm_fprintf (stream, "\tlea.l (%Rpc,%s.l),%s\n",
222                    reg_names[PIC_OFFSET_TABLE_REGNUM],
223                    reg_names[PIC_OFFSET_TABLE_REGNUM]);
224 #else
225       asm_fprintf (stream, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
226                    reg_names[PIC_OFFSET_TABLE_REGNUM]);
227       asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",
228                    reg_names[PIC_OFFSET_TABLE_REGNUM],
229                    reg_names[PIC_OFFSET_TABLE_REGNUM]);
230 #endif
231     }
232 }
233 \f
234 /* Return true if this function's epilogue can be output as RTL.  */
235
236 int
237 use_return_insn ()
238 {
239   int regno;
240
241   if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
242     return 0;
243   
244   /* Copied from output_function_epilogue ().  We should probably create a
245      separate layout routine to perform the common work.  */
246   
247   for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
248     if (regs_ever_live[regno] && ! call_used_regs[regno])
249       return 0;
250   
251   return 1;
252 }
253
254 /* This function generates the assembly code for function exit,
255    on machines that need it.  Args are same as for FUNCTION_PROLOGUE.
256
257    The function epilogue should not depend on the current stack pointer!
258    It should use the frame pointer only, if there is a frame pointer.
259    This is mandatory because of alloca; we also take advantage of it to
260    omit stack adjustments before returning.  */
261
262 void
263 output_function_epilogue (stream, size)
264      FILE *stream;
265      int size;
266 {
267   register int regno;
268   register int mask, fmask;
269   register int nregs;
270   int offset, foffset, fpoffset;
271   extern char call_used_regs[];
272   int fsize = (size + 3) & -4;
273   int big = 0;
274   rtx insn = get_last_insn ();
275   
276   /* If the last insn was a BARRIER, we don't have to write any code.  */
277   if (GET_CODE (insn) == NOTE)
278     insn = prev_nonnote_insn (insn);
279   if (insn && GET_CODE (insn) == BARRIER)
280     {
281       /* Output just a no-op so that debuggers don't get confused
282          about which function the pc is in at this address.  */
283       asm_fprintf (stream, "\tnop\n");
284       return;
285     }
286
287 #ifdef FUNCTION_EXTRA_EPILOGUE
288   FUNCTION_EXTRA_EPILOGUE (stream, size);
289 #endif
290   nregs = 0;  fmask = 0; fpoffset = 0;
291 #ifdef SUPPORT_SUN_FPA
292   for (regno = 24 ; regno < 56 ; regno++)
293     if (regs_ever_live[regno] && ! call_used_regs[regno])
294       nregs++;
295   fpoffset = nregs * 8;
296 #endif
297   nregs = 0;
298   for (regno = 16; regno < 24; regno++)
299     if (regs_ever_live[regno] && ! call_used_regs[regno])
300       {
301         nregs++;
302         fmask |= 1 << (23 - regno);
303       }
304   foffset = fpoffset + nregs * 12;
305   nregs = 0;  mask = 0;
306   if (frame_pointer_needed)
307     regs_ever_live[FRAME_POINTER_REGNUM] = 0;
308   for (regno = 0; regno < 16; regno++)
309     if (regs_ever_live[regno] && ! call_used_regs[regno])
310       {
311         nregs++;
312         mask |= 1 << regno;
313       }
314   offset = foffset + nregs * 4;
315   if (offset + fsize >= 0x8000
316       && frame_pointer_needed
317       && (mask || fmask || fpoffset))
318     {
319 #ifdef MOTOROLA
320       asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra0\n", -fsize);
321 #else
322       asm_fprintf (stream, "\tmovel %0I%d,%Ra0\n", -fsize);
323 #endif
324       fsize = 0, big = 1;
325     }
326   if (nregs <= 2)
327     {
328       /* Restore each separately in the same order moveml does.
329          Using two movel instructions instead of a single moveml
330          is about 15% faster for the 68020 and 68030 at no expense
331          in code size. */
332
333       int i;
334
335       /* Undo the work from above. */
336       for (i = 0; i< 16; i++)
337         if (mask & (1 << i))
338           {
339             if (big)
340               {
341 #ifdef MOTOROLA
342                 asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra0.l),%s\n",
343                              offset + fsize,
344                              reg_names[FRAME_POINTER_REGNUM],
345                              reg_names[i]);
346 #else
347                 asm_fprintf (stream, "\tmovel %s@(-%d,%Ra0:l),%s\n",
348                              reg_names[FRAME_POINTER_REGNUM],
349                              offset + fsize, reg_names[i]);
350 #endif
351               }
352             else if (! frame_pointer_needed)
353               {
354 #ifdef MOTOROLA
355                 asm_fprintf (stream, "\t%Omove.l (%Rsp)+,%s\n",
356                              reg_names[i]);
357 #else
358                 asm_fprintf (stream, "\tmovel %Rsp@+,%s\n",
359                              reg_names[i]);
360 #endif
361               }
362             else
363               {
364 #ifdef MOTOROLA
365                 asm_fprintf (stream, "\t%Omove.l -%d(%s),%s\n",
366                              offset + fsize,
367                              reg_names[FRAME_POINTER_REGNUM],
368                              reg_names[i]);
369 #else
370                 asm_fprintf (stream, "\tmovel %s@(-%d),%s\n",
371                              reg_names[FRAME_POINTER_REGNUM],
372                              offset + fsize, reg_names[i]);
373 #endif
374               }
375             offset = offset - 4;
376           }
377     }
378   else if (mask)
379     {
380       if (big)
381         {
382 #ifdef MOTOROLA
383           asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra0.l),%0I0x%x\n",
384                        offset + fsize,
385                        reg_names[FRAME_POINTER_REGNUM],
386                        mask);
387 #else
388           asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra0:l),%0I0x%x\n",
389                        reg_names[FRAME_POINTER_REGNUM],
390                        offset + fsize, mask);
391 #endif
392         }
393       else if (! frame_pointer_needed)
394         {
395 #ifdef MOTOROLA
396           asm_fprintf (stream, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask);
397 #else
398           asm_fprintf (stream, "\tmoveml %Rsp@+,%0I0x%x\n", mask);
399 #endif
400         }
401       else
402         {
403 #ifdef MOTOROLA
404           asm_fprintf (stream, "\tmovm.l -%d(%s),%0I0x%x\n",
405                        offset + fsize,
406                        reg_names[FRAME_POINTER_REGNUM],
407                        mask);
408 #else
409           asm_fprintf (stream, "\tmoveml %s@(-%d),%0I0x%x\n",
410                        reg_names[FRAME_POINTER_REGNUM],
411                        offset + fsize, mask);
412 #endif
413         }
414     }
415   if (fmask)
416     {
417       if (big)
418         {
419 #ifdef MOTOROLA
420           asm_fprintf (stream, "\tfmovm -%d(%s,%Ra0.l),%0I0x%x\n",
421                        foffset + fsize,
422                        reg_names[FRAME_POINTER_REGNUM],
423                        fmask);
424 #else
425           asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra0:l),%0I0x%x\n",
426                        reg_names[FRAME_POINTER_REGNUM],
427                        foffset + fsize, fmask);
428 #endif
429         }
430       else if (! frame_pointer_needed)
431         {
432 #ifdef MOTOROLA
433           asm_fprintf (stream, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask);
434 #else
435           asm_fprintf (stream, "\tfmovem %Rsp@+,%0I0x%x\n", fmask);
436 #endif
437         }
438       else
439         {
440 #ifdef MOTOROLA
441           asm_fprintf (stream, "\tfmovm -%d(%s),%0I0x%x\n",
442                        foffset + fsize,
443                        reg_names[FRAME_POINTER_REGNUM],
444                        fmask);
445 #else
446           asm_fprintf (stream, "\tfmovem %s@(-%d),%0I0x%x\n",
447                        reg_names[FRAME_POINTER_REGNUM],
448                        foffset + fsize, fmask);
449 #endif
450         }
451     }
452   if (fpoffset != 0)
453     for (regno = 55; regno >= 24; regno--)
454       if (regs_ever_live[regno] && ! call_used_regs[regno])
455         {
456           if (big)
457             {
458 #ifdef MOTOROLA
459               asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra0.l), %s\n",
460                            fpoffset + fsize,
461                            reg_names[FRAME_POINTER_REGNUM],
462                            reg_names[regno]);
463 #else
464               asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra0:l), %s\n",
465                            reg_names[FRAME_POINTER_REGNUM],
466                            fpoffset + fsize, reg_names[regno]);
467 #endif
468             }
469           else if (! frame_pointer_needed)
470             {
471 #ifdef MOTOROLA
472               asm_fprintf (stream, "\tfpmovd (%Rsp)+,%s\n",
473                            reg_names[regno]);
474 #else
475               asm_fprintf (stream, "\tfpmoved %Rsp@+, %s\n",
476                            reg_names[regno]);
477 #endif
478             }
479           else
480             {
481 #ifdef MOTOROLA
482               asm_fprintf (stream, "\tfpmovd -%d(%s), %s\n",
483                            fpoffset + fsize,
484                            reg_names[FRAME_POINTER_REGNUM],
485                            reg_names[regno]);
486 #else
487               asm_fprintf (stream, "\tfpmoved %s@(-%d), %s\n",
488                            reg_names[FRAME_POINTER_REGNUM],
489                            fpoffset + fsize, reg_names[regno]);
490 #endif
491             }
492           fpoffset -= 8;
493         }
494   if (frame_pointer_needed)
495     fprintf (stream, "\tunlk %s\n",
496              reg_names[FRAME_POINTER_REGNUM]);
497   else if (fsize)
498     {
499       if (fsize + 4 < 0x8000)
500         {
501 #ifdef MOTOROLA
502           asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4);
503 #else
504           asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", fsize + 4);
505 #endif
506         }
507       else
508         {
509 #ifdef MOTOROLA
510           asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4);
511 #else
512           asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4);
513 #endif
514         }
515     }
516   if (current_function_pops_args)
517     asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
518   else
519     fprintf (stream, "\trts\n");
520 }
521 \f
522 /* Similar to general_operand, but exclude stack_pointer_rtx.  */
523
524 int
525 not_sp_operand (op, mode)
526      register rtx op;
527      enum machine_mode mode;
528 {
529   return op != stack_pointer_rtx && general_operand (op, mode);
530 }
531
532 /* Return TRUE if X is a valid comparison operator for the dbcc 
533    instruction.  
534
535    Note it rejects floating point comparison operators.
536    (In the future we could use Fdbcc).
537
538    It also rejects some comparisons when CC_NO_OVERFLOW is set.  */
539    
540 int
541 valid_dbcc_comparison_p (x, mode)
542      rtx x;
543      enum machine_mode mode;
544 {
545   /* We could add support for these in the future */
546   if (cc_prev_status.flags & CC_IN_68881)
547     return 0;
548
549   switch (GET_CODE (x))
550     {
551
552       case EQ: case NE: case GTU: case LTU:
553       case GEU: case LEU:
554         return 1;
555
556       /* Reject some when CC_NO_OVERFLOW is set.  This may be over
557          conservative */
558       case GT: case LT: case GE: case LE:
559         return ! (cc_prev_status.flags & CC_NO_OVERFLOW);
560       default:
561         return 0;
562     }
563 }
564
565 /* Output a dbCC; jCC sequence.  Note we do not handle the 
566    floating point version of this sequence (Fdbcc).  We also
567    do not handle alternative conditions when CC_NO_OVERFLOW is
568    set.  It is assumed that valid_dbcc_comparison_p will kick
569    those out before we get here.  */
570
571 output_dbcc_and_branch (operands)
572      rtx *operands;
573 {
574  
575   switch (GET_CODE (operands[3]))
576     {
577       case EQ:
578 #ifdef MOTOROLA
579         output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands);
580 #else
581         output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands);
582 #endif
583         break;
584
585       case NE:
586 #ifdef MOTOROLA
587         output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands);
588 #else
589         output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands);
590 #endif
591         break;
592
593       case GT:
594 #ifdef MOTOROLA
595         output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands);
596 #else
597         output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands);
598 #endif
599         break;
600
601       case GTU:
602 #ifdef MOTOROLA
603         output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands);
604 #else
605         output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands);
606 #endif
607         break;
608
609       case LT:
610 #ifdef MOTOROLA
611         output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands);
612 #else
613         output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands);
614 #endif
615         break;
616
617       case LTU:
618 #ifdef MOTOROLA
619         output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands);
620 #else
621         output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands);
622 #endif
623         break;
624
625       case GE:
626 #ifdef MOTOROLA
627         output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands);
628 #else
629         output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands);
630 #endif
631         break;
632
633       case GEU:
634 #ifdef MOTOROLA
635         output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands);
636 #else
637         output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands);
638 #endif
639         break;
640
641       case LE:
642 #ifdef MOTOROLA
643         output_asm_insn ("dble %0,%l1\n\tjble %l2", operands);
644 #else
645         output_asm_insn ("dble %0,%l1\n\tjle %l2", operands);
646 #endif
647         break;
648
649       case LEU:
650 #ifdef MOTOROLA
651         output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands);
652 #else
653         output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands);
654 #endif
655         break;
656
657       default:
658         abort ();
659     }
660
661   /* If the decrement is to be done in SImode, then we have
662      to compensate for the fact that dbcc decrements in HImode. */
663   switch (GET_MODE (operands[0]))
664     {
665       case SImode:
666 #ifdef MOTOROLA
667         output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands);
668 #else
669         output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands);
670 #endif
671         break;
672
673       case HImode:
674         break;
675
676       default:
677         abort ();
678     }
679 }
680
681 char *
682 output_btst (operands, countop, dataop, insn, signpos)
683      rtx *operands;
684      rtx countop, dataop;
685      rtx insn;
686      int signpos;
687 {
688   operands[0] = countop;
689   operands[1] = dataop;
690
691   if (GET_CODE (countop) == CONST_INT)
692     {
693       register int count = INTVAL (countop);
694       /* If COUNT is bigger than size of storage unit in use,
695          advance to the containing unit of same size.  */
696       if (count > signpos)
697         {
698           int offset = (count & ~signpos) / 8;
699           count = count & signpos;
700           operands[1] = dataop = adj_offsettable_operand (dataop, offset);
701         }
702       if (count == signpos)
703         cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
704       else
705         cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N;
706
707       /* These three statements used to use next_insns_test_no...
708          but it appears that this should do the same job.  */
709       if (count == 31
710           && next_insn_tests_no_inequality (insn))
711         return "tst%.l %1";
712       if (count == 15
713           && next_insn_tests_no_inequality (insn))
714         return "tst%.w %1";
715       if (count == 7
716           && next_insn_tests_no_inequality (insn))
717         return "tst%.b %1";
718
719       cc_status.flags = CC_NOT_NEGATIVE;
720     }
721   return "btst %0,%1";
722 }
723 \f
724 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
725    reference and a constant.  */
726
727 int
728 symbolic_operand (op, mode)
729      register rtx op;
730      enum machine_mode mode;
731 {
732   switch (GET_CODE (op))
733     {
734     case SYMBOL_REF:
735     case LABEL_REF:
736       return 1;
737
738     case CONST:
739       op = XEXP (op, 0);
740       return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
741                || GET_CODE (XEXP (op, 0)) == LABEL_REF)
742               && GET_CODE (XEXP (op, 1)) == CONST_INT);
743
744 #if 0 /* Deleted, with corresponding change in m68k.h,
745          so as to fit the specs.  No CONST_DOUBLE is ever symbolic.  */
746     case CONST_DOUBLE:
747       return GET_MODE (op) == mode;
748 #endif
749
750     default:
751       return 0;
752     }
753 }
754
755 \f
756 /* Legitimize PIC addresses.  If the address is already
757    position-independent, we return ORIG.  Newly generated
758    position-independent addresses go to REG.  If we need more
759    than one register, we lose.  
760
761    An address is legitimized by making an indirect reference
762    through the Global Offset Table with the name of the symbol
763    used as an offset.  
764
765    The assembler and linker are responsible for placing the 
766    address of the symbol in the GOT.  The function prologue
767    is responsible for initializing a5 to the starting address
768    of the GOT.
769
770    The assembler is also responsible for translating a symbol name
771    into a constant displacement from the start of the GOT.  
772
773    A quick example may make things a little clearer:
774
775    When not generating PIC code to store the value 12345 into _foo
776    we would generate the following code:
777
778         movel #12345, _foo
779
780    When generating PIC two transformations are made.  First, the compiler
781    loads the address of foo into a register.  So the first transformation makes:
782
783         lea     _foo, a0
784         movel   #12345, a0@
785
786    The code in movsi will intercept the lea instruction and call this
787    routine which will transform the instructions into:
788
789         movel   a5@(_foo:w), a0
790         movel   #12345, a0@
791    
792
793    That (in a nutshell) is how *all* symbol and label references are 
794    handled.  */
795
796 rtx
797 legitimize_pic_address (orig, mode, reg)
798      rtx orig, reg;
799      enum machine_mode mode;
800 {
801   rtx pic_ref = orig;
802
803   /* First handle a simple SYMBOL_REF or LABEL_REF */
804   if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
805     {
806       if (reg == 0)
807         abort ();
808
809       pic_ref = gen_rtx (MEM, Pmode,
810                          gen_rtx (PLUS, Pmode,
811                                   pic_offset_table_rtx, orig));
812       current_function_uses_pic_offset_table = 1;
813       RTX_UNCHANGING_P (pic_ref) = 1;
814       emit_move_insn (reg, pic_ref);
815       return reg;
816     }
817   else if (GET_CODE (orig) == CONST)
818     {
819       rtx base, offset;
820
821       /* Make sure this is CONST has not already been legitimized */
822       if (GET_CODE (XEXP (orig, 0)) == PLUS
823           && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
824         return orig;
825
826       if (reg == 0)
827         abort ();
828
829       /* legitimize both operands of the PLUS */
830       if (GET_CODE (XEXP (orig, 0)) == PLUS)
831         {
832           base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
833           orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
834                                          base == reg ? 0 : reg);
835         }
836       else abort ();
837
838       if (GET_CODE (orig) == CONST_INT)
839         return plus_constant_for_output (base, INTVAL (orig));
840       pic_ref = gen_rtx (PLUS, Pmode, base, orig);
841       /* Likewise, should we set special REG_NOTEs here?  */
842     }
843   return pic_ref;
844 }
845
846 \f
847 /* Return the best assembler insn template
848    for moving operands[1] into operands[0] as a fullword.  */
849
850 static char *
851 singlemove_string (operands)
852      rtx *operands;
853 {
854 #ifdef SUPPORT_SUN_FPA
855   if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))
856     return "fpmoves %1,%0";
857 #endif
858   if (DATA_REG_P (operands[0])
859       && GET_CODE (operands[1]) == CONST_INT
860       && INTVAL (operands[1]) < 128
861       && INTVAL (operands[1]) >= -128)
862     {
863 #if defined (MOTOROLA) && !defined (CRDS)
864       return "moveq%.l %1,%0";
865 #else
866       return "moveq %1,%0";
867 #endif
868     }
869   if (operands[1] != const0_rtx)
870     return "move%.l %1,%0";
871   if (! ADDRESS_REG_P (operands[0]))
872     return "clr%.l %0";
873   return "sub%.l %0,%0";
874 }
875
876 /* Output assembler code to perform a doubleword move insn
877    with operands OPERANDS.  */
878
879 char *
880 output_move_double (operands)
881      rtx *operands;
882 {
883   enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
884   rtx latehalf[2];
885   rtx addreg0 = 0, addreg1 = 0;
886
887   /* First classify both operands.  */
888
889   if (REG_P (operands[0]))
890     optype0 = REGOP;
891   else if (offsettable_memref_p (operands[0]))
892     optype0 = OFFSOP;
893   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
894     optype0 = POPOP;
895   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
896     optype0 = PUSHOP;
897   else if (GET_CODE (operands[0]) == MEM)
898     optype0 = MEMOP;
899   else
900     optype0 = RNDOP;
901
902   if (REG_P (operands[1]))
903     optype1 = REGOP;
904   else if (CONSTANT_P (operands[1]))
905     optype1 = CNSTOP;
906   else if (offsettable_memref_p (operands[1]))
907     optype1 = OFFSOP;
908   else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
909     optype1 = POPOP;
910   else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
911     optype1 = PUSHOP;
912   else if (GET_CODE (operands[1]) == MEM)
913     optype1 = MEMOP;
914   else
915     optype1 = RNDOP;
916
917   /* Check for the cases that the operand constraints are not
918      supposed to allow to happen.  Abort if we get one,
919      because generating code for these cases is painful.  */
920
921   if (optype0 == RNDOP || optype1 == RNDOP)
922     abort ();
923
924   /* If one operand is decrementing and one is incrementing
925      decrement the former register explicitly
926      and change that operand into ordinary indexing.  */
927
928   if (optype0 == PUSHOP && optype1 == POPOP)
929     {
930       operands[0] = XEXP (XEXP (operands[0], 0), 0);
931       output_asm_insn ("subq%.l %#8,%0", operands);
932       operands[0] = gen_rtx (MEM, DImode, operands[0]);
933       optype0 = OFFSOP;
934     }
935   if (optype0 == POPOP && optype1 == PUSHOP)
936     {
937       operands[1] = XEXP (XEXP (operands[1], 0), 0);
938       output_asm_insn ("subq%.l %#8,%1", operands);
939       operands[1] = gen_rtx (MEM, DImode, operands[1]);
940       optype1 = OFFSOP;
941     }
942
943   /* If an operand is an unoffsettable memory ref, find a register
944      we can increment temporarily to make it refer to the second word.  */
945
946   if (optype0 == MEMOP)
947     addreg0 = find_addr_reg (XEXP (operands[0], 0));
948
949   if (optype1 == MEMOP)
950     addreg1 = find_addr_reg (XEXP (operands[1], 0));
951
952   /* Ok, we can do one word at a time.
953      Normally we do the low-numbered word first,
954      but if either operand is autodecrementing then we
955      do the high-numbered word first.
956
957      In either case, set up in LATEHALF the operands to use
958      for the high-numbered word and in some cases alter the
959      operands in OPERANDS to be suitable for the low-numbered word.  */
960
961   if (optype0 == REGOP)
962     latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
963   else if (optype0 == OFFSOP)
964     latehalf[0] = adj_offsettable_operand (operands[0], 4);
965   else
966     latehalf[0] = operands[0];
967
968   if (optype1 == REGOP)
969     latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
970   else if (optype1 == OFFSOP)
971     latehalf[1] = adj_offsettable_operand (operands[1], 4);
972   else if (optype1 == CNSTOP)
973     split_double (operands[1], &operands[1], &latehalf[1]);
974   else
975     latehalf[1] = operands[1];
976
977   /* If insn is effectively movd N(sp),-(sp) then we will do the
978      high word first.  We should use the adjusted operand 1 (which is N+4(sp))
979      for the low word as well, to compensate for the first decrement of sp.  */
980   if (optype0 == PUSHOP
981       && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
982       && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
983     operands[1] = latehalf[1];
984
985   /* If one or both operands autodecrementing,
986      do the two words, high-numbered first.  */
987
988   /* Likewise,  the first move would clobber the source of the second one,
989      do them in the other order.  This happens only for registers;
990      such overlap can't happen in memory unless the user explicitly
991      sets it up, and that is an undefined circumstance.  */
992
993   if (optype0 == PUSHOP || optype1 == PUSHOP
994       || (optype0 == REGOP && optype1 == REGOP
995           && REGNO (operands[0]) == REGNO (latehalf[1])))
996     {
997       /* Make any unoffsettable addresses point at high-numbered word.  */
998       if (addreg0)
999         output_asm_insn ("addql %#4,%0", &addreg0);
1000       if (addreg1)
1001         output_asm_insn ("addql %#4,%0", &addreg1);
1002
1003       /* Do that word.  */
1004       output_asm_insn (singlemove_string (latehalf), latehalf);
1005
1006       /* Undo the adds we just did.  */
1007       if (addreg0)
1008         output_asm_insn ("subql %#4,%0", &addreg0);
1009       if (addreg1)
1010         output_asm_insn ("subql %#4,%0", &addreg1);
1011
1012       /* Do low-numbered word.  */
1013       return singlemove_string (operands);
1014     }
1015
1016   /* Normal case: do the two words, low-numbered first.  */
1017
1018   output_asm_insn (singlemove_string (operands), operands);
1019
1020   /* Make any unoffsettable addresses point at high-numbered word.  */
1021   if (addreg0)
1022     output_asm_insn ("addql %#4,%0", &addreg0);
1023   if (addreg1)
1024     output_asm_insn ("addql %#4,%0", &addreg1);
1025
1026   /* Do that word.  */
1027   output_asm_insn (singlemove_string (latehalf), latehalf);
1028
1029   /* Undo the adds we just did.  */
1030   if (addreg0)
1031     output_asm_insn ("subql %#4,%0", &addreg0);
1032   if (addreg1)
1033     output_asm_insn ("subql %#4,%0", &addreg1);
1034
1035   return "";
1036 }
1037
1038 /* Return a REG that occurs in ADDR with coefficient 1.
1039    ADDR can be effectively incremented by incrementing REG.  */
1040
1041 static rtx
1042 find_addr_reg (addr)
1043      rtx addr;
1044 {
1045   while (GET_CODE (addr) == PLUS)
1046     {
1047       if (GET_CODE (XEXP (addr, 0)) == REG)
1048         addr = XEXP (addr, 0);
1049       else if (GET_CODE (XEXP (addr, 1)) == REG)
1050         addr = XEXP (addr, 1);
1051       else if (CONSTANT_P (XEXP (addr, 0)))
1052         addr = XEXP (addr, 1);
1053       else if (CONSTANT_P (XEXP (addr, 1)))
1054         addr = XEXP (addr, 0);
1055       else
1056         abort ();
1057     }
1058   if (GET_CODE (addr) == REG)
1059     return addr;
1060   abort ();
1061 }
1062 \f
1063 /* Store in cc_status the expressions that the condition codes will
1064    describe after execution of an instruction whose pattern is EXP.
1065    Do not alter them if the instruction would not alter the cc's.  */
1066
1067 /* On the 68000, all the insns to store in an address register fail to
1068    set the cc's.  However, in some cases these instructions can make it
1069    possibly invalid to use the saved cc's.  In those cases we clear out
1070    some or all of the saved cc's so they won't be used.  */
1071
1072 notice_update_cc (exp, insn)
1073      rtx exp;
1074      rtx insn;
1075 {
1076   /* If the cc is being set from the fpa and the expression is not an
1077      explicit floating point test instruction (which has code to deal with
1078      this), reinit the CC.  */
1079   if (((cc_status.value1 && FPA_REG_P (cc_status.value1))
1080        || (cc_status.value2 && FPA_REG_P (cc_status.value2)))
1081       && !(GET_CODE (exp) == PARALLEL
1082            && GET_CODE (XVECEXP (exp, 0, 0)) == SET
1083            && XEXP (XVECEXP (exp, 0, 0), 0) == cc0_rtx))
1084     {
1085       CC_STATUS_INIT; 
1086     }
1087   else if (GET_CODE (exp) == SET)
1088     {
1089       if (GET_CODE (SET_SRC (exp)) == CALL)
1090         {
1091           CC_STATUS_INIT; 
1092         }
1093       else if (ADDRESS_REG_P (SET_DEST (exp)))
1094         {
1095           if (cc_status.value1
1096               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1097             cc_status.value1 = 0;
1098           if (cc_status.value2
1099               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1100             cc_status.value2 = 0; 
1101         }
1102       else if (!FP_REG_P (SET_DEST (exp))
1103                && SET_DEST (exp) != cc0_rtx
1104                && (FP_REG_P (SET_SRC (exp))
1105                    || GET_CODE (SET_SRC (exp)) == FIX
1106                    || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE
1107                    || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND))
1108         {
1109           CC_STATUS_INIT; 
1110         }
1111       /* A pair of move insns doesn't produce a useful overall cc.  */
1112       else if (!FP_REG_P (SET_DEST (exp))
1113                && !FP_REG_P (SET_SRC (exp))
1114                && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
1115                && (GET_CODE (SET_SRC (exp)) == REG
1116                    || GET_CODE (SET_SRC (exp)) == MEM
1117                    || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
1118         {
1119           CC_STATUS_INIT; 
1120         }
1121       else if (GET_CODE (SET_SRC (exp)) == CALL)
1122         {
1123           CC_STATUS_INIT; 
1124         }
1125       else if (XEXP (exp, 0) != pc_rtx)
1126         {
1127           cc_status.flags = 0;
1128           cc_status.value1 = XEXP (exp, 0);
1129           cc_status.value2 = XEXP (exp, 1);
1130         }
1131     }
1132   else if (GET_CODE (exp) == PARALLEL
1133            && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1134     {
1135       if (ADDRESS_REG_P (XEXP (XVECEXP (exp, 0, 0), 0)))
1136         CC_STATUS_INIT;
1137       else if (XEXP (XVECEXP (exp, 0, 0), 0) != pc_rtx)
1138         {
1139           cc_status.flags = 0;
1140           cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
1141           cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1);
1142         }
1143     }
1144   else
1145     CC_STATUS_INIT;
1146   if (cc_status.value2 != 0
1147       && ADDRESS_REG_P (cc_status.value2)
1148       && GET_MODE (cc_status.value2) == QImode)
1149     CC_STATUS_INIT;
1150   if (cc_status.value2 != 0
1151       && !(cc_status.value1 && FPA_REG_P (cc_status.value1)))
1152     switch (GET_CODE (cc_status.value2))
1153       {
1154       case PLUS: case MINUS: case MULT:
1155       case DIV: case UDIV: case MOD: case UMOD: case NEG:
1156       case ASHIFT: case LSHIFT: case ASHIFTRT: case LSHIFTRT:
1157       case ROTATE: case ROTATERT:
1158         if (GET_MODE (cc_status.value2) != VOIDmode)
1159           cc_status.flags |= CC_NO_OVERFLOW;
1160         break;
1161       case ZERO_EXTEND:
1162         /* (SET r1 (ZERO_EXTEND r2)) on this machine
1163            ends with a move insn moving r2 in r2's mode.
1164            Thus, the cc's are set for r2.
1165            This can set N bit spuriously. */
1166         cc_status.flags |= CC_NOT_NEGATIVE; 
1167       }
1168   if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
1169       && cc_status.value2
1170       && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
1171     cc_status.value2 = 0;
1172   if (((cc_status.value1 && FP_REG_P (cc_status.value1))
1173        || (cc_status.value2 && FP_REG_P (cc_status.value2)))
1174       && !((cc_status.value1 && FPA_REG_P (cc_status.value1))
1175            || (cc_status.value2 && FPA_REG_P (cc_status.value2))))
1176     cc_status.flags = CC_IN_68881;
1177 }
1178 \f
1179 char *
1180 output_move_const_double (operands)
1181      rtx *operands;
1182 {
1183 #ifdef SUPPORT_SUN_FPA
1184   if (TARGET_FPA && FPA_REG_P (operands[0]))
1185     {
1186       int code = standard_sun_fpa_constant_p (operands[1]);
1187
1188       if (code != 0)
1189         {
1190           static char buf[40];
1191
1192           sprintf (buf, "fpmove%%.d %%%%%d,%%0", code & 0x1ff);
1193           return buf;
1194         }
1195       return "fpmove%.d %1,%0";
1196     }
1197   else
1198 #endif
1199     {
1200       int code = standard_68881_constant_p (operands[1]);
1201
1202       if (code != 0)
1203         {
1204           static char buf[40];
1205
1206           sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
1207           return buf;
1208         }
1209       return "fmove%.d %1,%0";
1210     }
1211 }
1212
1213 char *
1214 output_move_const_single (operands)
1215      rtx *operands;
1216 {
1217 #ifdef SUPPORT_SUN_FPA
1218   if (TARGET_FPA)
1219     {
1220       int code = standard_sun_fpa_constant_p (operands[1]);
1221
1222       if (code != 0)
1223         {
1224           static char buf[40];
1225
1226           sprintf (buf, "fpmove%%.s %%%%%d,%%0", code & 0x1ff);
1227           return buf;
1228         }
1229       return "fpmove%.s %1,%0";
1230     }
1231   else
1232 #endif /* defined SUPPORT_SUN_FPA */
1233     {
1234       int code = standard_68881_constant_p (operands[1]);
1235
1236       if (code != 0)
1237         {
1238           static char buf[40];
1239
1240           sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
1241           return buf;
1242         }
1243       return "fmove%.s %f1,%0";
1244     }
1245 }
1246
1247 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
1248    from the "fmovecr" instruction.
1249    The value, anded with 0xff, gives the code to use in fmovecr
1250    to get the desired constant.  */
1251
1252 /* ??? This code should be fixed for cross-compilation. */
1253
1254 int
1255 standard_68881_constant_p (x)
1256      rtx x;
1257 {
1258   union {double d; int i[2];} u;
1259   register double d;
1260
1261   /* fmovecr must be emulated on the 68040, so it shouldn't be used at all. */
1262   if (TARGET_68040)
1263     return 0;
1264
1265 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
1266   if (! flag_pretend_float)
1267     return 0;
1268 #endif
1269
1270 #ifdef HOST_WORDS_BIG_ENDIAN
1271   u.i[0] = CONST_DOUBLE_LOW (x);
1272   u.i[1] = CONST_DOUBLE_HIGH (x);
1273 #else
1274   u.i[0] = CONST_DOUBLE_HIGH (x);
1275   u.i[1] = CONST_DOUBLE_LOW (x);
1276 #endif 
1277   d = u.d;
1278
1279   if (d == 0)
1280     return 0x0f;
1281   /* Note: there are various other constants available
1282      but it is a nuisance to put in their values here.  */
1283   if (d == 1)
1284     return 0x32;
1285   if (d == 10)
1286     return 0x33;
1287   if (d == 100)
1288     return 0x34;
1289   if (d == 10000)
1290     return 0x35;
1291   if (d == 1e8)
1292     return 0x36;
1293   if (GET_MODE (x) == SFmode)
1294     return 0;
1295   if (d == 1e16)
1296     return 0x37;
1297   /* larger powers of ten in the constants ram are not used
1298      because they are not equal to a `double' C constant.  */
1299   return 0;
1300 }
1301
1302 /* If X is a floating-point constant, return the logarithm of X base 2,
1303    or 0 if X is not a power of 2.  */
1304
1305 int
1306 floating_exact_log2 (x)
1307      rtx x;
1308 {
1309   union {double d; int i[2];} u;
1310   register double d, d1;
1311   int i;
1312
1313 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
1314   if (! flag_pretend_float)
1315     return 0;
1316 #endif
1317
1318 #ifdef HOST_WORDS_BIG_ENDIAN
1319   u.i[0] = CONST_DOUBLE_LOW (x);
1320   u.i[1] = CONST_DOUBLE_HIGH (x);
1321 #else
1322   u.i[0] = CONST_DOUBLE_HIGH (x);
1323   u.i[1] = CONST_DOUBLE_LOW (x);
1324 #endif 
1325   d = u.d;
1326
1327   if (! (d > 0))
1328     return 0;
1329
1330   for (d1 = 1.0, i = 0; d1 < d; d1 *= 2.0, i++)
1331     ;
1332
1333   if (d == d1)
1334     return i;
1335
1336   return 0;
1337 }
1338 \f
1339 #ifdef SUPPORT_SUN_FPA
1340 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
1341    from the Sun FPA's constant RAM.
1342    The value returned, anded with 0x1ff, gives the code to use in fpmove
1343    to get the desired constant. */
1344 #define S_E (2.718281745910644531)
1345 #define D_E (2.718281828459045091)
1346 #define S_PI (3.141592741012573242)
1347 #define D_PI (3.141592653589793116)
1348 #define S_SQRT2 (1.414213538169860840)
1349 #define D_SQRT2 (1.414213562373095145)
1350 #define S_LOG2ofE (1.442695021629333496)
1351 #define D_LOG2ofE (1.442695040888963387)
1352 #define S_LOG2of10 (3.321928024291992188)
1353 #define D_LOG2of10 (3.321928024887362182)
1354 #define S_LOGEof2 (0.6931471824645996094)
1355 #define D_LOGEof2 (0.6931471805599452862)
1356 #define S_LOGEof10 (2.302585124969482442)
1357 #define D_LOGEof10 (2.302585092994045901)
1358 #define S_LOG10of2 (0.3010300099849700928)
1359 #define D_LOG10of2 (0.3010299956639811980)
1360 #define S_LOG10ofE (0.4342944920063018799)
1361 #define D_LOG10ofE (0.4342944819032518167)
1362
1363 /* This code should be fixed for cross-compilation. */
1364
1365 int
1366 standard_sun_fpa_constant_p (x)
1367      rtx x;
1368 {
1369   union {double d; int i[2];} u;
1370   register double d;
1371
1372 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
1373   if (! flag_pretend_float)
1374     return 0;
1375 #endif
1376
1377
1378   u.i[0] = CONST_DOUBLE_LOW (x);
1379   u.i[1] = CONST_DOUBLE_HIGH (x);
1380   d = u.d;
1381
1382   if (d == 0.0)
1383     return 0x200;               /* 0 once 0x1ff is anded with it */
1384   if (d == 1.0)
1385     return 0xe;
1386   if (d == 0.5)
1387     return 0xf;
1388   if (d == -1.0)
1389     return 0x10;
1390   if (d == 2.0)
1391     return 0x11;
1392   if (d == 3.0)
1393     return 0xB1;
1394   if (d == 4.0)
1395     return 0x12;
1396   if (d == 8.0)
1397     return 0x13;
1398   if (d == 0.25)
1399     return 0x15;
1400   if (d == 0.125)
1401     return 0x16;
1402   if (d == 10.0)
1403     return 0x17;
1404   if (d == -(1.0/2.0))
1405     return 0x2E;
1406
1407 /*
1408  * Stuff that looks different if it's single or double
1409  */
1410   if (GET_MODE (x) == SFmode)
1411     {
1412       if (d == S_E)
1413         return 0x8;
1414       if (d == (2*S_PI))
1415         return 0x9;
1416       if (d == S_PI)
1417         return 0xA;
1418       if (d == (S_PI / 2.0))
1419         return 0xB;
1420       if (d == S_SQRT2)
1421         return 0xC;
1422       if (d == (1.0 / S_SQRT2))
1423         return 0xD;
1424       /* Large powers of 10 in the constant 
1425          ram are not used because they are
1426          not equal to a C double constant  */
1427       if (d == -(S_PI / 2.0))
1428         return 0x27;
1429       if (d == S_LOG2ofE)
1430         return 0x28;
1431       if (d == S_LOG2of10)
1432         return 0x29;
1433       if (d == S_LOGEof2)
1434         return 0x2A;
1435       if (d == S_LOGEof10)
1436         return 0x2B;
1437       if (d == S_LOG10of2)
1438         return 0x2C;
1439       if (d == S_LOG10ofE)
1440         return 0x2D;
1441     }
1442   else
1443     {
1444       if (d == D_E)
1445         return 0x8;
1446       if (d == (2*D_PI))
1447         return 0x9;
1448       if (d == D_PI)
1449         return 0xA;
1450       if (d == (D_PI / 2.0))
1451         return 0xB;
1452       if (d == D_SQRT2)
1453         return 0xC;
1454       if (d == (1.0 / D_SQRT2))
1455         return 0xD;
1456       /* Large powers of 10 in the constant 
1457          ram are not used because they are
1458          not equal to a C double constant  */
1459       if (d == -(D_PI / 2.0))
1460         return 0x27;
1461       if (d == D_LOG2ofE)
1462         return 0x28;
1463       if (d == D_LOG2of10)
1464         return 0x29;
1465       if (d == D_LOGEof2)
1466         return 0x2A;
1467       if (d == D_LOGEof10)
1468         return 0x2B;
1469       if (d == D_LOG10of2)
1470         return 0x2C;
1471       if (d == D_LOG10ofE)
1472         return 0x2D;
1473     }
1474   return 0x0;
1475 }
1476 #endif /* define SUPPORT_SUN_FPA */
1477 \f
1478 /* A C compound statement to output to stdio stream STREAM the
1479    assembler syntax for an instruction operand X.  X is an RTL
1480    expression.
1481
1482    CODE is a value that can be used to specify one of several ways
1483    of printing the operand.  It is used when identical operands
1484    must be printed differently depending on the context.  CODE
1485    comes from the `%' specification that was used to request
1486    printing of the operand.  If the specification was just `%DIGIT'
1487    then CODE is 0; if the specification was `%LTR DIGIT' then CODE
1488    is the ASCII code for LTR.
1489
1490    If X is a register, this macro should print the register's name.
1491    The names can be found in an array `reg_names' whose type is
1492    `char *[]'.  `reg_names' is initialized from `REGISTER_NAMES'.
1493
1494    When the machine description has a specification `%PUNCT' (a `%'
1495    followed by a punctuation character), this macro is called with
1496    a null pointer for X and the punctuation character for CODE.
1497
1498    The m68k specific codes are:
1499
1500    '.' for dot needed in Motorola-style opcode names.
1501    '-' for an operand pushing on the stack:
1502        sp@-, -(sp) or -(%sp) depending on the style of syntax.
1503    '+' for an operand pushing on the stack:
1504        sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
1505    '@' for a reference to the top word on the stack:
1506        sp@, (sp) or (%sp) depending on the style of syntax.
1507    '#' for an immediate operand prefix (# in MIT and Motorola syntax
1508        but & in SGS syntax).
1509    '!' for the cc register (used in an `and to cc' insn).
1510    '$' for the letter `s' in an op code, but only on the 68040.
1511    '&' for the letter `d' in an op code, but only on the 68040.
1512
1513    'b' for byte insn (no effect, on the Sun; this is for the ISI).
1514    'd' to force memory addressing to be absolute, not relative.
1515    'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
1516    'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
1517        than directly).  Second part of 'y' below.
1518    'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
1519        or print pair of registers as rx:ry.
1520    'y' for a FPA insn (print pair of registers as rx:ry).  This also outputs
1521        CONST_DOUBLE's as SunFPA constant RAM registers if
1522        possible, so it should not be used except for the SunFPA.
1523
1524    */
1525
1526 void
1527 print_operand (file, op, letter)
1528      FILE *file;                /* file to write to */
1529      rtx op;                    /* operand to print */
1530      int letter;                /* %<letter> or 0 */
1531 {
1532   int i;
1533
1534   if (letter == '.')
1535     {
1536 #ifdef MOTOROLA
1537       asm_fprintf (file, ".");
1538 #endif
1539     }
1540   else if (letter == '#')
1541     {
1542       asm_fprintf (file, "%0I");
1543     }
1544   else if (letter == '-')
1545     {
1546 #ifdef MOTOROLA
1547       asm_fprintf (file, "-(%Rsp)");
1548 #else
1549       asm_fprintf (file, "%Rsp@-");
1550 #endif
1551     }
1552   else if (letter == '+')
1553     {
1554 #ifdef MOTOROLA
1555       asm_fprintf (file, "(%Rsp)+");
1556 #else
1557       asm_fprintf (file, "%Rsp@+");
1558 #endif
1559     }
1560   else if (letter == '@')
1561     {
1562 #ifdef MOTOROLA
1563       asm_fprintf (file, "(%Rsp)");
1564 #else
1565       asm_fprintf (file, "%Rsp@");
1566 #endif
1567     }
1568   else if (letter == '!')
1569     {
1570       asm_fprintf (file, "%Rfpcr");
1571     }
1572   else if (letter == '$')
1573     {
1574       if (TARGET_68040_ONLY)
1575         {
1576           fprintf (file, "s");
1577         }
1578     }
1579   else if (letter == '&')
1580     {
1581       if (TARGET_68040_ONLY)
1582         {
1583           fprintf (file, "d");
1584         }
1585     }
1586   else if (GET_CODE (op) == REG)
1587     {
1588       if (REGNO (op) < 16
1589           && (letter == 'y' || letter == 'x')
1590           && GET_MODE (op) == DFmode)
1591         {
1592           fprintf (file, "%s:%s", reg_names[REGNO (op)],
1593                    reg_names[REGNO (op)+1]);
1594         }
1595       else
1596         {
1597           fprintf (file, "%s", reg_names[REGNO (op)]);
1598         }
1599     }
1600   else if (GET_CODE (op) == MEM)
1601     {
1602       output_address (XEXP (op, 0));
1603       if (letter == 'd' && ! TARGET_68020
1604           && CONSTANT_ADDRESS_P (XEXP (op, 0))
1605           && !(GET_CODE (XEXP (op, 0)) == CONST_INT
1606                && INTVAL (XEXP (op, 0)) < 0x8000
1607                && INTVAL (XEXP (op, 0)) >= -0x8000))
1608         {
1609           fprintf (file, ":l");
1610         }
1611     }
1612 #ifdef SUPPORT_SUN_FPA
1613   else if ((letter == 'y' || letter == 'w')
1614            && GET_CODE (op) == CONST_DOUBLE
1615            && (i = standard_sun_fpa_constant_p (op)))
1616     {
1617       fprintf (file, "%%%d", i & 0x1ff);
1618     }
1619 #endif
1620   else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
1621     {
1622       union { double d; int i[2]; } u;
1623       union { float f; int i; } u1;
1624       PRINT_OPERAND_EXTRACT_FLOAT (op);
1625       u1.f = u.d;
1626       PRINT_OPERAND_PRINT_FLOAT (letter, file);
1627     }
1628   else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) != DImode)
1629     {
1630       union { double d; int i[2]; } u;
1631       PRINT_OPERAND_EXTRACT_FLOAT (op);
1632       ASM_OUTPUT_DOUBLE_OPERAND (file, u.d);
1633     }
1634   else
1635     {
1636       asm_fprintf (file, "%0I"); output_addr_const (file, op);
1637     }
1638 }
1639
1640 \f
1641 /* A C compound statement to output to stdio stream STREAM the
1642    assembler syntax for an instruction operand that is a memory
1643    reference whose address is ADDR.  ADDR is an RTL expression.
1644
1645    Note that this contains a kludge that knows that the only reason
1646    we have an address (plus (label_ref...) (reg...)) when not generating
1647    PIC code is in the insn before a tablejump, and we know that m68k.md
1648    generates a label LInnn: on such an insn.
1649
1650    It is possible for PIC to generate a (plus (label_ref...) (reg...))
1651    and we handle that just like we would a (plus (symbol_ref...) (reg...)).
1652
1653    Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
1654    fails to assemble.  Luckily "Lnnn(pc,d0.l*2)" produces the results
1655    we want.  This difference can be accommodated by using an assembler
1656    define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
1657    string, as necessary.  This is accomplished via the ASM_OUTPUT_CASE_END
1658    macro.  See m68ksgs.h for an example; for versions without the bug.
1659
1660    They also do not like things like "pea 1.w", so we simple leave off
1661    the .w on small constants. 
1662
1663    This routine is responsible for distinguishing between -fpic and -fPIC 
1664    style relocations in an address.  When generating -fpic code the
1665    offset is output in word mode (eg movel a5@(_foo:w), a0).  When generating
1666    -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
1667
1668 void
1669 print_operand_address (file, addr)
1670      FILE *file;
1671      rtx addr;
1672 {
1673   register rtx reg1, reg2, breg, ireg;
1674   rtx offset;
1675
1676   switch (GET_CODE (addr))
1677     {
1678       case REG:
1679 #ifdef MOTOROLA
1680         fprintf (file, "(%s)", reg_names[REGNO (addr)]);
1681 #else
1682         fprintf (file, "%s@", reg_names[REGNO (addr)]);
1683 #endif
1684         break;
1685       case PRE_DEC:
1686 #ifdef MOTOROLA
1687         fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
1688 #else
1689         fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);
1690 #endif
1691         break;
1692       case POST_INC:
1693 #ifdef MOTOROLA
1694         fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
1695 #else
1696         fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);
1697 #endif
1698         break;
1699       case PLUS:
1700         reg1 = reg2 = ireg = breg = offset = 0;
1701         if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
1702           {
1703             offset = XEXP (addr, 0);
1704             addr = XEXP (addr, 1);
1705           }
1706         else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
1707           {
1708             offset = XEXP (addr, 1);
1709             addr = XEXP (addr, 0);
1710           }
1711         if (GET_CODE (addr) != PLUS)
1712           {
1713             ;
1714           }
1715         else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
1716           {
1717             reg1 = XEXP (addr, 0);
1718             addr = XEXP (addr, 1);
1719           }
1720         else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
1721           {
1722             reg1 = XEXP (addr, 1);
1723             addr = XEXP (addr, 0);
1724           }
1725         else if (GET_CODE (XEXP (addr, 0)) == MULT)
1726           {
1727             reg1 = XEXP (addr, 0);
1728             addr = XEXP (addr, 1);
1729           }
1730         else if (GET_CODE (XEXP (addr, 1)) == MULT)
1731           {
1732             reg1 = XEXP (addr, 1);
1733             addr = XEXP (addr, 0);
1734           }
1735         else if (GET_CODE (XEXP (addr, 0)) == REG)
1736           {
1737             reg1 = XEXP (addr, 0);
1738             addr = XEXP (addr, 1);
1739           }
1740         else if (GET_CODE (XEXP (addr, 1)) == REG)
1741           {
1742             reg1 = XEXP (addr, 1);
1743             addr = XEXP (addr, 0);
1744           }
1745         if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
1746             || GET_CODE (addr) == SIGN_EXTEND)
1747           {
1748             if (reg1 == 0)
1749               {
1750                 reg1 = addr;
1751               }
1752             else
1753               {
1754                 reg2 = addr;
1755               }
1756             addr = 0;
1757           }
1758 #if 0   /* for OLD_INDEXING */
1759         else if (GET_CODE (addr) == PLUS)
1760           {
1761             if (GET_CODE (XEXP (addr, 0)) == REG)
1762               {
1763                 reg2 = XEXP (addr, 0);
1764                 addr = XEXP (addr, 1);
1765               }
1766             else if (GET_CODE (XEXP (addr, 1)) == REG)
1767               {
1768                 reg2 = XEXP (addr, 1);
1769                 addr = XEXP (addr, 0);
1770               }
1771           }
1772 #endif
1773         if (offset != 0)
1774           {
1775             if (addr != 0)
1776               {
1777                 abort ();
1778               }
1779             addr = offset;
1780           }
1781         if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
1782                       || GET_CODE (reg1) == MULT))
1783             || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
1784           {
1785             breg = reg2;
1786             ireg = reg1;
1787           }
1788         else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
1789           {
1790             breg = reg1;
1791             ireg = reg2;
1792           }
1793         if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
1794           && ! (flag_pic && ireg == pic_offset_table_rtx))
1795           {
1796             int scale = 1;
1797             if (GET_CODE (ireg) == MULT)
1798               {
1799                 scale = INTVAL (XEXP (ireg, 1));
1800                 ireg = XEXP (ireg, 0);
1801               }
1802             if (GET_CODE (ireg) == SIGN_EXTEND)
1803               {
1804 #ifdef MOTOROLA
1805 #ifdef SGS
1806                 asm_fprintf (file, "%LLD%d(%Rpc,%s.w",
1807                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
1808                              reg_names[REGNO (XEXP (ireg, 0))]);
1809 #else
1810                 asm_fprintf (file, "%LL%d-%LLI%d-2.b(%Rpc,%s.w",
1811                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
1812                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
1813                              reg_names[REGNO (XEXP (ireg, 0))]);
1814 #endif
1815 #else
1816                 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:w",
1817                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
1818                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
1819                              reg_names[REGNO (XEXP (ireg, 0))]);
1820 #endif
1821               }
1822             else
1823               {
1824 #ifdef MOTOROLA
1825 #ifdef SGS
1826                 asm_fprintf (file, "%LLD%d(%Rpc,%s.l",
1827                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
1828                              reg_names[REGNO (ireg)]);
1829 #else
1830                 asm_fprintf (file, "%LL%d-%LLI%d-2.b(%Rpc,%s.l",
1831                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
1832                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
1833                              reg_names[REGNO (ireg)]);
1834 #endif
1835 #else
1836                 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l",
1837                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
1838                              CODE_LABEL_NUMBER (XEXP (addr, 0)),
1839                              reg_names[REGNO (ireg)]);
1840 #endif
1841               }
1842             if (scale != 1)
1843               {
1844 #ifdef MOTOROLA
1845                 fprintf (file, "*%d", scale);
1846 #else
1847                 fprintf (file, ":%d", scale);
1848 #endif
1849               }
1850             putc (')', file);
1851             break;
1852           }
1853         if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
1854           && ! (flag_pic && breg == pic_offset_table_rtx))
1855           {
1856 #ifdef MOTOROLA
1857 #ifdef SGS
1858             asm_fprintf (file, "%LLD%d(%Rpc,%s.l",
1859                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
1860                          reg_names[REGNO (breg)]);
1861 #else
1862             asm_fprintf (file, "%LL%d-%LLI%d-2.b(%Rpc,%s.l",
1863                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
1864                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
1865                          reg_names[REGNO (breg)]);
1866 #endif
1867 #else
1868             asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l",
1869                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
1870                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
1871                          reg_names[REGNO (breg)]);
1872 #endif
1873             putc (')', file);
1874             break;
1875           }
1876         if (ireg != 0 || breg != 0)
1877           {
1878             int scale = 1;
1879             if (breg == 0)
1880               {
1881                 abort ();
1882               }
1883             if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)
1884               {
1885                 abort ();
1886               }
1887 #ifdef MOTOROLA
1888             if (addr != 0)
1889               {
1890                 output_addr_const (file, addr);
1891                 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
1892                   fprintf (file, ".w");
1893                 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
1894                   fprintf (file, ".l");
1895               }
1896             fprintf (file, "(%s", reg_names[REGNO (breg)]);
1897             if (ireg != 0)
1898               {
1899                 putc (',', file);
1900               }
1901 #else
1902             fprintf (file, "%s@(", reg_names[REGNO (breg)]);
1903             if (addr != 0)
1904               {
1905                 output_addr_const (file, addr);
1906                 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
1907                   fprintf (file, ":w");
1908                 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
1909                   fprintf (file, ":l");
1910               }
1911             if (addr != 0 && ireg != 0)
1912               {
1913                 putc (',', file);
1914               }
1915 #endif
1916             if (ireg != 0 && GET_CODE (ireg) == MULT)
1917               {
1918                 scale = INTVAL (XEXP (ireg, 1));
1919                 ireg = XEXP (ireg, 0);
1920               }
1921             if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
1922               {
1923 #ifdef MOTOROLA
1924                 fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);
1925 #else
1926                 fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);
1927 #endif
1928               }
1929             else if (ireg != 0)
1930               {
1931 #ifdef MOTOROLA
1932                 fprintf (file, "%s.l", reg_names[REGNO (ireg)]);
1933 #else
1934                 fprintf (file, "%s:l", reg_names[REGNO (ireg)]);
1935 #endif
1936               }
1937             if (scale != 1)
1938               {
1939 #ifdef MOTOROLA
1940                 fprintf (file, "*%d", scale);
1941 #else
1942                 fprintf (file, ":%d", scale);
1943 #endif
1944               }
1945             putc (')', file);
1946             break;
1947           }
1948         else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
1949                && ! (flag_pic && reg1 == pic_offset_table_rtx)) 
1950           {
1951 #ifdef MOTOROLA
1952 #ifdef SGS
1953             asm_fprintf (file, "%LLD%d(%Rpc,%s.l)",
1954                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
1955                          reg_names[REGNO (reg1)]);
1956 #else
1957             asm_fprintf (file, "%LL%d-%LLI%d-2.b(%Rpc,%s.l)",
1958                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
1959                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
1960                          reg_names[REGNO (reg1)]);
1961 #endif
1962 #else
1963             asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l)",
1964                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
1965                          CODE_LABEL_NUMBER (XEXP (addr, 0)),
1966                          reg_names[REGNO (reg1)]);
1967 #endif
1968             break;
1969           }
1970         /* FALL-THROUGH (is this really what we want? */
1971       default:
1972         if (GET_CODE (addr) == CONST_INT
1973             && INTVAL (addr) < 0x8000
1974             && INTVAL (addr) >= -0x8000)
1975           {
1976 #ifdef MOTOROLA
1977 #ifdef SGS
1978             /* Many SGS assemblers croak on size specifiers for constants. */
1979             fprintf (file, "%d", INTVAL (addr));
1980 #else
1981             fprintf (file, "%d.w", INTVAL (addr));
1982 #endif
1983 #else
1984             fprintf (file, "%d:w", INTVAL (addr));
1985 #endif
1986           }
1987         else
1988           {
1989             output_addr_const (file, addr);
1990           }
1991         break;
1992     }
1993 }