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