Initial revision
[official-gcc.git] / gcc / config / m68k / tower-as.h
blob46aa30a7478a32cc154e643c2ec780afc37f7fa0
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 { extern int current_function_returns_pointer; \
189 if ((current_function_returns_pointer) && \
190 ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
191 asm_fprintf (FILE, "\tmov.l %Rd0,%Ra0\n"); }
193 /* This is how to output an insn to push a register on the stack.
194 It need not be very fast code. */
196 #undef ASM_OUTPUT_REG_PUSH
197 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
198 fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[REGNO])
200 /* This is how to output an insn to pop a register from the stack.
201 It need not be very fast code. */
203 #undef ASM_OUTPUT_REG_POP
204 #define ASM_OUTPUT_REG_POP(FILE,REGNO) \
205 fprintf (FILE, "\tmov.l (%%sp)+,%s\n", reg_names[REGNO])
207 #undef ASM_FILE_START
208 #define ASM_FILE_START(FILE) \
209 ( fprintf (FILE, "#NO_APP\n"), \
210 output_file_directive ((FILE), main_input_filename))
212 #undef TEXT_SECTION_ASM_OP
213 #define TEXT_SECTION_ASM_OP "text"
215 #undef DATA_SECTION_ASM_OP
216 #define DATA_SECTION_ASM_OP "data"
218 /* This says how to output an assembler line to define a global common symbol.
219 We use SIZE rather than ROUNDED, as this is what the native cc does. */
221 #undef ASM_OUTPUT_COMMON
222 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
223 ( fputs ("\tcomm ", (FILE)), \
224 assemble_name ((FILE), (NAME)), \
225 fprintf ((FILE), ",%d\n", ((SIZE) == 0) ? (ROUNDED) : (SIZE)))
227 /* This says how to output an assembler line to define a local common symbol.
228 We use SIZE rather than ROUNDED, as this is what the native cc does. */
230 #undef ASM_OUTPUT_LOCAL
231 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
232 ( fputs ("\tlcomm ", (FILE)), \
233 assemble_name ((FILE), (NAME)), \
234 fprintf ((FILE), ",%d\n", ((SIZE) == 0) ? (ROUNDED) : (SIZE)))
236 /* Store in OUTPUT a string (made with alloca) containing
237 an assembler-name for a local static variable named NAME.
238 LABELNO is an integer which is different for each call. */
240 #undef ASM_FORMAT_PRIVATE_NAME
241 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
242 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 11), \
243 sprintf ((OUTPUT), "%s%%%%%d", (NAME), (LABELNO)))
245 /* This is the command to make the user-level label named NAME
246 defined for reference from other files. */
248 #undef GLOBAL_ASM_OP
249 #define GLOBAL_ASM_OP "global"
251 #undef ASM_GENERATE_INTERNAL_LABEL
252 #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
253 sprintf ((LABEL), "%s%%%d", (PREFIX), (NUM))
255 #undef ASM_OUTPUT_INTERNAL_LABEL
256 #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
257 fprintf ((FILE), "%s%%%d:\n", (PREFIX), (NUM))
259 #undef ASM_OUTPUT_CASE_LABEL
260 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
261 fprintf (FILE, "\tswbeg &%d\n%s%%%d:\n", \
262 XVECLEN (PATTERN (TABLE), 1), (PREFIX), (NUM)); \
264 #undef ASM_OUTPUT_DOUBLE
265 #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
266 do { long l[2]; \
267 REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \
268 fprintf (FILE, "\tlong 0x%x,0x%x\n", l[0], l[1]); \
269 } while (0)
271 #undef ASM_OUTPUT_LONG_DOUBLE
272 #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \
273 do { long l[3]; \
274 REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \
275 fprintf (FILE, "\tlong 0x%x,0x%x,0x%x\n", l[0], l[1], l[2]); \
276 } while (0)
278 #undef ASM_OUTPUT_FLOAT
279 #define ASM_OUTPUT_FLOAT(FILE,VALUE) \
280 do { long l; \
281 REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
282 fprintf ((FILE), "\tlong 0x%x\n", l); \
283 } while (0)
285 /* This is how to output an assembler line defining an `int' constant. */
287 #undef ASM_OUTPUT_INT
288 #define ASM_OUTPUT_INT(FILE,VALUE) \
289 ( fprintf (FILE, "\tlong "), \
290 output_addr_const (FILE, (VALUE)), \
291 fprintf (FILE, "\n"))
293 /* Likewise for `char' and `short' constants. */
295 #undef ASM_OUTPUT_SHORT
296 #define ASM_OUTPUT_SHORT(FILE,VALUE) \
297 ( fprintf (FILE, "\tshort "), \
298 output_addr_const (FILE, (VALUE)), \
299 fprintf (FILE, "\n"))
301 #undef ASM_OUTPUT_CHAR
302 #define ASM_OUTPUT_CHAR(FILE,VALUE) \
303 ( fprintf (FILE, "\tbyte "), \
304 output_addr_const (FILE, (VALUE)), \
305 fprintf (FILE, "\n"))
307 /* This is how to output an assembler line for a numeric constant byte. */
309 #undef ASM_OUTPUT_BYTE
310 #define ASM_OUTPUT_BYTE(FILE,VALUE) \
311 fprintf (FILE, "\tbyte 0x%x\n", (VALUE))
313 #undef ASM_OUTPUT_ADDR_VEC_ELT
314 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
315 fprintf (FILE, "\tlong L%%%d\n", (VALUE))
317 #undef ASM_OUTPUT_ADDR_DIFF_ELT
318 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
319 fprintf (FILE, "\tshort L%%%d-L%%%d\n", (VALUE), (REL))
321 #undef ASM_OUTPUT_ALIGN
322 #define ASM_OUTPUT_ALIGN(FILE,LOG) \
323 if ((LOG) == 1) \
324 fprintf (FILE, "\teven\n"); \
325 else if ((LOG) != 0) \
326 abort ();
328 #undef ASM_OUTPUT_SKIP
329 #define ASM_OUTPUT_SKIP(FILE,SIZE) \
330 fprintf (FILE, "\tspace %d\n", (SIZE))
332 /* Output a float value (represented as a C double) as an immediate operand.
333 This macro is a 68k-specific macro. */
335 #undef ASM_OUTPUT_FLOAT_OPERAND
336 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \
337 do { long l; \
338 REAL_VALUE_TO_TARGET_SINGLE (r, l); \
339 /* Use hex representation even if CODE is f. as needs it. */ \
340 fprintf ((FILE), "&0x%lx", l); \
341 } while (0)
343 /* Output a double value (represented as a C double) as an immediate operand.
344 This macro is a 68k-specific macro. */
345 #undef ASM_OUTPUT_DOUBLE_OPERAND
346 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \
347 do { long l[2]; \
348 REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \
349 fprintf ((FILE), "&0x%lx%08lx", l[0], l[1]); \
350 } while (0)
352 #if 0
353 #undef PRINT_OPERAND
354 #define PRINT_OPERAND(FILE, X, CODE) \
355 { if (CODE == '.') fprintf (FILE, "."); \
356 else if (CODE == '#') fprintf (FILE, "&"); \
357 else if (CODE == '-') fprintf (FILE, "-(%%sp)"); \
358 else if (CODE == '+') fprintf (FILE, "(%%sp)+"); \
359 else if (CODE == '@') fprintf (FILE, "(%%sp)"); \
360 else if (CODE == '!') fprintf (FILE, "%%fpcr"); \
361 else if (CODE == '/') \
362 fprintf (FILE, "%%"); \
363 else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \
364 else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \
365 else if (GET_CODE (X) == REG) \
366 fprintf (FILE, "%s", reg_names[REGNO (X)]); \
367 else if (GET_CODE (X) == MEM) \
368 output_address (XEXP (X, 0)); \
369 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \
370 { REAL_VALUE_TYPE r; long l; \
371 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \
372 REAL_VALUE_TO_TARGET_SINGLE (r, l); \
373 fprintf (FILE, "&0x%x", l); } \
374 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode) \
375 { REAL_VALUE_TYPE r; int i[2]; \
376 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \
377 REAL_VALUE_TO_TARGET_DOUBLE (r, i); \
378 fprintf (FILE, "&0x%x%08x", i[0], i[1]); } \
379 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == XFmode) \
380 { REAL_VALUE_TYPE r; \
381 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \
382 ASM_OUTPUT_LONG_DOUBLE_OPERAND (FILE, r); } \
383 else { putc ('&', FILE); output_addr_const (FILE, X); }}
384 #endif
386 /* Note that this contains a kludge that knows that the only reason
387 we have an address (plus (label_ref...) (reg...))
388 is in the insn before a tablejump, and we know that the table is
389 exactly 10 bytes away. */
391 #undef PRINT_OPERAND_ADDRESS
392 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
393 { register rtx reg1, reg2, breg, ireg; \
394 register rtx addr = ADDR; \
395 rtx offset; \
396 switch (GET_CODE (addr)) \
398 case REG: \
399 fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \
400 break; \
401 case PRE_DEC: \
402 fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \
403 break; \
404 case POST_INC: \
405 fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \
406 break; \
407 case PLUS: \
408 reg1 = 0; reg2 = 0; \
409 ireg = 0; breg = 0; \
410 offset = 0; \
411 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \
413 offset = XEXP (addr, 0); \
414 addr = XEXP (addr, 1); \
416 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \
418 offset = XEXP (addr, 1); \
419 addr = XEXP (addr, 0); \
421 if (GET_CODE (addr) != PLUS) ; \
422 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \
424 reg1 = XEXP (addr, 0); \
425 addr = XEXP (addr, 1); \
427 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \
429 reg1 = XEXP (addr, 1); \
430 addr = XEXP (addr, 0); \
432 else if (GET_CODE (XEXP (addr, 0)) == MULT) \
434 reg1 = XEXP (addr, 0); \
435 addr = XEXP (addr, 1); \
437 else if (GET_CODE (XEXP (addr, 1)) == MULT) \
439 reg1 = XEXP (addr, 1); \
440 addr = XEXP (addr, 0); \
442 else if (GET_CODE (XEXP (addr, 0)) == REG) \
444 reg1 = XEXP (addr, 0); \
445 addr = XEXP (addr, 1); \
447 else if (GET_CODE (XEXP (addr, 1)) == REG) \
449 reg1 = XEXP (addr, 1); \
450 addr = XEXP (addr, 0); \
452 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT \
453 || GET_CODE (addr) == SIGN_EXTEND) \
454 { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \
455 /* for OLD_INDEXING \
456 else if (GET_CODE (addr) == PLUS) \
458 if (GET_CODE (XEXP (addr, 0)) == REG) \
460 reg2 = XEXP (addr, 0); \
461 addr = XEXP (addr, 1); \
463 else if (GET_CODE (XEXP (addr, 1)) == REG) \
465 reg2 = XEXP (addr, 1); \
466 addr = XEXP (addr, 0); \
469 */ \
470 if (offset != 0) { if (addr != 0) abort (); addr = offset; } \
471 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \
472 || GET_CODE (reg1) == MULT)) \
473 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \
474 { breg = reg2; ireg = reg1; } \
475 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \
476 { breg = reg1; ireg = reg2; } \
477 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \
478 { int scale = 1; \
479 if (GET_CODE (ireg) == MULT) \
480 { scale = INTVAL (XEXP (ireg, 1)); \
481 ireg = XEXP (ireg, 0); } \
482 if (GET_CODE (ireg) == SIGN_EXTEND) \
483 fprintf (FILE, "10(%%pc,%s.w", \
484 reg_names[REGNO (XEXP (ireg, 0))]); \
485 else \
486 fprintf (FILE, "10(%%pc,%s.l", \
487 reg_names[REGNO (ireg)]); \
488 if (scale != 1) fprintf (FILE, "*%d", scale); \
489 putc (')', FILE); \
490 break; } \
491 if (ireg != 0 || breg != 0) \
492 { int scale = 1; \
493 if (breg == 0) \
494 abort (); \
495 if (addr != 0) \
496 output_addr_const (FILE, addr); \
497 fprintf (FILE, "(%s", reg_names[REGNO (breg)]); \
498 if (ireg != 0) \
499 putc (',', FILE); \
500 if (ireg != 0 && GET_CODE (ireg) == MULT) \
501 { scale = INTVAL (XEXP (ireg, 1)); \
502 ireg = XEXP (ireg, 0); } \
503 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \
504 fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \
505 else if (ireg != 0) \
506 fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \
507 if (scale != 1) fprintf (FILE, "*%d", scale); \
508 putc (')', FILE); \
509 break; \
511 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \
512 { fprintf (FILE, "10(%%pc,%s.w)", \
513 reg_names[REGNO (reg1)]); \
514 break; } \
515 default: \
516 output_addr_const (FILE, addr); \
521 /* Override usual definitions of SDB output macros.
522 These definitions differ only in the absence of the period
523 at the beginning of the name of the directive
524 and in the use of `~' as the symbol for the current location. */
526 #define PUT_SDB_SCL(a) fprintf(asm_out_file, "\tscl\t%d;", (a))
527 #define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\tval\t%d;", (a))
528 #define PUT_SDB_VAL(a) \
529 ( fputs ("\tval\t", asm_out_file), \
530 output_addr_const (asm_out_file, (a)), \
531 fputc (';', asm_out_file))
533 #define PUT_SDB_DEF(a) \
534 do { fprintf (asm_out_file, "\tdef\t"); \
535 ASM_OUTPUT_LABELREF (asm_out_file, a); \
536 fprintf (asm_out_file, ";"); } while (0)
538 #define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\tdef\t~%s;",a)
539 #define PUT_SDB_ENDEF fputs("\tendef\n", asm_out_file)
540 #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\ttype\t0%o;", a)
541 #define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\tsize\t%d;", a)
542 #define PUT_SDB_START_DIM fprintf(asm_out_file, "\tdim\t")
543 #define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)
544 #define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d;", a)
546 #define PUT_SDB_TAG(a) \
547 do { fprintf (asm_out_file, "\ttag\t"); \
548 ASM_OUTPUT_LABELREF (asm_out_file, a); \
549 fprintf (asm_out_file, ";"); } while (0)
551 #define PUT_SDB_BLOCK_START(LINE) \
552 fprintf (asm_out_file, \
553 "\tdef\t~bb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n", \
554 (LINE))
556 #define PUT_SDB_BLOCK_END(LINE) \
557 fprintf (asm_out_file, \
558 "\tdef\t~eb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n", \
559 (LINE))
561 #define PUT_SDB_FUNCTION_START(LINE) \
562 fprintf (asm_out_file, \
563 "\tdef\t~bf;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n", \
564 (LINE))
566 #define PUT_SDB_FUNCTION_END(LINE) \
567 fprintf (asm_out_file, \
568 "\tdef\t~ef;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n", \
569 (LINE))
571 #define PUT_SDB_EPILOGUE_END(NAME) \
572 fprintf (asm_out_file, \
573 "\tdef\t%s;\tval\t~;\tscl\t-1;\tendef\n", \
574 (NAME))
576 #define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
577 sprintf ((BUFFER), "~%dfake", (NUMBER));
579 #define NO_DOLLAR_IN_LABEL
580 #define NO_DOT_IN_LABEL
582 /* The usual definitions don't work because neither $ nor . is allowed. */
583 #define CONSTRUCTOR_NAME_FORMAT "_GLOBAL_%%I\%%%s"
585 /* Define a few machine-specific details
586 of the implementation of constructors.
588 The __CTORS_LIST__ goes in the .init section. Define CTOR_LIST_BEGIN
589 and CTOR_LIST_END to contribute to the .init section an instruction to
590 push a word containing 0 (or some equivalent of that).
592 ASM_OUTPUT_CONSTRUCTOR should be defined
593 to push the address of the constructor. */
595 #define ASM_LONG "\tlong"
596 #undef INIT_SECTION_ASM_OP
597 #define INIT_SECTION_ASM_OP "section\t~init"
598 #undef FINI_SECTION_ASM_OP
599 #define FINI_SECTION_ASM_OP "section\t~fini"
600 #undef CONST_SECTION_ASM_OP
601 #define CONST_SECTION_ASM_OP "section\t~rodata"
603 #define CTOR_LIST_BEGIN \
604 asm (INIT_SECTION_ASM_OP); \
605 asm ("clr.l -(%sp)")
606 #define CTOR_LIST_END CTOR_LIST_BEGIN
608 #define BSS_SECTION_ASM_OP "section\t~bss"
610 #define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
611 do { \
612 init_section (); \
613 fprintf (FILE, "\tmov.l &"); \
614 assemble_name (FILE, NAME); \
615 fprintf (FILE, ",-(%%sp)\n"); \
616 } while (0)