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