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