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