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