update copyrights in config dir.
[official-gcc.git] / gcc / config / m68k / tower-as.h
blobaeb5478849759997c671faf606eaf0c040377489
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 Free Software Foundation, Inc.
4 Contributed by Robert Andersson (ra@intsys.no), International Systems,
5 Oslo, Norway.
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)
12 any later version.
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
29 1.37.1 version. */
31 #include "m68k/tower.h"
32 #undef SELECT_RTX_SECTION
34 /* Use default settings for system V.3. */
36 #include "svr3.h"
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 /* This is only useful if gdb is changed, but doesn't harm anyway. */
72 #define ASM_IDENTIFY_GCC(FILE) \
73 fprintf (FILE, "gcc2_compiled%%:\n")
75 /* All the ASM_OUTPUT macros need to conform to the Tower as syntax. */
77 #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \
78 do { \
79 fprintf (FILE, "\tfile\t"); \
80 output_quoted_string (FILE, FILENAME); \
81 fprintf (FILE, "\n"); \
82 fprintf (FILE, "section ~init,\"x\"\n"); \
83 fprintf (FILE, "section ~fini,\"x\"\n"); \
84 fprintf (FILE, "section ~rodata,\"x\"\n"); \
85 fprintf (FILE, "text\n"); \
86 } while (0)
88 #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO) \
89 fprintf (FILE, "\tln\t%d\n", \
90 (sdb_begin_function_line \
91 ? last_linenum - sdb_begin_function_line : 1))
93 #undef ASM_OUTPUT_IDENT
94 #define ASM_OUTPUT_IDENT(FILE, NAME) \
95 fprintf (FILE, "\tident\t\"%s\" \n", NAME)
97 #define ASM_OUTPUT_ASCII(FILE,PTR,LEN) \
98 do { register int sp = 0, lp = 0; \
99 fprintf ((FILE), "\tbyte\t"); \
100 loop: \
101 if ((PTR)[sp] > ' ' && ! ((PTR)[sp] & 0x80) && (PTR)[sp] != '\\') \
102 { lp += 3; \
103 fprintf ((FILE), "'%c", (PTR)[sp]); } \
104 else \
105 { lp += 5; \
106 fprintf ((FILE), "0x%x", (PTR)[sp]); } \
107 if (++sp < (LEN)) \
108 { if (lp > 60) \
109 { lp = 0; \
110 fprintf ((FILE), "\n\tbyte\t"); } \
111 else \
112 putc (',', (FILE)); \
113 goto loop; } \
114 putc ('\n', (FILE)); } while (0)
116 /* Translate Motorola opcodes such as `jbeq'
117 into SGS/Tower opcodes such as `beq.w'.
118 Change `move' to `mov'.
119 Change `cmpm' to `cmp'.
120 Change `divsl' to `tdivs'.
121 Change `divul' to `tdivu'.
122 Change `ftst' to `ftest'.
123 Change `fmove' to `fmov'. */
125 #define ASM_OUTPUT_OPCODE(FILE, PTR) \
126 { if ((PTR)[0] == 'j' && (PTR)[1] == 'b') \
127 { ++(PTR); \
128 while (*(PTR) != ' ') \
129 { putc (*(PTR), (FILE)); ++(PTR); } \
130 fprintf ((FILE), ".w"); } \
131 else if ((PTR)[0] == 'm' && (PTR)[1] == 'o' \
132 && (PTR)[2] == 'v' && (PTR)[3] == 'e') \
133 { fprintf ((FILE), "mov"); (PTR) += 4; } \
134 else if ((PTR)[0] == 'c' && (PTR)[1] == 'm' \
135 && (PTR)[2] == 'p' && (PTR)[3] == 'm') \
136 { fprintf ((FILE), "cmp"); (PTR) += 4; } \
137 else if ((PTR)[0] == 'd' && (PTR)[1] == 'i' \
138 && (PTR)[2] == 'v' && (PTR)[3] == 's' \
139 && (PTR)[4] == 'l') \
140 { fprintf ((FILE), "tdivs"); (PTR) += 5; } \
141 else if ((PTR)[0] == 'd' && (PTR)[1] == 'i' \
142 && (PTR)[2] == 'v' && (PTR)[3] == 'u' \
143 && (PTR)[4] == 'l') \
144 { fprintf ((FILE), "tdivu"); (PTR) += 5; } \
145 else if ((PTR)[0] == 'f' && (PTR)[1] == 't' \
146 && (PTR)[2] == 's' && (PTR)[3] == 't') \
147 { fprintf ((FILE), "ftest"); (PTR) += 4; } \
148 else if ((PTR)[0] == 'f' && (PTR)[1] == 'm' \
149 && (PTR)[2] == 'o' && (PTR)[3] == 'v' \
150 && (PTR)[4] == 'e') \
151 { fprintf ((FILE), "fmov"); (PTR) += 5; } \
156 /* Override parts of m68k.h to fit the Tower assembler.
157 This section needs to track changes done to m68k.h in the future. */
159 #undef TARGET_VERSION
160 #define TARGET_VERSION fprintf (stderr, " (68k, Motorola/SGS/Tower32 syntax)");
162 #undef FUNCTION_BLOCK_PROFILER
163 #define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \
164 do { \
165 char label1[20], label2[20]; \
166 ASM_GENERATE_INTERNAL_LABEL (label1, "LPBX", 0); \
167 ASM_GENERATE_INTERNAL_LABEL (label2, "LPI", LABELNO); \
168 fprintf (FILE, "\ttst.l %s\n\tbne %s\n\tpea %s\n\tjsr __bb_init_func\n\taddq.l &4,%%sp\n", \
169 label1, label2, label1); \
170 ASM_OUTPUT_INTERNAL_LABEL (FILE, "LPI", LABELNO); \
171 putc ('\n', FILE); \
172 } while (0)
174 #undef BLOCK_PROFILER
175 #define BLOCK_PROFILER(FILE, BLOCKNO) \
176 do { \
177 char label[20]; \
178 ASM_GENERATE_INTERNAL_LABEL (label, "LPBX", 2); \
179 fprintf (FILE, "\taddq.l &1,%s+%d\n", label, 4 * BLOCKNO); \
180 } while (0)
182 #undef FUNCTION_PROFILER
183 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
184 fprintf (FILE, "\tmov.l &LP%%%d,%%a0\n\tjsr mcount%%\n", (LABEL_NO))
186 #undef FUNCTION_EXTRA_EPILOGUE
187 #define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \
188 { if (current_function_returns_pointer \
189 && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
190 asm_fprintf (FILE, "\tmov.l %Rd0,%Ra0\n"); }
192 /* This is how to output an insn to push a register on the stack.
193 It need not be very fast code. */
195 #undef ASM_OUTPUT_REG_PUSH
196 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
197 fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[REGNO])
199 /* This is how to output an insn to pop a register from the stack.
200 It need not be very fast code. */
202 #undef ASM_OUTPUT_REG_POP
203 #define ASM_OUTPUT_REG_POP(FILE,REGNO) \
204 fprintf (FILE, "\tmov.l (%%sp)+,%s\n", reg_names[REGNO])
206 #undef ASM_FILE_START
207 #define ASM_FILE_START(FILE) \
208 ( fprintf (FILE, "#NO_APP\n"), \
209 output_file_directive ((FILE), main_input_filename))
211 #undef TEXT_SECTION_ASM_OP
212 #define TEXT_SECTION_ASM_OP "text"
214 #undef DATA_SECTION_ASM_OP
215 #define DATA_SECTION_ASM_OP "data"
217 /* This says how to output an assembler line to define a global common symbol.
218 We use SIZE rather than ROUNDED, as this is what the native cc does. */
220 #undef ASM_OUTPUT_COMMON
221 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
222 ( fputs ("\tcomm ", (FILE)), \
223 assemble_name ((FILE), (NAME)), \
224 fprintf ((FILE), ",%d\n", ((SIZE) == 0) ? (ROUNDED) : (SIZE)))
226 /* This says how to output an assembler line to define a local common symbol.
227 We use SIZE rather than ROUNDED, as this is what the native cc does. */
229 #undef ASM_OUTPUT_LOCAL
230 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
231 ( fputs ("\tlcomm ", (FILE)), \
232 assemble_name ((FILE), (NAME)), \
233 fprintf ((FILE), ",%d\n", ((SIZE) == 0) ? (ROUNDED) : (SIZE)))
235 /* Store in OUTPUT a string (made with alloca) containing
236 an assembler-name for a local static variable named NAME.
237 LABELNO is an integer which is different for each call. */
239 #undef ASM_FORMAT_PRIVATE_NAME
240 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
241 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 11), \
242 sprintf ((OUTPUT), "%s%%%%%d", (NAME), (LABELNO)))
244 /* This is the command to make the user-level label named NAME
245 defined for reference from other files. */
247 #undef GLOBAL_ASM_OP
248 #define GLOBAL_ASM_OP "global"
250 #undef ASM_GENERATE_INTERNAL_LABEL
251 #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
252 sprintf ((LABEL), "%s%%%d", (PREFIX), (NUM))
254 #undef ASM_OUTPUT_INTERNAL_LABEL
255 #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
256 fprintf ((FILE), "%s%%%d:\n", (PREFIX), (NUM))
258 #undef ASM_OUTPUT_CASE_LABEL
259 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
260 fprintf (FILE, "\tswbeg &%d\n%s%%%d:\n", \
261 XVECLEN (PATTERN (TABLE), 1), (PREFIX), (NUM)); \
263 #undef ASM_OUTPUT_DOUBLE
264 #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
265 do { long l[2]; \
266 REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \
267 fprintf (FILE, "\tlong 0x%x,0x%x\n", l[0], l[1]); \
268 } while (0)
270 #undef ASM_OUTPUT_LONG_DOUBLE
271 #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \
272 do { long l[3]; \
273 REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \
274 fprintf (FILE, "\tlong 0x%x,0x%x,0x%x\n", l[0], l[1], l[2]); \
275 } while (0)
277 #undef ASM_OUTPUT_FLOAT
278 #define ASM_OUTPUT_FLOAT(FILE,VALUE) \
279 do { long l; \
280 REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
281 fprintf ((FILE), "\tlong 0x%x\n", l); \
282 } while (0)
284 /* This is how to output an assembler line defining an `int' constant. */
286 #undef ASM_OUTPUT_INT
287 #define ASM_OUTPUT_INT(FILE,VALUE) \
288 ( fprintf (FILE, "\tlong "), \
289 output_addr_const (FILE, (VALUE)), \
290 fprintf (FILE, "\n"))
292 /* Likewise for `char' and `short' constants. */
294 #undef ASM_OUTPUT_SHORT
295 #define ASM_OUTPUT_SHORT(FILE,VALUE) \
296 ( fprintf (FILE, "\tshort "), \
297 output_addr_const (FILE, (VALUE)), \
298 fprintf (FILE, "\n"))
300 #undef ASM_OUTPUT_CHAR
301 #define ASM_OUTPUT_CHAR(FILE,VALUE) \
302 ( fprintf (FILE, "\tbyte "), \
303 output_addr_const (FILE, (VALUE)), \
304 fprintf (FILE, "\n"))
306 /* This is how to output an assembler line for a numeric constant byte. */
308 #undef ASM_OUTPUT_BYTE
309 #define ASM_OUTPUT_BYTE(FILE,VALUE) \
310 fprintf (FILE, "\tbyte 0x%x\n", (VALUE))
312 #undef ASM_OUTPUT_ADDR_VEC_ELT
313 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
314 fprintf (FILE, "\tlong L%%%d\n", (VALUE))
316 #undef ASM_OUTPUT_ADDR_DIFF_ELT
317 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
318 fprintf (FILE, "\tshort L%%%d-L%%%d\n", (VALUE), (REL))
320 #undef ASM_OUTPUT_ALIGN
321 #define ASM_OUTPUT_ALIGN(FILE,LOG) \
322 if ((LOG) == 1) \
323 fprintf (FILE, "\teven\n"); \
324 else if ((LOG) != 0) \
325 abort ();
327 #undef ASM_OUTPUT_SKIP
328 #define ASM_OUTPUT_SKIP(FILE,SIZE) \
329 fprintf (FILE, "\tspace %d\n", (SIZE))
331 /* Output a float value (represented as a C double) as an immediate operand.
332 This macro is a 68k-specific macro. */
334 #undef ASM_OUTPUT_FLOAT_OPERAND
335 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \
336 do { long l; \
337 REAL_VALUE_TO_TARGET_SINGLE (r, l); \
338 /* Use hex representation even if CODE is f. as needs it. */ \
339 fprintf ((FILE), "&0x%lx", l); \
340 } while (0)
342 /* Output a double value (represented as a C double) as an immediate operand.
343 This macro is a 68k-specific macro. */
344 #undef ASM_OUTPUT_DOUBLE_OPERAND
345 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \
346 do { long l[2]; \
347 REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \
348 fprintf ((FILE), "&0x%lx%08lx", l[0], l[1]); \
349 } while (0)
351 #if 0
352 #undef PRINT_OPERAND
353 #define PRINT_OPERAND(FILE, X, CODE) \
354 { if (CODE == '.') fprintf (FILE, "."); \
355 else if (CODE == '#') fprintf (FILE, "&"); \
356 else if (CODE == '-') fprintf (FILE, "-(%%sp)"); \
357 else if (CODE == '+') fprintf (FILE, "(%%sp)+"); \
358 else if (CODE == '@') fprintf (FILE, "(%%sp)"); \
359 else if (CODE == '!') fprintf (FILE, "%%fpcr"); \
360 else if (CODE == '/') \
361 fprintf (FILE, "%%"); \
362 else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \
363 else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \
364 else if (GET_CODE (X) == REG) \
365 fprintf (FILE, "%s", reg_names[REGNO (X)]); \
366 else if (GET_CODE (X) == MEM) \
367 output_address (XEXP (X, 0)); \
368 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \
369 { REAL_VALUE_TYPE r; long l; \
370 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \
371 REAL_VALUE_TO_TARGET_SINGLE (r, l); \
372 fprintf (FILE, "&0x%x", l); } \
373 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode) \
374 { REAL_VALUE_TYPE r; int i[2]; \
375 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \
376 REAL_VALUE_TO_TARGET_DOUBLE (r, i); \
377 fprintf (FILE, "&0x%x%08x", i[0], i[1]); } \
378 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == XFmode) \
379 { REAL_VALUE_TYPE r; \
380 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \
381 ASM_OUTPUT_LONG_DOUBLE_OPERAND (FILE, r); } \
382 else { putc ('&', FILE); output_addr_const (FILE, X); }}
383 #endif
385 /* Note that this contains a kludge that knows that the only reason
386 we have an address (plus (label_ref...) (reg...))
387 is in the insn before a tablejump, and we know that the table is
388 exactly 10 bytes away. */
390 #undef PRINT_OPERAND_ADDRESS
391 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
392 { register rtx reg1, reg2, breg, ireg; \
393 register rtx addr = ADDR; \
394 rtx offset; \
395 switch (GET_CODE (addr)) \
397 case REG: \
398 fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \
399 break; \
400 case PRE_DEC: \
401 fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \
402 break; \
403 case POST_INC: \
404 fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \
405 break; \
406 case PLUS: \
407 reg1 = 0; reg2 = 0; \
408 ireg = 0; breg = 0; \
409 offset = 0; \
410 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \
412 offset = XEXP (addr, 0); \
413 addr = XEXP (addr, 1); \
415 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \
417 offset = XEXP (addr, 1); \
418 addr = XEXP (addr, 0); \
420 if (GET_CODE (addr) != PLUS) ; \
421 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \
423 reg1 = XEXP (addr, 0); \
424 addr = XEXP (addr, 1); \
426 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \
428 reg1 = XEXP (addr, 1); \
429 addr = XEXP (addr, 0); \
431 else if (GET_CODE (XEXP (addr, 0)) == MULT) \
433 reg1 = XEXP (addr, 0); \
434 addr = XEXP (addr, 1); \
436 else if (GET_CODE (XEXP (addr, 1)) == MULT) \
438 reg1 = XEXP (addr, 1); \
439 addr = XEXP (addr, 0); \
441 else if (GET_CODE (XEXP (addr, 0)) == REG) \
443 reg1 = XEXP (addr, 0); \
444 addr = XEXP (addr, 1); \
446 else if (GET_CODE (XEXP (addr, 1)) == REG) \
448 reg1 = XEXP (addr, 1); \
449 addr = XEXP (addr, 0); \
451 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT \
452 || GET_CODE (addr) == SIGN_EXTEND) \
453 { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \
454 /* for OLD_INDEXING \
455 else if (GET_CODE (addr) == PLUS) \
457 if (GET_CODE (XEXP (addr, 0)) == REG) \
459 reg2 = XEXP (addr, 0); \
460 addr = XEXP (addr, 1); \
462 else if (GET_CODE (XEXP (addr, 1)) == REG) \
464 reg2 = XEXP (addr, 1); \
465 addr = XEXP (addr, 0); \
468 */ \
469 if (offset != 0) { if (addr != 0) abort (); addr = offset; } \
470 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \
471 || GET_CODE (reg1) == MULT)) \
472 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \
473 { breg = reg2; ireg = reg1; } \
474 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \
475 { breg = reg1; ireg = reg2; } \
476 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \
477 { int scale = 1; \
478 if (GET_CODE (ireg) == MULT) \
479 { scale = INTVAL (XEXP (ireg, 1)); \
480 ireg = XEXP (ireg, 0); } \
481 if (GET_CODE (ireg) == SIGN_EXTEND) \
482 fprintf (FILE, "10(%%pc,%s.w", \
483 reg_names[REGNO (XEXP (ireg, 0))]); \
484 else \
485 fprintf (FILE, "10(%%pc,%s.l", \
486 reg_names[REGNO (ireg)]); \
487 if (scale != 1) fprintf (FILE, "*%d", scale); \
488 putc (')', FILE); \
489 break; } \
490 if (ireg != 0 || breg != 0) \
491 { int scale = 1; \
492 if (breg == 0) \
493 abort (); \
494 if (addr != 0) \
495 output_addr_const (FILE, addr); \
496 fprintf (FILE, "(%s", reg_names[REGNO (breg)]); \
497 if (ireg != 0) \
498 putc (',', FILE); \
499 if (ireg != 0 && GET_CODE (ireg) == MULT) \
500 { scale = INTVAL (XEXP (ireg, 1)); \
501 ireg = XEXP (ireg, 0); } \
502 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \
503 fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \
504 else if (ireg != 0) \
505 fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \
506 if (scale != 1) fprintf (FILE, "*%d", scale); \
507 putc (')', FILE); \
508 break; \
510 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \
511 { fprintf (FILE, "10(%%pc,%s.w)", \
512 reg_names[REGNO (reg1)]); \
513 break; } \
514 default: \
515 output_addr_const (FILE, addr); \
520 /* Override usual definitions of SDB output macros.
521 These definitions differ only in the absence of the period
522 at the beginning of the name of the directive
523 and in the use of `~' as the symbol for the current location. */
525 #define PUT_SDB_SCL(a) fprintf(asm_out_file, "\tscl\t%d;", (a))
526 #define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\tval\t%d;", (a))
527 #define PUT_SDB_VAL(a) \
528 ( fputs ("\tval\t", asm_out_file), \
529 output_addr_const (asm_out_file, (a)), \
530 fputc (';', asm_out_file))
532 #define PUT_SDB_DEF(a) \
533 do { fprintf (asm_out_file, "\tdef\t"); \
534 ASM_OUTPUT_LABELREF (asm_out_file, a); \
535 fprintf (asm_out_file, ";"); } while (0)
537 #define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\tdef\t~%s;",a)
538 #define PUT_SDB_ENDEF fputs("\tendef\n", asm_out_file)
539 #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\ttype\t0%o;", a)
540 #define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\tsize\t%d;", a)
541 #define PUT_SDB_START_DIM fprintf(asm_out_file, "\tdim\t")
542 #define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)
543 #define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d;", a)
545 #define PUT_SDB_TAG(a) \
546 do { fprintf (asm_out_file, "\ttag\t"); \
547 ASM_OUTPUT_LABELREF (asm_out_file, a); \
548 fprintf (asm_out_file, ";"); } while (0)
550 #define PUT_SDB_BLOCK_START(LINE) \
551 fprintf (asm_out_file, \
552 "\tdef\t~bb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n", \
553 (LINE))
555 #define PUT_SDB_BLOCK_END(LINE) \
556 fprintf (asm_out_file, \
557 "\tdef\t~eb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n", \
558 (LINE))
560 #define PUT_SDB_FUNCTION_START(LINE) \
561 fprintf (asm_out_file, \
562 "\tdef\t~bf;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n", \
563 (LINE))
565 #define PUT_SDB_FUNCTION_END(LINE) \
566 fprintf (asm_out_file, \
567 "\tdef\t~ef;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n", \
568 (LINE))
570 #define PUT_SDB_EPILOGUE_END(NAME) \
571 fprintf (asm_out_file, \
572 "\tdef\t%s;\tval\t~;\tscl\t-1;\tendef\n", \
573 (NAME))
575 #define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
576 sprintf ((BUFFER), "~%dfake", (NUMBER));
578 #define NO_DOLLAR_IN_LABEL
579 #define NO_DOT_IN_LABEL
581 /* The usual definitions don't work because neither $ nor . is allowed. */
582 #define CONSTRUCTOR_NAME_FORMAT "_GLOBAL_%%I\%%%s"
584 /* Define a few machine-specific details
585 of the implementation of constructors.
587 The __CTORS_LIST__ goes in the .init section. Define CTOR_LIST_BEGIN
588 and CTOR_LIST_END to contribute to the .init section an instruction to
589 push a word containing 0 (or some equivalent of that).
591 ASM_OUTPUT_CONSTRUCTOR should be defined
592 to push the address of the constructor. */
594 #define ASM_LONG "\tlong"
595 #undef INIT_SECTION_ASM_OP
596 #define INIT_SECTION_ASM_OP "section\t~init"
597 #undef FINI_SECTION_ASM_OP
598 #define FINI_SECTION_ASM_OP "section\t~fini"
599 #undef CONST_SECTION_ASM_OP
600 #define CONST_SECTION_ASM_OP "section\t~rodata"
602 #define CTOR_LIST_BEGIN \
603 asm (INIT_SECTION_ASM_OP); \
604 asm ("clr.l -(%sp)")
605 #define CTOR_LIST_END CTOR_LIST_BEGIN
607 #define BSS_SECTION_ASM_OP "section\t~bss"
609 #define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
610 do { \
611 init_section (); \
612 fprintf (FILE, "\tmov.l &"); \
613 assemble_name (FILE, NAME); \
614 fprintf (FILE, ",-(%%sp)\n"); \
615 } while (0)