OSDN Git Service

* config/rs6000/rs6000.c (rs6000_emit_load_toc_table): Don't call
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / tower-as.h
1 /* Definitions of target machine for GNU compiler.
2    For NCR Tower 32/4x0 and 32/6x0 running System V Release 3.
3    Copyright (C) 1990, 1993, 1994, 1996, 1997, 2000, 2002
4    Free Software Foundation, Inc.
5    Contributed by Robert Andersson (ra@intsys.no), International Systems,
6    Oslo, Norway.
7
8 This file is part of GNU CC.
9
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING.  If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.  */
24
25
26 /* This file outputs assembler source suitable for the native Tower as
27    and with sdb debugging symbols.  See tower.h for more comments.
28
29    This file was based on m68k.h, hp320.h and 3b1.h as of the
30    1.37.1 version.  */
31
32 #include "m68k/tower.h"
33
34 /* Use default settings for system V.3.  */
35
36 #include "svr3.h"
37
38 /* Names to predefine in the preprocessor for this target machine.  */
39
40 #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_600 -D__motorola__ -Asystem=unix -Asystem=svr3 -Acpu=m68k -Amachine=m68k"
41
42 /* Define __HAVE_68881 in preprocessor only if -m68881 is specified.
43    This will control the use of inline 68881 insns in certain macros.
44    Also, define special define used to identify the Tower assembler.  */
45
46 #define CPP_SPEC "-D__TOWER_ASM__ %{m68881:-D__HAVE_68881__}"
47
48 /* We don't want local labels to start with period.
49    See (*targetm.asm_out.internal_label).  */
50 #undef LOCAL_LABEL_PREFIX
51 #define LOCAL_LABEL_PREFIX ""
52
53 /* The prefix to add to user-visible assembler symbols.  */
54 /* We do not want leading underscores.  */
55
56 #undef USER_LABEL_PREFIX
57 #define USER_LABEL_PREFIX ""
58
59 /* These four macros control how m68k.md is expanded.  */
60
61 #define MOTOROLA                /* Use Motorola syntax rather than "MIT" */
62 #define SGS                     /* Uses SGS assembler */
63 #define SGS_CMP_ORDER           /* Takes cmp operands in reverse order */
64 #define SGS_NO_LI               /* Suppress jump table label usage */
65
66 #undef INT_OP_GROUP
67 #define INT_OP_GROUP INT_OP_NO_DOT
68
69 /* Turn on SDB debugging info.  */
70
71 #define SDB_DEBUGGING_INFO 1
72
73 /* All the ASM_OUTPUT macros need to conform to the Tower as syntax.  */
74
75 #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \
76   do {                                             \
77     fprintf (FILE, "\tfile\t");                    \
78     output_quoted_string (FILE, FILENAME);         \
79     fprintf (FILE, "\n");                          \
80     fprintf (FILE, "section ~init,\"x\"\n");       \
81     fprintf (FILE, "section ~fini,\"x\"\n");       \
82     fprintf (FILE, "section ~rodata,\"x\"\n");   \
83     fprintf (FILE, "text\n");                      \
84   } while (0)
85
86 #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO)    \
87   fprintf (FILE, "\tln\t%d\n",                  \
88            (sdb_begin_function_line > -1        \
89             ? (LINENO) - sdb_begin_function_line : 1))
90
91 #undef ASM_OUTPUT_IDENT
92 #define ASM_OUTPUT_IDENT(FILE, NAME) \
93   fprintf (FILE, "\tident\t\"%s\" \n", NAME)
94
95 #define ASM_OUTPUT_ASCII(FILE,PTR,LEN) \
96   do { register size_t sp = 0, lp = 0, limit = (LEN); \
97     fprintf ((FILE), "\tbyte\t"); \
98   loop: \
99     if ((PTR)[sp] > ' ' && ! ((PTR)[sp] & 0x80) && (PTR)[sp] != '\\') \
100       { lp += 3; \
101         fprintf ((FILE), "'%c", (PTR)[sp]); } \
102     else \
103       { lp += 5; \
104         fprintf ((FILE), "0x%x", (PTR)[sp]); } \
105     if (++sp < limit) \
106       { if (lp > 60) \
107           { lp = 0; \
108             fprintf ((FILE), "\n\tbyte\t"); }   \
109         else \
110           putc (',', (FILE)); \
111         goto loop; } \
112     putc ('\n', (FILE)); } while (0)
113
114 /* Translate Motorola opcodes such as `jbeq'
115    into SGS/Tower opcodes such as `beq.w'.
116    Change `move' to `mov'.
117    Change `cmpm' to `cmp'.
118    Change `divsl' to `tdivs'.
119    Change `divul' to `tdivu'.
120    Change `ftst' to `ftest'.
121    Change `fmove' to `fmov'.  */
122
123 #define ASM_OUTPUT_OPCODE(FILE, PTR)                    \
124 { if ((PTR)[0] == 'j' && (PTR)[1] == 'b')               \
125     { ++(PTR);                                          \
126       while (*(PTR) != ' ')                             \
127         { putc (*(PTR), (FILE)); ++(PTR); }             \
128       fprintf ((FILE), ".w"); }                         \
129   else if ((PTR)[0] == 'm' && (PTR)[1] == 'o'           \
130            && (PTR)[2] == 'v' && (PTR)[3] == 'e')       \
131     { fprintf ((FILE), "mov"); (PTR) += 4; }            \
132   else if ((PTR)[0] == 'c' && (PTR)[1] == 'm'           \
133            && (PTR)[2] == 'p' && (PTR)[3] == 'm')       \
134     { fprintf ((FILE), "cmp"); (PTR) += 4; }            \
135   else if ((PTR)[0] == 'd' && (PTR)[1] == 'i'           \
136            && (PTR)[2] == 'v' && (PTR)[3] == 's'        \
137            && (PTR)[4] == 'l')                          \
138     { fprintf ((FILE), "tdivs"); (PTR) += 5; }          \
139   else if ((PTR)[0] == 'd' && (PTR)[1] == 'i'           \
140            && (PTR)[2] == 'v' && (PTR)[3] == 'u'        \
141            && (PTR)[4] == 'l')                          \
142     { fprintf ((FILE), "tdivu"); (PTR) += 5; }          \
143   else if ((PTR)[0] == 'f' && (PTR)[1] == 't'           \
144            && (PTR)[2] == 's' && (PTR)[3] == 't')       \
145     { fprintf ((FILE), "ftest"); (PTR) += 4; }          \
146   else if ((PTR)[0] == 'f' && (PTR)[1] == 'm'           \
147            && (PTR)[2] == 'o' && (PTR)[3] == 'v'        \
148            && (PTR)[4] == 'e')                          \
149     { fprintf ((FILE), "fmov"); (PTR) += 5; }           \
150 }
151
152
153 \f
154 /* Override parts of m68k.h to fit the Tower assembler.
155    This section needs to track changes done to m68k.h in the future.  */
156
157 #undef TARGET_VERSION
158 #define TARGET_VERSION fprintf (stderr, " (68k, Motorola/SGS/Tower32 syntax)");
159
160 #undef FUNCTION_PROFILER
161 #define FUNCTION_PROFILER(FILE, LABEL_NO)       \
162     fprintf (FILE, "\tmov.l &LP%%%d,%%a0\n\tjsr mcount%%\n", (LABEL_NO))
163
164 #undef FUNCTION_EXTRA_EPILOGUE
165 #define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE)                             \
166 { if (current_function_returns_pointer                                  \
167       && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode))     \
168     asm_fprintf (FILE, "\tmov.l %Rd0,%Ra0\n"); } 
169
170 /* This is how to output an insn to push a register on the stack.
171    It need not be very fast code.  */
172
173 #undef ASM_OUTPUT_REG_PUSH
174 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
175   fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[REGNO])
176
177 /* This is how to output an insn to pop a register from the stack.
178    It need not be very fast code.  */
179
180 #undef ASM_OUTPUT_REG_POP
181 #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
182   fprintf (FILE, "\tmov.l (%%sp)+,%s\n", reg_names[REGNO])
183
184 #undef ASM_FILE_START
185 #define ASM_FILE_START(FILE) \
186 ( fprintf (FILE, "#NO_APP\n"), \
187   output_file_directive ((FILE), main_input_filename))
188
189 #undef TEXT_SECTION_ASM_OP
190 #define TEXT_SECTION_ASM_OP "\ttext"
191
192 #undef DATA_SECTION_ASM_OP
193 #define DATA_SECTION_ASM_OP "\tdata"
194
195 /* This says how to output an assembler line to define a global common symbol.
196    We use SIZE rather than ROUNDED, as this is what the native cc does.  */
197
198 #undef ASM_OUTPUT_COMMON
199 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
200 ( fputs ("\tcomm ", (FILE)),                    \
201   assemble_name ((FILE), (NAME)),               \
202   fprintf ((FILE), ",%d\n", ((SIZE) == 0) ? (ROUNDED) : (SIZE)))
203
204 /* This says how to output an assembler line to define a local common symbol.
205    We use SIZE rather than ROUNDED, as this is what the native cc does.  */
206
207 #undef ASM_OUTPUT_LOCAL
208 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
209 ( fputs ("\tlcomm ", (FILE)),                   \
210   assemble_name ((FILE), (NAME)),               \
211   fprintf ((FILE), ",%d\n", ((SIZE) == 0) ? (ROUNDED) : (SIZE)))
212
213 #define ASM_PN_FORMAT "%s%%%%%lu"
214  
215 /* This is the command to make the user-level label named NAME
216    defined for reference from other files.  */
217
218 #undef GLOBAL_ASM_OP
219 #define GLOBAL_ASM_OP "\tglobal\t"
220
221 #undef ASM_GENERATE_INTERNAL_LABEL
222 #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
223   sprintf ((LABEL), "%s%%%ld", (PREFIX), (long)(NUM))
224
225 #undef ASM_OUTPUT_CASE_LABEL
226 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLE)                    \
227   fprintf (FILE, "\tswbeg &%d\n%s%%%d:\n",                              \
228            XVECLEN (PATTERN (TABLE), 1), (PREFIX), (NUM));              \
229
230 #undef ASM_OUTPUT_ADDR_VEC_ELT
231 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
232   fprintf (FILE, "\tlong L%%%d\n", (VALUE))
233
234 #undef ASM_OUTPUT_ADDR_DIFF_ELT
235 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)  \
236   fprintf (FILE, "\tshort L%%%d-L%%%d\n", (VALUE), (REL))
237
238 #undef ASM_OUTPUT_ALIGN
239 #define ASM_OUTPUT_ALIGN(FILE,LOG)      \
240 do {                                    \
241   if ((LOG) == 1)                       \
242     fprintf (FILE, "\teven\n");         \
243   else if ((LOG) != 0)                  \
244     abort ();                           \
245 } while (0)
246
247 #undef ASM_OUTPUT_SKIP
248 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
249   fprintf (FILE, "\tspace %d\n", (SIZE))
250
251 /* Output a float value (represented as a C double) as an immediate operand.
252    This macro is a 68k-specific macro.  */
253
254 #undef ASM_OUTPUT_FLOAT_OPERAND
255 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)                       \
256  do { long l;                                                           \
257       REAL_VALUE_TO_TARGET_SINGLE (r, l);                               \
258       /* Use hex representation even if CODE is f.  as needs it.  */    \
259       fprintf ((FILE), "&0x%lx", l);                                    \
260     } while (0)
261
262 /* Output a double value (represented as a C double) as an immediate operand.
263    This macro is a 68k-specific macro.  */
264 #undef ASM_OUTPUT_DOUBLE_OPERAND
265 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE)                           \
266  do { long l[2];                                                        \
267       REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l);                           \
268       fprintf ((FILE), "&0x%lx%08lx", l[0], l[1]);                      \
269     } while (0)
270
271 #if 0
272 #undef PRINT_OPERAND
273 #define PRINT_OPERAND(FILE, X, CODE)  \
274 { if (CODE == '.') fprintf (FILE, ".");                                 \
275   else if (CODE == '#') fprintf (FILE, "&");                            \
276   else if (CODE == '-') fprintf (FILE, "-(%%sp)");                      \
277   else if (CODE == '+') fprintf (FILE, "(%%sp)+");                      \
278   else if (CODE == '@') fprintf (FILE, "(%%sp)");                       \
279   else if (CODE == '!') fprintf (FILE, "%%fpcr");                       \
280   else if (CODE == '/')                                                 \
281     fprintf (FILE, "%%");                                               \
282   else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \
283   else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \
284   else if (GET_CODE (X) == REG)                                         \
285     fprintf (FILE, "%s", reg_names[REGNO (X)]);                         \
286   else if (GET_CODE (X) == MEM)                                         \
287     output_address (XEXP (X, 0));                                       \
288   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)      \
289     { REAL_VALUE_TYPE r; long l;                                        \
290       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
291       REAL_VALUE_TO_TARGET_SINGLE (r, l);                               \
292       fprintf (FILE, "&0x%lx", l); }                                    \
293   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode)      \
294     { REAL_VALUE_TYPE r; int i[2];                                      \
295       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
296       REAL_VALUE_TO_TARGET_DOUBLE (r, i);                               \
297       fprintf (FILE, "&0x%x%08x", i[0], i[1]); }                        \
298   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == XFmode)      \
299     { REAL_VALUE_TYPE r;                                                \
300       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
301       ASM_OUTPUT_LONG_DOUBLE_OPERAND (FILE, r); }                       \
302   else { putc ('&', FILE); output_addr_const (FILE, X); }}
303 #endif
304
305 /* Note that this contains a kludge that knows that the only reason
306    we have an address (plus (label_ref...) (reg...))
307    is in the insn before a tablejump, and we know that the table is
308    exactly 10 bytes away.  */
309
310 #undef PRINT_OPERAND_ADDRESS
311 #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
312 { register rtx reg1, reg2, breg, ireg;                                  \
313   register rtx addr = ADDR;                                             \
314   rtx offset;                                                           \
315   switch (GET_CODE (addr))                                              \
316     {                                                                   \
317     case REG:                                                           \
318       fprintf (FILE, "(%s)", reg_names[REGNO (addr)]);                  \
319       break;                                                            \
320     case PRE_DEC:                                                       \
321       fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);       \
322       break;                                                            \
323     case POST_INC:                                                      \
324       fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);       \
325       break;                                                            \
326     case PLUS:                                                          \
327       reg1 = 0; reg2 = 0;                                               \
328       ireg = 0; breg = 0;                                               \
329       offset = 0;                                                       \
330       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))                          \
331         {                                                               \
332           offset = XEXP (addr, 0);                                      \
333           addr = XEXP (addr, 1);                                        \
334         }                                                               \
335       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))                     \
336         {                                                               \
337           offset = XEXP (addr, 1);                                      \
338           addr = XEXP (addr, 0);                                        \
339         }                                                               \
340       if (GET_CODE (addr) != PLUS) ;                                    \
341       else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)                \
342         {                                                               \
343           reg1 = XEXP (addr, 0);                                        \
344           addr = XEXP (addr, 1);                                        \
345         }                                                               \
346       else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)                \
347         {                                                               \
348           reg1 = XEXP (addr, 1);                                        \
349           addr = XEXP (addr, 0);                                        \
350         }                                                               \
351       else if (GET_CODE (XEXP (addr, 0)) == MULT)                       \
352         {                                                               \
353           reg1 = XEXP (addr, 0);                                        \
354           addr = XEXP (addr, 1);                                        \
355         }                                                               \
356       else if (GET_CODE (XEXP (addr, 1)) == MULT)                       \
357         {                                                               \
358           reg1 = XEXP (addr, 1);                                        \
359           addr = XEXP (addr, 0);                                        \
360         }                                                               \
361       else if (GET_CODE (XEXP (addr, 0)) == REG)                        \
362         {                                                               \
363           reg1 = XEXP (addr, 0);                                        \
364           addr = XEXP (addr, 1);                                        \
365         }                                                               \
366       else if (GET_CODE (XEXP (addr, 1)) == REG)                        \
367         {                                                               \
368           reg1 = XEXP (addr, 1);                                        \
369           addr = XEXP (addr, 0);                                        \
370         }                                                               \
371       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT             \
372           || GET_CODE (addr) == SIGN_EXTEND)                            \
373         { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; }     \
374 /*  for OLD_INDEXING                                                    \
375       else if (GET_CODE (addr) == PLUS)                                 \
376         {                                                               \
377           if (GET_CODE (XEXP (addr, 0)) == REG)                         \
378             {                                                           \
379               reg2 = XEXP (addr, 0);                                    \
380               addr = XEXP (addr, 1);                                    \
381             }                                                           \
382           else if (GET_CODE (XEXP (addr, 1)) == REG)                    \
383             {                                                           \
384               reg2 = XEXP (addr, 1);                                    \
385               addr = XEXP (addr, 0);                                    \
386             }                                                           \
387         }                                                               \
388   */                                                                    \
389       if (offset != 0) { if (addr != 0) abort (); addr = offset; }      \
390       if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND                      \
391                     || GET_CODE (reg1) == MULT))                        \
392           || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))         \
393         { breg = reg2; ireg = reg1; }                                   \
394       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))         \
395         { breg = reg1; ireg = reg2; }                                   \
396       if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF)       \
397         { int scale = 1;                                                \
398           if (GET_CODE (ireg) == MULT)                                  \
399             { scale = INTVAL (XEXP (ireg, 1));                          \
400               ireg = XEXP (ireg, 0); }                                  \
401           if (GET_CODE (ireg) == SIGN_EXTEND)                           \
402             fprintf (FILE, "10(%%pc,%s.w",                              \
403                      reg_names[REGNO (XEXP (ireg, 0))]);                \
404           else                                                          \
405             fprintf (FILE, "10(%%pc,%s.l",                              \
406                      reg_names[REGNO (ireg)]);                          \
407           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
408           putc (')', FILE);                                             \
409           break; }                                                      \
410       if (ireg != 0 || breg != 0)                                       \
411         { int scale = 1;                                                \
412           if (breg == 0)                                                \
413             abort ();                                                   \
414           if (addr != 0)                                                \
415             output_addr_const (FILE, addr);                             \
416           fprintf (FILE, "(%s", reg_names[REGNO (breg)]);               \
417           if (ireg != 0)                                                \
418             putc (',', FILE);                                           \
419           if (ireg != 0 && GET_CODE (ireg) == MULT)                     \
420             { scale = INTVAL (XEXP (ireg, 1));                          \
421               ireg = XEXP (ireg, 0); }                                  \
422           if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)              \
423             fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);  \
424           else if (ireg != 0)                                           \
425             fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]);            \
426           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
427           putc (')', FILE);                                             \
428           break;                                                        \
429         }                                                               \
430       else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)               \
431         { fprintf (FILE, "10(%%pc,%s.w)",                               \
432                    reg_names[REGNO (reg1)]);                            \
433           break; }                                                      \
434     default:                                                            \
435         output_addr_const (FILE, addr);                                 \
436     }}
437
438
439 \f
440 /* Override usual definitions of SDB output macros.
441    These definitions differ only in the absence of the period
442    at the beginning of the name of the directive
443    and in the use of `~' as the symbol for the current location.  */
444
445 #define PUT_SDB_SCL(a) fprintf(asm_out_file, "\tscl\t%d;", (a))
446 #define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\tval\t%d;", (a))
447 #define PUT_SDB_VAL(a)                          \
448 ( fputs ("\tval\t", asm_out_file),              \
449   output_addr_const (asm_out_file, (a)),        \
450   fputc (';', asm_out_file))
451
452 #define PUT_SDB_DEF(a)                          \
453 do { fprintf (asm_out_file, "\tdef\t"); \
454      ASM_OUTPUT_LABELREF (asm_out_file, a);     \
455      fprintf (asm_out_file, ";"); } while (0)
456
457 #define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\tdef\t~%s;",a)
458 #define PUT_SDB_ENDEF fputs("\tendef\n", asm_out_file)
459 #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\ttype\t0%o;", a)
460 #define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\tsize\t%d;", a)
461 #define PUT_SDB_START_DIM fprintf(asm_out_file, "\tdim\t")
462 #define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)
463 #define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d;", a)
464
465 #define PUT_SDB_TAG(a)                          \
466 do { fprintf (asm_out_file, "\ttag\t"); \
467      ASM_OUTPUT_LABELREF (asm_out_file, a);     \
468      fprintf (asm_out_file, ";"); } while (0)
469
470 #define PUT_SDB_BLOCK_START(LINE)               \
471   fprintf (asm_out_file,                        \
472            "\tdef\t~bb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n",       \
473            (LINE))
474
475 #define PUT_SDB_BLOCK_END(LINE)                 \
476   fprintf (asm_out_file,                        \
477            "\tdef\t~eb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n",       \
478            (LINE))
479
480 #define PUT_SDB_FUNCTION_START(LINE)            \
481   fprintf (asm_out_file,                        \
482            "\tdef\t~bf;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n",       \
483            (LINE))
484
485 #define PUT_SDB_FUNCTION_END(LINE)              \
486   fprintf (asm_out_file,                        \
487            "\tdef\t~ef;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n",       \
488            (LINE))
489
490 #define PUT_SDB_EPILOGUE_END(NAME)              \
491   fprintf (asm_out_file,                        \
492            "\tdef\t%s;\tval\t~;\tscl\t-1;\tendef\n",    \
493            (NAME))
494
495 #define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
496   sprintf ((BUFFER), "~%dfake", (NUMBER));
497
498 #define NO_DOLLAR_IN_LABEL
499 #define NO_DOT_IN_LABEL
500
501 /* The usual definitions don't work because neither $ nor . is allowed.  */
502 #define CONSTRUCTOR_NAME_FORMAT "_GLOBAL_%%I\%%%s"
503
504 /* Define a few machine-specific details
505    of the implementation of constructors.
506
507    The __CTORS_LIST__ goes in the .init section.  Define CTOR_LIST_BEGIN
508    and CTOR_LIST_END to contribute to the .init section an instruction to
509    push a word containing 0 (or some equivalent of that).  */
510
511 #undef INIT_SECTION_ASM_OP
512 #define INIT_SECTION_ASM_OP     "\tsection\t~init"
513 #undef FINI_SECTION_ASM_OP
514 #define FINI_SECTION_ASM_OP     "\tsection\t~fini"
515 #undef READONLY_DATA_SECTION_ASM_OP
516 #define READONLY_DATA_SECTION_ASM_OP    "\tsection\t~rodata"
517
518 #define CTOR_LIST_BEGIN                         \
519   asm (INIT_SECTION_ASM_OP);                    \
520   asm ("clr.l -(%sp)")
521 #define CTOR_LIST_END CTOR_LIST_BEGIN
522
523 #define BSS_SECTION_ASM_OP      "\tsection\t~bss"
524
525 #define TARGET_ASM_CONSTRUCTOR  m68k_svr3_asm_out_constructor