OSDN Git Service

* rtl.h (addr_diff_vec_flags): New typedef.
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / mot3300.h
1 /* Definitions of target machine for GNU compiler,
2    SysV68 Motorola 3300 Delta Series.
3    Copyright (C) 1987, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
4    Contributed by Abramo and Roberto Bagnara (bagnara@dipisa.di.unipi.it)
5    based on Alex Crain's 3B1 definitions.
6    Maintained by Philippe De Muyter (phdm@info.ucl.ac.be).
7    Support for GAS added by merging mot3300g.h into this file by
8    Manfred Hollstein (manfred@lts.sel.alcatel.de).
9
10 This file is part of GNU CC.
11
12 GNU CC is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
15 any later version.
16
17 GNU CC is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with GNU CC; see the file COPYING.  If not, write to
24 the Free Software Foundation, 59 Temple Place - Suite 330,
25 Boston, MA 02111-1307, USA.  */
26
27 #ifndef USE_GAS
28 #define MOTOROLA                /* Use Motorola syntax rather than "MIT" */
29 #define MOTOROLA_BSR            /* Use Span-dependent optimized bsr */
30 #define SGS                     /* Uses SGS assembler */
31 #define SGS_CMP_ORDER           /* Takes cmp operands in reverse order */
32 #define SGS_SWAP_W              /* Use swap.w rather than just plain swap */
33 #endif /* USE_GAS */
34
35 #define NO_DOLLAR_IN_LABEL
36 #define NO_DOT_IN_LABEL
37
38 #include "m68k/m68k.h"
39
40 /* See m68k.h.  0407 means 68020-68040.  */
41
42 #ifndef TARGET_DEFAULT
43 #define TARGET_DEFAULT (MASK_68040|MASK_BITFIELD|MASK_68881|MASK_68020)
44 #endif
45
46 /* -m[c]6800 requires special flag to the assembler.  */
47
48 #undef ASM_SPEC
49 #ifndef USE_GAS
50 #define ASM_SPEC "%{m68000:-p 000}%{mc68000:-p 000}"
51 #else /* USE_GAS */
52 #define ASM_SPEC \
53   "%{v:-v} %{m68000:-mc68000}%{mc68000:-mc68000}%{!mc68000:%{!m68000:-mc68020}}"
54 #endif /* USE_GAS */
55
56 /* NYI: FP= is equivalent to -msoft-float  */
57
58 /* We use /lib/libp/lib* when profiling.  */
59
60 /* NYI: if FP=M68881U library is -lc881u  */
61 /* NYI: if FP= library is -lc.  */
62 /* Default for us: FP=M68881 library is -lc881  */
63 #undef LIB_SPEC
64 #define LIB_SPEC "%{!shlib:%{!msoft-float:-lc881}%{msoft-float:-lc}}"
65 #ifdef CROSS_COMPILE
66 #ifndef USE_GLD
67 #define DEFAULT_A_OUT_NAME "m68ka.out"
68 #endif
69 #endif
70
71 #ifdef USE_GLD
72 #undef LINK_SPEC
73 #define LINK_SPEC "%{v:-v}"
74 #endif /* defined (USE_GLD) */
75
76 #define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__}\
77 %{!mc68000:%{!m68000: -D__mc68020__}}"
78
79 /* Shared libraries need to use crt0s.o  */
80
81 #undef STARTFILE_SPEC
82 #ifdef CROSS_COMPILE
83 #define STARTFILE_SPEC \
84   "%{!shlib:%{pg:mcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}\
85    %{shlib:crt0s.o%s shlib.ifile%s} %{p:-L"TOOLDIR_BASE_PREFIX DEFAULT_TARGET_MACHINE"/lib/libp} %{pg:-L"TOOLDIR_BASE_PREFIX DEFAULT_TARGET_MACHINE"/lib/libp} "
86 #else /* CROSS_COMPILE */
87 #define STARTFILE_SPEC \
88   "%{!shlib:%{pg:mcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}\
89    %{shlib:crt0s.o%s shlib.ifile%s} %{p:-L/usr/lib/libp} %{pg:-L/usr/lib/libp} "
90 #endif /* CROSS_COMPILE */
91
92 /* Generate calls to memcpy, memcmp and memset.  */
93
94 #define TARGET_MEM_FUNCTIONS
95
96 /* size_t is unsigned int.  */
97
98 #define SIZE_TYPE "unsigned int"
99
100 /* Every structure or union's size must be a multiple of 2 bytes.  */
101
102 #define STRUCTURE_SIZE_BOUNDARY 16
103
104 /* Follow sysV68 cc regarding alignment imposed by char:0; */
105
106 #define PCC_BITFIELD_TYPE_MATTERS 1
107   
108 /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
109 /* Be compatible with native compiler.  */
110 #undef PARM_BOUNDARY
111 #define PARM_BOUNDARY 16
112
113 /* cpp has to support a #sccs directive for the /usr/include files */
114
115 #define SCCS_DIRECTIVE
116
117 /* Make output for SDB.  */
118
119 #define SDB_DEBUGGING_INFO
120
121 #undef REGISTER_PREFIX
122 #define REGISTER_PREFIX "%"
123
124 #undef LOCAL_LABEL_PREFIX
125 #ifdef USE_GAS
126 #define LOCAL_LABEL_PREFIX ".L"
127 #else
128 #define LOCAL_LABEL_PREFIX "L%"
129 #endif
130
131 #undef USER_LABEL_PREFIX
132
133 #undef IMMEDIATE_PREFIX
134 #define IMMEDIATE_PREFIX "&"
135
136 #undef REGISTER_NAMES
137 #define REGISTER_NAMES \
138 {"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",        \
139  "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",        \
140  "%fp0", "%fp1", "%fp2", "%fp3", "%fp4", "%fp5", "%fp6", "%fp7"}
141
142 #undef FUNCTION_EXTRA_EPILOGUE
143 #define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE)                             \
144   { extern int current_function_returns_pointer;                        \
145     if ((current_function_returns_pointer) &&                           \
146       ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode))        \
147       asm_fprintf (FILE, "\tmov.l %Ra0,%Rd0\n"); } 
148
149 #undef FUNCTION_PROFILER
150 #define FUNCTION_PROFILER(FILE, LABEL_NO)       \
151     asm_fprintf (FILE, "\tmov.l %I%LLP%d,%Ra0\n\tjsr mcount%%\n", (LABEL_NO))
152
153 /* This is how to output an insn to push a register on the stack.
154    It need not be very fast code.  */
155
156 #undef ASM_OUTPUT_REG_PUSH
157 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
158   fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[REGNO])
159
160 /* This is how to output an insn to pop a register from the stack.
161    It need not be very fast code.  */
162
163 #undef ASM_OUTPUT_REG_POP
164 #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
165   fprintf (FILE, "\tmov.l (%%sp)+,%s\n", reg_names[REGNO])
166
167 #ifndef USE_GAS
168
169 #undef ASM_APP_ON
170 #define ASM_APP_ON ""
171
172 #undef ASM_APP_OFF
173 #define ASM_APP_OFF ""
174
175 #undef TEXT_SECTION_ASM_OP
176 #define TEXT_SECTION_ASM_OP "text"
177 #undef DATA_SECTION_ASM_OP
178 #define DATA_SECTION_ASM_OP "data"
179 #undef ASCII_DATA_ASM_OP
180 #define ASCII_DATA_ASM_OP "byte"
181
182 #undef SET_ASM_OP
183 #define SET_ASM_OP "set"
184
185 #endif /* USE_GAS */
186
187 #ifdef USE_GLD
188 /* Support the ctors and dtors sections for g++.  */
189
190 #define CTORS_SECTION_ASM_OP    ".section\t.ctors,\"x\""
191 #define DTORS_SECTION_ASM_OP    ".section\t.dtors,\"x\""
192
193 /* A list of other sections which the compiler might be "in" at any
194    given time.  */
195
196 #undef EXTRA_SECTIONS
197 #define EXTRA_SECTIONS in_ctors, in_dtors
198
199 /* A list of extra section function definitions.  */
200
201 #undef EXTRA_SECTION_FUNCTIONS
202 #define EXTRA_SECTION_FUNCTIONS                                         \
203   CTORS_SECTION_FUNCTION                                                \
204   DTORS_SECTION_FUNCTION
205
206 #define CTORS_SECTION_FUNCTION                                          \
207 void                                                                    \
208 ctors_section ()                                                        \
209 {                                                                       \
210   if (in_section != in_ctors)                                           \
211     {                                                                   \
212       fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP);             \
213       in_section = in_ctors;                                            \
214     }                                                                   \
215 }
216
217 #define DTORS_SECTION_FUNCTION                                          \
218 void                                                                    \
219 dtors_section ()                                                        \
220 {                                                                       \
221   if (in_section != in_dtors)                                           \
222     {                                                                   \
223       fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP);             \
224       in_section = in_dtors;                                            \
225     }                                                                   \
226 }
227
228 /* A C statement (sans semicolon) to output an element in the table of
229    global constructors.  */
230 #define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME)                               \
231   do {                                                                  \
232     ctors_section ();                                                   \
233     fprintf (FILE, "\t%s\t ", ASM_LONG);                                \
234     assemble_name (FILE, NAME);                                         \
235     fprintf (FILE, "\n");                                               \
236   } while (0)
237
238 /* A C statement (sans semicolon) to output an element in the table of
239    global destructors.  */
240 #define ASM_OUTPUT_DESTRUCTOR(FILE,NAME)                                \
241   do {                                                                  \
242     dtors_section ();                                                   \
243     fprintf (FILE, "\t%s\t ", ASM_LONG);                                \
244     assemble_name (FILE, NAME);                                         \
245     fprintf (FILE, "\n");                                               \
246   } while (0)
247 #endif /* defined (USE_GLD) */
248
249 /* The file command should always begin the output.  */
250
251 #undef ASM_FILE_START
252 #ifndef USE_GAS
253 #define ASM_FILE_START(FILE) \
254   output_file_directive ((FILE), main_input_filename)
255 #else /* USE_GAS */
256 #define ASM_FILE_START(FILE) \
257     { \
258        fprintf (FILE, "%s", ASM_APP_OFF); \
259        output_file_directive ((FILE), main_input_filename); \
260     }
261 #endif /* USE_GAS */
262
263 /* The sysV68 assembler does not accept dots in labels.
264    Let's use percent instead  */
265
266 #define ASM_IDENTIFY_GCC(FILE)        fputs("gcc2_compiled%:\n", FILE)
267
268 /* Names to predefine in the preprocessor for this target machine.  */
269 /* ihnp4!lmayk!lgm@eddie.mit.edu says mc68000 and m68k should not be here,
270    on the other hand I don't care what he says.  */
271
272 #undef CPP_PREDEFINES
273 #define CPP_PREDEFINES "-Dm68k -Dunix -DsysV68 -D__motorola__ -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)"
274
275 #undef TARGET_VERSION
276 #ifndef USE_GAS
277 #define TARGET_VERSION fprintf (stderr, " (68k, SGS/AT&T sysV68 syntax)");
278 #endif /* USE_GAS */
279
280 /* This will return small structs in d0.  */
281 #define RETURN_IN_MEMORY(type) \
282   ((TYPE_MODE (type) == BLKmode) \
283    || (AGGREGATE_TYPE_P (type) \
284        && GET_MODE_SIZE (TYPE_MODE (type)) > UNITS_PER_WORD))
285
286 /* Don't default to pcc-struct-return, because we have already specified
287    exactly how to return structures in the RETURN_IN_MEMORY macro.  */
288 #define DEFAULT_PCC_STRUCT_RETURN 0
289
290 /* If TARGET_68881, return SF and DF values in fp0 instead of d0.  */
291 /* NYI: If FP=M68881U return SF and DF values in d0. */
292 /* NYI: If -mold return pointer in a0 and d0 */
293
294 #undef FUNCTION_VALUE
295 /* sysV68 (brain damaged) cc convention support. */
296 #define FUNCTION_VALUE(VALTYPE,FUNC) \
297   (TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_68881     \
298    ? gen_rtx (REG, TYPE_MODE (VALTYPE), 16)             \
299    : (POINTER_TYPE_P (VALTYPE)                          \
300       ? gen_rtx (REG, TYPE_MODE (VALTYPE), 8)           \
301       : gen_rtx (REG, TYPE_MODE (VALTYPE), 0)))
302
303 /* If TARGET_68881, SF and DF values are returned in fp0 instead of d0.  */
304
305 /* Is LIBCALL_VALUE never called with a pointer ? */
306 #undef LIBCALL_VALUE
307 #define LIBCALL_VALUE(MODE)                                                \
308  gen_rtx (REG, (MODE),                                                     \
309           ((TARGET_68881                                                   \
310             && ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode)) \
311            ? 16 : 0))
312
313 /* 1 if N is a possible register number for a function value.
314    d0 may be used, and fp0 as well if -msoft-float is not specified.  */
315
316 #undef FUNCTION_VALUE_REGNO_P
317 /* sysV68 (brain damaged) cc convention support. */
318 #define FUNCTION_VALUE_REGNO_P(N) \
319  ((N) == 0 || (N) == 8 || (TARGET_68881 && (N) == 16))
320
321 /* Define this to be true when FUNCTION_VALUE_REGNO_P is true for
322    more than one register.  */
323
324 #undef NEEDS_UNTYPED_CALL
325 #define NEEDS_UNTYPED_CALL 1
326  
327 #ifndef USE_GAS
328 /* This is the command to make the user-level label named NAME
329    defined for reference from other files.  */
330
331 #undef GLOBAL_ASM_OP
332 #define GLOBAL_ASM_OP "global"
333 #endif /* USE_GAS */
334
335 /* Store in OUTPUT a string (made with alloca) containing
336    an assembler-name for a local static variable named NAME.
337    LABELNO is an integer which is different for each call.  */
338
339 #undef ASM_FORMAT_PRIVATE_NAME
340 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)  \
341 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 12),    \
342   sprintf ((OUTPUT), "%s_%%%d", (NAME), (LABELNO)))
343
344 #ifdef USE_GAS
345 #undef ASM_LONG
346 #define ASM_LONG        ".long"
347 #undef ASM_SHORT
348 #define ASM_SHORT       ".short"
349 #undef ASM_CHAR
350 #define ASM_CHAR        ".byte"
351 #undef ASM_BYTE
352 #define ASM_BYTE        ".byte"
353 #undef ASM_BYTE_OP
354 #define ASM_BYTE_OP     ".byte"
355 #else
356 #undef ASM_LONG
357 #define ASM_LONG        "long"
358 #undef ASM_SHORT
359 #define ASM_SHORT       "short"
360 #undef ASM_CHAR
361 #define ASM_CHAR        "byte"
362 #undef ASM_BYTE
363 #define ASM_BYTE        "byte"
364 #undef ASM_BYTE_OP
365 #define ASM_BYTE_OP     "byte"
366 #endif /* USE_GAS */
367
368 /* The sysV68 as doesn't know about double's and float's.  */
369 /* This is how to output an assembler line defining a `double' constant.  */
370
371 #undef ASM_OUTPUT_DOUBLE
372 #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
373 do { long l[2];                                         \
374      REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l);            \
375      fprintf (FILE, "\t%s 0x%x,0x%x\n", ASM_LONG, l[0], l[1]); \
376    } while (0)
377
378 #undef ASM_OUTPUT_LONG_DOUBLE
379 #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE)                              \
380 do { long l[3];                                                         \
381      REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l);                       \
382      fprintf (FILE, "\t%s 0x%x,0x%x,0x%x\n", ASM_LONG, l[0], l[1], l[2]);       \
383    } while (0)
384
385 /* This is how to output an assembler line defining a `float' constant.  */
386
387 #undef ASM_OUTPUT_FLOAT
388 #define ASM_OUTPUT_FLOAT(FILE,VALUE)  \
389 do { long l;                                    \
390      REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);    \
391      fprintf ((FILE), "\t%s 0x%x\n", ASM_LONG, l);      \
392    } while (0)
393
394 /* This is how to output an assembler line defining an `int' constant.  */
395
396 #undef ASM_OUTPUT_INT
397 #define ASM_OUTPUT_INT(FILE,VALUE)  \
398 ( fprintf (FILE, "\t%s ", ASM_LONG),            \
399   output_addr_const (FILE, (VALUE)),            \
400   fprintf (FILE, "\n"))
401
402 /* Likewise for `char' and `short' constants.  */
403
404 #undef ASM_OUTPUT_SHORT
405 #define ASM_OUTPUT_SHORT(FILE,VALUE)  \
406 ( fprintf (FILE, "\t%s ", ASM_SHORT),           \
407   output_addr_const (FILE, (VALUE)),            \
408   fprintf (FILE, "\n"))
409
410 #undef ASM_OUTPUT_CHAR
411 #define ASM_OUTPUT_CHAR(FILE,VALUE)  \
412 ( fprintf (FILE, "\t%s ", ASM_CHAR),            \
413   output_addr_const (FILE, (VALUE)),            \
414   fprintf (FILE, "\n"))
415
416 /* This is how to output an assembler line for a numeric constant byte.  */
417
418 #undef ASM_OUTPUT_BYTE
419 #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
420   fprintf (FILE, "\t%s 0x%x\n", ASM_BYTE, (VALUE))
421
422 /* This is how to output an assembler line
423    that says to advance the location counter
424    to a multiple of 2**LOG bytes.  */
425
426 #ifndef USE_GAS
427 #define ALIGN_ASM_OP    "even"
428 #else /* USE_GAS */
429 #define ALIGN_ASM_OP    ".even"
430 #endif /* USE_GAS */
431
432 #undef ASM_OUTPUT_ALIGN
433 #define ASM_OUTPUT_ALIGN(FILE,LOG)      \
434   if ((LOG) >= 1)                       \
435     fprintf (FILE, "\t%s\n", ALIGN_ASM_OP);
436
437 #ifndef USE_GAS
438 #define SKIP_ASM_OP     "space"
439 #else /* USE_GAS */
440 #define SKIP_ASM_OP     ".skip"
441 #endif /* USE_GAS */
442
443 #undef ASM_OUTPUT_SKIP
444 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
445   fprintf (FILE, "\t%s %u\n", SKIP_ASM_OP, (SIZE))
446
447 /* Can't use ASM_OUTPUT_SKIP in text section.  */
448
449 #define ASM_NO_SKIP_IN_TEXT 1
450
451 /* The beginnings of sdb support...  */
452
453 /* Undefining these will allow `output_file_directive' (in toplev.c)
454    to default to the right thing. */
455 #undef ASM_OUTPUT_MAIN_SOURCE_FILENAME
456 #ifndef USE_GAS
457 #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \
458   do {  fprintf (FILE, "\tfile\t");             \
459         output_quoted_string (FILE, FILENAME);  \
460         fprintf (FILE, "\n");                   \
461   } while (0)
462
463 #undef ASM_OUTPUT_SOURCE_LINE
464 #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO)    \
465   fprintf (FILE, "\tln\t%d\n",                  \
466            (sdb_begin_function_line             \
467             ? last_linenum - sdb_begin_function_line : 1))
468
469 /* Yet another null terminated string format.  */
470
471 #undef ASM_OUTPUT_ASCII
472 #define ASM_OUTPUT_ASCII(FILE,PTR,LEN) \
473   do { register int sp = 0, lp = 0;                             \
474     fprintf ((FILE), "\t%s\t", ASM_BYTE_OP);                    \
475   loop:                                                         \
476     if ((PTR)[sp] > ' ' && ! ((PTR)[sp] & 0x80) && (PTR)[sp] != '\\')   \
477       { lp += 3;                                                \
478         fprintf ((FILE), "'%c", (PTR)[sp]); }                   \
479     else                                                        \
480       { lp += 5;                                                \
481         fprintf ((FILE), "0x%x", (PTR)[sp]); }                  \
482     if (++sp < (LEN))                                           \
483       { if (lp > 60)                                            \
484           { lp = 0;                                             \
485             fprintf ((FILE), "\n\t%s ", ASCII_DATA_ASM_OP); }   \
486         else                                                    \
487           putc (',', (FILE));                                   \
488         goto loop; }                                            \
489     putc ('\n', (FILE)); } while (0)
490 #endif /* USE_GAS */
491
492 #ifndef USE_GAS
493 /* Output a float value (represented as a C double) as an immediate operand.
494    This macro is a 68k-specific macro.  */
495
496 #undef ASM_OUTPUT_FLOAT_OPERAND
497 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)                       \
498  do { long l;                                                           \
499       REAL_VALUE_TO_TARGET_SINGLE (r, l);                               \
500       /* Use hex representation even if CODE is f.  as needs it.  */    \
501       fprintf ((FILE), "&0x%lx", l);                                    \
502     } while (0)
503
504 /* Output a double value (represented as a C double) as an immediate operand.
505    This macro is a 68k-specific macro.  */
506 #undef ASM_OUTPUT_DOUBLE_OPERAND
507 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE)                           \
508  do { long l[2];                                                        \
509       REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l);                           \
510       fprintf ((FILE), "&0x%lx%08lx", l[0], l[1]);                      \
511     } while (0)
512 #endif /* USE_GAS */
513
514 /* This is how to store into the string LABEL
515    the symbol_ref name of an internal numbered label where
516    PREFIX is the class of label and NUM is the number within the class.
517    This is suitable for output with `assemble_name'.  */
518
519 #undef ASM_GENERATE_INTERNAL_LABEL
520 #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
521   sprintf ((LABEL), "%s%s%d", LOCAL_LABEL_PREFIX, (PREFIX), (NUM))
522
523 /* This is how to output an internal numbered label where
524    PREFIX is the class of label and NUM is the number within the class.  */
525
526 #undef ASM_OUTPUT_INTERNAL_LABEL
527 #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)      \
528     asm_fprintf (FILE, "%L%s%d:\n", PREFIX, NUM)
529
530 /* The prefix to add to user-visible assembler symbols. */
531
532 #undef USER_LABEL_PREFIX
533 #define USER_LABEL_PREFIX ""
534
535 /* This is how to output an element of a case-vector that is absolute.
536    (The 68000 does not use such vectors,
537    but we must define this macro anyway.)  */
538 /* The L after the local prefix is the "L" prefix for the normal labels
539    generated by gcc; why are ASM_OUTPUT_ADDR_VEC_ELT and
540    ASM_OUTPUT_ADDR_DIFF_ELT not called with a PREFIX parameter, like
541    ASM_OUTPUT_INTERNAL_LABEL ? */
542
543 #undef ASM_OUTPUT_ADDR_VEC_ELT
544 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)    \
545     asm_fprintf (FILE, "\t%s %LL%d\n", ASM_LONG, (VALUE))
546
547 /* This is how to output an element of a case-vector that is relative.  */
548
549 #undef ASM_OUTPUT_ADDR_DIFF_ELT
550 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)        \
551     asm_fprintf (FILE, "\t%s %LL%d-%LL%d\n", ASM_SHORT, (VALUE), (REL))
552
553 #ifndef USE_GAS
554
555 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLE)                    \
556     asm_fprintf (FILE, "\tswbeg &%d\n%L%s%d:\n",                        \
557              XVECLEN (PATTERN (TABLE), 1), (PREFIX), (NUM))
558
559 /* sysV68 as cannot handle LD%n(%pc,%reg) */ 
560 #define SGS_NO_LI
561
562 /* labelno is not used here */
563 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
564         asm_fprintf (file, "12(%Rpc,%s.", regname)
565
566 #define ASM_RETURN_CASE_JUMP \
567   do {                                          \
568     if (TARGET_5200)                            \
569       return "ext%.l %0\n\tjmp 8(%%pc,%0.l)";   \
570     else                                        \
571       return "jmp 8(%%pc,%0.w)";                \
572   } while (0)
573              
574 #else /* USE_GAS */
575
576 /* labelno is not used here */
577 #define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\
578         asm_fprintf (file, "%Rpc@(6,%s:", regname)
579
580 #define ASM_RETURN_CASE_JUMP return "jmp %%pc@(2,%0:w)"
581
582 #endif /* USE_GAS */
583
584 #ifndef USE_GAS
585
586 /* Translate some opcodes to fit the sysV68 assembler syntax.  */
587 /* The opcodes fdmov and fsmov are guesses.  */
588
589 /* cliffm@netcom.com says no need for .w suffix on jumps.  */
590 #undef ASM_OUTPUT_OPCODE
591 #define ASM_OUTPUT_OPCODE(FILE, PTR)                    \
592 { if ((PTR)[0] == 'j' && (PTR)[1] == 'b')               \
593     { ++(PTR);                                          \
594       while (*(PTR) != ' ')                             \
595         { putc (*(PTR), (FILE)); ++(PTR); }             \
596     }                                                   \
597   else if ((PTR)[0] == 's')                             \
598     {                                                   \
599       if (!strncmp ((PTR), "swap", 4))                  \
600         { fprintf ((FILE), "swap.w"); (PTR) += 4; }     \
601     }                                                   \
602   else if ((PTR)[0] == 'f')                             \
603     {                                                   \
604       if (!strncmp ((PTR), "fmove", 5))                 \
605         { fprintf ((FILE), "fmov"); (PTR) += 5; }       \
606       else if (!strncmp ((PTR), "f%$move", 7))          \
607         { if (TARGET_68040_ONLY)                        \
608             { fprintf ((FILE), "fsmov"); (PTR) += 7; }  \
609           else                                          \
610             { fprintf ((FILE), "fmov"); (PTR) += 7; } } \
611       else if (!strncmp ((PTR), "f%&move", 7))          \
612         { if (TARGET_68040_ONLY)                        \
613             { fprintf ((FILE), "fdmov"); (PTR) += 7; }  \
614           else                                          \
615             { fprintf ((FILE), "fmov"); (PTR) += 7; } } \
616       else if (!strncmp ((PTR), "ftst", 4))             \
617         { fprintf ((FILE), "ftest"); (PTR) += 4; }      \
618       else if (!strncmp ((PTR), "fbne", 4))             \
619         { fprintf ((FILE), "fbneq"); (PTR) += 4; }      \
620       else if (!strncmp ((PTR), "fsne", 4))             \
621         { fprintf ((FILE), "fsneq"); (PTR) += 4; }      \
622     }                                                   \
623 /* MOVE, MOVEA, MOVEQ, MOVEC ==> MOV    */              \
624   else if ((PTR)[0] == 'm' && (PTR)[1] == 'o'           \
625            && (PTR)[2] == 'v' && (PTR)[3] == 'e')       \
626     { fprintf ((FILE), "mov"); (PTR) += 4;              \
627        if ((PTR)[0] == 'q' || (PTR)[0] == 'a'           \
628            || (PTR)[0] == 'c') (PTR)++; }               \
629 /* SUB, SUBQ, SUBA, SUBI ==> SUB */                     \
630   else if ((PTR)[0] == 's' && (PTR)[1] == 'u'           \
631            && (PTR)[2] == 'b')                          \
632     { fprintf ((FILE), "sub"); (PTR) += 3;              \
633        if ((PTR)[0] == 'q' || (PTR)[0] == 'i'           \
634            || (PTR)[0] == 'a') (PTR)++; }               \
635 /* CMP, CMPA, CMPI, CMPM ==> CMP        */              \
636   else if ((PTR)[0] == 'c' && (PTR)[1] == 'm'           \
637            && (PTR)[2] == 'p')                          \
638     { fprintf ((FILE), "cmp"); (PTR) += 3;              \
639        if ((PTR)[0] == 'a' || (PTR)[0] == 'i'           \
640            || (PTR)[0] == 'm') (PTR)++; }               \
641 }
642 #endif /* USE_GAS */
643
644 /* phdm@info.ucl.ac.be says to pass SIZE, not ROUNDED.  */
645
646 /* This says how to output an assembler line
647    to define a global common symbol.  */
648
649 #undef ASM_OUTPUT_COMMON
650 #ifndef USE_GAS
651 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
652 ( fputs ("\tcomm ", (FILE)),                    \
653   assemble_name ((FILE), (NAME)),               \
654   fprintf ((FILE), ",%u\n", (SIZE)))
655 #else /* USE_GAS */
656 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
657 ( fputs ("\t.comm ", (FILE)),                   \
658   assemble_name ((FILE), (NAME)),               \
659   fprintf ((FILE), ",%u\n", (SIZE)))
660 #endif /* USE_GAS */
661
662 /* This says how to output an assembler line
663    to define a local common symbol.  */
664
665 #undef ASM_OUTPUT_LOCAL
666 #ifndef USE_GAS
667 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
668 ( fputs ("\tlcomm ", (FILE)),                   \
669   assemble_name ((FILE), (NAME)),               \
670   fprintf ((FILE), ",%u\n", (SIZE)))
671 #else /* USE_GAS */
672 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
673 ( fputs ("\t.lcomm ", (FILE)),                  \
674   assemble_name ((FILE), (NAME)),               \
675   fprintf ((FILE), ",%u\n", (SIZE)))
676 #endif /* USE_GAS */
677
678 #ifndef USE_GAS
679 /* Override usual definitions of SDB output macros.
680    These definitions differ only in the absence of the period
681    at the beginning of the name of the directive
682    and in the use of `~' as the symbol for the current location.  */
683
684 #define PUT_SDB_SCL(a) fprintf(asm_out_file, "\tscl\t%d;", (a))
685 #define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\tval\t%d;", (a))
686 #define PUT_SDB_VAL(a)                          \
687 ( fputs ("\tval\t", asm_out_file),              \
688   output_addr_const (asm_out_file, (a)),        \
689   fputc (';', asm_out_file))
690
691 #define PUT_SDB_DEF(a)                          \
692 do { fprintf (asm_out_file, "\tdef\t"); \
693      ASM_OUTPUT_LABELREF (asm_out_file, a);     \
694      fprintf (asm_out_file, ";"); } while (0)
695
696 #define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\tdef\t~%s;",a)
697 #define PUT_SDB_ENDEF fputs("\tendef\n", asm_out_file)
698 #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\ttype\t0%o;", a)
699 #define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\tsize\t%d;", a)
700 #define PUT_SDB_START_DIM fprintf(asm_out_file, "\tdim\t")
701 #define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)
702 #define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d;", a)
703
704 #define PUT_SDB_TAG(a)                          \
705 do { fprintf (asm_out_file, "\ttag\t"); \
706      ASM_OUTPUT_LABELREF (asm_out_file, a);     \
707      fprintf (asm_out_file, ";"); } while (0)
708
709 #define PUT_SDB_BLOCK_START(LINE)               \
710   fprintf (asm_out_file,                        \
711            "\tdef\t~bb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n",       \
712            (LINE))
713
714 #define PUT_SDB_BLOCK_END(LINE)                 \
715   fprintf (asm_out_file,                        \
716            "\tdef\t~eb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n",       \
717            (LINE))
718
719 #define PUT_SDB_FUNCTION_START(LINE)            \
720   fprintf (asm_out_file,                        \
721            "\tdef\t~bf;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n",       \
722            (LINE))
723
724 #define PUT_SDB_FUNCTION_END(LINE)              \
725   fprintf (asm_out_file,                        \
726            "\tdef\t~ef;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n",       \
727            (LINE))
728
729 #define PUT_SDB_EPILOGUE_END(NAME)              \
730   fprintf (asm_out_file,                        \
731            "\tdef\t%s;\tval\t~;\tscl\t-1;\tendef\n",    \
732            (NAME))
733
734 #define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
735   sprintf ((BUFFER), "~%dfake", (NUMBER));
736
737 #endif /* USE_GAS */
738
739 /* Define subroutines to call to handle multiply, divide, and remainder.
740    Use the subroutines that the sysV68's library provides.
741    The `*' prevents an underscore from being prepended by the compiler.  */
742 /* The '*' is also used by INIT_CUMULATIVE_ARGS */
743
744 #define DIVSI3_LIBCALL "*ldiv%%"
745 #define UDIVSI3_LIBCALL "*uldiv%%"
746 #define MODSI3_LIBCALL "*lrem%%"
747 #define UMODSI3_LIBCALL "*ulrem%%"
748 #define MULSI3_LIBCALL "*lmul%%"
749
750 struct sysV68_cumulative_args
751         {
752         int     offset;
753         int     libcall;
754         };
755
756 #undef CUMULATIVE_ARGS
757 #define CUMULATIVE_ARGS struct sysV68_cumulative_args
758
759 #undef INIT_CUMULATIVE_ARGS
760 #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT)       \
761 do {(CUM).offset = 0;\
762 (CUM).libcall = (LIBNAME) && (*XSTR((LIBNAME), 0) == '*');} while(0)
763
764 #undef FUNCTION_ARG_ADVANCE
765 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)    \
766  ((CUM).offset += ((MODE) != BLKmode                    \
767             ? (GET_MODE_SIZE (MODE) + 3) & ~3   \
768             : (int_size_in_bytes (TYPE) + 3) & ~3))
769
770 #undef FUNCTION_ARG
771 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
772 (((CUM).libcall && (CUM).offset == 0) ? gen_rtx(REG, (MODE), 0)\
773 : (TARGET_REGPARM && (CUM).offset < 8) ? gen_rtx (REG, (MODE), (CUM).offset / 4) : 0)
774
775 #undef FUNCTION_ARG_PARTIAL_NREGS
776 #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
777 ((TARGET_REGPARM && (CUM).offset < 8                            \
778   && 8 < ((CUM).offset + ((MODE) == BLKmode                     \
779                       ? int_size_in_bytes (TYPE)                \
780                       : GET_MODE_SIZE (MODE))))                 \
781  ? 2 - (CUM).offset / 4 : 0)
782
783 #undef FUNCTION_ARG_REGNO_P
784 #define FUNCTION_ARG_REGNO_P(N) (TARGET_68020 ? 0 : (N) == 0)
785
786 /* manfred@lts.sel.alcatel.de: I believe that most delta machines are configured to have
787    a 6888[12] FPU for which we need to link -lm881 instead of -lm; define ALT_LIBM to
788    tell g++.c about that.  */
789 #define ALT_LIBM        "-lm881"
790
791 #if (TARGET_DEFAULT & MASK_68881)      /* The default configuration has a 6888[12] FPU. */
792 #define MATH_LIBRARY    "-lm881"
793 #endif
794
795 /* Currently we do not have the atexit() function,
796    so take that from libgcc2.c */
797
798 #define NEED_ATEXIT 1
799 #define HAVE_ATEXIT 1
800
801 #define EXIT_BODY       \
802   do                                                            \
803     {                                                           \
804       __stop_monitor ();                                        \
805       _cleanup ();                                              \
806     } while (0)
807
808 /* FINALIZE_TRAMPOLINE clears the instruction cache. */
809
810 #undef FINALIZE_TRAMPOLINE
811 #define FINALIZE_TRAMPOLINE(TRAMP)      \
812   if (!TARGET_68040)                    \
813     ;                                   \
814   else                                  \
815     emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__clear_insn_cache"), \
816                        0, VOIDmode, 0)