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