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