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