OSDN Git Service

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