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