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 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 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 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 /* Store in OUTPUT a string (made with alloca) containing 214 an assembler-name for a local static variable named NAME. 215 LABELNO is an integer which is different for each call. */ 216 217 #undef ASM_FORMAT_PRIVATE_NAME 218 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ 219 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 11), \ 220 sprintf ((OUTPUT), "%s%%%%%d", (NAME), (LABELNO))) 221 222 /* This is the command to make the user-level label named NAME 223 defined for reference from other files. */ 224 225 #undef GLOBAL_ASM_OP 226 #define GLOBAL_ASM_OP "\tglobal\t" 227 228 #undef ASM_GENERATE_INTERNAL_LABEL 229 #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ 230 sprintf ((LABEL), "%s%%%ld", (PREFIX), (long)(NUM)) 231 232 #undef ASM_OUTPUT_INTERNAL_LABEL 233 #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ 234 fprintf ((FILE), "%s%%%d:\n", (PREFIX), (NUM)) 235 236 #undef ASM_OUTPUT_CASE_LABEL 237 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \ 238 fprintf (FILE, "\tswbeg &%d\n%s%%%d:\n", \ 239 XVECLEN (PATTERN (TABLE), 1), (PREFIX), (NUM)); \ 240 241 #undef ASM_OUTPUT_ADDR_VEC_ELT 242 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ 243 fprintf (FILE, "\tlong L%%%d\n", (VALUE)) 244 245 #undef ASM_OUTPUT_ADDR_DIFF_ELT 246 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ 247 fprintf (FILE, "\tshort L%%%d-L%%%d\n", (VALUE), (REL)) 248 249 #undef ASM_OUTPUT_ALIGN 250 #define ASM_OUTPUT_ALIGN(FILE,LOG) \ 251 do { \ 252 if ((LOG) == 1) \ 253 fprintf (FILE, "\teven\n"); \ 254 else if ((LOG) != 0) \ 255 abort (); \ 256 } while (0) 257 258 #undef ASM_OUTPUT_SKIP 259 #define ASM_OUTPUT_SKIP(FILE,SIZE) \ 260 fprintf (FILE, "\tspace %d\n", (SIZE)) 261 262 /* Output a float value (represented as a C double) as an immediate operand. 263 This macro is a 68k-specific macro. */ 264 265 #undef ASM_OUTPUT_FLOAT_OPERAND 266 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \ 267 do { long l; \ 268 REAL_VALUE_TO_TARGET_SINGLE (r, l); \ 269 /* Use hex representation even if CODE is f. as needs it. */ \ 270 fprintf ((FILE), "&0x%lx", l); \ 271 } while (0) 272 273 /* Output a double value (represented as a C double) as an immediate operand. 274 This macro is a 68k-specific macro. */ 275 #undef ASM_OUTPUT_DOUBLE_OPERAND 276 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \ 277 do { long l[2]; \ 278 REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \ 279 fprintf ((FILE), "&0x%lx%08lx", l[0], l[1]); \ 280 } while (0) 281 282 #if 0 283 #undef PRINT_OPERAND 284 #define PRINT_OPERAND(FILE, X, CODE) \ 285 { if (CODE == '.') fprintf (FILE, "."); \ 286 else if (CODE == '#') fprintf (FILE, "&"); \ 287 else if (CODE == '-') fprintf (FILE, "-(%%sp)"); \ 288 else if (CODE == '+') fprintf (FILE, "(%%sp)+"); \ 289 else if (CODE == '@') fprintf (FILE, "(%%sp)"); \ 290 else if (CODE == '!') fprintf (FILE, "%%fpcr"); \ 291 else if (CODE == '/') \ 292 fprintf (FILE, "%%"); \ 293 else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \ 294 else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \ 295 else if (GET_CODE (X) == REG) \ 296 fprintf (FILE, "%s", reg_names[REGNO (X)]); \ 297 else if (GET_CODE (X) == MEM) \ 298 output_address (XEXP (X, 0)); \ 299 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \ 300 { REAL_VALUE_TYPE r; long l; \ 301 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \ 302 REAL_VALUE_TO_TARGET_SINGLE (r, l); \ 303 fprintf (FILE, "&0x%lx", l); } \ 304 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode) \ 305 { REAL_VALUE_TYPE r; int i[2]; \ 306 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \ 307 REAL_VALUE_TO_TARGET_DOUBLE (r, i); \ 308 fprintf (FILE, "&0x%x%08x", i[0], i[1]); } \ 309 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == XFmode) \ 310 { REAL_VALUE_TYPE r; \ 311 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \ 312 ASM_OUTPUT_LONG_DOUBLE_OPERAND (FILE, r); } \ 313 else { putc ('&', FILE); output_addr_const (FILE, X); }} 314 #endif 315 316 /* Note that this contains a kludge that knows that the only reason 317 we have an address (plus (label_ref...) (reg...)) 318 is in the insn before a tablejump, and we know that the table is 319 exactly 10 bytes away. */ 320 321 #undef PRINT_OPERAND_ADDRESS 322 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ 323 { register rtx reg1, reg2, breg, ireg; \ 324 register rtx addr = ADDR; \ 325 rtx offset; \ 326 switch (GET_CODE (addr)) \ 327 { \ 328 case REG: \ 329 fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \ 330 break; \ 331 case PRE_DEC: \ 332 fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \ 333 break; \ 334 case POST_INC: \ 335 fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \ 336 break; \ 337 case PLUS: \ 338 reg1 = 0; reg2 = 0; \ 339 ireg = 0; breg = 0; \ 340 offset = 0; \ 341 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \ 342 { \ 343 offset = XEXP (addr, 0); \ 344 addr = XEXP (addr, 1); \ 345 } \ 346 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \ 347 { \ 348 offset = XEXP (addr, 1); \ 349 addr = XEXP (addr, 0); \ 350 } \ 351 if (GET_CODE (addr) != PLUS) ; \ 352 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \ 353 { \ 354 reg1 = XEXP (addr, 0); \ 355 addr = XEXP (addr, 1); \ 356 } \ 357 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \ 358 { \ 359 reg1 = XEXP (addr, 1); \ 360 addr = XEXP (addr, 0); \ 361 } \ 362 else if (GET_CODE (XEXP (addr, 0)) == MULT) \ 363 { \ 364 reg1 = XEXP (addr, 0); \ 365 addr = XEXP (addr, 1); \ 366 } \ 367 else if (GET_CODE (XEXP (addr, 1)) == MULT) \ 368 { \ 369 reg1 = XEXP (addr, 1); \ 370 addr = XEXP (addr, 0); \ 371 } \ 372 else if (GET_CODE (XEXP (addr, 0)) == REG) \ 373 { \ 374 reg1 = XEXP (addr, 0); \ 375 addr = XEXP (addr, 1); \ 376 } \ 377 else if (GET_CODE (XEXP (addr, 1)) == REG) \ 378 { \ 379 reg1 = XEXP (addr, 1); \ 380 addr = XEXP (addr, 0); \ 381 } \ 382 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT \ 383 || GET_CODE (addr) == SIGN_EXTEND) \ 384 { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \ 385 /* for OLD_INDEXING \ 386 else if (GET_CODE (addr) == PLUS) \ 387 { \ 388 if (GET_CODE (XEXP (addr, 0)) == REG) \ 389 { \ 390 reg2 = XEXP (addr, 0); \ 391 addr = XEXP (addr, 1); \ 392 } \ 393 else if (GET_CODE (XEXP (addr, 1)) == REG) \ 394 { \ 395 reg2 = XEXP (addr, 1); \ 396 addr = XEXP (addr, 0); \ 397 } \ 398 } \ 399 */ \ 400 if (offset != 0) { if (addr != 0) abort (); addr = offset; } \ 401 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \ 402 || GET_CODE (reg1) == MULT)) \ 403 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \ 404 { breg = reg2; ireg = reg1; } \ 405 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \ 406 { breg = reg1; ireg = reg2; } \ 407 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \ 408 { int scale = 1; \ 409 if (GET_CODE (ireg) == MULT) \ 410 { scale = INTVAL (XEXP (ireg, 1)); \ 411 ireg = XEXP (ireg, 0); } \ 412 if (GET_CODE (ireg) == SIGN_EXTEND) \ 413 fprintf (FILE, "10(%%pc,%s.w", \ 414 reg_names[REGNO (XEXP (ireg, 0))]); \ 415 else \ 416 fprintf (FILE, "10(%%pc,%s.l", \ 417 reg_names[REGNO (ireg)]); \ 418 if (scale != 1) fprintf (FILE, "*%d", scale); \ 419 putc (')', FILE); \ 420 break; } \ 421 if (ireg != 0 || breg != 0) \ 422 { int scale = 1; \ 423 if (breg == 0) \ 424 abort (); \ 425 if (addr != 0) \ 426 output_addr_const (FILE, addr); \ 427 fprintf (FILE, "(%s", reg_names[REGNO (breg)]); \ 428 if (ireg != 0) \ 429 putc (',', FILE); \ 430 if (ireg != 0 && GET_CODE (ireg) == MULT) \ 431 { scale = INTVAL (XEXP (ireg, 1)); \ 432 ireg = XEXP (ireg, 0); } \ 433 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \ 434 fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \ 435 else if (ireg != 0) \ 436 fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \ 437 if (scale != 1) fprintf (FILE, "*%d", scale); \ 438 putc (')', FILE); \ 439 break; \ 440 } \ 441 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \ 442 { fprintf (FILE, "10(%%pc,%s.w)", \ 443 reg_names[REGNO (reg1)]); \ 444 break; } \ 445 default: \ 446 output_addr_const (FILE, addr); \ 447 }} 448 449 450 451 /* Override usual definitions of SDB output macros. 452 These definitions differ only in the absence of the period 453 at the beginning of the name of the directive 454 and in the use of `~' as the symbol for the current location. */ 455 456 #define PUT_SDB_SCL(a) fprintf(asm_out_file, "\tscl\t%d;", (a)) 457 #define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\tval\t%d;", (a)) 458 #define PUT_SDB_VAL(a) \ 459 ( fputs ("\tval\t", asm_out_file), \ 460 output_addr_const (asm_out_file, (a)), \ 461 fputc (';', asm_out_file)) 462 463 #define PUT_SDB_DEF(a) \ 464 do { fprintf (asm_out_file, "\tdef\t"); \ 465 ASM_OUTPUT_LABELREF (asm_out_file, a); \ 466 fprintf (asm_out_file, ";"); } while (0) 467 468 #define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\tdef\t~%s;",a) 469 #define PUT_SDB_ENDEF fputs("\tendef\n", asm_out_file) 470 #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\ttype\t0%o;", a) 471 #define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\tsize\t%d;", a) 472 #define PUT_SDB_START_DIM fprintf(asm_out_file, "\tdim\t") 473 #define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a) 474 #define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d;", a) 475 476 #define PUT_SDB_TAG(a) \ 477 do { fprintf (asm_out_file, "\ttag\t"); \ 478 ASM_OUTPUT_LABELREF (asm_out_file, a); \ 479 fprintf (asm_out_file, ";"); } while (0) 480 481 #define PUT_SDB_BLOCK_START(LINE) \ 482 fprintf (asm_out_file, \ 483 "\tdef\t~bb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n", \ 484 (LINE)) 485 486 #define PUT_SDB_BLOCK_END(LINE) \ 487 fprintf (asm_out_file, \ 488 "\tdef\t~eb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n", \ 489 (LINE)) 490 491 #define PUT_SDB_FUNCTION_START(LINE) \ 492 fprintf (asm_out_file, \ 493 "\tdef\t~bf;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n", \ 494 (LINE)) 495 496 #define PUT_SDB_FUNCTION_END(LINE) \ 497 fprintf (asm_out_file, \ 498 "\tdef\t~ef;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n", \ 499 (LINE)) 500 501 #define PUT_SDB_EPILOGUE_END(NAME) \ 502 fprintf (asm_out_file, \ 503 "\tdef\t%s;\tval\t~;\tscl\t-1;\tendef\n", \ 504 (NAME)) 505 506 #define SDB_GENERATE_FAKE(BUFFER, NUMBER) \ 507 sprintf ((BUFFER), "~%dfake", (NUMBER)); 508 509 #define NO_DOLLAR_IN_LABEL 510 #define NO_DOT_IN_LABEL 511 512 /* The usual definitions don't work because neither $ nor . is allowed. */ 513 #define CONSTRUCTOR_NAME_FORMAT "_GLOBAL_%%I\%%%s" 514 515 /* Define a few machine-specific details 516 of the implementation of constructors. 517 518 The __CTORS_LIST__ goes in the .init section. Define CTOR_LIST_BEGIN 519 and CTOR_LIST_END to contribute to the .init section an instruction to 520 push a word containing 0 (or some equivalent of that). */ 521 522 #undef INIT_SECTION_ASM_OP 523 #define INIT_SECTION_ASM_OP "\tsection\t~init" 524 #undef FINI_SECTION_ASM_OP 525 #define FINI_SECTION_ASM_OP "\tsection\t~fini" 526 #undef READONLY_DATA_SECTION_ASM_OP 527 #define READONLY_DATA_SECTION_ASM_OP "\tsection\t~rodata" 528 529 #define CTOR_LIST_BEGIN \ 530 asm (INIT_SECTION_ASM_OP); \ 531 asm ("clr.l -(%sp)") 532 #define CTOR_LIST_END CTOR_LIST_BEGIN 533 534 #define BSS_SECTION_ASM_OP "\tsection\t~bss" 535 536 #define TARGET_ASM_CONSTRUCTOR m68k_svr3_asm_out_constructor 537