00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "flags.h"
00027 #include "tree.h"
00028 #include "rtl.h"
00029 #include "output.h"
00030 #include "target.h"
00031 #include "dwarf2asm.h"
00032 #include "dwarf2.h"
00033 #include "splay-tree.h"
00034 #include "ggc.h"
00035 #include "tm_p.h"
00036
00037
00038
00039 #ifndef ASM_COMMENT_START
00040 #define ASM_COMMENT_START ";#"
00041 #endif
00042
00043
00044
00045
00046
00047 void
00048 dw2_assemble_integer (int size, rtx x)
00049 {
00050 const char *op = integer_asm_op (size, FALSE);
00051
00052 if (op)
00053 {
00054 fputs (op, asm_out_file);
00055 if (GET_CODE (x) == CONST_INT)
00056 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
00057 else
00058 output_addr_const (asm_out_file, x);
00059 }
00060 else
00061 assemble_integer (x, size, BITS_PER_UNIT, 1);
00062 }
00063
00064
00065
00066
00067 void
00068 dw2_asm_output_data (int size, unsigned HOST_WIDE_INT value,
00069 const char *comment, ...)
00070 {
00071 va_list ap;
00072
00073 va_start (ap, comment);
00074
00075 if (size * 8 < HOST_BITS_PER_WIDE_INT)
00076 value &= ~(~(unsigned HOST_WIDE_INT) 0 << (size * 8));
00077
00078 dw2_assemble_integer (size, GEN_INT (value));
00079
00080 if (flag_debug_asm && comment)
00081 {
00082 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
00083 vfprintf (asm_out_file, comment, ap);
00084 }
00085 fputc ('\n', asm_out_file);
00086
00087 va_end (ap);
00088 }
00089
00090
00091
00092
00093
00094
00095
00096 void
00097 dw2_asm_output_delta (int size, const char *lab1, const char *lab2,
00098 const char *comment, ...)
00099 {
00100 va_list ap;
00101
00102 va_start (ap, comment);
00103
00104 #ifdef ASM_OUTPUT_DWARF_DELTA
00105 ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2);
00106 #else
00107 dw2_assemble_integer (size,
00108 gen_rtx_MINUS (Pmode,
00109 gen_rtx_SYMBOL_REF (Pmode, lab1),
00110 gen_rtx_SYMBOL_REF (Pmode, lab2)));
00111 #endif
00112 if (flag_debug_asm && comment)
00113 {
00114 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
00115 vfprintf (asm_out_file, comment, ap);
00116 }
00117 fputc ('\n', asm_out_file);
00118
00119 va_end (ap);
00120 }
00121
00122
00123
00124
00125
00126
00127
00128 void
00129 dw2_asm_output_offset (int size, const char *label,
00130 const char *comment, ...)
00131 {
00132 va_list ap;
00133
00134 va_start (ap, comment);
00135
00136 #ifdef ASM_OUTPUT_DWARF_OFFSET
00137 ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label);
00138 #else
00139 dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
00140 #endif
00141
00142 if (flag_debug_asm && comment)
00143 {
00144 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
00145 vfprintf (asm_out_file, comment, ap);
00146 }
00147 fputc ('\n', asm_out_file);
00148
00149 va_end (ap);
00150 }
00151
00152 #if 0
00153
00154
00155
00156
00157 void
00158 dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED,
00159 const char *label ATTRIBUTE_UNUSED,
00160 const char *comment, ...)
00161 {
00162 va_list ap;
00163
00164 va_start (ap, comment);
00165
00166 #ifdef ASM_OUTPUT_DWARF_PCREL
00167 ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label);
00168 #else
00169 dw2_assemble_integer (size,
00170 gen_rtx_MINUS (Pmode,
00171 gen_rtx_SYMBOL_REF (Pmode, label),
00172 pc_rtx));
00173 #endif
00174
00175 if (flag_debug_asm && comment)
00176 {
00177 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
00178 vfprintf (asm_out_file, comment, ap);
00179 }
00180 fputc ('\n', asm_out_file);
00181
00182 va_end (ap);
00183 }
00184 #endif
00185
00186
00187
00188 void
00189 dw2_asm_output_addr (int size, const char *label,
00190 const char *comment, ...)
00191 {
00192 va_list ap;
00193
00194 va_start (ap, comment);
00195
00196 dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
00197
00198 if (flag_debug_asm && comment)
00199 {
00200 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
00201 vfprintf (asm_out_file, comment, ap);
00202 }
00203 fputc ('\n', asm_out_file);
00204
00205 va_end (ap);
00206 }
00207
00208
00209
00210 void
00211 dw2_asm_output_addr_rtx (int size, rtx addr,
00212 const char *comment, ...)
00213 {
00214 va_list ap;
00215
00216 va_start (ap, comment);
00217
00218 dw2_assemble_integer (size, addr);
00219
00220 if (flag_debug_asm && comment)
00221 {
00222 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
00223 vfprintf (asm_out_file, comment, ap);
00224 }
00225 fputc ('\n', asm_out_file);
00226
00227 va_end (ap);
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237 void
00238 dw2_asm_output_nstring (const char *str, size_t orig_len,
00239 const char *comment, ...)
00240 {
00241 size_t i, len;
00242 va_list ap;
00243
00244 va_start (ap, comment);
00245
00246 len = orig_len;
00247
00248 if (len == (size_t) -1)
00249 len = strlen (str);
00250
00251 if (flag_debug_asm && comment)
00252 {
00253 fputs ("\t.ascii \"", asm_out_file);
00254 for (i = 0; i < len; i++)
00255 {
00256 int c = str[i];
00257 if (c == '\"' || c == '\\')
00258 fputc ('\\', asm_out_file);
00259 if (ISPRINT(c))
00260 fputc (c, asm_out_file);
00261 else
00262 fprintf (asm_out_file, "\\%o", c);
00263 }
00264 fprintf (asm_out_file, "\\0\"\t%s ", ASM_COMMENT_START);
00265 vfprintf (asm_out_file, comment, ap);
00266 fputc ('\n', asm_out_file);
00267 }
00268 else
00269 {
00270
00271
00272 if (orig_len == (size_t) -1)
00273 len += 1;
00274 ASM_OUTPUT_ASCII (asm_out_file, str, len);
00275 if (orig_len != (size_t) -1)
00276 assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1);
00277 }
00278
00279 va_end (ap);
00280 }
00281
00282
00283
00284
00285 int
00286 size_of_uleb128 (unsigned HOST_WIDE_INT value)
00287 {
00288 int size = 0;
00289
00290 do
00291 {
00292 value >>= 7;
00293 size += 1;
00294 }
00295 while (value != 0);
00296
00297 return size;
00298 }
00299
00300
00301
00302 int
00303 size_of_sleb128 (HOST_WIDE_INT value)
00304 {
00305 int size = 0, byte;
00306
00307 do
00308 {
00309 byte = (value & 0x7f);
00310 value >>= 7;
00311 size += 1;
00312 }
00313 while (!((value == 0 && (byte & 0x40) == 0)
00314 || (value == -1 && (byte & 0x40) != 0)));
00315
00316 return size;
00317 }
00318
00319
00320
00321
00322
00323 int
00324 size_of_encoded_value (int encoding)
00325 {
00326 if (encoding == DW_EH_PE_omit)
00327 return 0;
00328
00329 switch (encoding & 0x07)
00330 {
00331 case DW_EH_PE_absptr:
00332 return POINTER_SIZE / BITS_PER_UNIT;
00333 case DW_EH_PE_udata2:
00334 return 2;
00335 case DW_EH_PE_udata4:
00336 return 4;
00337 case DW_EH_PE_udata8:
00338 return 8;
00339 default:
00340 gcc_unreachable ();
00341 }
00342 }
00343
00344
00345
00346 const char *
00347 eh_data_format_name (int format)
00348 {
00349 #if HAVE_DESIGNATED_INITIALIZERS
00350 #define S(p, v) [p] = v,
00351 #else
00352 #define S(p, v) case p: return v;
00353 #endif
00354
00355 #if HAVE_DESIGNATED_INITIALIZERS
00356 __extension__ static const char * const format_names[256] = {
00357 #else
00358 switch (format) {
00359 #endif
00360
00361 S(DW_EH_PE_absptr, "absolute")
00362 S(DW_EH_PE_omit, "omit")
00363 S(DW_EH_PE_aligned, "aligned absolute")
00364
00365 S(DW_EH_PE_uleb128, "uleb128")
00366 S(DW_EH_PE_udata2, "udata2")
00367 S(DW_EH_PE_udata4, "udata4")
00368 S(DW_EH_PE_udata8, "udata8")
00369 S(DW_EH_PE_sleb128, "sleb128")
00370 S(DW_EH_PE_sdata2, "sdata2")
00371 S(DW_EH_PE_sdata4, "sdata4")
00372 S(DW_EH_PE_sdata8, "sdata8")
00373
00374 S(DW_EH_PE_absptr | DW_EH_PE_pcrel, "pcrel")
00375 S(DW_EH_PE_uleb128 | DW_EH_PE_pcrel, "pcrel uleb128")
00376 S(DW_EH_PE_udata2 | DW_EH_PE_pcrel, "pcrel udata2")
00377 S(DW_EH_PE_udata4 | DW_EH_PE_pcrel, "pcrel udata4")
00378 S(DW_EH_PE_udata8 | DW_EH_PE_pcrel, "pcrel udata8")
00379 S(DW_EH_PE_sleb128 | DW_EH_PE_pcrel, "pcrel sleb128")
00380 S(DW_EH_PE_sdata2 | DW_EH_PE_pcrel, "pcrel sdata2")
00381 S(DW_EH_PE_sdata4 | DW_EH_PE_pcrel, "pcrel sdata4")
00382 S(DW_EH_PE_sdata8 | DW_EH_PE_pcrel, "pcrel sdata8")
00383
00384 S(DW_EH_PE_absptr | DW_EH_PE_textrel, "textrel")
00385 S(DW_EH_PE_uleb128 | DW_EH_PE_textrel, "textrel uleb128")
00386 S(DW_EH_PE_udata2 | DW_EH_PE_textrel, "textrel udata2")
00387 S(DW_EH_PE_udata4 | DW_EH_PE_textrel, "textrel udata4")
00388 S(DW_EH_PE_udata8 | DW_EH_PE_textrel, "textrel udata8")
00389 S(DW_EH_PE_sleb128 | DW_EH_PE_textrel, "textrel sleb128")
00390 S(DW_EH_PE_sdata2 | DW_EH_PE_textrel, "textrel sdata2")
00391 S(DW_EH_PE_sdata4 | DW_EH_PE_textrel, "textrel sdata4")
00392 S(DW_EH_PE_sdata8 | DW_EH_PE_textrel, "textrel sdata8")
00393
00394 S(DW_EH_PE_absptr | DW_EH_PE_datarel, "datarel")
00395 S(DW_EH_PE_uleb128 | DW_EH_PE_datarel, "datarel uleb128")
00396 S(DW_EH_PE_udata2 | DW_EH_PE_datarel, "datarel udata2")
00397 S(DW_EH_PE_udata4 | DW_EH_PE_datarel, "datarel udata4")
00398 S(DW_EH_PE_udata8 | DW_EH_PE_datarel, "datarel udata8")
00399 S(DW_EH_PE_sleb128 | DW_EH_PE_datarel, "datarel sleb128")
00400 S(DW_EH_PE_sdata2 | DW_EH_PE_datarel, "datarel sdata2")
00401 S(DW_EH_PE_sdata4 | DW_EH_PE_datarel, "datarel sdata4")
00402 S(DW_EH_PE_sdata8 | DW_EH_PE_datarel, "datarel sdata8")
00403
00404 S(DW_EH_PE_absptr | DW_EH_PE_funcrel, "funcrel")
00405 S(DW_EH_PE_uleb128 | DW_EH_PE_funcrel, "funcrel uleb128")
00406 S(DW_EH_PE_udata2 | DW_EH_PE_funcrel, "funcrel udata2")
00407 S(DW_EH_PE_udata4 | DW_EH_PE_funcrel, "funcrel udata4")
00408 S(DW_EH_PE_udata8 | DW_EH_PE_funcrel, "funcrel udata8")
00409 S(DW_EH_PE_sleb128 | DW_EH_PE_funcrel, "funcrel sleb128")
00410 S(DW_EH_PE_sdata2 | DW_EH_PE_funcrel, "funcrel sdata2")
00411 S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4")
00412 S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8")
00413
00414 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel,
00415 "indirect pcrel")
00416 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel,
00417 "indirect pcrel uleb128")
00418 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_pcrel,
00419 "indirect pcrel udata2")
00420 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_pcrel,
00421 "indirect pcrel udata4")
00422 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_pcrel,
00423 "indirect pcrel udata8")
00424 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_pcrel,
00425 "indirect pcrel sleb128")
00426 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_pcrel,
00427 "indirect pcrel sdata2")
00428 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_pcrel,
00429 "indirect pcrel sdata4")
00430 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_pcrel,
00431 "indirect pcrel sdata8")
00432
00433 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_textrel,
00434 "indirect textrel")
00435 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_textrel,
00436 "indirect textrel uleb128")
00437 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_textrel,
00438 "indirect textrel udata2")
00439 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_textrel,
00440 "indirect textrel udata4")
00441 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_textrel,
00442 "indirect textrel udata8")
00443 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_textrel,
00444 "indirect textrel sleb128")
00445 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_textrel,
00446 "indirect textrel sdata2")
00447 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_textrel,
00448 "indirect textrel sdata4")
00449 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_textrel,
00450 "indirect textrel sdata8")
00451
00452 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_datarel,
00453 "indirect datarel")
00454 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_datarel,
00455 "indirect datarel uleb128")
00456 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_datarel,
00457 "indirect datarel udata2")
00458 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_datarel,
00459 "indirect datarel udata4")
00460 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_datarel,
00461 "indirect datarel udata8")
00462 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_datarel,
00463 "indirect datarel sleb128")
00464 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_datarel,
00465 "indirect datarel sdata2")
00466 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_datarel,
00467 "indirect datarel sdata4")
00468 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_datarel,
00469 "indirect datarel sdata8")
00470
00471 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_funcrel,
00472 "indirect funcrel")
00473 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_funcrel,
00474 "indirect funcrel uleb128")
00475 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_funcrel,
00476 "indirect funcrel udata2")
00477 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_funcrel,
00478 "indirect funcrel udata4")
00479 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_funcrel,
00480 "indirect funcrel udata8")
00481 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_funcrel,
00482 "indirect funcrel sleb128")
00483 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_funcrel,
00484 "indirect funcrel sdata2")
00485 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_funcrel,
00486 "indirect funcrel sdata4")
00487 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_funcrel,
00488 "indirect funcrel sdata8")
00489
00490 #if HAVE_DESIGNATED_INITIALIZERS
00491 };
00492
00493 gcc_assert (format >= 0 && format < 0x100 && format_names[format]);
00494
00495 return format_names[format];
00496 #else
00497 }
00498 gcc_unreachable ();
00499 #endif
00500 }
00501
00502
00503
00504 void
00505 dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value,
00506 const char *comment, ...)
00507 {
00508 va_list ap;
00509
00510 va_start (ap, comment);
00511
00512 #ifdef HAVE_AS_LEB128
00513 fprintf (asm_out_file, "\t.uleb128 " HOST_WIDE_INT_PRINT_HEX , value);
00514
00515 if (flag_debug_asm && comment)
00516 {
00517 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
00518 vfprintf (asm_out_file, comment, ap);
00519 }
00520 #else
00521 {
00522 unsigned HOST_WIDE_INT work = value;
00523 const char *byte_op = targetm.asm_out.byte_op;
00524
00525 if (byte_op)
00526 fputs (byte_op, asm_out_file);
00527 do
00528 {
00529 int byte = (work & 0x7f);
00530 work >>= 7;
00531 if (work != 0)
00532
00533 byte |= 0x80;
00534
00535 if (byte_op)
00536 {
00537 fprintf (asm_out_file, "0x%x", byte);
00538 if (work != 0)
00539 fputc (',', asm_out_file);
00540 }
00541 else
00542 assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
00543 }
00544 while (work != 0);
00545
00546 if (flag_debug_asm)
00547 {
00548 fprintf (asm_out_file, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX,
00549 ASM_COMMENT_START, value);
00550 if (comment)
00551 {
00552 fputs ("; ", asm_out_file);
00553 vfprintf (asm_out_file, comment, ap);
00554 }
00555 }
00556 }
00557 #endif
00558 fputc ('\n', asm_out_file);
00559
00560 va_end (ap);
00561 }
00562
00563
00564
00565 void
00566 dw2_asm_output_data_sleb128 (HOST_WIDE_INT value,
00567 const char *comment, ...)
00568 {
00569 va_list ap;
00570
00571 va_start (ap, comment);
00572
00573 #ifdef HAVE_AS_LEB128
00574 fprintf (asm_out_file, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC, value);
00575
00576 if (flag_debug_asm && comment)
00577 {
00578 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
00579 vfprintf (asm_out_file, comment, ap);
00580 }
00581 #else
00582 {
00583 HOST_WIDE_INT work = value;
00584 int more, byte;
00585 const char *byte_op = targetm.asm_out.byte_op;
00586
00587 if (byte_op)
00588 fputs (byte_op, asm_out_file);
00589 do
00590 {
00591 byte = (work & 0x7f);
00592
00593 work >>= 7;
00594 more = !((work == 0 && (byte & 0x40) == 0)
00595 || (work == -1 && (byte & 0x40) != 0));
00596 if (more)
00597 byte |= 0x80;
00598
00599 if (byte_op)
00600 {
00601 fprintf (asm_out_file, "0x%x", byte);
00602 if (more)
00603 fputc (',', asm_out_file);
00604 }
00605 else
00606 assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
00607 }
00608 while (more);
00609
00610 if (flag_debug_asm)
00611 {
00612 fprintf (asm_out_file, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC,
00613 ASM_COMMENT_START, value);
00614 if (comment)
00615 {
00616 fputs ("; ", asm_out_file);
00617 vfprintf (asm_out_file, comment, ap);
00618 }
00619 }
00620 }
00621 #endif
00622 fputc ('\n', asm_out_file);
00623
00624 va_end (ap);
00625 }
00626
00627 void
00628 dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
00629 const char *lab2 ATTRIBUTE_UNUSED,
00630 const char *comment, ...)
00631 {
00632 va_list ap;
00633
00634 va_start (ap, comment);
00635
00636 #ifdef HAVE_AS_LEB128
00637 fputs ("\t.uleb128 ", asm_out_file);
00638 assemble_name (asm_out_file, lab1);
00639 fputc ('-', asm_out_file);
00640 assemble_name (asm_out_file, lab2);
00641 #else
00642 gcc_unreachable ();
00643 #endif
00644
00645 if (flag_debug_asm && comment)
00646 {
00647 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
00648 vfprintf (asm_out_file, comment, ap);
00649 }
00650 fputc ('\n', asm_out_file);
00651
00652 va_end (ap);
00653 }
00654
00655 #if 0
00656
00657 void
00658 dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED,
00659 const char *lab2 ATTRIBUTE_UNUSED,
00660 const char *comment, ...)
00661 {
00662 va_list ap;
00663
00664 va_start (ap, comment);
00665
00666 #ifdef HAVE_AS_LEB128
00667 fputs ("\t.sleb128 ", asm_out_file);
00668 assemble_name (asm_out_file, lab1);
00669 fputc ('-', asm_out_file);
00670 assemble_name (asm_out_file, lab2);
00671 #else
00672 gcc_unreachable ();
00673 #endif
00674
00675 if (flag_debug_asm && comment)
00676 {
00677 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
00678 vfprintf (asm_out_file, comment, ap);
00679 }
00680 fputc ('\n', asm_out_file);
00681
00682 va_end (ap);
00683 }
00684 #endif
00685
00686 static rtx dw2_force_const_mem (rtx);
00687 static int dw2_output_indirect_constant_1 (splay_tree_node, void *);
00688
00689 static GTY((param1_is (char *), param2_is (tree))) splay_tree indirect_pool;
00690
00691 static GTY(()) int dw2_const_labelno;
00692
00693 #if defined(HAVE_GAS_HIDDEN) && defined(SUPPORTS_ONE_ONLY)
00694 # define USE_LINKONCE_INDIRECT 1
00695 #else
00696 # define USE_LINKONCE_INDIRECT 0
00697 #endif
00698
00699
00700
00701
00702
00703
00704 static rtx
00705 dw2_force_const_mem (rtx x)
00706 {
00707 splay_tree_node node;
00708 const char *str;
00709 tree decl;
00710
00711 if (! indirect_pool)
00712 indirect_pool = splay_tree_new_ggc (splay_tree_compare_pointers);
00713
00714 gcc_assert (GET_CODE (x) == SYMBOL_REF);
00715
00716 str = targetm.strip_name_encoding (XSTR (x, 0));
00717 node = splay_tree_lookup (indirect_pool, (splay_tree_key) str);
00718 if (node)
00719 decl = (tree) node->value;
00720 else
00721 {
00722 tree id;
00723
00724 if (USE_LINKONCE_INDIRECT)
00725 {
00726 char *ref_name = alloca (strlen (str) + sizeof "DW.ref.");
00727
00728 sprintf (ref_name, "DW.ref.%s", str);
00729 id = get_identifier (ref_name);
00730 decl = build_decl (VAR_DECL, id, ptr_type_node);
00731 DECL_ARTIFICIAL (decl) = 1;
00732 DECL_IGNORED_P (decl) = 1;
00733 TREE_PUBLIC (decl) = 1;
00734 DECL_INITIAL (decl) = decl;
00735 make_decl_one_only (decl);
00736 }
00737 else
00738 {
00739 char label[32];
00740
00741 ASM_GENERATE_INTERNAL_LABEL (label, "LDFCM", dw2_const_labelno);
00742 ++dw2_const_labelno;
00743 id = get_identifier (label);
00744 decl = build_decl (VAR_DECL, id, ptr_type_node);
00745 DECL_ARTIFICIAL (decl) = 1;
00746 DECL_IGNORED_P (decl) = 1;
00747 TREE_STATIC (decl) = 1;
00748 DECL_INITIAL (decl) = decl;
00749 }
00750
00751 id = maybe_get_identifier (str);
00752 if (id)
00753 TREE_SYMBOL_REFERENCED (id) = 1;
00754
00755 splay_tree_insert (indirect_pool, (splay_tree_key) str,
00756 (splay_tree_value) decl);
00757 }
00758
00759 return XEXP (DECL_RTL (decl), 0);
00760 }
00761
00762
00763
00764
00765 static int
00766 dw2_output_indirect_constant_1 (splay_tree_node node,
00767 void *data ATTRIBUTE_UNUSED)
00768 {
00769 const char *sym;
00770 rtx sym_ref;
00771
00772 sym = (const char *) node->key;
00773 sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
00774 if (USE_LINKONCE_INDIRECT)
00775 fprintf (asm_out_file, "\t.hidden %sDW.ref.%s\n", user_label_prefix, sym);
00776 assemble_variable ((tree) node->value, 1, 1, 1);
00777 assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
00778
00779 return 0;
00780 }
00781
00782
00783
00784 void
00785 dw2_output_indirect_constants (void)
00786 {
00787 if (indirect_pool)
00788 splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL);
00789 }
00790
00791
00792
00793 void
00794 dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr,
00795 const char *comment, ...)
00796 {
00797 int size;
00798 va_list ap;
00799
00800 va_start (ap, comment);
00801
00802 size = size_of_encoded_value (encoding);
00803
00804 if (encoding == DW_EH_PE_aligned)
00805 {
00806 assemble_align (POINTER_SIZE);
00807 assemble_integer (addr, size, POINTER_SIZE, 1);
00808 return;
00809 }
00810
00811
00812
00813 if (addr == const0_rtx || addr == const1_rtx)
00814 assemble_integer (addr, size, BITS_PER_UNIT, 1);
00815 else
00816 {
00817 restart:
00818
00819
00820
00821 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
00822 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file, encoding, size,
00823 addr, done);
00824 #endif
00825
00826
00827
00828 if (encoding & DW_EH_PE_indirect)
00829 {
00830
00831
00832
00833
00834
00835 addr = dw2_force_const_mem (addr);
00836 encoding &= ~DW_EH_PE_indirect;
00837 goto restart;
00838 }
00839
00840 switch (encoding & 0xF0)
00841 {
00842 case DW_EH_PE_absptr:
00843 dw2_assemble_integer (size, addr);
00844 break;
00845
00846 case DW_EH_PE_pcrel:
00847 gcc_assert (GET_CODE (addr) == SYMBOL_REF);
00848 #ifdef ASM_OUTPUT_DWARF_PCREL
00849 ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, XSTR (addr, 0));
00850 #else
00851 dw2_assemble_integer (size, gen_rtx_MINUS (Pmode, addr, pc_rtx));
00852 #endif
00853 break;
00854
00855 default:
00856
00857
00858 gcc_unreachable ();
00859 }
00860
00861 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
00862 done:;
00863 #endif
00864 }
00865
00866 if (flag_debug_asm && comment)
00867 {
00868 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
00869 vfprintf (asm_out_file, comment, ap);
00870 }
00871 fputc ('\n', asm_out_file);
00872
00873 va_end (ap);
00874 }
00875
00876 #include "gt-dwarf2asm.h"