OSDN Git Service

* config/xtensa/xtensa.c (xtensa_va_arg): Fix to handle arguments
[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 Free Software Foundation, Inc.
4    Contributed by Robert Andersson (ra@intsys.no), International Systems,
5    Oslo, Norway.
6
7 This file is part of GNU CC.
8
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING.  If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.  */
23
24
25 /* This file outputs assembler source suitable for the native Tower as
26    and with sdb debugging symbols.  See tower.h for more comments.
27
28    This file was based on m68k.h, hp320.h and 3b1.h as of the
29    1.37.1 version.  */
30
31 #include "m68k/tower.h"
32 #undef SELECT_RTX_SECTION
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 ASM_OUTPUT_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
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_BLOCK_PROFILER
161 #define FUNCTION_BLOCK_PROFILER(FILE, LABELNO)                          \
162   do {                                                                  \
163     char label1[20], label2[20];                                        \
164     ASM_GENERATE_INTERNAL_LABEL (label1, "LPBX", 0);                    \
165     ASM_GENERATE_INTERNAL_LABEL (label2, "LPI", LABELNO);               \
166     fprintf (FILE, "\ttst.l %s\n\tbne %s\n\tpea %s\n\tjsr __bb_init_func\n\taddq.l &4,%%sp\n",  \
167              label1, label2, label1);                                   \
168     ASM_OUTPUT_INTERNAL_LABEL (FILE, "LPI", LABELNO);                   \
169     putc ('\n', FILE);                                          \
170     } while (0)
171
172 #undef BLOCK_PROFILER
173 #define BLOCK_PROFILER(FILE, BLOCKNO)                           \
174   do {                                                          \
175     char label[20];                                             \
176     ASM_GENERATE_INTERNAL_LABEL (label, "LPBX", 2);             \
177     fprintf (FILE, "\taddq.l &1,%s+%d\n", label, 4 * BLOCKNO);  \
178     } while (0)
179
180 #undef FUNCTION_PROFILER
181 #define FUNCTION_PROFILER(FILE, LABEL_NO)       \
182     fprintf (FILE, "\tmov.l &LP%%%d,%%a0\n\tjsr mcount%%\n", (LABEL_NO))
183
184 #undef FUNCTION_EXTRA_EPILOGUE
185 #define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE)                             \
186 { if (current_function_returns_pointer                                  \
187       && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode))     \
188     asm_fprintf (FILE, "\tmov.l %Rd0,%Ra0\n"); } 
189
190 /* This is how to output an insn to push a register on the stack.
191    It need not be very fast code.  */
192
193 #undef ASM_OUTPUT_REG_PUSH
194 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
195   fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[REGNO])
196
197 /* This is how to output an insn to pop a register from the stack.
198    It need not be very fast code.  */
199
200 #undef ASM_OUTPUT_REG_POP
201 #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
202   fprintf (FILE, "\tmov.l (%%sp)+,%s\n", reg_names[REGNO])
203
204 #undef ASM_FILE_START
205 #define ASM_FILE_START(FILE) \
206 ( fprintf (FILE, "#NO_APP\n"), \
207   output_file_directive ((FILE), main_input_filename))
208
209 #undef TEXT_SECTION_ASM_OP
210 #define TEXT_SECTION_ASM_OP "\ttext"
211
212 #undef DATA_SECTION_ASM_OP
213 #define DATA_SECTION_ASM_OP "\tdata"
214
215 /* This says how to output an assembler line to define a global common symbol.
216    We use SIZE rather than ROUNDED, as this is what the native cc does.  */
217
218 #undef ASM_OUTPUT_COMMON
219 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
220 ( fputs ("\tcomm ", (FILE)),                    \
221   assemble_name ((FILE), (NAME)),               \
222   fprintf ((FILE), ",%d\n", ((SIZE) == 0) ? (ROUNDED) : (SIZE)))
223
224 /* This says how to output an assembler line to define a local common symbol.
225    We use SIZE rather than ROUNDED, as this is what the native cc does.  */
226
227 #undef ASM_OUTPUT_LOCAL
228 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
229 ( fputs ("\tlcomm ", (FILE)),                   \
230   assemble_name ((FILE), (NAME)),               \
231   fprintf ((FILE), ",%d\n", ((SIZE) == 0) ? (ROUNDED) : (SIZE)))
232
233 /* Store in OUTPUT a string (made with alloca) containing
234    an assembler-name for a local static variable named NAME.
235    LABELNO is an integer which is different for each call.  */
236
237 #undef ASM_FORMAT_PRIVATE_NAME
238 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)  \
239 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 11),    \
240   sprintf ((OUTPUT), "%s%%%%%d", (NAME), (LABELNO)))
241  
242 /* This is the command to make the user-level label named NAME
243    defined for reference from other files.  */
244
245 #undef GLOBAL_ASM_OP
246 #define GLOBAL_ASM_OP "\tglobal\t"
247
248 #undef ASM_GENERATE_INTERNAL_LABEL
249 #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
250   sprintf ((LABEL), "%s%%%ld", (PREFIX), (long)(NUM))
251
252 #undef ASM_OUTPUT_INTERNAL_LABEL
253 #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)      \
254   fprintf ((FILE), "%s%%%d:\n", (PREFIX), (NUM))
255
256 #undef ASM_OUTPUT_CASE_LABEL
257 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLE)                    \
258   fprintf (FILE, "\tswbeg &%d\n%s%%%d:\n",                              \
259            XVECLEN (PATTERN (TABLE), 1), (PREFIX), (NUM));              \
260
261 #undef ASM_OUTPUT_ADDR_VEC_ELT
262 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
263   fprintf (FILE, "\tlong L%%%d\n", (VALUE))
264
265 #undef ASM_OUTPUT_ADDR_DIFF_ELT
266 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)  \
267   fprintf (FILE, "\tshort L%%%d-L%%%d\n", (VALUE), (REL))
268
269 #undef ASM_OUTPUT_ALIGN
270 #define ASM_OUTPUT_ALIGN(FILE,LOG)      \
271 do {                                    \
272   if ((LOG) == 1)                       \
273     fprintf (FILE, "\teven\n");         \
274   else if ((LOG) != 0)                  \
275     abort ();                           \
276 } while (0)
277
278 #undef ASM_OUTPUT_SKIP
279 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
280   fprintf (FILE, "\tspace %d\n", (SIZE))
281
282 /* Output a float value (represented as a C double) as an immediate operand.
283    This macro is a 68k-specific macro.  */
284
285 #undef ASM_OUTPUT_FLOAT_OPERAND
286 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)                       \
287  do { long l;                                                           \
288       REAL_VALUE_TO_TARGET_SINGLE (r, l);                               \
289       /* Use hex representation even if CODE is f.  as needs it.  */    \
290       fprintf ((FILE), "&0x%lx", l);                                    \
291     } while (0)
292
293 /* Output a double value (represented as a C double) as an immediate operand.
294    This macro is a 68k-specific macro.  */
295 #undef ASM_OUTPUT_DOUBLE_OPERAND
296 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE)                           \
297  do { long l[2];                                                        \
298       REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l);                           \
299       fprintf ((FILE), "&0x%lx%08lx", l[0], l[1]);                      \
300     } while (0)
301
302 #if 0
303 #undef PRINT_OPERAND
304 #define PRINT_OPERAND(FILE, X, CODE)  \
305 { if (CODE == '.') fprintf (FILE, ".");                                 \
306   else if (CODE == '#') fprintf (FILE, "&");                            \
307   else if (CODE == '-') fprintf (FILE, "-(%%sp)");                      \
308   else if (CODE == '+') fprintf (FILE, "(%%sp)+");                      \
309   else if (CODE == '@') fprintf (FILE, "(%%sp)");                       \
310   else if (CODE == '!') fprintf (FILE, "%%fpcr");                       \
311   else if (CODE == '/')                                                 \
312     fprintf (FILE, "%%");                                               \
313   else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \
314   else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \
315   else if (GET_CODE (X) == REG)                                         \
316     fprintf (FILE, "%s", reg_names[REGNO (X)]);                         \
317   else if (GET_CODE (X) == MEM)                                         \
318     output_address (XEXP (X, 0));                                       \
319   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)      \
320     { REAL_VALUE_TYPE r; long l;                                        \
321       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
322       REAL_VALUE_TO_TARGET_SINGLE (r, l);                               \
323       fprintf (FILE, "&0x%lx", l); }                                    \
324   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode)      \
325     { REAL_VALUE_TYPE r; int i[2];                                      \
326       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
327       REAL_VALUE_TO_TARGET_DOUBLE (r, i);                               \
328       fprintf (FILE, "&0x%x%08x", i[0], i[1]); }                        \
329   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == XFmode)      \
330     { REAL_VALUE_TYPE r;                                                \
331       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
332       ASM_OUTPUT_LONG_DOUBLE_OPERAND (FILE, r); }                       \
333   else { putc ('&', FILE); output_addr_const (FILE, X); }}
334 #endif
335
336 /* Note that this contains a kludge that knows that the only reason
337    we have an address (plus (label_ref...) (reg...))
338    is in the insn before a tablejump, and we know that the table is
339    exactly 10 bytes away.  */
340
341 #undef PRINT_OPERAND_ADDRESS
342 #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
343 { register rtx reg1, reg2, breg, ireg;                                  \
344   register rtx addr = ADDR;                                             \
345   rtx offset;                                                           \
346   switch (GET_CODE (addr))                                              \
347     {                                                                   \
348     case REG:                                                           \
349       fprintf (FILE, "(%s)", reg_names[REGNO (addr)]);                  \
350       break;                                                            \
351     case PRE_DEC:                                                       \
352       fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);       \
353       break;                                                            \
354     case POST_INC:                                                      \
355       fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);       \
356       break;                                                            \
357     case PLUS:                                                          \
358       reg1 = 0; reg2 = 0;                                               \
359       ireg = 0; breg = 0;                                               \
360       offset = 0;                                                       \
361       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))                          \
362         {                                                               \
363           offset = XEXP (addr, 0);                                      \
364           addr = XEXP (addr, 1);                                        \
365         }                                                               \
366       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))                     \
367         {                                                               \
368           offset = XEXP (addr, 1);                                      \
369           addr = XEXP (addr, 0);                                        \
370         }                                                               \
371       if (GET_CODE (addr) != PLUS) ;                                    \
372       else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)                \
373         {                                                               \
374           reg1 = XEXP (addr, 0);                                        \
375           addr = XEXP (addr, 1);                                        \
376         }                                                               \
377       else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)                \
378         {                                                               \
379           reg1 = XEXP (addr, 1);                                        \
380           addr = XEXP (addr, 0);                                        \
381         }                                                               \
382       else if (GET_CODE (XEXP (addr, 0)) == MULT)                       \
383         {                                                               \
384           reg1 = XEXP (addr, 0);                                        \
385           addr = XEXP (addr, 1);                                        \
386         }                                                               \
387       else if (GET_CODE (XEXP (addr, 1)) == MULT)                       \
388         {                                                               \
389           reg1 = XEXP (addr, 1);                                        \
390           addr = XEXP (addr, 0);                                        \
391         }                                                               \
392       else if (GET_CODE (XEXP (addr, 0)) == REG)                        \
393         {                                                               \
394           reg1 = XEXP (addr, 0);                                        \
395           addr = XEXP (addr, 1);                                        \
396         }                                                               \
397       else if (GET_CODE (XEXP (addr, 1)) == REG)                        \
398         {                                                               \
399           reg1 = XEXP (addr, 1);                                        \
400           addr = XEXP (addr, 0);                                        \
401         }                                                               \
402       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT             \
403           || GET_CODE (addr) == SIGN_EXTEND)                            \
404         { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; }     \
405 /*  for OLD_INDEXING                                                    \
406       else if (GET_CODE (addr) == PLUS)                                 \
407         {                                                               \
408           if (GET_CODE (XEXP (addr, 0)) == REG)                         \
409             {                                                           \
410               reg2 = XEXP (addr, 0);                                    \
411               addr = XEXP (addr, 1);                                    \
412             }                                                           \
413           else if (GET_CODE (XEXP (addr, 1)) == REG)                    \
414             {                                                           \
415               reg2 = XEXP (addr, 1);                                    \
416               addr = XEXP (addr, 0);                                    \
417             }                                                           \
418         }                                                               \
419   */                                                                    \
420       if (offset != 0) { if (addr != 0) abort (); addr = offset; }      \
421       if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND                      \
422                     || GET_CODE (reg1) == MULT))                        \
423           || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))         \
424         { breg = reg2; ireg = reg1; }                                   \
425       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))         \
426         { breg = reg1; ireg = reg2; }                                   \
427       if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF)       \
428         { int scale = 1;                                                \
429           if (GET_CODE (ireg) == MULT)                                  \
430             { scale = INTVAL (XEXP (ireg, 1));                          \
431               ireg = XEXP (ireg, 0); }                                  \
432           if (GET_CODE (ireg) == SIGN_EXTEND)                           \
433             fprintf (FILE, "10(%%pc,%s.w",                              \
434                      reg_names[REGNO (XEXP (ireg, 0))]);                \
435           else                                                          \
436             fprintf (FILE, "10(%%pc,%s.l",                              \
437                      reg_names[REGNO (ireg)]);                          \
438           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
439           putc (')', FILE);                                             \
440           break; }                                                      \
441       if (ireg != 0 || breg != 0)                                       \
442         { int scale = 1;                                                \
443           if (breg == 0)                                                \
444             abort ();                                                   \
445           if (addr != 0)                                                \
446             output_addr_const (FILE, addr);                             \
447           fprintf (FILE, "(%s", reg_names[REGNO (breg)]);               \
448           if (ireg != 0)                                                \
449             putc (',', FILE);                                           \
450           if (ireg != 0 && GET_CODE (ireg) == MULT)                     \
451             { scale = INTVAL (XEXP (ireg, 1));                          \
452               ireg = XEXP (ireg, 0); }                                  \
453           if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)              \
454             fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);  \
455           else if (ireg != 0)                                           \
456             fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]);            \
457           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
458           putc (')', FILE);                                             \
459           break;                                                        \
460         }                                                               \
461       else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)               \
462         { fprintf (FILE, "10(%%pc,%s.w)",                               \
463                    reg_names[REGNO (reg1)]);                            \
464           break; }                                                      \
465     default:                                                            \
466         output_addr_const (FILE, addr);                                 \
467     }}
468
469
470 \f
471 /* Override usual definitions of SDB output macros.
472    These definitions differ only in the absence of the period
473    at the beginning of the name of the directive
474    and in the use of `~' as the symbol for the current location.  */
475
476 #define PUT_SDB_SCL(a) fprintf(asm_out_file, "\tscl\t%d;", (a))
477 #define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\tval\t%d;", (a))
478 #define PUT_SDB_VAL(a)                          \
479 ( fputs ("\tval\t", asm_out_file),              \
480   output_addr_const (asm_out_file, (a)),        \
481   fputc (';', asm_out_file))
482
483 #define PUT_SDB_DEF(a)                          \
484 do { fprintf (asm_out_file, "\tdef\t"); \
485      ASM_OUTPUT_LABELREF (asm_out_file, a);     \
486      fprintf (asm_out_file, ";"); } while (0)
487
488 #define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\tdef\t~%s;",a)
489 #define PUT_SDB_ENDEF fputs("\tendef\n", asm_out_file)
490 #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\ttype\t0%o;", a)
491 #define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\tsize\t%d;", a)
492 #define PUT_SDB_START_DIM fprintf(asm_out_file, "\tdim\t")
493 #define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)
494 #define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d;", a)
495
496 #define PUT_SDB_TAG(a)                          \
497 do { fprintf (asm_out_file, "\ttag\t"); \
498      ASM_OUTPUT_LABELREF (asm_out_file, a);     \
499      fprintf (asm_out_file, ";"); } while (0)
500
501 #define PUT_SDB_BLOCK_START(LINE)               \
502   fprintf (asm_out_file,                        \
503            "\tdef\t~bb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n",       \
504            (LINE))
505
506 #define PUT_SDB_BLOCK_END(LINE)                 \
507   fprintf (asm_out_file,                        \
508            "\tdef\t~eb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n",       \
509            (LINE))
510
511 #define PUT_SDB_FUNCTION_START(LINE)            \
512   fprintf (asm_out_file,                        \
513            "\tdef\t~bf;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n",       \
514            (LINE))
515
516 #define PUT_SDB_FUNCTION_END(LINE)              \
517   fprintf (asm_out_file,                        \
518            "\tdef\t~ef;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n",       \
519            (LINE))
520
521 #define PUT_SDB_EPILOGUE_END(NAME)              \
522   fprintf (asm_out_file,                        \
523            "\tdef\t%s;\tval\t~;\tscl\t-1;\tendef\n",    \
524            (NAME))
525
526 #define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
527   sprintf ((BUFFER), "~%dfake", (NUMBER));
528
529 #define NO_DOLLAR_IN_LABEL
530 #define NO_DOT_IN_LABEL
531
532 /* The usual definitions don't work because neither $ nor . is allowed.  */
533 #define CONSTRUCTOR_NAME_FORMAT "_GLOBAL_%%I\%%%s"
534
535 /* Define a few machine-specific details
536    of the implementation of constructors.
537
538    The __CTORS_LIST__ goes in the .init section.  Define CTOR_LIST_BEGIN
539    and CTOR_LIST_END to contribute to the .init section an instruction to
540    push a word containing 0 (or some equivalent of that).  */
541
542 #undef INIT_SECTION_ASM_OP
543 #define INIT_SECTION_ASM_OP     "\tsection\t~init"
544 #undef FINI_SECTION_ASM_OP
545 #define FINI_SECTION_ASM_OP     "\tsection\t~fini"
546 #undef CONST_SECTION_ASM_OP
547 #define CONST_SECTION_ASM_OP    "\tsection\t~rodata"
548
549 #define CTOR_LIST_BEGIN                         \
550   asm (INIT_SECTION_ASM_OP);                    \
551   asm ("clr.l -(%sp)")
552 #define CTOR_LIST_END CTOR_LIST_BEGIN
553
554 #define BSS_SECTION_ASM_OP      "\tsection\t~bss"
555
556 #define TARGET_ASM_CONSTRUCTOR  m68k_svr3_asm_out_constructor