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,
7 This file is part of GNU CC.
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)
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.
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. */
25 /* This file outputs assembler source suitable for the native Tower as
26 and with sdb debugging symbols. See tower.h for more comments.
28 This file was based on m68k.h, hp320.h and 3b1.h as of the
31 #include "m68k/tower.h"
32 #undef SELECT_RTX_SECTION
34 /* Use default settings for system V.3. */
38 /* Names to predefine in the preprocessor for this target machine. */
40 #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_600 -D__motorola__ -Asystem=unix -Asystem=svr3 -Acpu=m68k -Amachine=m68k"
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. */
46 #define CPP_SPEC "-D__TOWER_ASM__ %{m68881:-D__HAVE_68881__}"
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 ""
53 /* The prefix to add to user-visible assembler symbols. */
54 /* We do not want leading underscores. */
56 #undef USER_LABEL_PREFIX
57 #define USER_LABEL_PREFIX ""
59 /* These four macros control how m68k.md is expanded. */
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 */
66 /* Turn on SDB debugging info. */
68 #define SDB_DEBUGGING_INFO
70 /* All the ASM_OUTPUT macros need to conform to the Tower as syntax. */
72 #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \
74 fprintf (FILE, "\tfile\t"); \
75 output_quoted_string (FILE, FILENAME); \
76 fprintf (FILE, "\n"); \
77 fprintf (FILE, "section ~init,\"x\"\n"); \
78 fprintf (FILE, "section ~fini,\"x\"\n"); \
79 fprintf (FILE, "section ~rodata,\"x\"\n"); \
80 fprintf (FILE, "text\n"); \
83 #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO) \
84 fprintf (FILE, "\tln\t%d\n", \
85 (sdb_begin_function_line \
86 ? last_linenum - sdb_begin_function_line : 1))
88 #undef ASM_OUTPUT_IDENT
89 #define ASM_OUTPUT_IDENT(FILE, NAME) \
90 fprintf (FILE, "\tident\t\"%s\" \n", NAME)
92 #define ASM_OUTPUT_ASCII(FILE,PTR,LEN) \
93 do { register int sp = 0, lp = 0; \
94 fprintf ((FILE), "\tbyte\t"); \
96 if ((PTR)[sp] > ' ' && ! ((PTR)[sp] & 0x80) && (PTR)[sp] != '\\') \
98 fprintf ((FILE), "'%c", (PTR)[sp]); } \
101 fprintf ((FILE), "0x%x", (PTR)[sp]); } \
105 fprintf ((FILE), "\n\tbyte\t"); } \
107 putc (',', (FILE)); \
109 putc ('\n', (FILE)); } while (0)
111 /* Translate Motorola opcodes such as `jbeq'
112 into SGS/Tower opcodes such as `beq.w'.
113 Change `move' to `mov'.
114 Change `cmpm' to `cmp'.
115 Change `divsl' to `tdivs'.
116 Change `divul' to `tdivu'.
117 Change `ftst' to `ftest'.
118 Change `fmove' to `fmov'. */
120 #define ASM_OUTPUT_OPCODE(FILE, PTR) \
121 { if ((PTR)[0] == 'j' && (PTR)[1] == 'b') \
123 while (*(PTR) != ' ') \
124 { putc (*(PTR), (FILE)); ++(PTR); } \
125 fprintf ((FILE), ".w"); } \
126 else if ((PTR)[0] == 'm' && (PTR)[1] == 'o' \
127 && (PTR)[2] == 'v' && (PTR)[3] == 'e') \
128 { fprintf ((FILE), "mov"); (PTR) += 4; } \
129 else if ((PTR)[0] == 'c' && (PTR)[1] == 'm' \
130 && (PTR)[2] == 'p' && (PTR)[3] == 'm') \
131 { fprintf ((FILE), "cmp"); (PTR) += 4; } \
132 else if ((PTR)[0] == 'd' && (PTR)[1] == 'i' \
133 && (PTR)[2] == 'v' && (PTR)[3] == 's' \
134 && (PTR)[4] == 'l') \
135 { fprintf ((FILE), "tdivs"); (PTR) += 5; } \
136 else if ((PTR)[0] == 'd' && (PTR)[1] == 'i' \
137 && (PTR)[2] == 'v' && (PTR)[3] == 'u' \
138 && (PTR)[4] == 'l') \
139 { fprintf ((FILE), "tdivu"); (PTR) += 5; } \
140 else if ((PTR)[0] == 'f' && (PTR)[1] == 't' \
141 && (PTR)[2] == 's' && (PTR)[3] == 't') \
142 { fprintf ((FILE), "ftest"); (PTR) += 4; } \
143 else if ((PTR)[0] == 'f' && (PTR)[1] == 'm' \
144 && (PTR)[2] == 'o' && (PTR)[3] == 'v' \
145 && (PTR)[4] == 'e') \
146 { fprintf ((FILE), "fmov"); (PTR) += 5; } \
151 /* Override parts of m68k.h to fit the Tower assembler.
152 This section needs to track changes done to m68k.h in the future. */
154 #undef TARGET_VERSION
155 #define TARGET_VERSION fprintf (stderr, " (68k, Motorola/SGS/Tower32 syntax)");
157 #undef FUNCTION_BLOCK_PROFILER
158 #define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \
160 char label1[20], label2[20]; \
161 ASM_GENERATE_INTERNAL_LABEL (label1, "LPBX", 0); \
162 ASM_GENERATE_INTERNAL_LABEL (label2, "LPI", LABELNO); \
163 fprintf (FILE, "\ttst.l %s\n\tbne %s\n\tpea %s\n\tjsr __bb_init_func\n\taddq.l &4,%%sp\n", \
164 label1, label2, label1); \
165 ASM_OUTPUT_INTERNAL_LABEL (FILE, "LPI", LABELNO); \
169 #undef BLOCK_PROFILER
170 #define BLOCK_PROFILER(FILE, BLOCKNO) \
173 ASM_GENERATE_INTERNAL_LABEL (label, "LPBX", 2); \
174 fprintf (FILE, "\taddq.l &1,%s+%d\n", label, 4 * BLOCKNO); \
177 #undef FUNCTION_PROFILER
178 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
179 fprintf (FILE, "\tmov.l &LP%%%d,%%a0\n\tjsr mcount%%\n", (LABEL_NO))
181 #undef FUNCTION_EXTRA_EPILOGUE
182 #define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \
183 { if (current_function_returns_pointer \
184 && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
185 asm_fprintf (FILE, "\tmov.l %Rd0,%Ra0\n"); }
187 /* This is how to output an insn to push a register on the stack.
188 It need not be very fast code. */
190 #undef ASM_OUTPUT_REG_PUSH
191 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
192 fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[REGNO])
194 /* This is how to output an insn to pop a register from the stack.
195 It need not be very fast code. */
197 #undef ASM_OUTPUT_REG_POP
198 #define ASM_OUTPUT_REG_POP(FILE,REGNO) \
199 fprintf (FILE, "\tmov.l (%%sp)+,%s\n", reg_names[REGNO])
201 #undef ASM_FILE_START
202 #define ASM_FILE_START(FILE) \
203 ( fprintf (FILE, "#NO_APP\n"), \
204 output_file_directive ((FILE), main_input_filename))
206 #undef TEXT_SECTION_ASM_OP
207 #define TEXT_SECTION_ASM_OP "\ttext"
209 #undef DATA_SECTION_ASM_OP
210 #define DATA_SECTION_ASM_OP "\tdata"
212 /* This says how to output an assembler line to define a global common symbol.
213 We use SIZE rather than ROUNDED, as this is what the native cc does. */
215 #undef ASM_OUTPUT_COMMON
216 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
217 ( fputs ("\tcomm ", (FILE)), \
218 assemble_name ((FILE), (NAME)), \
219 fprintf ((FILE), ",%d\n", ((SIZE) == 0) ? (ROUNDED) : (SIZE)))
221 /* This says how to output an assembler line to define a local common symbol.
222 We use SIZE rather than ROUNDED, as this is what the native cc does. */
224 #undef ASM_OUTPUT_LOCAL
225 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
226 ( fputs ("\tlcomm ", (FILE)), \
227 assemble_name ((FILE), (NAME)), \
228 fprintf ((FILE), ",%d\n", ((SIZE) == 0) ? (ROUNDED) : (SIZE)))
230 /* Store in OUTPUT a string (made with alloca) containing
231 an assembler-name for a local static variable named NAME.
232 LABELNO is an integer which is different for each call. */
234 #undef ASM_FORMAT_PRIVATE_NAME
235 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
236 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 11), \
237 sprintf ((OUTPUT), "%s%%%%%d", (NAME), (LABELNO)))
239 /* This is the command to make the user-level label named NAME
240 defined for reference from other files. */
243 #define GLOBAL_ASM_OP "\tglobal\t"
245 #undef ASM_GENERATE_INTERNAL_LABEL
246 #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
247 sprintf ((LABEL), "%s%%%d", (PREFIX), (NUM))
249 #undef ASM_OUTPUT_INTERNAL_LABEL
250 #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
251 fprintf ((FILE), "%s%%%d:\n", (PREFIX), (NUM))
253 #undef ASM_OUTPUT_CASE_LABEL
254 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
255 fprintf (FILE, "\tswbeg &%d\n%s%%%d:\n", \
256 XVECLEN (PATTERN (TABLE), 1), (PREFIX), (NUM)); \
258 #undef ASM_OUTPUT_DOUBLE
259 #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
261 REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \
262 fprintf (FILE, "\tlong 0x%x,0x%x\n", l[0], l[1]); \
265 #undef ASM_OUTPUT_LONG_DOUBLE
266 #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \
268 REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \
269 fprintf (FILE, "\tlong 0x%x,0x%x,0x%x\n", l[0], l[1], l[2]); \
272 #undef ASM_OUTPUT_FLOAT
273 #define ASM_OUTPUT_FLOAT(FILE,VALUE) \
275 REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
276 fprintf ((FILE), "\tlong 0x%x\n", l); \
279 /* This is how to output an assembler line defining an `int' constant. */
281 #undef ASM_OUTPUT_INT
282 #define ASM_OUTPUT_INT(FILE,VALUE) \
283 ( fprintf (FILE, "\tlong "), \
284 output_addr_const (FILE, (VALUE)), \
285 fprintf (FILE, "\n"))
287 /* Likewise for `char' and `short' constants. */
289 #undef ASM_OUTPUT_SHORT
290 #define ASM_OUTPUT_SHORT(FILE,VALUE) \
291 ( fprintf (FILE, "\tshort "), \
292 output_addr_const (FILE, (VALUE)), \
293 fprintf (FILE, "\n"))
295 #undef ASM_OUTPUT_CHAR
296 #define ASM_OUTPUT_CHAR(FILE,VALUE) \
297 ( fprintf (FILE, "\tbyte "), \
298 output_addr_const (FILE, (VALUE)), \
299 fprintf (FILE, "\n"))
301 /* This is how to output an assembler line for a numeric constant byte. */
303 #undef ASM_OUTPUT_BYTE
304 #define ASM_OUTPUT_BYTE(FILE,VALUE) \
305 fprintf (FILE, "\tbyte 0x%x\n", (VALUE))
307 #undef ASM_OUTPUT_ADDR_VEC_ELT
308 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
309 fprintf (FILE, "\tlong L%%%d\n", (VALUE))
311 #undef ASM_OUTPUT_ADDR_DIFF_ELT
312 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
313 fprintf (FILE, "\tshort L%%%d-L%%%d\n", (VALUE), (REL))
315 #undef ASM_OUTPUT_ALIGN
316 #define ASM_OUTPUT_ALIGN(FILE,LOG) \
318 fprintf (FILE, "\teven\n"); \
319 else if ((LOG) != 0) \
322 #undef ASM_OUTPUT_SKIP
323 #define ASM_OUTPUT_SKIP(FILE,SIZE) \
324 fprintf (FILE, "\tspace %d\n", (SIZE))
326 /* Output a float value (represented as a C double) as an immediate operand.
327 This macro is a 68k-specific macro. */
329 #undef ASM_OUTPUT_FLOAT_OPERAND
330 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \
332 REAL_VALUE_TO_TARGET_SINGLE (r, l); \
333 /* Use hex representation even if CODE is f. as needs it. */ \
334 fprintf ((FILE), "&0x%lx", l); \
337 /* Output a double value (represented as a C double) as an immediate operand.
338 This macro is a 68k-specific macro. */
339 #undef ASM_OUTPUT_DOUBLE_OPERAND
340 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \
342 REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \
343 fprintf ((FILE), "&0x%lx%08lx", l[0], l[1]); \
348 #define PRINT_OPERAND(FILE, X, CODE) \
349 { if (CODE == '.') fprintf (FILE, "."); \
350 else if (CODE == '#') fprintf (FILE, "&"); \
351 else if (CODE == '-') fprintf (FILE, "-(%%sp)"); \
352 else if (CODE == '+') fprintf (FILE, "(%%sp)+"); \
353 else if (CODE == '@') fprintf (FILE, "(%%sp)"); \
354 else if (CODE == '!') fprintf (FILE, "%%fpcr"); \
355 else if (CODE == '/') \
356 fprintf (FILE, "%%"); \
357 else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \
358 else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \
359 else if (GET_CODE (X) == REG) \
360 fprintf (FILE, "%s", reg_names[REGNO (X)]); \
361 else if (GET_CODE (X) == MEM) \
362 output_address (XEXP (X, 0)); \
363 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \
364 { REAL_VALUE_TYPE r; long l; \
365 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \
366 REAL_VALUE_TO_TARGET_SINGLE (r, l); \
367 fprintf (FILE, "&0x%x", l); } \
368 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode) \
369 { REAL_VALUE_TYPE r; int i[2]; \
370 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \
371 REAL_VALUE_TO_TARGET_DOUBLE (r, i); \
372 fprintf (FILE, "&0x%x%08x", i[0], i[1]); } \
373 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == XFmode) \
374 { REAL_VALUE_TYPE r; \
375 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \
376 ASM_OUTPUT_LONG_DOUBLE_OPERAND (FILE, r); } \
377 else { putc ('&', FILE); output_addr_const (FILE, X); }}
380 /* Note that this contains a kludge that knows that the only reason
381 we have an address (plus (label_ref...) (reg...))
382 is in the insn before a tablejump, and we know that the table is
383 exactly 10 bytes away. */
385 #undef PRINT_OPERAND_ADDRESS
386 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
387 { register rtx reg1, reg2, breg, ireg; \
388 register rtx addr = ADDR; \
390 switch (GET_CODE (addr)) \
393 fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \
396 fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \
399 fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \
402 reg1 = 0; reg2 = 0; \
403 ireg = 0; breg = 0; \
405 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \
407 offset = XEXP (addr, 0); \
408 addr = XEXP (addr, 1); \
410 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \
412 offset = XEXP (addr, 1); \
413 addr = XEXP (addr, 0); \
415 if (GET_CODE (addr) != PLUS) ; \
416 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \
418 reg1 = XEXP (addr, 0); \
419 addr = XEXP (addr, 1); \
421 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \
423 reg1 = XEXP (addr, 1); \
424 addr = XEXP (addr, 0); \
426 else if (GET_CODE (XEXP (addr, 0)) == MULT) \
428 reg1 = XEXP (addr, 0); \
429 addr = XEXP (addr, 1); \
431 else if (GET_CODE (XEXP (addr, 1)) == MULT) \
433 reg1 = XEXP (addr, 1); \
434 addr = XEXP (addr, 0); \
436 else if (GET_CODE (XEXP (addr, 0)) == REG) \
438 reg1 = XEXP (addr, 0); \
439 addr = XEXP (addr, 1); \
441 else if (GET_CODE (XEXP (addr, 1)) == REG) \
443 reg1 = XEXP (addr, 1); \
444 addr = XEXP (addr, 0); \
446 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT \
447 || GET_CODE (addr) == SIGN_EXTEND) \
448 { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \
449 /* for OLD_INDEXING \
450 else if (GET_CODE (addr) == PLUS) \
452 if (GET_CODE (XEXP (addr, 0)) == REG) \
454 reg2 = XEXP (addr, 0); \
455 addr = XEXP (addr, 1); \
457 else if (GET_CODE (XEXP (addr, 1)) == REG) \
459 reg2 = XEXP (addr, 1); \
460 addr = XEXP (addr, 0); \
464 if (offset != 0) { if (addr != 0) abort (); addr = offset; } \
465 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \
466 || GET_CODE (reg1) == MULT)) \
467 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \
468 { breg = reg2; ireg = reg1; } \
469 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \
470 { breg = reg1; ireg = reg2; } \
471 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \
473 if (GET_CODE (ireg) == MULT) \
474 { scale = INTVAL (XEXP (ireg, 1)); \
475 ireg = XEXP (ireg, 0); } \
476 if (GET_CODE (ireg) == SIGN_EXTEND) \
477 fprintf (FILE, "10(%%pc,%s.w", \
478 reg_names[REGNO (XEXP (ireg, 0))]); \
480 fprintf (FILE, "10(%%pc,%s.l", \
481 reg_names[REGNO (ireg)]); \
482 if (scale != 1) fprintf (FILE, "*%d", scale); \
485 if (ireg != 0 || breg != 0) \
490 output_addr_const (FILE, addr); \
491 fprintf (FILE, "(%s", reg_names[REGNO (breg)]); \
494 if (ireg != 0 && GET_CODE (ireg) == MULT) \
495 { scale = INTVAL (XEXP (ireg, 1)); \
496 ireg = XEXP (ireg, 0); } \
497 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \
498 fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \
499 else if (ireg != 0) \
500 fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \
501 if (scale != 1) fprintf (FILE, "*%d", scale); \
505 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \
506 { fprintf (FILE, "10(%%pc,%s.w)", \
507 reg_names[REGNO (reg1)]); \
510 output_addr_const (FILE, addr); \
515 /* Override usual definitions of SDB output macros.
516 These definitions differ only in the absence of the period
517 at the beginning of the name of the directive
518 and in the use of `~' as the symbol for the current location. */
520 #define PUT_SDB_SCL(a) fprintf(asm_out_file, "\tscl\t%d;", (a))
521 #define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\tval\t%d;", (a))
522 #define PUT_SDB_VAL(a) \
523 ( fputs ("\tval\t", asm_out_file), \
524 output_addr_const (asm_out_file, (a)), \
525 fputc (';', asm_out_file))
527 #define PUT_SDB_DEF(a) \
528 do { fprintf (asm_out_file, "\tdef\t"); \
529 ASM_OUTPUT_LABELREF (asm_out_file, a); \
530 fprintf (asm_out_file, ";"); } while (0)
532 #define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\tdef\t~%s;",a)
533 #define PUT_SDB_ENDEF fputs("\tendef\n", asm_out_file)
534 #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\ttype\t0%o;", a)
535 #define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\tsize\t%d;", a)
536 #define PUT_SDB_START_DIM fprintf(asm_out_file, "\tdim\t")
537 #define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)
538 #define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d;", a)
540 #define PUT_SDB_TAG(a) \
541 do { fprintf (asm_out_file, "\ttag\t"); \
542 ASM_OUTPUT_LABELREF (asm_out_file, a); \
543 fprintf (asm_out_file, ";"); } while (0)
545 #define PUT_SDB_BLOCK_START(LINE) \
546 fprintf (asm_out_file, \
547 "\tdef\t~bb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n", \
550 #define PUT_SDB_BLOCK_END(LINE) \
551 fprintf (asm_out_file, \
552 "\tdef\t~eb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n", \
555 #define PUT_SDB_FUNCTION_START(LINE) \
556 fprintf (asm_out_file, \
557 "\tdef\t~bf;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n", \
560 #define PUT_SDB_FUNCTION_END(LINE) \
561 fprintf (asm_out_file, \
562 "\tdef\t~ef;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n", \
565 #define PUT_SDB_EPILOGUE_END(NAME) \
566 fprintf (asm_out_file, \
567 "\tdef\t%s;\tval\t~;\tscl\t-1;\tendef\n", \
570 #define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
571 sprintf ((BUFFER), "~%dfake", (NUMBER));
573 #define NO_DOLLAR_IN_LABEL
574 #define NO_DOT_IN_LABEL
576 /* The usual definitions don't work because neither $ nor . is allowed. */
577 #define CONSTRUCTOR_NAME_FORMAT "_GLOBAL_%%I\%%%s"
579 /* Define a few machine-specific details
580 of the implementation of constructors.
582 The __CTORS_LIST__ goes in the .init section. Define CTOR_LIST_BEGIN
583 and CTOR_LIST_END to contribute to the .init section an instruction to
584 push a word containing 0 (or some equivalent of that).
586 ASM_OUTPUT_CONSTRUCTOR should be defined
587 to push the address of the constructor. */
589 #define ASM_LONG "\tlong"
590 #undef INIT_SECTION_ASM_OP
591 #define INIT_SECTION_ASM_OP "\tsection\t~init"
592 #undef FINI_SECTION_ASM_OP
593 #define FINI_SECTION_ASM_OP "\tsection\t~fini"
594 #undef CONST_SECTION_ASM_OP
595 #define CONST_SECTION_ASM_OP "\tsection\t~rodata"
597 #define CTOR_LIST_BEGIN \
598 asm (INIT_SECTION_ASM_OP); \
600 #define CTOR_LIST_END CTOR_LIST_BEGIN
602 #define BSS_SECTION_ASM_OP "\tsection\t~bss"
604 #define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
607 fprintf (FILE, "\tmov.l &"); \
608 assemble_name (FILE, NAME); \
609 fprintf (FILE, ",-(%%sp)\n"); \