Update copyrights.
[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 char *m68k_align_loops_string;
62 /* Specify power of two alignment used for non-loop jumps. */
63 char *m68k_align_jumps_string;
64 /* Specify power of two alignment used for functions. */
65 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 for (i = 0; i < 6; i++)
2464 {
2465 if (REAL_VALUES_EQUAL (r, values_68881[i]))
2466 return (codes_68881[i]);
2467 }
2468
2469 if (GET_MODE (x) == SFmode)
2470 return 0;
2471
2472 if (REAL_VALUES_EQUAL (r, values_68881[6]))
2473 return (codes_68881[6]);
2474
2475 /* larger powers of ten in the constants ram are not used
2476 because they are not equal to a `double' C constant. */
2477 return 0;
2478 }
2479
2480 /* If X is a floating-point constant, return the logarithm of X base 2,
2481 or 0 if X is not a power of 2. */
2482
2483 int
2484 floating_exact_log2 (x)
2485 rtx x;
2486 {
2487 REAL_VALUE_TYPE r, r1;
2488 int i;
2489
2490 #ifndef REAL_ARITHMETIC
2491 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2492 if (! flag_pretend_float)
2493 return 0;
2494 #endif
2495 #endif
2496
2497 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2498
2499 if (REAL_VALUES_LESS (r, dconst0))
2500 return 0;
2501
2502 r1 = dconst1;
2503 i = 0;
2504 while (REAL_VALUES_LESS (r1, r))
2505 {
2506 r1 = REAL_VALUE_LDEXP (dconst1, i);
2507 if (REAL_VALUES_EQUAL (r1, r))
2508 return i;
2509 i = i + 1;
2510 }
2511 return 0;
2512 }
2513 \f
2514 #ifdef SUPPORT_SUN_FPA
2515 /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
2516 from the Sun FPA's constant RAM.
2517 The value returned, anded with 0x1ff, gives the code to use in fpmove
2518 to get the desired constant. */
2519
2520 static int inited_FPA_table = 0;
2521
2522 char *strings_FPA[38] = {
2523 /* small rationals */
2524 "0.0",
2525 "1.0",
2526 "0.5",
2527 "-1.0",
2528 "2.0",
2529 "3.0",
2530 "4.0",
2531 "8.0",
2532 "0.25",
2533 "0.125",
2534 "10.0",
2535 "-0.5",
2536 /* Decimal equivalents of double precision values */
2537 "2.718281828459045091", /* D_E */
2538 "6.283185307179586477", /* 2 pi */
2539 "3.141592653589793116", /* D_PI */
2540 "1.570796326794896619", /* pi/2 */
2541 "1.414213562373095145", /* D_SQRT2 */
2542 "0.7071067811865475244", /* 1/sqrt(2) */
2543 "-1.570796326794896619", /* -pi/2 */
2544 "1.442695040888963387", /* D_LOG2ofE */
2545 "3.321928024887362182", /* D_LOG2of10 */
2546 "0.6931471805599452862", /* D_LOGEof2 */
2547 "2.302585092994045901", /* D_LOGEof10 */
2548 "0.3010299956639811980", /* D_LOG10of2 */
2549 "0.4342944819032518167", /* D_LOG10ofE */
2550 /* Decimal equivalents of single precision values */
2551 "2.718281745910644531", /* S_E */
2552 "6.283185307179586477", /* 2 pi */
2553 "3.141592741012573242", /* S_PI */
2554 "1.570796326794896619", /* pi/2 */
2555 "1.414213538169860840", /* S_SQRT2 */
2556 "0.7071067811865475244", /* 1/sqrt(2) */
2557 "-1.570796326794896619", /* -pi/2 */
2558 "1.442695021629333496", /* S_LOG2ofE */
2559 "3.321928024291992188", /* S_LOG2of10 */
2560 "0.6931471824645996094", /* S_LOGEof2 */
2561 "2.302585124969482442", /* S_LOGEof10 */
2562 "0.3010300099849700928", /* S_LOG10of2 */
2563 "0.4342944920063018799", /* S_LOG10ofE */
2564 };
2565
2566
2567 int codes_FPA[38] = {
2568 /* small rationals */
2569 0x200,
2570 0xe,
2571 0xf,
2572 0x10,
2573 0x11,
2574 0xb1,
2575 0x12,
2576 0x13,
2577 0x15,
2578 0x16,
2579 0x17,
2580 0x2e,
2581 /* double precision */
2582 0x8,
2583 0x9,
2584 0xa,
2585 0xb,
2586 0xc,
2587 0xd,
2588 0x27,
2589 0x28,
2590 0x29,
2591 0x2a,
2592 0x2b,
2593 0x2c,
2594 0x2d,
2595 /* single precision */
2596 0x8,
2597 0x9,
2598 0xa,
2599 0xb,
2600 0xc,
2601 0xd,
2602 0x27,
2603 0x28,
2604 0x29,
2605 0x2a,
2606 0x2b,
2607 0x2c,
2608 0x2d
2609 };
2610
2611 REAL_VALUE_TYPE values_FPA[38];
2612
2613 /* This code has been fixed for cross-compilation. */
2614
2615 void
2616 init_FPA_table ()
2617 {
2618 enum machine_mode mode;
2619 int i;
2620 REAL_VALUE_TYPE r;
2621
2622 mode = DFmode;
2623 for (i = 0; i < 38; i++)
2624 {
2625 if (i == 25)
2626 mode = SFmode;
2627 r = REAL_VALUE_ATOF (strings_FPA[i], mode);
2628 values_FPA[i] = r;
2629 }
2630 inited_FPA_table = 1;
2631 }
2632
2633
2634 int
2635 standard_sun_fpa_constant_p (x)
2636 rtx x;
2637 {
2638 REAL_VALUE_TYPE r;
2639 int i;
2640
2641 #ifndef REAL_ARITHMETIC
2642 #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2643 if (! flag_pretend_float)
2644 return 0;
2645 #endif
2646 #endif
2647
2648 if (! inited_FPA_table)
2649 init_FPA_table ();
2650
2651 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2652
2653 for (i=0; i<12; i++)
2654 {
2655 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2656 return (codes_FPA[i]);
2657 }
2658
2659 if (GET_MODE (x) == SFmode)
2660 {
2661 for (i=25; i<38; i++)
2662 {
2663 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2664 return (codes_FPA[i]);
2665 }
2666 }
2667 else
2668 {
2669 for (i=12; i<25; i++)
2670 {
2671 if (REAL_VALUES_EQUAL (r, values_FPA[i]))
2672 return (codes_FPA[i]);
2673 }
2674 }
2675 return 0x0;
2676 }
2677 #endif /* define SUPPORT_SUN_FPA */
2678 \f
2679 /* A C compound statement to output to stdio stream STREAM the
2680 assembler syntax for an instruction operand X. X is an RTL
2681 expression.
2682
2683 CODE is a value that can be used to specify one of several ways
2684 of printing the operand. It is used when identical operands
2685 must be printed differently depending on the context. CODE
2686 comes from the `%' specification that was used to request
2687 printing of the operand. If the specification was just `%DIGIT'
2688 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
2689 is the ASCII code for LTR.
2690
2691 If X is a register, this macro should print the register's name.
2692 The names can be found in an array `reg_names' whose type is
2693 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
2694
2695 When the machine description has a specification `%PUNCT' (a `%'
2696 followed by a punctuation character), this macro is called with
2697 a null pointer for X and the punctuation character for CODE.
2698
2699 The m68k specific codes are:
2700
2701 '.' for dot needed in Motorola-style opcode names.
2702 '-' for an operand pushing on the stack:
2703 sp@-, -(sp) or -(%sp) depending on the style of syntax.
2704 '+' for an operand pushing on the stack:
2705 sp@+, (sp)+ or (%sp)+ depending on the style of syntax.
2706 '@' for a reference to the top word on the stack:
2707 sp@, (sp) or (%sp) depending on the style of syntax.
2708 '#' for an immediate operand prefix (# in MIT and Motorola syntax
2709 but & in SGS syntax, $ in CRDS/UNOS syntax).
2710 '!' for the cc register (used in an `and to cc' insn).
2711 '$' for the letter `s' in an op code, but only on the 68040.
2712 '&' for the letter `d' in an op code, but only on the 68040.
2713 '/' for register prefix needed by longlong.h.
2714
2715 'b' for byte insn (no effect, on the Sun; this is for the ISI).
2716 'd' to force memory addressing to be absolute, not relative.
2717 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
2718 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
2719 than directly). Second part of 'y' below.
2720 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
2721 or print pair of registers as rx:ry.
2722 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs
2723 CONST_DOUBLE's as SunFPA constant RAM registers if
2724 possible, so it should not be used except for the SunFPA.
2725
2726 */
2727
2728 void
2729 print_operand (file, op, letter)
2730 FILE *file; /* file to write to */
2731 rtx op; /* operand to print */
2732 int letter; /* %<letter> or 0 */
2733 {
2734 #ifdef SUPPORT_SUN_FPA
2735 int i;
2736 #endif
2737
2738 if (letter == '.')
2739 {
2740 #if defined (MOTOROLA) && !defined (CRDS)
2741 asm_fprintf (file, ".");
2742 #endif
2743 }
2744 else if (letter == '#')
2745 {
2746 asm_fprintf (file, "%0I");
2747 }
2748 else if (letter == '-')
2749 {
2750 #ifdef MOTOROLA
2751 asm_fprintf (file, "-(%Rsp)");
2752 #else
2753 asm_fprintf (file, "%Rsp@-");
2754 #endif
2755 }
2756 else if (letter == '+')
2757 {
2758 #ifdef MOTOROLA
2759 asm_fprintf (file, "(%Rsp)+");
2760 #else
2761 asm_fprintf (file, "%Rsp@+");
2762 #endif
2763 }
2764 else if (letter == '@')
2765 {
2766 #ifdef MOTOROLA
2767 asm_fprintf (file, "(%Rsp)");
2768 #else
2769 asm_fprintf (file, "%Rsp@");
2770 #endif
2771 }
2772 else if (letter == '!')
2773 {
2774 asm_fprintf (file, "%Rfpcr");
2775 }
2776 else if (letter == '$')
2777 {
2778 if (TARGET_68040_ONLY)
2779 {
2780 fprintf (file, "s");
2781 }
2782 }
2783 else if (letter == '&')
2784 {
2785 if (TARGET_68040_ONLY)
2786 {
2787 fprintf (file, "d");
2788 }
2789 }
2790 else if (letter == '/')
2791 {
2792 asm_fprintf (file, "%R");
2793 }
2794 else if (GET_CODE (op) == REG)
2795 {
2796 #ifdef SUPPORT_SUN_FPA
2797 if (REGNO (op) < 16
2798 && (letter == 'y' || letter == 'x')
2799 && GET_MODE (op) == DFmode)
2800 {
2801 fprintf (file, "%s:%s", reg_names[REGNO (op)],
2802 reg_names[REGNO (op)+1]);
2803 }
2804 else
2805 #endif
2806 {
2807 if (letter == 'R')
2808 /* Print out the second register name of a register pair.
2809 I.e., R (6) => 7. */
2810 fputs (reg_names[REGNO (op) + 1], file);
2811 else
2812 fputs (reg_names[REGNO (op)], file);
2813 }
2814 }
2815 else if (GET_CODE (op) == MEM)
2816 {
2817 output_address (XEXP (op, 0));
2818 if (letter == 'd' && ! TARGET_68020
2819 && CONSTANT_ADDRESS_P (XEXP (op, 0))
2820 && !(GET_CODE (XEXP (op, 0)) == CONST_INT
2821 && INTVAL (XEXP (op, 0)) < 0x8000
2822 && INTVAL (XEXP (op, 0)) >= -0x8000))
2823 {
2824 #ifdef MOTOROLA
2825 fprintf (file, ".l");
2826 #else
2827 fprintf (file, ":l");
2828 #endif
2829 }
2830 }
2831 #ifdef SUPPORT_SUN_FPA
2832 else if ((letter == 'y' || letter == 'w')
2833 && GET_CODE (op) == CONST_DOUBLE
2834 && (i = standard_sun_fpa_constant_p (op)))
2835 {
2836 fprintf (file, "%%%d", i & 0x1ff);
2837 }
2838 #endif
2839 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
2840 {
2841 REAL_VALUE_TYPE r;
2842 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2843 ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);
2844 }
2845 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
2846 {
2847 REAL_VALUE_TYPE r;
2848 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2849 ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);
2850 }
2851 else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
2852 {
2853 REAL_VALUE_TYPE r;
2854 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
2855 ASM_OUTPUT_DOUBLE_OPERAND (file, r);
2856 }
2857 else
2858 {
2859 asm_fprintf (file, "%0I"); output_addr_const (file, op);
2860 }
2861 }
2862
2863 \f
2864 /* A C compound statement to output to stdio stream STREAM the
2865 assembler syntax for an instruction operand that is a memory
2866 reference whose address is ADDR. ADDR is an RTL expression.
2867
2868 Note that this contains a kludge that knows that the only reason
2869 we have an address (plus (label_ref...) (reg...)) when not generating
2870 PIC code is in the insn before a tablejump, and we know that m68k.md
2871 generates a label LInnn: on such an insn.
2872
2873 It is possible for PIC to generate a (plus (label_ref...) (reg...))
2874 and we handle that just like we would a (plus (symbol_ref...) (reg...)).
2875
2876 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
2877 fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results
2878 we want. This difference can be accommodated by using an assembler
2879 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
2880 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
2881 macro. See m68k/sgs.h for an example; for versions without the bug.
2882 Some assemblers refuse all the above solutions. The workaround is to
2883 emit "K(pc,d0.l*2)" with K being a small constant known to give the
2884 right behaviour.
2885
2886 They also do not like things like "pea 1.w", so we simple leave off
2887 the .w on small constants.
2888
2889 This routine is responsible for distinguishing between -fpic and -fPIC
2890 style relocations in an address. When generating -fpic code the
2891 offset is output in word mode (eg movel a5@(_foo:w), a0). When generating
2892 -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */
2893
2894 #ifndef ASM_OUTPUT_CASE_FETCH
2895 #ifdef MOTOROLA
2896 #ifdef SGS
2897 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2898 asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)
2899 #else
2900 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2901 asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
2902 #endif
2903 #else
2904 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
2905 asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
2906 #endif
2907 #endif /* ASM_OUTPUT_CASE_FETCH */
2908
2909 void
2910 print_operand_address (file, addr)
2911 FILE *file;
2912 rtx addr;
2913 {
2914 register rtx reg1, reg2, breg, ireg;
2915 rtx offset;
2916
2917 switch (GET_CODE (addr))
2918 {
2919 case REG:
2920 #ifdef MOTOROLA
2921 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
2922 #else
2923 fprintf (file, "%s@", reg_names[REGNO (addr)]);
2924 #endif
2925 break;
2926 case PRE_DEC:
2927 #ifdef MOTOROLA
2928 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
2929 #else
2930 fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);
2931 #endif
2932 break;
2933 case POST_INC:
2934 #ifdef MOTOROLA
2935 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
2936 #else
2937 fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);
2938 #endif
2939 break;
2940 case PLUS:
2941 reg1 = reg2 = ireg = breg = offset = 0;
2942 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
2943 {
2944 offset = XEXP (addr, 0);
2945 addr = XEXP (addr, 1);
2946 }
2947 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
2948 {
2949 offset = XEXP (addr, 1);
2950 addr = XEXP (addr, 0);
2951 }
2952 if (GET_CODE (addr) != PLUS)
2953 {
2954 ;
2955 }
2956 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
2957 {
2958 reg1 = XEXP (addr, 0);
2959 addr = XEXP (addr, 1);
2960 }
2961 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
2962 {
2963 reg1 = XEXP (addr, 1);
2964 addr = XEXP (addr, 0);
2965 }
2966 else if (GET_CODE (XEXP (addr, 0)) == MULT)
2967 {
2968 reg1 = XEXP (addr, 0);
2969 addr = XEXP (addr, 1);
2970 }
2971 else if (GET_CODE (XEXP (addr, 1)) == MULT)
2972 {
2973 reg1 = XEXP (addr, 1);
2974 addr = XEXP (addr, 0);
2975 }
2976 else if (GET_CODE (XEXP (addr, 0)) == REG)
2977 {
2978 reg1 = XEXP (addr, 0);
2979 addr = XEXP (addr, 1);
2980 }
2981 else if (GET_CODE (XEXP (addr, 1)) == REG)
2982 {
2983 reg1 = XEXP (addr, 1);
2984 addr = XEXP (addr, 0);
2985 }
2986 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
2987 || GET_CODE (addr) == SIGN_EXTEND)
2988 {
2989 if (reg1 == 0)
2990 {
2991 reg1 = addr;
2992 }
2993 else
2994 {
2995 reg2 = addr;
2996 }
2997 addr = 0;
2998 }
2999 #if 0 /* for OLD_INDEXING */
3000 else if (GET_CODE (addr) == PLUS)
3001 {
3002 if (GET_CODE (XEXP (addr, 0)) == REG)
3003 {
3004 reg2 = XEXP (addr, 0);
3005 addr = XEXP (addr, 1);
3006 }
3007 else if (GET_CODE (XEXP (addr, 1)) == REG)
3008 {
3009 reg2 = XEXP (addr, 1);
3010 addr = XEXP (addr, 0);
3011 }
3012 }
3013 #endif
3014 if (offset != 0)
3015 {
3016 if (addr != 0)
3017 {
3018 abort ();
3019 }
3020 addr = offset;
3021 }
3022 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
3023 || GET_CODE (reg1) == MULT))
3024 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3025 {
3026 breg = reg2;
3027 ireg = reg1;
3028 }
3029 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3030 {
3031 breg = reg1;
3032 ireg = reg2;
3033 }
3034 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
3035 && ! (flag_pic && ireg == pic_offset_table_rtx))
3036 {
3037 int scale = 1;
3038 if (GET_CODE (ireg) == MULT)
3039 {
3040 scale = INTVAL (XEXP (ireg, 1));
3041 ireg = XEXP (ireg, 0);
3042 }
3043 if (GET_CODE (ireg) == SIGN_EXTEND)
3044 {
3045 ASM_OUTPUT_CASE_FETCH (file,
3046 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3047 reg_names[REGNO (XEXP (ireg, 0))]);
3048 fprintf (file, "w");
3049 }
3050 else
3051 {
3052 ASM_OUTPUT_CASE_FETCH (file,
3053 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3054 reg_names[REGNO (ireg)]);
3055 fprintf (file, "l");
3056 }
3057 if (scale != 1)
3058 {
3059 #ifdef MOTOROLA
3060 fprintf (file, "*%d", scale);
3061 #else
3062 fprintf (file, ":%d", scale);
3063 #endif
3064 }
3065 putc (')', file);
3066 break;
3067 }
3068 if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
3069 && ! (flag_pic && breg == pic_offset_table_rtx))
3070 {
3071 ASM_OUTPUT_CASE_FETCH (file,
3072 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3073 reg_names[REGNO (breg)]);
3074 fprintf (file, "l)");
3075 break;
3076 }
3077 if (ireg != 0 || breg != 0)
3078 {
3079 int scale = 1;
3080 if (breg == 0)
3081 {
3082 abort ();
3083 }
3084 if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)
3085 {
3086 abort ();
3087 }
3088 #ifdef MOTOROLA
3089 if (addr != 0)
3090 {
3091 output_addr_const (file, addr);
3092 if (flag_pic && (breg == pic_offset_table_rtx))
3093 {
3094 fprintf (file, "@GOT");
3095 if (flag_pic == 1)
3096 fprintf (file, ".w");
3097 }
3098 }
3099 fprintf (file, "(%s", reg_names[REGNO (breg)]);
3100 if (ireg != 0)
3101 {
3102 putc (',', file);
3103 }
3104 #else
3105 fprintf (file, "%s@(", reg_names[REGNO (breg)]);
3106 if (addr != 0)
3107 {
3108 output_addr_const (file, addr);
3109 if ((flag_pic == 1) && (breg == pic_offset_table_rtx))
3110 fprintf (file, ":w");
3111 if ((flag_pic == 2) && (breg == pic_offset_table_rtx))
3112 fprintf (file, ":l");
3113 }
3114 if (addr != 0 && ireg != 0)
3115 {
3116 putc (',', file);
3117 }
3118 #endif
3119 if (ireg != 0 && GET_CODE (ireg) == MULT)
3120 {
3121 scale = INTVAL (XEXP (ireg, 1));
3122 ireg = XEXP (ireg, 0);
3123 }
3124 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
3125 {
3126 #ifdef MOTOROLA
3127 fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);
3128 #else
3129 fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);
3130 #endif
3131 }
3132 else if (ireg != 0)
3133 {
3134 #ifdef MOTOROLA
3135 fprintf (file, "%s.l", reg_names[REGNO (ireg)]);
3136 #else
3137 fprintf (file, "%s:l", reg_names[REGNO (ireg)]);
3138 #endif
3139 }
3140 if (scale != 1)
3141 {
3142 #ifdef MOTOROLA
3143 fprintf (file, "*%d", scale);
3144 #else
3145 fprintf (file, ":%d", scale);
3146 #endif
3147 }
3148 putc (')', file);
3149 break;
3150 }
3151 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
3152 && ! (flag_pic && reg1 == pic_offset_table_rtx))
3153 {
3154 ASM_OUTPUT_CASE_FETCH (file,
3155 CODE_LABEL_NUMBER (XEXP (addr, 0)),
3156 reg_names[REGNO (reg1)]);
3157 fprintf (file, "l)");
3158 break;
3159 }
3160 /* FALL-THROUGH (is this really what we want? */
3161 default:
3162 if (GET_CODE (addr) == CONST_INT
3163 && INTVAL (addr) < 0x8000
3164 && INTVAL (addr) >= -0x8000)
3165 {
3166 #ifdef MOTOROLA
3167 #ifdef SGS
3168 /* Many SGS assemblers croak on size specifiers for constants. */
3169 fprintf (file, "%d", INTVAL (addr));
3170 #else
3171 fprintf (file, "%d.w", INTVAL (addr));
3172 #endif
3173 #else
3174 fprintf (file, "%d:w", INTVAL (addr));
3175 #endif
3176 }
3177 else
3178 {
3179 output_addr_const (file, addr);
3180 }
3181 break;
3182 }
3183 }
3184 \f
3185 /* Check for cases where a clr insns can be omitted from code using
3186 strict_low_part sets. For example, the second clrl here is not needed:
3187 clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ...
3188
3189 MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear
3190 insn we are checking for redundancy. TARGET is the register set by the
3191 clear insn. */
3192
3193 int
3194 strict_low_part_peephole_ok (mode, first_insn, target)
3195 enum machine_mode mode;
3196 rtx first_insn;
3197 rtx target;
3198 {
3199 rtx p;
3200
3201 p = prev_nonnote_insn (first_insn);
3202
3203 while (p)
3204 {
3205 /* If it isn't an insn, then give up. */
3206 if (GET_CODE (p) != INSN)
3207 return 0;
3208
3209 if (reg_set_p (target, p))
3210 {
3211 rtx set = single_set (p);
3212 rtx dest;
3213
3214 /* If it isn't an easy to recognize insn, then give up. */
3215 if (! set)
3216 return 0;
3217
3218 dest = SET_DEST (set);
3219
3220 /* If this sets the entire target register to zero, then our
3221 first_insn is redundant. */
3222 if (rtx_equal_p (dest, target)
3223 && SET_SRC (set) == const0_rtx)
3224 return 1;
3225 else if (GET_CODE (dest) == STRICT_LOW_PART
3226 && GET_CODE (XEXP (dest, 0)) == REG
3227 && REGNO (XEXP (dest, 0)) == REGNO (target)
3228 && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0)))
3229 <= GET_MODE_SIZE (mode)))
3230 /* This is a strict low part set which modifies less than
3231 we are using, so it is safe. */
3232 ;
3233 else
3234 return 0;
3235 }
3236
3237 p = prev_nonnote_insn (p);
3238
3239 }
3240
3241 return 0;
3242 }
3243
3244 /* Accept integer operands in the range 0..0xffffffff. We have to check the
3245 range carefully since this predicate is used in DImode contexts. Also, we
3246 need some extra crud to make it work when hosted on 64-bit machines. */
3247
3248 int
3249 const_uint32_operand (op, mode)
3250 rtx op;
3251 enum machine_mode mode ATTRIBUTE_UNUSED;
3252 {
3253 #if HOST_BITS_PER_WIDE_INT > 32
3254 /* All allowed constants will fit a CONST_INT. */
3255 return (GET_CODE (op) == CONST_INT
3256 && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
3257 #else
3258 return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0)
3259 || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
3260 #endif
3261 }
3262
3263 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
3264 to check the range carefully since this predicate is used in DImode
3265 contexts. */
3266
3267 int
3268 const_sint32_operand (op, mode)
3269 rtx op;
3270 enum machine_mode mode ATTRIBUTE_UNUSED;
3271 {
3272 /* All allowed constants will fit a CONST_INT. */
3273 return (GET_CODE (op) == CONST_INT
3274 && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
3275 }
3276
3277 char *
3278 output_andsi3 (operands)
3279 rtx *operands;
3280 {
3281 int logval;
3282 if (GET_CODE (operands[2]) == CONST_INT
3283 && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
3284 && (DATA_REG_P (operands[0])
3285 || offsettable_memref_p (operands[0]))
3286 && !TARGET_5200)
3287 {
3288 if (GET_CODE (operands[0]) != REG)
3289 operands[0] = adj_offsettable_operand (operands[0], 2);
3290 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
3291 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3292 CC_STATUS_INIT;
3293 if (operands[2] == const0_rtx)
3294 return "clr%.w %0";
3295 return "and%.w %2,%0";
3296 }
3297 if (GET_CODE (operands[2]) == CONST_INT
3298 && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
3299 && (DATA_REG_P (operands[0])
3300 || offsettable_memref_p (operands[0])))
3301 {
3302 if (DATA_REG_P (operands[0]))
3303 {
3304 operands[1] = GEN_INT (logval);
3305 }
3306 else
3307 {
3308 operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
3309 operands[1] = GEN_INT (logval % 8);
3310 }
3311 /* This does not set condition codes in a standard way. */
3312 CC_STATUS_INIT;
3313 return "bclr %1,%0";
3314 }
3315 return "and%.l %2,%0";
3316 }
3317
3318 char *
3319 output_iorsi3 (operands)
3320 rtx *operands;
3321 {
3322 register int logval;
3323 if (GET_CODE (operands[2]) == CONST_INT
3324 && INTVAL (operands[2]) >> 16 == 0
3325 && (DATA_REG_P (operands[0])
3326 || offsettable_memref_p (operands[0]))
3327 && !TARGET_5200)
3328 {
3329 if (GET_CODE (operands[0]) != REG)
3330 operands[0] = adj_offsettable_operand (operands[0], 2);
3331 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3332 CC_STATUS_INIT;
3333 if (INTVAL (operands[2]) == 0xffff)
3334 return "mov%.w %2,%0";
3335 return "or%.w %2,%0";
3336 }
3337 if (GET_CODE (operands[2]) == CONST_INT
3338 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3339 && (DATA_REG_P (operands[0])
3340 || offsettable_memref_p (operands[0])))
3341 {
3342 if (DATA_REG_P (operands[0]))
3343 {
3344 operands[1] = GEN_INT (logval);
3345 }
3346 else
3347 {
3348 operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
3349 operands[1] = GEN_INT (logval % 8);
3350 }
3351 CC_STATUS_INIT;
3352 return "bset %1,%0";
3353 }
3354 return "or%.l %2,%0";
3355 }
3356
3357 char *
3358 output_xorsi3 (operands)
3359 rtx *operands;
3360 {
3361 register int logval;
3362 if (GET_CODE (operands[2]) == CONST_INT
3363 && INTVAL (operands[2]) >> 16 == 0
3364 && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))
3365 && !TARGET_5200)
3366 {
3367 if (! DATA_REG_P (operands[0]))
3368 operands[0] = adj_offsettable_operand (operands[0], 2);
3369 /* Do not delete a following tstl %0 insn; that would be incorrect. */
3370 CC_STATUS_INIT;
3371 if (INTVAL (operands[2]) == 0xffff)
3372 return "not%.w %0";
3373 return "eor%.w %2,%0";
3374 }
3375 if (GET_CODE (operands[2]) == CONST_INT
3376 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
3377 && (DATA_REG_P (operands[0])
3378 || offsettable_memref_p (operands[0])))
3379 {
3380 if (DATA_REG_P (operands[0]))
3381 {
3382 operands[1] = GEN_INT (logval);
3383 }
3384 else
3385 {
3386 operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
3387 operands[1] = GEN_INT (logval % 8);
3388 }
3389 CC_STATUS_INIT;
3390 return "bchg %1,%0";
3391 }
3392 return "eor%.l %2,%0";
3393 }