(const_method): Do not synthesize long constants with byte or word
[gcc.git] / gcc / config / m68k / m68k.c
1 /* Subroutines for insn-output.c for Motorola 68000 family.
2 Copyright (C) 1987, 1993, 1994, 1995, 1996 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, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 /* Some output-actions in m68k.md need these. */
23 #include <stdio.h>
24 #include "config.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "real.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
32 #include "output.h"
33 #include "insn-attr.h"
34
35 /* Needed for use_return_insn. */
36 #include "flags.h"
37
38 #ifdef SUPPORT_SUN_FPA
39
40 /* Index into this array by (register number >> 3) to find the
41 smallest class which contains that register. */
42 enum reg_class regno_reg_class[]
43 = { DATA_REGS, ADDR_REGS, FP_REGS,
44 LO_FPA_REGS, LO_FPA_REGS, FPA_REGS, FPA_REGS };
45
46 #endif /* defined SUPPORT_SUN_FPA */
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 ();
53 rtx legitimize_pic_address ();
54 \f
55
56 /* Emit a (use pic_offset_table_rtx) if we used PIC relocation in the
57 function at any time during the compilation process. In the future
58 we should try and eliminate the USE if we can easily determine that
59 all PIC references were deleted from the current function. That would
60 save an address register */
61
62 void
63 finalize_pic ()
64 {
65 if (flag_pic && current_function_uses_pic_offset_table)
66 {
67 rtx insn = gen_rtx (USE, VOIDmode, pic_offset_table_rtx);
68 emit_insn_after (insn, get_insns ());
69 emit_insn (insn);
70 }
71 }
72
73 \f
74 /* This function generates the assembly code for function entry.
75 STREAM is a stdio stream to output the code to.
76 SIZE is an int: how many units of temporary storage to allocate.
77 Refer to the array `regs_ever_live' to determine which registers
78 to save; `regs_ever_live[I]' is nonzero if register number I
79 is ever used in the function. This function is responsible for
80 knowing which registers should not be saved even if used. */
81
82
83 /* Note that the order of the bit mask for fmovem is the opposite
84 of the order for movem! */
85
86
87 void
88 output_function_prologue (stream, size)
89 FILE *stream;
90 int size;
91 {
92 register int regno;
93 register int mask = 0;
94 int num_saved_regs = 0;
95 extern char call_used_regs[];
96 int fsize = (size + 3) & -4;
97
98
99 if (frame_pointer_needed)
100 {
101 if (fsize == 0 && TARGET_68040)
102 {
103 /* on the 68040, pea + move is faster than link.w 0 */
104 #ifdef MOTOROLA
105 asm_fprintf (stream, "\tpea (%s)\n\tmove.l %s,%s\n",
106 reg_names[FRAME_POINTER_REGNUM], reg_names[STACK_POINTER_REGNUM],
107 reg_names[FRAME_POINTER_REGNUM]);
108 #else
109 asm_fprintf (stream, "\tpea %s@\n\tmovel %s,%s\n",
110 reg_names[FRAME_POINTER_REGNUM], reg_names[STACK_POINTER_REGNUM],
111 reg_names[FRAME_POINTER_REGNUM]);
112 #endif
113 }
114 else if (fsize < 0x8000)
115 {
116 #ifdef MOTOROLA
117 asm_fprintf (stream, "\tlink.w %s,%0I%d\n",
118 reg_names[FRAME_POINTER_REGNUM], -fsize);
119 #else
120 asm_fprintf (stream, "\tlink %s,%0I%d\n",
121 reg_names[FRAME_POINTER_REGNUM], -fsize);
122 #endif
123 }
124 else if (TARGET_68020)
125 {
126 #ifdef MOTOROLA
127 asm_fprintf (stream, "\tlink.l %s,%0I%d\n",
128 reg_names[FRAME_POINTER_REGNUM], -fsize);
129 #else
130 asm_fprintf (stream, "\tlink %s,%0I%d\n",
131 reg_names[FRAME_POINTER_REGNUM], -fsize);
132 #endif
133 }
134 else
135 {
136 /* Adding negative number is faster on the 68040. */
137 #ifdef MOTOROLA
138 asm_fprintf (stream, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n",
139 reg_names[FRAME_POINTER_REGNUM], -fsize);
140 #else
141 asm_fprintf (stream, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n",
142 reg_names[FRAME_POINTER_REGNUM], -fsize);
143 #endif
144 }
145 }
146 else if (fsize)
147 {
148 /* Adding negative number is faster on the 68040. */
149 if (fsize + 4 < 0x8000)
150 {
151 /* asm_fprintf() cannot handle %. */
152 #ifdef MOTOROLA
153 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", - (fsize + 4));
154 #else
155 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", - (fsize + 4));
156 #endif
157 }
158 else
159 {
160 /* asm_fprintf() cannot handle %. */
161 #ifdef MOTOROLA
162 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", - (fsize + 4));
163 #else
164 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", - (fsize + 4));
165 #endif
166 }
167 }
168 #ifdef SUPPORT_SUN_FPA
169 for (regno = 24; regno < 56; regno++)
170 if (regs_ever_live[regno] && ! call_used_regs[regno])
171 {
172 #ifdef MOTOROLA
173 asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
174 reg_names[regno]);
175 #else
176 asm_fprintf (stream, "\tfpmoved %s,%Rsp@-\n",
177 reg_names[regno]);
178 #endif
179 }
180 #endif
181 for (regno = 16; regno < 24; regno++)
182 if (regs_ever_live[regno] && ! call_used_regs[regno])
183 mask |= 1 << (regno - 16);
184 if ((mask & 0xff) != 0)
185 {
186 #ifdef MOTOROLA
187 asm_fprintf (stream, "\tfmovm %0I0x%x,-(%Rsp)\n", mask & 0xff);
188 #else
189 asm_fprintf (stream, "\tfmovem %0I0x%x,%Rsp@-\n", mask & 0xff);
190 #endif
191 }
192 mask = 0;
193 for (regno = 0; regno < 16; regno++)
194 if (regs_ever_live[regno] && ! call_used_regs[regno])
195 {
196 mask |= 1 << (15 - regno);
197 num_saved_regs++;
198 }
199 if (frame_pointer_needed)
200 {
201 mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM));
202 num_saved_regs--;
203 }
204
205 #if NEED_PROBE
206 fprintf (stream, "\ttstl sp@(%d)\n", NEED_PROBE - num_saved_regs * 4);
207 #endif
208
209 if (num_saved_regs <= 2)
210 {
211 /* Store each separately in the same order moveml uses.
212 Using two movel instructions instead of a single moveml
213 is about 15% faster for the 68020 and 68030 at no expense
214 in code size */
215
216 int i;
217
218 /* Undo the work from above. */
219 for (i = 0; i< 16; i++)
220 if (mask & (1 << i))
221 asm_fprintf (stream,
222 #ifdef MOTOROLA
223 "\t%Omove.l %s,-(%Rsp)\n",
224 #else
225 "\tmovel %s,%Rsp@-\n",
226 #endif
227 reg_names[15 - i]);
228 }
229 else if (mask)
230 {
231 #ifdef MOTOROLA
232 asm_fprintf (stream, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask);
233 #else
234 asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@-\n", mask);
235 #endif
236 }
237 if (flag_pic && current_function_uses_pic_offset_table)
238 {
239 #ifdef MOTOROLA
240 asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
241 reg_names[PIC_OFFSET_TABLE_REGNUM]);
242 #else
243 asm_fprintf (stream, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
244 reg_names[PIC_OFFSET_TABLE_REGNUM]);
245 asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",
246 reg_names[PIC_OFFSET_TABLE_REGNUM],
247 reg_names[PIC_OFFSET_TABLE_REGNUM]);
248 #endif
249 }
250 }
251 \f
252 /* Return true if this function's epilogue can be output as RTL. */
253
254 int
255 use_return_insn ()
256 {
257 int regno;
258
259 if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
260 return 0;
261
262 /* Copied from output_function_epilogue (). We should probably create a
263 separate layout routine to perform the common work. */
264
265 for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
266 if (regs_ever_live[regno] && ! call_used_regs[regno])
267 return 0;
268
269 return 1;
270 }
271
272 /* This function generates the assembly code for function exit,
273 on machines that need it. Args are same as for FUNCTION_PROLOGUE.
274
275 The function epilogue should not depend on the current stack pointer!
276 It should use the frame pointer only, if there is a frame pointer.
277 This is mandatory because of alloca; we also take advantage of it to
278 omit stack adjustments before returning. */
279
280 void
281 output_function_epilogue (stream, size)
282 FILE *stream;
283 int size;
284 {
285 register int regno;
286 register int mask, fmask;
287 register int nregs;
288 int offset, foffset, fpoffset;
289 extern char call_used_regs[];
290 int fsize = (size + 3) & -4;
291 int big = 0;
292 rtx insn = get_last_insn ();
293 int restore_from_sp = 0;
294
295 /* If the last insn was a BARRIER, we don't have to write any code. */
296 if (GET_CODE (insn) == NOTE)
297 insn = prev_nonnote_insn (insn);
298 if (insn && GET_CODE (insn) == BARRIER)
299 {
300 /* Output just a no-op so that debuggers don't get confused
301 about which function the pc is in at this address. */
302 asm_fprintf (stream, "\tnop\n");
303 return;
304 }
305
306 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
307 if (profile_block_flag == 2)
308 {
309 FUNCTION_BLOCK_PROFILER_EXIT (stream);
310 }
311 #endif
312
313 #ifdef FUNCTION_EXTRA_EPILOGUE
314 FUNCTION_EXTRA_EPILOGUE (stream, size);
315 #endif
316 nregs = 0; fmask = 0; fpoffset = 0;
317 #ifdef SUPPORT_SUN_FPA
318 for (regno = 24 ; regno < 56 ; regno++)
319 if (regs_ever_live[regno] && ! call_used_regs[regno])
320 nregs++;
321 fpoffset = nregs * 8;
322 #endif
323 nregs = 0;
324 for (regno = 16; regno < 24; regno++)
325 if (regs_ever_live[regno] && ! call_used_regs[regno])
326 {
327 nregs++;
328 fmask |= 1 << (23 - regno);
329 }
330 foffset = fpoffset + nregs * 12;
331 nregs = 0; mask = 0;
332 if (frame_pointer_needed)
333 regs_ever_live[FRAME_POINTER_REGNUM] = 0;
334 for (regno = 0; regno < 16; regno++)
335 if (regs_ever_live[regno] && ! call_used_regs[regno])
336 {
337 nregs++;
338 mask |= 1 << regno;
339 }
340 offset = foffset + nregs * 4;
341 restore_from_sp = ! frame_pointer_needed
342 || (! current_function_calls_alloca && leaf_function_p ());
343 if (offset + fsize >= 0x8000
344 && ! restore_from_sp
345 && (mask || fmask || fpoffset))
346 {
347 #ifdef MOTOROLA
348 asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra1\n", -fsize);
349 #else
350 asm_fprintf (stream, "\tmovel %0I%d,%Ra1\n", -fsize);
351 #endif
352 fsize = 0, big = 1;
353 }
354 if (nregs <= 2)
355 {
356 /* Restore each separately in the same order moveml does.
357 Using two movel instructions instead of a single moveml
358 is about 15% faster for the 68020 and 68030 at no expense
359 in code size. */
360
361 int i;
362
363 /* Undo the work from above. */
364 for (i = 0; i< 16; i++)
365 if (mask & (1 << i))
366 {
367 if (big)
368 {
369 #ifdef MOTOROLA
370 asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra1.l),%s\n",
371 offset + fsize,
372 reg_names[FRAME_POINTER_REGNUM],
373 reg_names[i]);
374 #else
375 asm_fprintf (stream, "\tmovel %s@(-%d,%Ra1:l),%s\n",
376 reg_names[FRAME_POINTER_REGNUM],
377 offset + fsize, reg_names[i]);
378 #endif
379 }
380 else if (restore_from_sp)
381 {
382 #ifdef MOTOROLA
383 asm_fprintf (stream, "\t%Omove.l (%Rsp)+,%s\n",
384 reg_names[i]);
385 #else
386 asm_fprintf (stream, "\tmovel %Rsp@+,%s\n",
387 reg_names[i]);
388 #endif
389 }
390 else
391 {
392 #ifdef MOTOROLA
393 asm_fprintf (stream, "\t%Omove.l -%d(%s),%s\n",
394 offset + fsize,
395 reg_names[FRAME_POINTER_REGNUM],
396 reg_names[i]);
397 #else
398 asm_fprintf (stream, "\tmovel %s@(-%d),%s\n",
399 reg_names[FRAME_POINTER_REGNUM],
400 offset + fsize, reg_names[i]);
401 #endif
402 }
403 offset = offset - 4;
404 }
405 }
406 else if (mask)
407 {
408 if (big)
409 {
410 #ifdef MOTOROLA
411 asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra1.l),%0I0x%x\n",
412 offset + fsize,
413 reg_names[FRAME_POINTER_REGNUM],
414 mask);
415 #else
416 asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra1:l),%0I0x%x\n",
417 reg_names[FRAME_POINTER_REGNUM],
418 offset + fsize, mask);
419 #endif
420 }
421 else if (restore_from_sp)
422 {
423 #ifdef MOTOROLA
424 asm_fprintf (stream, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask);
425 #else
426 asm_fprintf (stream, "\tmoveml %Rsp@+,%0I0x%x\n", mask);
427 #endif
428 }
429 else
430 {
431 #ifdef MOTOROLA
432 asm_fprintf (stream, "\tmovm.l -%d(%s),%0I0x%x\n",
433 offset + fsize,
434 reg_names[FRAME_POINTER_REGNUM],
435 mask);
436 #else
437 asm_fprintf (stream, "\tmoveml %s@(-%d),%0I0x%x\n",
438 reg_names[FRAME_POINTER_REGNUM],
439 offset + fsize, mask);
440 #endif
441 }
442 }
443 if (fmask)
444 {
445 if (big)
446 {
447 #ifdef MOTOROLA
448 asm_fprintf (stream, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n",
449 foffset + fsize,
450 reg_names[FRAME_POINTER_REGNUM],
451 fmask);
452 #else
453 asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n",
454 reg_names[FRAME_POINTER_REGNUM],
455 foffset + fsize, fmask);
456 #endif
457 }
458 else if (restore_from_sp)
459 {
460 #ifdef MOTOROLA
461 asm_fprintf (stream, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask);
462 #else
463 asm_fprintf (stream, "\tfmovem %Rsp@+,%0I0x%x\n", fmask);
464 #endif
465 }
466 else
467 {
468 #ifdef MOTOROLA
469 asm_fprintf (stream, "\tfmovm -%d(%s),%0I0x%x\n",
470 foffset + fsize,
471 reg_names[FRAME_POINTER_REGNUM],
472 fmask);
473 #else
474 asm_fprintf (stream, "\tfmovem %s@(-%d),%0I0x%x\n",
475 reg_names[FRAME_POINTER_REGNUM],
476 foffset + fsize, fmask);
477 #endif
478 }
479 }
480 if (fpoffset != 0)
481 for (regno = 55; regno >= 24; regno--)
482 if (regs_ever_live[regno] && ! call_used_regs[regno])
483 {
484 if (big)
485 {
486 #ifdef MOTOROLA
487 asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra1.l), %s\n",
488 fpoffset + fsize,
489 reg_names[FRAME_POINTER_REGNUM],
490 reg_names[regno]);
491 #else
492 asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra1:l), %s\n",
493 reg_names[FRAME_POINTER_REGNUM],
494 fpoffset + fsize, reg_names[regno]);
495 #endif
496 }
497 else if (restore_from_sp)
498 {
499 #ifdef MOTOROLA
500 asm_fprintf (stream, "\tfpmovd (%Rsp)+,%s\n",
501 reg_names[regno]);
502 #else
503 asm_fprintf (stream, "\tfpmoved %Rsp@+, %s\n",
504 reg_names[regno]);
505 #endif
506 }
507 else
508 {
509 #ifdef MOTOROLA
510 asm_fprintf (stream, "\tfpmovd -%d(%s), %s\n",
511 fpoffset + fsize,
512 reg_names[FRAME_POINTER_REGNUM],
513 reg_names[regno]);
514 #else
515 asm_fprintf (stream, "\tfpmoved %s@(-%d), %s\n",
516 reg_names[FRAME_POINTER_REGNUM],
517 fpoffset + fsize, reg_names[regno]);
518 #endif
519 }
520 fpoffset -= 8;
521 }
522 if (frame_pointer_needed)
523 fprintf (stream, "\tunlk %s\n",
524 reg_names[FRAME_POINTER_REGNUM]);
525 else if (fsize)
526 {
527 if (fsize + 4 < 0x8000)
528 {
529 /* asm_fprintf() cannot handle %. */
530 #ifdef MOTOROLA
531 asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4);
532 #else
533 asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", fsize + 4);
534 #endif
535 }
536 else
537 {
538 /* asm_fprintf() cannot handle %. */
539 #ifdef MOTOROLA
540 asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4);
541 #else
542 asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4);
543 #endif
544 }
545 }
546 if (current_function_pops_args)
547 asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
548 else
549 fprintf (stream, "\trts\n");
550 }
551 \f
552 /* Similar to general_operand, but exclude stack_pointer_rtx. */
553
554 int
555 not_sp_operand (op, mode)
556 register rtx op;
557 enum machine_mode mode;
558 {
559 return op != stack_pointer_rtx && general_operand (op, mode);
560 }
561
562 /* Return TRUE if X is a valid comparison operator for the dbcc
563 instruction.
564
565 Note it rejects floating point comparison operators.
566 (In the future we could use Fdbcc).
567
568 It also rejects some comparisons when CC_NO_OVERFLOW is set. */
569
570 int
571 valid_dbcc_comparison_p (x, mode)
572 rtx x;
573 enum machine_mode mode;
574 {
575 switch (GET_CODE (x))
576 {
577 case EQ: case NE: case GTU: case LTU:
578 case GEU: case LEU:
579 return 1;
580
581 /* Reject some when CC_NO_OVERFLOW is set. This may be over
582 conservative */
583 case GT: case LT: case GE: case LE:
584 return ! (cc_prev_status.flags & CC_NO_OVERFLOW);
585 default:
586 return 0;
587 }
588 }
589
590 /* Return non-zero if flags are currently in the 68881 flag register. */
591 int
592 flags_in_68881 ()
593 {
594 /* We could add support for these in the future */
595 return cc_status.flags & CC_IN_68881;
596 }
597
598 /* Output a dbCC; jCC sequence. Note we do not handle the
599 floating point version of this sequence (Fdbcc). We also
600 do not handle alternative conditions when CC_NO_OVERFLOW is
601 set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
602 kick those out before we get here. */
603
604 output_dbcc_and_branch (operands)
605 rtx *operands;
606 {
607 switch (GET_CODE (operands[3]))
608 {
609 case EQ:
610 #ifdef MOTOROLA
611 output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands);
612 #else
613 output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands);
614 #endif
615 break;
616
617 case NE:
618 #ifdef MOTOROLA
619 output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands);
620 #else
621 output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands);
622 #endif
623 break;
624
625 case GT:
626 #ifdef MOTOROLA
627 output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands);
628 #else
629 output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands);
630 #endif
631 break;
632
633 case GTU:
634 #ifdef MOTOROLA
635 output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands);
636 #else
637 output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands);
638 #endif
639 break;
640
641 case LT:
642 #ifdef MOTOROLA
643 output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands);
644 #else
645 output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands);
646 #endif
647 break;
648
649 case LTU:
650 #ifdef MOTOROLA
651 output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands);
652 #else
653 output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands);
654 #endif
655 break;
656
657 case GE:
658 #ifdef MOTOROLA
659 output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands);
660 #else
661 output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands);
662 #endif
663 break;
664
665 case GEU:
666 #ifdef MOTOROLA
667 output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands);
668 #else
669 output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands);
670 #endif
671 break;
672
673 case LE:
674 #ifdef MOTOROLA
675 output_asm_insn ("dble %0,%l1\n\tjble %l2", operands);
676 #else
677 output_asm_insn ("dble %0,%l1\n\tjle %l2", operands);
678 #endif
679 break;
680
681 case LEU:
682 #ifdef MOTOROLA
683 output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands);
684 #else
685 output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands);
686 #endif
687 break;
688
689 default:
690 abort ();
691 }
692
693 /* If the decrement is to be done in SImode, then we have
694 to compensate for the fact that dbcc decrements in HImode. */
695 switch (GET_MODE (operands[0]))
696 {
697 case SImode:
698 #ifdef MOTOROLA
699 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands);
700 #else
701 output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands);
702 #endif
703 break;
704
705 case HImode:
706 break;
707
708 default:
709 abort ();
710 }
711 }
712
713 char *
714 output_scc_di(op, operand1, operand2, dest)
715 rtx op;
716 rtx operand1;
717 rtx operand2;
718 rtx dest;
719 {
720 rtx loperands[7];
721 enum rtx_code op_code = GET_CODE (op);
722
723 /* The m68k cmp.l instruction requires operand1 to be a reg as used
724 below. Swap the operands and change the op if these requirements
725 are not fulfilled. */
726 if (GET_CODE (operand2) == REG && GET_CODE (operand1) != REG)
727 {
728 rtx tmp = operand1;
729
730 operand1 = operand2;
731 operand2 = tmp;
732 op_code = swap_condition (op_code);
733 }
734 loperands[0] = operand1;
735 if (GET_CODE (operand1) == REG)
736 loperands[1] = gen_rtx (REG, SImode, REGNO (operand1) + 1);
737 else
738 loperands[1] = adj_offsettable_operand (operand1, 4);
739 if (operand2 != const0_rtx)
740 {
741 loperands[2] = operand2;
742 if (GET_CODE (operand2) == REG)
743 loperands[3] = gen_rtx (REG, SImode, REGNO (operand2) + 1);
744 else
745 loperands[3] = adj_offsettable_operand (operand2, 4);
746 }
747 loperands[4] = gen_label_rtx();
748 if (operand2 != const0_rtx)
749 #ifdef MOTOROLA
750 #ifdef SGS_CMP_ORDER
751 output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands);
752 #else
753 output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands);
754 #endif
755 #else
756 #ifdef SGS_CMP_ORDER
757 output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands);
758 #else
759 output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands);
760 #endif
761 #endif
762 else
763 #ifdef MOTOROLA
764 output_asm_insn ("tst%.l %0\n\tjbne %l4\n\ttst%.l %1", loperands);
765 #else
766 output_asm_insn ("tst%.l %0\n\tjne %l4\n\ttst%.l %1", loperands);
767 #endif
768 loperands[5] = dest;
769
770 switch (op_code)
771 {
772 case EQ:
773 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
774 CODE_LABEL_NUMBER (loperands[4]));
775 output_asm_insn ("seq %5", loperands);
776 break;
777
778 case NE:
779 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
780 CODE_LABEL_NUMBER (loperands[4]));
781 output_asm_insn ("sne %5", loperands);
782 break;
783
784 case GT:
785 loperands[6] = gen_label_rtx();
786 #ifdef MOTOROLA
787 output_asm_insn ("shi %5\n\tjbra %l6", loperands);
788 #else
789 output_asm_insn ("shi %5\n\tjra %l6", loperands);
790 #endif
791 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
792 CODE_LABEL_NUMBER (loperands[4]));
793 output_asm_insn ("sgt %5", loperands);
794 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
795 CODE_LABEL_NUMBER (loperands[6]));
796 break;
797
798 case GTU:
799 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
800 CODE_LABEL_NUMBER (loperands[4]));
801 output_asm_insn ("shi %5", loperands);
802 break;
803
804 case LT:
805 loperands[6] = gen_label_rtx();
806 #ifdef MOTOROLA
807 output_asm_insn ("scs %5\n\tjbra %l6", loperands);
808 #else
809 output_asm_insn ("scs %5\n\tjra %l6", loperands);
810 #endif
811 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
812 CODE_LABEL_NUMBER (loperands[4]));
813 output_asm_insn ("slt %5", loperands);
814 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
815 CODE_LABEL_NUMBER (loperands[6]));
816 break;
817
818 case LTU:
819 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
820 CODE_LABEL_NUMBER (loperands[4]));
821 output_asm_insn ("scs %5", loperands);
822 break;
823
824 case GE:
825 loperands[6] = gen_label_rtx();
826 #ifdef MOTOROLA
827 output_asm_insn ("scc %5\n\tjbra %l6", loperands);
828 #else
829 output_asm_insn ("scc %5\n\tjra %l6", loperands);
830 #endif
831 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
832 CODE_LABEL_NUMBER (loperands[4]));
833 output_asm_insn ("sge %5", loperands);
834 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
835 CODE_LABEL_NUMBER (loperands[6]));
836 break;
837
838 case GEU:
839 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
840 CODE_LABEL_NUMBER (loperands[4]));
841 output_asm_insn ("scc %5", loperands);
842 break;
843
844 case LE:
845 loperands[6] = gen_label_rtx();
846 #ifdef MOTOROLA
847 output_asm_insn ("sls %5\n\tjbra %l6", loperands);
848 #else
849 output_asm_insn ("sls %5\n\tjra %l6", loperands);
850 #endif
851 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
852 CODE_LABEL_NUMBER (loperands[4]));
853 output_asm_insn ("sle %5", loperands);
854 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
855 CODE_LABEL_NUMBER (loperands[6]));
856 break;
857
858 case LEU:
859 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
860 CODE_LABEL_NUMBER (loperands[4]));
861 output_asm_insn ("sls %5", loperands);
862 break;
863
864 default:
865 abort ();
866 }
867 return "";
868 }
869
870 char *
871 output_btst (operands, countop, dataop, insn, signpos)
872 rtx *operands;
873 rtx countop, dataop;
874 rtx insn;
875 int signpos;
876 {
877 operands[0] = countop;
878 operands[1] = dataop;
879
880 if (GET_CODE (countop) == CONST_INT)
881 {
882 register int count = INTVAL (countop);
883 /* If COUNT is bigger than size of storage unit in use,
884 advance to the containing unit of same size. */
885 if (count > signpos)
886 {
887 int offset = (count & ~signpos) / 8;
888 count = count & signpos;
889 operands[1] = dataop = adj_offsettable_operand (dataop, offset);
890 }
891 if (count == signpos)
892 cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
893 else
894 cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N;
895
896 /* These three statements used to use next_insns_test_no...
897 but it appears that this should do the same job. */
898 if (count == 31
899 && next_insn_tests_no_inequality (insn))
900 return "tst%.l %1";
901 if (count == 15
902 && next_insn_tests_no_inequality (insn))
903 return "tst%.w %1";
904 if (count == 7
905 && next_insn_tests_no_inequality (insn))
906 return "tst%.b %1";
907
908 cc_status.flags = CC_NOT_NEGATIVE;
909 }
910 return "btst %0,%1";
911 }
912 \f
913 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
914 reference and a constant. */
915
916 int
917 symbolic_operand (op, mode)
918 register rtx op;
919 enum machine_mode mode;
920 {
921 switch (GET_CODE (op))
922 {
923 case SYMBOL_REF:
924 case LABEL_REF:
925 return 1;
926
927 case CONST:
928 op = XEXP (op, 0);
929 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
930 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
931 && GET_CODE (XEXP (op, 1)) == CONST_INT);
932
933 #if 0 /* Deleted, with corresponding change in m68k.h,
934 so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
935 case CONST_DOUBLE:
936 return GET_MODE (op) == mode;
937 #endif
938
939 default:
940 return 0;
941 }
942 }
943 \f
944 /* Check for sign_extend or zero_extend. Used for bit-count operands. */
945
946 int
947 extend_operator(x, mode)
948 rtx x;
949 enum machine_mode mode;
950 {
951 if (mode != VOIDmode && GET_MODE(x) != mode)
952 return 0;
953 switch (GET_CODE(x))
954 {
955 case SIGN_EXTEND :
956 case ZERO_EXTEND :
957 return 1;
958 default :
959 return 0;
960 }
961 }
962
963 \f
964 /* Legitimize PIC addresses. If the address is already
965 position-independent, we return ORIG. Newly generated
966 position-independent addresses go to REG. If we need more
967 than one register, we lose.
968
969 An address is legitimized by making an indirect reference
970 through the Global Offset Table with the name of the symbol
971 used as an offset.
972
973 The assembler and linker are responsible for placing the
974 address of the symbol in the GOT. The function prologue
975 is responsible for initializing a5 to the starting address
976 of the GOT.
977
978 The assembler is also responsible for translating a symbol name
979 into a constant displacement from the start of the GOT.
980
981 A quick example may make things a little clearer:
982
983 When not generating PIC code to store the value 12345 into _foo
984 we would generate the following code:
985
986 movel #12345, _foo
987
988 When generating PIC two transformations are made. First, the compiler
989 loads the address of foo into a register. So the first transformation makes:
990
991 lea _foo, a0
992 movel #12345, a0@
993
994 The code in movsi will intercept the lea instruction and call this
995 routine which will transform the instructions into:
996
997 movel a5@(_foo:w), a0
998 movel #12345, a0@
999
1000
1001 That (in a nutshell) is how *all* symbol and label references are
1002 handled. */
1003
1004 rtx
1005 legitimize_pic_address (orig, mode, reg)
1006 rtx orig, reg;
1007 enum machine_mode mode;
1008 {
1009 rtx pic_ref = orig;
1010
1011 /* First handle a simple SYMBOL_REF or LABEL_REF */
1012 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1013 {
1014 if (reg == 0)
1015 abort ();
1016
1017 pic_ref = gen_rtx (MEM, Pmode,
1018 gen_rtx (PLUS, Pmode,
1019 pic_offset_table_rtx, orig));
1020 current_function_uses_pic_offset_table = 1;
1021 RTX_UNCHANGING_P (pic_ref) = 1;
1022 emit_move_insn (reg, pic_ref);
1023 return reg;
1024 }
1025 else if (GET_CODE (orig) == CONST)
1026 {
1027 rtx base, offset;
1028
1029 /* Make sure this is CONST has not already been legitimized */
1030 if (GET_CODE (XEXP (orig, 0)) == PLUS
1031 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1032 return orig;
1033
1034 if (reg == 0)
1035 abort ();
1036
1037 /* legitimize both operands of the PLUS */
1038 if (GET_CODE (XEXP (orig, 0)) == PLUS)
1039 {
1040 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1041 orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1042 base == reg ? 0 : reg);
1043 }
1044 else abort ();
1045
1046 if (GET_CODE (orig) == CONST_INT)
1047 return plus_constant_for_output (base, INTVAL (orig));
1048 pic_ref = gen_rtx (PLUS, Pmode, base, orig);
1049 /* Likewise, should we set special REG_NOTEs here? */
1050 }
1051 return pic_ref;
1052 }
1053
1054 \f
1055 typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ } CONST_METHOD;
1056
1057 #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
1058
1059 CONST_METHOD
1060 const_method (constant)
1061 rtx constant;
1062 {
1063 int i;
1064 unsigned u;
1065
1066 i = INTVAL (constant);
1067 if (USE_MOVQ (i))
1068 return MOVQ;
1069
1070 /* The Coldfire doesn't have byte or word operations. */
1071 /* FIXME: This may not be useful for the m68060 either */
1072 if (!TARGET_5200)
1073 {
1074 /* if -256 < N < 256 but N is not in range for a moveq
1075 N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
1076 if (USE_MOVQ (i ^ 0xff))
1077 return NOTB;
1078 /* Likewise, try with not.w */
1079 if (USE_MOVQ (i ^ 0xffff))
1080 return NOTW;
1081 /* This is the only value where neg.w is useful */
1082 if (i == -65408)
1083 return NEGW;
1084 /* Try also with swap */
1085 u = i;
1086 if (USE_MOVQ ((u >> 16) | (u << 16)))
1087 return SWAP;
1088 }
1089 /* Otherwise, use move.l */
1090 return MOVL;
1091 }
1092
1093 const_int_cost (constant)
1094 rtx constant;
1095 {
1096 switch (const_method (constant))
1097 {
1098 case MOVQ :
1099 /* Constants between -128 and 127 are cheap due to moveq */
1100 return 0;
1101 case NOTB :
1102 case NOTW :
1103 case NEGW :
1104 case SWAP :
1105 /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
1106 return 1;
1107 case MOVL :
1108 return 2;
1109 default :
1110 abort ();
1111 }
1112 }
1113
1114 char *
1115 output_move_const_into_data_reg (operands)
1116 rtx *operands;
1117 {
1118 int i;
1119
1120 i = INTVAL (operands[1]);
1121 switch (const_method (operands[1]))
1122 {
1123 case MOVQ :
1124 #if defined (MOTOROLA) && !defined (CRDS)
1125 return "moveq%.l %1,%0";
1126 #else
1127 return "moveq %1,%0";
1128 #endif
1129 case NOTB :
1130 operands[1] = gen_rtx (CONST_INT, VOIDmode, i ^ 0xff);
1131 #if defined (MOTOROLA) && !defined (CRDS)
1132 return "moveq%.l %1,%0\n\tnot%.b %0";
1133 #else
1134 return "moveq %1,%0\n\tnot%.b %0";
1135 #endif
1136 case NOTW :
1137 operands[1] = gen_rtx (CONST_INT, VOIDmode, i ^ 0xffff);
1138 #if defined (MOTOROLA) && !defined (CRDS)
1139 return "moveq%.l %1,%0\n\tnot%.w %0";
1140 #else
1141 return "moveq %1,%0\n\tnot%.w %0";
1142 #endif
1143 case NEGW :
1144 #if defined (MOTOROLA) && !defined (CRDS)
1145 return "moveq%.l %#-128,%0\n\tneg%.w %0";
1146 #else
1147 return "moveq %#-128,%0\n\tneg%.w %0";
1148 #endif
1149 case SWAP :
1150 {
1151 unsigned u = i;
1152
1153 operands[1] = gen_rtx (CONST_INT, VOIDmode, (u << 16) | (u >> 16));
1154 #if defined (MOTOROLA) && !defined (CRDS)
1155 return "moveq%.l %1,%0\n\tswap %0";
1156 #else
1157 return "moveq %1,%0\n\tswap %0";
1158 #endif
1159 }
1160 case MOVL :
1161 return "move%.l %1,%0";
1162 default :
1163 abort ();
1164 }
1165 }
1166
1167 char *
1168 output_move_simode_const (operands)
1169 rtx *operands;
1170 {
1171 if (operands[1] == const0_rtx
1172 && (DATA_REG_P (operands[0])
1173 || GET_CODE (operands[0]) == MEM)
1174 /* clr insns on 68000 read before writing.
1175 This isn't so on the 68010, but we have no alternative for it. */
1176 && (TARGET_68020
1177 || !(GET_CODE (operands[0]) == MEM
1178 && MEM_VOLATILE_P (operands[0]))))
1179 return "clr%.l %0";
1180 else if (DATA_REG_P (operands[0]))
1181 return output_move_const_into_data_reg (operands);
1182 else if (ADDRESS_REG_P (operands[0])
1183 && INTVAL (operands[1]) < 0x8000
1184 && INTVAL (operands[1]) >= -0x8000)
1185 return "move%.w %1,%0";
1186 else if (GET_CODE (operands[0]) == MEM
1187 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1188 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1189 && INTVAL (operands[1]) < 0x8000
1190 && INTVAL (operands[1]) >= -0x8000)
1191 return "pea %a1";
1192 return "move%.l %1,%0";
1193 }
1194
1195 /* Return the best assembler insn template
1196 for moving operands[1] into operands[0] as a fullword. */
1197
1198 static char *
1199 singlemove_string (operands)
1200 rtx *operands;
1201 {
1202 #ifdef SUPPORT_SUN_FPA
1203 if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))
1204 return "fpmoves %1,%0";
1205 #endif
1206 if (GET_CODE (operands[1]) == CONST_INT)
1207 return output_move_simode_const (operands);
1208 return "move%.l %1,%0";
1209 }
1210
1211
1212 /* Output assembler code to perform a doubleword move insn
1213 with operands OPERANDS. */
1214
1215 char *
1216 output_move_double (operands)
1217 rtx *operands;
1218 {
1219 enum
1220 {
1221 REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP
1222 } optype0, optype1;
1223 rtx latehalf[2];
1224 rtx middlehalf[2];
1225 rtx xops[2];
1226 rtx addreg0 = 0, addreg1 = 0;
1227 int dest_overlapped_low = 0;
1228 int size = GET_MODE_SIZE (GET_MODE (operands[0]));
1229
1230 middlehalf[0] = 0;
1231 middlehalf[1] = 0;
1232
1233 /* First classify both operands. */
1234
1235 if (REG_P (operands[0]))
1236 optype0 = REGOP;
1237 else if (offsettable_memref_p (operands[0]))
1238 optype0 = OFFSOP;
1239 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1240 optype0 = POPOP;
1241 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1242 optype0 = PUSHOP;
1243 else if (GET_CODE (operands[0]) == MEM)
1244 optype0 = MEMOP;
1245 else
1246 optype0 = RNDOP;
1247
1248 if (REG_P (operands[1]))
1249 optype1 = REGOP;
1250 else if (CONSTANT_P (operands[1]))
1251 optype1 = CNSTOP;
1252 else if (offsettable_memref_p (operands[1]))
1253 optype1 = OFFSOP;
1254 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
1255 optype1 = POPOP;
1256 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1257 optype1 = PUSHOP;
1258 else if (GET_CODE (operands[1]) == MEM)
1259 optype1 = MEMOP;
1260 else
1261 optype1 = RNDOP;
1262
1263 /* Check for the cases that the operand constraints are not
1264 supposed to allow to happen. Abort if we get one,
1265 because generating code for these cases is painful. */
1266
1267 if (optype0 == RNDOP || optype1 == RNDOP)
1268 abort ();
1269
1270 /* If one operand is decrementing and one is incrementing
1271 decrement the former register explicitly
1272 and change that operand into ordinary indexing. */
1273
1274 if (optype0 == PUSHOP && optype1 == POPOP)
1275 {
1276 operands[0] = XEXP (XEXP (operands[0], 0), 0);
1277 if (size == 12)
1278 output_asm_insn ("sub%.l %#12,%0", operands);
1279 else
1280 output_asm_insn ("subq%.l %#8,%0", operands);
1281 if (GET_MODE (operands[1]) == XFmode)
1282 operands[0] = gen_rtx (MEM, XFmode, operands[0]);
1283 else if (GET_MODE (operands[0]) == DFmode)
1284 operands[0] = gen_rtx (MEM, DFmode, operands[0]);
1285 else
1286 operands[0] = gen_rtx (MEM, DImode, operands[0]);
1287 optype0 = OFFSOP;
1288 }
1289 if (optype0 == POPOP && optype1 == PUSHOP)
1290 {
1291 operands[1] = XEXP (XEXP (operands[1], 0), 0);
1292 if (size == 12)
1293 output_asm_insn ("sub%.l %#12,%1", operands);
1294 else
1295 output_asm_insn ("subq%.l %#8,%1", operands);
1296 if (GET_MODE (operands[1]) == XFmode)
1297 operands[1] = gen_rtx (MEM, XFmode, operands[1]);
1298 else if (GET_MODE (operands[1]) == DFmode)
1299 operands[1] = gen_rtx (MEM, DFmode, operands[1]);
1300 else
1301 operands[1] = gen_rtx (MEM, DImode, operands[1]);
1302 optype1 = OFFSOP;
1303 }
1304
1305 /* If an operand is an unoffsettable memory ref, find a register
1306 we can increment temporarily to make it refer to the second word. */
1307
1308 if (optype0 == MEMOP)
1309 addreg0 = find_addr_reg (XEXP (operands[0], 0));
1310
1311 if (optype1 == MEMOP)
1312 addreg1 = find_addr_reg (XEXP (operands[1], 0));
1313
1314 /* Ok, we can do one word at a time.
1315 Normally we do the low-numbered word first,
1316 but if either operand is autodecrementing then we
1317 do the high-numbered word first.
1318
1319 In either case, set up in LATEHALF the operands to use
1320 for the high-numbered word and in some cases alter the
1321 operands in OPERANDS to be suitable for the low-numbered word. */
1322
1323 if (size == 12)
1324 {
1325 if (optype0 == REGOP)
1326 {
1327 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2);
1328 middlehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1329 }
1330 else if (optype0 == OFFSOP)
1331 {
1332 middlehalf[0] = adj_offsettable_operand (operands[0], 4);
1333 latehalf[0] = adj_offsettable_operand (operands[0], size - 4);
1334 }
1335 else
1336 {
1337 middlehalf[0] = operands[0];
1338 latehalf[0] = operands[0];
1339 }
1340
1341 if (optype1 == REGOP)
1342 {
1343 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2);
1344 middlehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1345 }
1346 else if (optype1 == OFFSOP)
1347 {
1348 middlehalf[1] = adj_offsettable_operand (operands[1], 4);
1349 latehalf[1] = adj_offsettable_operand (operands[1], size - 4);
1350 }
1351 else if (optype1 == CNSTOP)
1352 {
1353 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1354 {
1355 REAL_VALUE_TYPE r;
1356 long l[3];
1357
1358 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1359 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
1360 operands[1] = GEN_INT (l[0]);
1361 middlehalf[1] = GEN_INT (l[1]);
1362 latehalf[1] = GEN_INT (l[2]);
1363 }
1364 else if (CONSTANT_P (operands[1]))
1365 {
1366 /* actually, no non-CONST_DOUBLE constant should ever
1367 appear here. */
1368 abort ();
1369 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
1370 latehalf[1] = constm1_rtx;
1371 else
1372 latehalf[1] = const0_rtx;
1373 }
1374 }
1375 else
1376 {
1377 middlehalf[1] = operands[1];
1378 latehalf[1] = operands[1];
1379 }
1380 }
1381 else
1382 /* size is not 12: */
1383 {
1384 if (optype0 == REGOP)
1385 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1386 else if (optype0 == OFFSOP)
1387 latehalf[0] = adj_offsettable_operand (operands[0], size - 4);
1388 else
1389 latehalf[0] = operands[0];
1390
1391 if (optype1 == REGOP)
1392 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1393 else if (optype1 == OFFSOP)
1394 latehalf[1] = adj_offsettable_operand (operands[1], size - 4);
1395 else if (optype1 == CNSTOP)
1396 split_double (operands[1], &operands[1], &latehalf[1]);
1397 else
1398 latehalf[1] = operands[1];
1399 }
1400
1401 /* If insn is effectively movd N(sp),-(sp) then we will do the
1402 high word first. We should use the adjusted operand 1 (which is N+4(sp))
1403 for the low word as well, to compensate for the first decrement of sp. */
1404 if (optype0 == PUSHOP
1405 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1406 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
1407 operands[1] = middlehalf[1] = latehalf[1];
1408
1409 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
1410 if the upper part of reg N does not appear in the MEM, arrange to
1411 emit the move late-half first. Otherwise, compute the MEM address
1412 into the upper part of N and use that as a pointer to the memory
1413 operand. */
1414 if (optype0 == REGOP
1415 && (optype1 == OFFSOP || optype1 == MEMOP))
1416 {
1417 rtx testlow = gen_rtx (REG, SImode, REGNO (operands[0]));
1418
1419 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
1420 && reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
1421 {
1422 /* If both halves of dest are used in the src memory address,
1423 compute the address into latehalf of dest.
1424 Note that this can't happen if the dest is two data regs. */
1425 compadr:
1426 xops[0] = latehalf[0];
1427 xops[1] = XEXP (operands[1], 0);
1428 output_asm_insn ("lea %a1,%0", xops);
1429 if( GET_MODE (operands[1]) == XFmode )
1430 {
1431 operands[1] = gen_rtx (MEM, XFmode, latehalf[0]);
1432 middlehalf[1] = adj_offsettable_operand (operands[1], size-8);
1433 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1434 }
1435 else
1436 {
1437 operands[1] = gen_rtx (MEM, DImode, latehalf[0]);
1438 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1439 }
1440 }
1441 else if (size == 12
1442 && reg_overlap_mentioned_p (middlehalf[0],
1443 XEXP (operands[1], 0)))
1444 {
1445 /* Check for two regs used by both source and dest.
1446 Note that this can't happen if the dest is all data regs.
1447 It can happen if the dest is d6, d7, a0.
1448 But in that case, latehalf is an addr reg, so
1449 the code at compadr does ok. */
1450
1451 if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
1452 || reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
1453 goto compadr;
1454
1455 /* JRV says this can't happen: */
1456 if (addreg0 || addreg1)
1457 abort ();
1458
1459 /* Only the middle reg conflicts; simply put it last. */
1460 output_asm_insn (singlemove_string (operands), operands);
1461 output_asm_insn (singlemove_string (latehalf), latehalf);
1462 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1463 return "";
1464 }
1465 else if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0)))
1466 /* If the low half of dest is mentioned in the source memory
1467 address, the arrange to emit the move late half first. */
1468 dest_overlapped_low = 1;
1469 }
1470
1471 /* If one or both operands autodecrementing,
1472 do the two words, high-numbered first. */
1473
1474 /* Likewise, the first move would clobber the source of the second one,
1475 do them in the other order. This happens only for registers;
1476 such overlap can't happen in memory unless the user explicitly
1477 sets it up, and that is an undefined circumstance. */
1478
1479 if (optype0 == PUSHOP || optype1 == PUSHOP
1480 || (optype0 == REGOP && optype1 == REGOP
1481 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
1482 || REGNO (operands[0]) == REGNO (latehalf[1])))
1483 || dest_overlapped_low)
1484 {
1485 /* Make any unoffsettable addresses point at high-numbered word. */
1486 if (addreg0)
1487 {
1488 if (size == 12)
1489 output_asm_insn ("addq%.l %#8,%0", &addreg0);
1490 else
1491 output_asm_insn ("addq%.l %#4,%0", &addreg0);
1492 }
1493 if (addreg1)
1494 {
1495 if (size == 12)
1496 output_asm_insn ("addq%.l %#8,%0", &addreg1);
1497 else
1498 output_asm_insn ("addq%.l %#4,%0", &addreg1);
1499 }
1500
1501 /* Do that word. */
1502 output_asm_insn (singlemove_string (latehalf), latehalf);
1503
1504 /* Undo the adds we just did. */
1505 if (addreg0)
1506 output_asm_insn ("subq%.l %#4,%0", &addreg0);
1507 if (addreg1)
1508 output_asm_insn ("subq%.l %#4,%0", &addreg1);
1509
1510 if (size == 12)
1511 {
1512 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1513 if (addreg0)
1514 output_asm_insn ("subq%.l %#4,%0", &addreg0);
1515 if (addreg1)
1516 output_asm_insn ("subq%.l %#4,%0", &addreg1);
1517 }
1518
1519 /* Do low-numbered word. */
1520 return singlemove_string (operands);
1521 }
1522
1523 /* Normal case: do the two words, low-numbered first. */
1524
1525 output_asm_insn (singlemove_string (operands), operands);
1526
1527 /* Do the middle one of the three words for long double */
1528 if (size == 12)
1529 {
1530 if (addreg0)
1531 output_asm_insn ("addq%.l %#4,%0", &addreg0);
1532 if (addreg1)
1533 output_asm_insn ("addq%.l %#4,%0", &addreg1);
1534
1535 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1536 }
1537
1538 /* Make any unoffsettable addresses point at high-numbered word. */
1539 if (addreg0)
1540 output_asm_insn ("addq%.l %#4,%0", &addreg0);
1541 if (addreg1)
1542 output_asm_insn ("addq%.l %#4,%0", &addreg1);
1543
1544 /* Do that word. */
1545 output_asm_insn (singlemove_string (latehalf), latehalf);
1546
1547 /* Undo the adds we just did. */
1548 if (addreg0)
1549 {
1550 if (size == 12)
1551 output_asm_insn ("subq%.l %#8,%0", &addreg0);
1552 else
1553 output_asm_insn ("subq%.l %#4,%0", &addreg0);
1554 }
1555 if (addreg1)
1556 {
1557 if (size == 12)
1558 output_asm_insn ("subq%.l %#8,%0", &addreg1);
1559 else
1560 output_asm_insn ("subq%.l %#4,%0", &addreg1);
1561 }
1562
1563 return "";
1564 }
1565
1566 /* Return a REG that occurs in ADDR with coefficient 1.
1567 ADDR can be effectively incremented by incrementing REG. */
1568
1569 static rtx
1570 find_addr_reg (addr)
1571 rtx addr;
1572 {
1573 while (GET_CODE (addr) == PLUS)
1574 {
1575 if (GET_CODE (XEXP (addr, 0)) == REG)
1576 addr = XEXP (addr, 0);
1577 else if (GET_CODE (XEXP (addr, 1)) == REG)
1578 addr = XEXP (addr, 1);
1579 else if (CONSTANT_P (XEXP (addr, 0)))
1580 addr = XEXP (addr, 1);
1581 else if (CONSTANT_P (XEXP (addr, 1)))
1582 addr = XEXP (addr, 0);
1583 else
1584 abort ();
1585 }
1586 if (GET_CODE (addr) == REG)
1587 return addr;
1588 abort ();
1589 }
1590 \f
1591 /* Store in cc_status the expressions that the condition codes will
1592 describe after execution of an instruction whose pattern is EXP.
1593 Do not alter them if the instruction would not alter the cc's. */
1594
1595 /* On the 68000, all the insns to store in an address register fail to
1596 set the cc's. However, in some cases these instructions can make it
1597 possibly invalid to use the saved cc's. In those cases we clear out
1598 some or all of the saved cc's so they won't be used. */
1599
1600 notice_update_cc (exp, insn)
1601 rtx exp;
1602 rtx insn;
1603 {
1604 /* If the cc is being set from the fpa and the expression is not an
1605 explicit floating point test instruction (which has code to deal with
1606 this), reinit the CC. */
1607 if (((cc_status.value1 && FPA_REG_P (cc_status.value1))
1608 || (cc_status.value2 && FPA_REG_P (cc_status.value2)))
1609 && !(GET_CODE (exp) == PARALLEL
1610 && GET_CODE (XVECEXP (exp, 0, 0)) == SET
1611 && XEXP (XVECEXP (exp, 0, 0), 0) == cc0_rtx))
1612 {
1613 CC_STATUS_INIT;
1614 }
1615 else if (GET_CODE (exp) == SET)
1616 {
1617 if (GET_CODE (SET_SRC (exp)) == CALL)
1618 {
1619 CC_STATUS_INIT;
1620 }
1621 else if (ADDRESS_REG_P (SET_DEST (exp)))
1622 {
1623 if (cc_status.value1
1624 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1625 cc_status.value1 = 0;
1626 if (cc_status.value2
1627 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1628 cc_status.value2 = 0;
1629 }
1630 else if (!FP_REG_P (SET_DEST (exp))
1631 && SET_DEST (exp) != cc0_rtx
1632 && (FP_REG_P (SET_SRC (exp))
1633 || GET_CODE (SET_SRC (exp)) == FIX
1634 || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE
1635 || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND))
1636 {
1637 CC_STATUS_INIT;
1638 }
1639 /* A pair of move insns doesn't produce a useful overall cc. */
1640 else if (!FP_REG_P (SET_DEST (exp))
1641 && !FP_REG_P (SET_SRC (exp))
1642 && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
1643 && (GET_CODE (SET_SRC (exp)) == REG
1644 || GET_CODE (SET_SRC (exp)) == MEM
1645 || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
1646 {
1647 CC_STATUS_INIT;
1648 }
1649 else if (GET_CODE (SET_SRC (exp)) == CALL)
1650 {
1651 CC_STATUS_INIT;
1652 }
1653 else if (XEXP (exp, 0) != pc_rtx)
1654 {
1655 cc_status.flags = 0;
1656 cc_status.value1 = XEXP (exp, 0);
1657 cc_status.value2 = XEXP (exp, 1);
1658 }
1659 }
1660 else if (GET_CODE (exp) == PARALLEL
1661 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1662 {
1663 if (ADDRESS_REG_P (XEXP (XVECEXP (exp, 0, 0), 0)))
1664 CC_STATUS_INIT;
1665 else if (XEXP (XVECEXP (exp, 0, 0), 0) != pc_rtx)
1666 {
1667 cc_status.flags = 0;
1668 cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
1669 cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1);
1670 }
1671 }
1672 else
1673 CC_STATUS_INIT;
1674 if (cc_status.value2 != 0
1675 && ADDRESS_REG_P (cc_status.value2)
1676 && GET_MODE (cc_status.value2) == QImode)
1677 CC_STATUS_INIT;
1678 if (cc_status.value2 != 0
1679 && !(cc_status.value1 && FPA_REG_P (cc_status.value1)))
1680 switch (GET_CODE (cc_status.value2))
1681 {
1682 case PLUS: case MINUS: case MULT:
1683 case DIV: case UDIV: case MOD: case UMOD: case NEG:
1684 #if 0 /* These instructions always clear the overflow bit */
1685 case ASHIFT: case ASHIFTRT: case LSHIFTRT:
1686 case ROTATE: case ROTATERT:
1687 #endif
1688 if (GET_MODE (cc_status.value2) != VOIDmode)
1689 cc_status.flags |= CC_NO_OVERFLOW;
1690 break;
1691 case ZERO_EXTEND:
1692 /* (SET r1 (ZERO_EXTEND r2)) on this machine
1693 ends with a move insn moving r2 in r2's mode.
1694 Thus, the cc's are set for r2.
1695 This can set N bit spuriously. */
1696 cc_status.flags |= CC_NOT_NEGATIVE;
1697 }
1698 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
1699 && cc_status.value2
1700 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
1701 cc_status.value2 = 0;
1702 if (((cc_status.value1 && FP_REG_P (cc_status.value1))
1703 || (cc_status.value2 && FP_REG_P (cc_status.value2)))
1704 && !((cc_status.value1 && FPA_REG_P (cc_status.value1))
1705 || (cc_status.value2 && FPA_REG_P (cc_status.value2))))
1706 cc_status.flags = CC_IN_68881;
1707 }
1708 \f
1709 char *
1710 output_move_const_double (operands)
1711 rtx *operands;
1712 {
1713 #ifdef SUPPORT_SUN_FPA
1714 if (TARGET_FPA && FPA_REG_P (operands[0]))
1715 {
1716 int code = standard_sun_fpa_constant_p (operands[1]);
1717
1718 if (code != 0)
1719 {
1720 static char buf[40];
1721
1722 sprintf (buf, "fpmove%%.d %%%%%d,%%0", code & 0x1ff);
1723 return buf;
1724 }
1725 return "fpmove%.d %1,%0";
1726 }
1727 else
1728 #endif
1729 {
1730 int code = standard_68881_constant_p (operands[1]);
1731
1732 if (code != 0)
1733 {
1734 static char buf[40];
1735
1736 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
1737 return buf;
1738 }
1739 return "fmove%.d %1,%0";
1740 }
1741 }
1742
1743 char *
1744 output_move_const_single (operands)
1745 rtx *operands;
1746 {
1747 #ifdef SUPPORT_SUN_FPA
1748 if (TARGET_FPA)
1749 {
1750 int code = standard_sun_fpa_constant_p (operands[1]);
1751
1752 if (code != 0)
1753 {
1754 static char buf[40];
1755
1756 sprintf (buf, "fpmove%%.s %%%%%d,%%0", code & 0x1ff);
1757 return buf;
1758 }
1759 return "fpmove%.s %1,%0";
1760 }
1761 else
1762 #endif /* defined SUPPORT_SUN_FPA */
1763 {
1764 int code = standard_68881_constant_p (operands[1]);
1765
1766 if (code != 0)
1767 {
1768 static char buf[40];
1769
1770 sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff);
1771 return buf;
1772 }
1773 return "fmove%.s %f1,%0";
1774 }
1775 }
1776
1777 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
1778 from the "fmovecr" instruction.
1779 The value, anded with 0xff, gives the code to use in fmovecr
1780 to get the desired constant. */
1781
1782 /* This code has been fixed for cross-compilation. */
1783
1784 static int inited_68881_table = 0;
1785
1786 char *strings_68881[7] = {
1787 "0.0",
1788 "1.0",
1789 "10.0",
1790 "100.0",
1791 "10000.0",
1792 "1e8",
1793 "1e16"
1794 };
1795
1796 int codes_68881[7] = {
1797 0x0f,
1798 0x32,
1799 0x33,
1800 0x34,
1801 0x35,
1802 0x36,
1803 0x37
1804 };
1805
1806 REAL_VALUE_TYPE values_68881[7];
1807
1808 /* Set up values_68881 array by converting the decimal values
1809 strings_68881 to binary. */
1810
1811 void
1812 init_68881_table ()
1813 {
1814 int i;
1815 REAL_VALUE_TYPE r;
1816 enum machine_mode mode;
1817
1818 mode = SFmode;
1819 for (i = 0; i < 7; i++)
1820 {
1821 if (i == 6)
1822 mode = DFmode;
1823 r = REAL_VALUE_ATOF (strings_68881[i], mode);
1824 values_68881[i] = r;
1825 }
1826 inited_68881_table = 1;
1827 }
1828
1829 int
1830 standard_68881_constant_p (x)
1831 rtx x;
1832 {
1833 REAL_VALUE_TYPE r;
1834 int i;
1835 enum machine_mode mode;
1836
1837 #ifdef NO_ASM_FMOVECR
1838 return 0;
1839 #endif
1840
1841 /* fmovecr must be emulated on the 68040, so it shouldn't be used at all. */
1842 if (TARGET_68040)
1843 return 0;
1844
1845 #ifndef REAL_ARITHMETIC
1846 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
1847 if (! flag_pretend_float)
1848 return 0;
1849 #endif
1850 #endif
1851
1852 if (! inited_68881_table)
1853 init_68881_table ();
1854
1855 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1856
1857 for (i = 0; i < 6; i++)
1858 {
1859 if (REAL_VALUES_EQUAL (r, values_68881[i]))
1860 return (codes_68881[i]);
1861 }
1862
1863 if (GET_MODE (x) == SFmode)
1864 return 0;
1865
1866 if (REAL_VALUES_EQUAL (r, values_68881[6]))
1867 return (codes_68881[6]);
1868
1869 /* larger powers of ten in the constants ram are not used
1870 because they are not equal to a `double' C constant. */
1871 return 0;
1872 }
1873
1874 /* If X is a floating-point constant, return the logarithm of X base 2,
1875 or 0 if X is not a power of 2. */
1876
1877 int
1878 floating_exact_log2 (x)
1879 rtx x;
1880 {
1881 REAL_VALUE_TYPE r, r1;
1882 int i;
1883
1884 #ifndef REAL_ARITHMETIC
1885 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
1886 if (! flag_pretend_float)
1887 return 0;
1888 #endif
1889 #endif
1890
1891 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1892
1893 if (REAL_VALUES_LESS (r, dconst0))
1894 return 0;
1895
1896 r1 = dconst1;
1897 i = 0;
1898 while (REAL_VALUES_LESS (r1, r))
1899 {
1900 r1 = REAL_VALUE_LDEXP (dconst1, i);
1901 if (REAL_VALUES_EQUAL (r1, r))
1902 return i;
1903 i = i + 1;
1904 }
1905 return 0;
1906 }
1907 \f
1908 #ifdef SUPPORT_SUN_FPA
1909 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
1910 from the Sun FPA's constant RAM.
1911 The value returned, anded with 0x1ff, gives the code to use in fpmove
1912 to get the desired constant. */
1913
1914 static int inited_FPA_table = 0;
1915
1916 char *strings_FPA[38] = {
1917 /* small rationals */
1918 "0.0",
1919 "1.0",
1920 "0.5",
1921 "-1.0",
1922 "2.0",
1923 "3.0",
1924 "4.0",
1925 "8.0",
1926 "0.25",
1927 "0.125",
1928 "10.0",
1929 "-0.5",
1930 /* Decimal equivalents of double precision values */
1931 "2.718281828459045091", /* D_E */
1932 "6.283185307179586477", /* 2 pi */
1933 "3.141592653589793116", /* D_PI */
1934 "1.570796326794896619", /* pi/2 */
1935 "1.414213562373095145", /* D_SQRT2 */
1936 "0.7071067811865475244", /* 1/sqrt(2) */
1937 "-1.570796326794896619", /* -pi/2 */
1938 "1.442695040888963387", /* D_LOG2ofE */
1939 "3.321928024887362182", /* D_LOG2of10 */
1940 "0.6931471805599452862", /* D_LOGEof2 */
1941 "2.302585092994045901", /* D_LOGEof10 */
1942 "0.3010299956639811980", /* D_LOG10of2 */
1943 "0.4342944819032518167", /* D_LOG10ofE */
1944 /* Decimal equivalents of single precision values */
1945 "2.718281745910644531", /* S_E */
1946 "6.283185307179586477", /* 2 pi */
1947 "3.141592741012573242", /* S_PI */
1948 "1.570796326794896619", /* pi/2 */
1949 "1.414213538169860840", /* S_SQRT2 */
1950 "0.7071067811865475244", /* 1/sqrt(2) */
1951 "-1.570796326794896619", /* -pi/2 */
1952 "1.442695021629333496", /* S_LOG2ofE */
1953 "3.321928024291992188", /* S_LOG2of10 */
1954 "0.6931471824645996094", /* S_LOGEof2 */
1955 "2.302585124969482442", /* S_LOGEof10 */
1956 "0.3010300099849700928", /* S_LOG10of2 */
1957 "0.4342944920063018799", /* S_LOG10ofE */
1958 };
1959
1960
1961 int codes_FPA[38] = {
1962 /* small rationals */
1963 0x200,
1964 0xe,
1965 0xf,
1966 0x10,
1967 0x11,
1968 0xb1,
1969 0x12,
1970 0x13,
1971 0x15,
1972 0x16,
1973 0x17,
1974 0x2e,
1975 /* double precision */
1976 0x8,
1977 0x9,
1978 0xa,
1979 0xb,
1980 0xc,
1981 0xd,
1982 0x27,
1983 0x28,
1984 0x29,
1985 0x2a,
1986 0x2b,
1987 0x2c,
1988 0x2d,
1989 /* single precision */
1990 0x8,
1991 0x9,
1992 0xa,
1993 0xb,
1994 0xc,
1995 0xd,
1996 0x27,
1997 0x28,
1998 0x29,
1999 0x2a,
2000 0x2b,
2001 0x2c,
2002 0x2d
2003 };
2004
2005 REAL_VALUE_TYPE values_FPA[38];
2006
2007 /* This code has been fixed for cross-compilation. */
2008
2009 void
2010 init_FPA_table ()
2011 {
2012 enum machine_mode mode;
2013 int i;
2014 REAL_VALUE_TYPE r;
2015
2016 mode = DFmode;
2017 for (i = 0; i < 38; i++)
2018 {
2019 if (i == 25)
2020 mode = SFmode;
2021 r = REAL_VALUE_ATOF (strings_FPA[i], mode);
2022 values_FPA[i] = r;
2023 }
2024 inited_FPA_table = 1;
2025 }
2026
2027
2028 int
2029 standard_sun_fpa_constant_p (x)
2030 rtx x;
2031 {
2032 REAL_VALUE_TYPE r;
2033 int i;
2034
2035 #ifndef REAL_ARITHMETIC
2036 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2037 if (! flag_pretend_float)
2038 return 0;
2039 #endif
2040 #endif
2041
2042 if (! inited_FPA_table)
2043 init_FPA_table ();
2044
2045 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2046
2047 for (i=0; i<12; i++)
2048 {
2049 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2050 return (codes_FPA[i]);
2051 }
2052
2053 if (GET_MODE (x) == SFmode)
2054 {
2055 for (i=25; i<38; i++)
2056 {
2057 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2058 return (codes_FPA[i]);
2059 }
2060 }
2061 else
2062 {
2063 for (i=12; i<25; i++)
2064 {
2065 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2066 return (codes_FPA[i]);
2067 }
2068 }
2069 return 0x0;
2070 }
2071 #endif /* define SUPPORT_SUN_FPA */
2072 \f
2073 /* A C compound statement to output to stdio stream STREAM the
2074 assembler syntax for an instruction operand X. X is an RTL
2075 expression.
2076
2077 CODE is a value that can be used to specify one of several ways
2078 of printing the operand. It is used when identical operands
2079 must be printed differently depending on the context. CODE
2080 comes from the `%' specification that was used to request
2081 printing of the operand. If the specification was just `%DIGIT'
2082 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2083 is the ASCII code for LTR.
2084
2085 If X is a register, this macro should print the register's name.
2086 The names can be found in an array `reg_names' whose type is
2087 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2088
2089 When the machine description has a specification `%PUNCT' (a `%'
2090 followed by a punctuation character), this macro is called with
2091 a null pointer for X and the punctuation character for CODE.
2092
2093 The m68k specific codes are:
2094
2095 '.' for dot needed in Motorola-style opcode names.
2096 '-' for an operand pushing on the stack:
2097 sp@-, -(sp) or -(%sp) depending on the style of syntax.
2098 '+' for an operand pushing on the stack:
2099 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2100 '@' for a reference to the top word on the stack:
2101 sp@, (sp) or (%sp) depending on the style of syntax.
2102 '#' for an immediate operand prefix (# in MIT and Motorola syntax
2103 but & in SGS syntax).
2104 '!' for the cc register (used in an `and to cc' insn).
2105 '$' for the letter `s' in an op code, but only on the 68040.
2106 '&' for the letter `d' in an op code, but only on the 68040.
2107 '/' for register prefix needed by longlong.h.
2108
2109 'b' for byte insn (no effect, on the Sun; this is for the ISI).
2110 'd' to force memory addressing to be absolute, not relative.
2111 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2112 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
2113 than directly). Second part of 'y' below.
2114 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2115 or print pair of registers as rx:ry.
2116 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
2117 CONST_DOUBLE's as SunFPA constant RAM registers if
2118 possible, so it should not be used except for the SunFPA.
2119
2120 */
2121
2122 void
2123 print_operand (file, op, letter)
2124 FILE *file; /* file to write to */
2125 rtx op; /* operand to print */
2126 int letter; /* %<letter> or 0 */
2127 {
2128 int i;
2129
2130 if (letter == '.')
2131 {
2132 #ifdef MOTOROLA
2133 asm_fprintf (file, ".");
2134 #endif
2135 }
2136 else if (letter == '#')
2137 {
2138 asm_fprintf (file, "%0I");
2139 }
2140 else if (letter == '-')
2141 {
2142 #ifdef MOTOROLA
2143 asm_fprintf (file, "-(%Rsp)");
2144 #else
2145 asm_fprintf (file, "%Rsp@-");
2146 #endif
2147 }
2148 else if (letter == '+')
2149 {
2150 #ifdef MOTOROLA
2151 asm_fprintf (file, "(%Rsp)+");
2152 #else
2153 asm_fprintf (file, "%Rsp@+");
2154 #endif
2155 }
2156 else if (letter == '@')
2157 {
2158 #ifdef MOTOROLA
2159 asm_fprintf (file, "(%Rsp)");
2160 #else
2161 asm_fprintf (file, "%Rsp@");
2162 #endif
2163 }
2164 else if (letter == '!')
2165 {
2166 asm_fprintf (file, "%Rfpcr");
2167 }
2168 else if (letter == '$')
2169 {
2170 if (TARGET_68040_ONLY)
2171 {
2172 fprintf (file, "s");
2173 }
2174 }
2175 else if (letter == '&')
2176 {
2177 if (TARGET_68040_ONLY)
2178 {
2179 fprintf (file, "d");
2180 }
2181 }
2182 else if (letter == '/')
2183 {
2184 asm_fprintf (file, "%R");
2185 }
2186 else if (GET_CODE (op) == REG)
2187 {
2188 #ifdef SUPPORT_SUN_FPA
2189 if (REGNO (op) < 16
2190 && (letter == 'y' || letter == 'x')
2191 && GET_MODE (op) == DFmode)
2192 {
2193 fprintf (file, "%s:%s", reg_names[REGNO (op)],
2194 reg_names[REGNO (op)+1]);
2195 }
2196 else
2197 #endif
2198 {
2199 if (letter == 'R')
2200 /* Print out the second register name of a register pair.
2201 I.e., R (6) => 7. */
2202 fputs (reg_names[REGNO (op) + 1], file);
2203 else
2204 fputs (reg_names[REGNO (op)], file);
2205 }
2206 }
2207 else if (GET_CODE (op) == MEM)
2208 {
2209 output_address (XEXP (op, 0));
2210 if (letter == 'd' && ! TARGET_68020
2211 && CONSTANT_ADDRESS_P (XEXP (op, 0))
2212 && !(GET_CODE (XEXP (op, 0)) == CONST_INT
2213 && INTVAL (XEXP (op, 0)) < 0x8000
2214 && INTVAL (XEXP (op, 0)) >= -0x8000))
2215 {
2216 #ifdef MOTOROLA
2217 fprintf (file, ".l");
2218 #else
2219 fprintf (file, ":l");
2220 #endif
2221 }
2222 }
2223 #ifdef SUPPORT_SUN_FPA
2224 else if ((letter == 'y' || letter == 'w')
2225 && GET_CODE (op) == CONST_DOUBLE
2226 && (i = standard_sun_fpa_constant_p (op)))
2227 {
2228 fprintf (file, "%%%d", i & 0x1ff);
2229 }
2230 #endif
2231 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
2232 {
2233 REAL_VALUE_TYPE r;
2234 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2235 ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
2236 }
2237 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
2238 {
2239 REAL_VALUE_TYPE r;
2240 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2241 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
2242 }
2243 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
2244 {
2245 REAL_VALUE_TYPE r;
2246 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2247 ASM_OUTPUT_DOUBLE_OPERAND (file, r);
2248 }
2249 else
2250 {
2251 asm_fprintf (file, "%0I"); output_addr_const (file, op);
2252 }
2253 }
2254
2255 \f
2256 /* A C compound statement to output to stdio stream STREAM the
2257 assembler syntax for an instruction operand that is a memory
2258 reference whose address is ADDR. ADDR is an RTL expression.
2259
2260 Note that this contains a kludge that knows that the only reason
2261 we have an address (plus (label_ref...) (reg...)) when not generating
2262 PIC code is in the insn before a tablejump, and we know that m68k.md
2263 generates a label LInnn: on such an insn.
2264
2265 It is possible for PIC to generate a (plus (label_ref...) (reg...))
2266 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2267
2268 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2269 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
2270 we want. This difference can be accommodated by using an assembler
2271 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2272 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
2273 macro. See m68k/sgs.h for an example; for versions without the bug.
2274 Some assemblers refuse all the above solutions. The workaround is to
2275 emit "K(pc,d0.l*2)" with K being a small constant known to give the
2276 right behaviour.
2277
2278 They also do not like things like "pea 1.w", so we simple leave off
2279 the .w on small constants.
2280
2281 This routine is responsible for distinguishing between -fpic and -fPIC
2282 style relocations in an address. When generating -fpic code the
2283 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
2284 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
2285
2286 #ifndef ASM_OUTPUT_CASE_FETCH
2287 #ifdef MOTOROLA
2288 #ifdef SGS
2289 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2290 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
2291 #else
2292 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2293 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2294 #endif
2295 #else
2296 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2297 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
2298 #endif
2299 #endif /* ASM_OUTPUT_CASE_FETCH */
2300
2301 void
2302 print_operand_address (file, addr)
2303 FILE *file;
2304 rtx addr;
2305 {
2306 register rtx reg1, reg2, breg, ireg;
2307 rtx offset;
2308
2309 switch (GET_CODE (addr))
2310 {
2311 case REG:
2312 #ifdef MOTOROLA
2313 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
2314 #else
2315 fprintf (file, "%s@", reg_names[REGNO (addr)]);
2316 #endif
2317 break;
2318 case PRE_DEC:
2319 #ifdef MOTOROLA
2320 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
2321 #else
2322 fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);
2323 #endif
2324 break;
2325 case POST_INC:
2326 #ifdef MOTOROLA
2327 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
2328 #else
2329 fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);
2330 #endif
2331 break;
2332 case PLUS:
2333 reg1 = reg2 = ireg = breg = offset = 0;
2334 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
2335 {
2336 offset = XEXP (addr, 0);
2337 addr = XEXP (addr, 1);
2338 }
2339 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
2340 {
2341 offset = XEXP (addr, 1);
2342 addr = XEXP (addr, 0);
2343 }
2344 if (GET_CODE (addr) != PLUS)
2345 {
2346 ;
2347 }
2348 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
2349 {
2350 reg1 = XEXP (addr, 0);
2351 addr = XEXP (addr, 1);
2352 }
2353 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
2354 {
2355 reg1 = XEXP (addr, 1);
2356 addr = XEXP (addr, 0);
2357 }
2358 else if (GET_CODE (XEXP (addr, 0)) == MULT)
2359 {
2360 reg1 = XEXP (addr, 0);
2361 addr = XEXP (addr, 1);
2362 }
2363 else if (GET_CODE (XEXP (addr, 1)) == MULT)
2364 {
2365 reg1 = XEXP (addr, 1);
2366 addr = XEXP (addr, 0);
2367 }
2368 else if (GET_CODE (XEXP (addr, 0)) == REG)
2369 {
2370 reg1 = XEXP (addr, 0);
2371 addr = XEXP (addr, 1);
2372 }
2373 else if (GET_CODE (XEXP (addr, 1)) == REG)
2374 {
2375 reg1 = XEXP (addr, 1);
2376 addr = XEXP (addr, 0);
2377 }
2378 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
2379 || GET_CODE (addr) == SIGN_EXTEND)
2380 {
2381 if (reg1 == 0)
2382 {
2383 reg1 = addr;
2384 }
2385 else
2386 {
2387 reg2 = addr;
2388 }
2389 addr = 0;
2390 }
2391 #if 0 /* for OLD_INDEXING */
2392 else if (GET_CODE (addr) == PLUS)
2393 {
2394 if (GET_CODE (XEXP (addr, 0)) == REG)
2395 {
2396 reg2 = XEXP (addr, 0);
2397 addr = XEXP (addr, 1);
2398 }
2399 else if (GET_CODE (XEXP (addr, 1)) == REG)
2400 {
2401 reg2 = XEXP (addr, 1);
2402 addr = XEXP (addr, 0);
2403 }
2404 }
2405 #endif
2406 if (offset != 0)
2407 {
2408 if (addr != 0)
2409 {
2410 abort ();
2411 }
2412 addr = offset;
2413 }
2414 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
2415 || GET_CODE (reg1) == MULT))
2416 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
2417 {
2418 breg = reg2;
2419 ireg = reg1;
2420 }
2421 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
2422 {
2423 breg = reg1;
2424 ireg = reg2;
2425 }
2426 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
2427 && ! (flag_pic && ireg == pic_offset_table_rtx))
2428 {
2429 int scale = 1;
2430 if (GET_CODE (ireg) == MULT)
2431 {
2432 scale = INTVAL (XEXP (ireg, 1));
2433 ireg = XEXP (ireg, 0);
2434 }
2435 if (GET_CODE (ireg) == SIGN_EXTEND)
2436 {
2437 ASM_OUTPUT_CASE_FETCH (file,
2438 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2439 reg_names[REGNO (XEXP (ireg, 0))]);
2440 fprintf (file, "w");
2441 }
2442 else
2443 {
2444 ASM_OUTPUT_CASE_FETCH (file,
2445 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2446 reg_names[REGNO (ireg)]);
2447 fprintf (file, "l");
2448 }
2449 if (scale != 1)
2450 {
2451 #ifdef MOTOROLA
2452 fprintf (file, "*%d", scale);
2453 #else
2454 fprintf (file, ":%d", scale);
2455 #endif
2456 }
2457 putc (')', file);
2458 break;
2459 }
2460 if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
2461 && ! (flag_pic && breg == pic_offset_table_rtx))
2462 {
2463 ASM_OUTPUT_CASE_FETCH (file,
2464 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2465 reg_names[REGNO (breg)]);
2466 fprintf (file, "l)");
2467 break;
2468 }
2469 if (ireg != 0 || breg != 0)
2470 {
2471 int scale = 1;
2472 if (breg == 0)
2473 {
2474 abort ();
2475 }
2476 if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)
2477 {
2478 abort ();
2479 }
2480 #ifdef MOTOROLA
2481 if (addr != 0)
2482 {
2483 output_addr_const (file, addr);
2484 if (flag_pic && (breg == pic_offset_table_rtx))
2485 fprintf (file, "@GOT");
2486 }
2487 fprintf (file, "(%s", reg_names[REGNO (breg)]);
2488 if (ireg != 0)
2489 {
2490 putc (',', file);
2491 }
2492 #else
2493 fprintf (file, "%s@(", reg_names[REGNO (breg)]);
2494 if (addr != 0)
2495 {
2496 output_addr_const (file, addr);
2497 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
2498 fprintf (file, ":w");
2499 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
2500 fprintf (file, ":l");
2501 }
2502 if (addr != 0 && ireg != 0)
2503 {
2504 putc (',', file);
2505 }
2506 #endif
2507 if (ireg != 0 && GET_CODE (ireg) == MULT)
2508 {
2509 scale = INTVAL (XEXP (ireg, 1));
2510 ireg = XEXP (ireg, 0);
2511 }
2512 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
2513 {
2514 #ifdef MOTOROLA
2515 fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);
2516 #else
2517 fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);
2518 #endif
2519 }
2520 else if (ireg != 0)
2521 {
2522 #ifdef MOTOROLA
2523 fprintf (file, "%s.l", reg_names[REGNO (ireg)]);
2524 #else
2525 fprintf (file, "%s:l", reg_names[REGNO (ireg)]);
2526 #endif
2527 }
2528 if (scale != 1)
2529 {
2530 #ifdef MOTOROLA
2531 fprintf (file, "*%d", scale);
2532 #else
2533 fprintf (file, ":%d", scale);
2534 #endif
2535 }
2536 putc (')', file);
2537 break;
2538 }
2539 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
2540 && ! (flag_pic && reg1 == pic_offset_table_rtx))
2541 {
2542 ASM_OUTPUT_CASE_FETCH (file,
2543 CODE_LABEL_NUMBER (XEXP (addr, 0)),
2544 reg_names[REGNO (reg1)]);
2545 fprintf (file, "l)");
2546 break;
2547 }
2548 /* FALL-THROUGH (is this really what we want? */
2549 default:
2550 if (GET_CODE (addr) == CONST_INT
2551 && INTVAL (addr) < 0x8000
2552 && INTVAL (addr) >= -0x8000)
2553 {
2554 #ifdef MOTOROLA
2555 #ifdef SGS
2556 /* Many SGS assemblers croak on size specifiers for constants. */
2557 fprintf (file, "%d", INTVAL (addr));
2558 #else
2559 fprintf (file, "%d.w", INTVAL (addr));
2560 #endif
2561 #else
2562 fprintf (file, "%d:w", INTVAL (addr));
2563 #endif
2564 }
2565 else
2566 {
2567 output_addr_const (file, addr);
2568 }
2569 break;
2570 }
2571 }
2572 \f
2573 /* Check for cases where a clr insns can be omitted from code using
2574 strict_low_part sets. For example, the second clrl here is not needed:
2575 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
2576
2577 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
2578 insn we are checking for redundancy. TARGET is the register set by the
2579 clear insn. */
2580
2581 int
2582 strict_low_part_peephole_ok (mode, first_insn, target)
2583 enum machine_mode mode;
2584 rtx first_insn;
2585 rtx target;
2586 {
2587 rtx p;
2588
2589 p = prev_nonnote_insn (first_insn);
2590
2591 while (p)
2592 {
2593 /* If it isn't an insn, then give up. */
2594 if (GET_CODE (p) != INSN)
2595 return 0;
2596
2597 if (reg_set_p (target, p))
2598 {
2599 rtx set = single_set (p);
2600 rtx dest;
2601
2602 /* If it isn't an easy to recognize insn, then give up. */
2603 if (! set)
2604 return 0;
2605
2606 dest = SET_DEST (set);
2607
2608 /* If this sets the entire target register to zero, then our
2609 first_insn is redundant. */
2610 if (rtx_equal_p (dest, target)
2611 && SET_SRC (set) == const0_rtx)
2612 return 1;
2613 else if (GET_CODE (dest) == STRICT_LOW_PART
2614 && GET_CODE (XEXP (dest, 0)) == REG
2615 && REGNO (XEXP (dest, 0)) == REGNO (target)
2616 && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0)))
2617 <= GET_MODE_SIZE (mode)))
2618 /* This is a strict low part set which modifies less than
2619 we are using, so it is safe. */
2620 ;
2621 else
2622 return 0;
2623 }
2624
2625 p = prev_nonnote_insn (p);
2626
2627 }
2628
2629 return 0;
2630 }
2631
2632 /* Accept integer operands in the range 0..0xffffffff. We have to check the
2633 range carefully since this predicate is used in DImode contexts. Also, we
2634 need some extra crud to make it work when hosted on 64-bit machines. */
2635
2636 int
2637 const_uint32_operand (op, mode)
2638 rtx op;
2639 enum machine_mode mode;
2640 {
2641 #if HOST_BITS_PER_WIDE_INT > 32
2642 /* All allowed constants will fit a CONST_INT. */
2643 return (GET_CODE (op) == CONST_INT
2644 && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
2645 #else
2646 return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0)
2647 || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
2648 #endif
2649 }
2650
2651 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
2652 to check the range carefully since this predicate is used in DImode
2653 contexts. */
2654
2655 int
2656 const_sint32_operand (op, mode)
2657 rtx op;
2658 enum machine_mode mode;
2659 {
2660 /* All allowed constants will fit a CONST_INT. */
2661 return (GET_CODE (op) == CONST_INT
2662 && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
2663 }