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