1 /* Dwarf2 assembler output helper routines.
2 Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "coretypes.h"
31 #include "dwarf2asm.h"
33 #include "splay-tree.h"
38 /* How to start an assembler comment. */
39 #ifndef ASM_COMMENT_START
40 #define ASM_COMMENT_START ";#"
44 /* Output an unaligned integer with the given value and size. Prefer not
45 to print a newline, since the caller may want to add a comment. */
48 dw2_assemble_integer (int size, rtx x)
50 const char *op = integer_asm_op (size, FALSE);
54 fputs (op, asm_out_file);
55 if (GET_CODE (x) == CONST_INT)
56 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
58 output_addr_const (asm_out_file, x);
61 assemble_integer (x, size, BITS_PER_UNIT, 1);
65 /* Output an immediate constant in a given size. */
68 dw2_asm_output_data (int size, unsigned HOST_WIDE_INT value,
69 const char *comment, ...)
73 va_start (ap, comment);
75 if (size * 8 < HOST_BITS_PER_WIDE_INT)
76 value &= ~(~(unsigned HOST_WIDE_INT) 0 << (size * 8));
78 dw2_assemble_integer (size, GEN_INT (value));
80 if (flag_debug_asm && comment)
82 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
83 vfprintf (asm_out_file, comment, ap);
85 fputc ('\n', asm_out_file);
90 /* Output the difference between two symbols in a given size. */
91 /* ??? There appear to be assemblers that do not like such
92 subtraction, but do support ASM_SET_OP. It's unfortunately
93 impossible to do here, since the ASM_SET_OP for the difference
94 symbol must appear after both symbols are defined. */
97 dw2_asm_output_delta (int size, const char *lab1, const char *lab2,
98 const char *comment, ...)
102 va_start (ap, comment);
104 #ifdef ASM_OUTPUT_DWARF_DELTA
105 ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2);
107 dw2_assemble_integer (size,
108 gen_rtx_MINUS (Pmode,
109 gen_rtx_SYMBOL_REF (Pmode, lab1),
110 gen_rtx_SYMBOL_REF (Pmode, lab2)));
112 if (flag_debug_asm && comment)
114 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
115 vfprintf (asm_out_file, comment, ap);
117 fputc ('\n', asm_out_file);
122 /* Output a section-relative reference to a LABEL, which was placed in
123 BASE. In general this can only be done for debugging symbols.
124 E.g. on most targets with the GNU linker, this is accomplished with
125 a direct reference and the knowledge that the debugging section
126 will be placed at VMA 0. Some targets have special relocations for
127 this that we must use. */
130 dw2_asm_output_offset (int size, const char *label, section * base,
131 const char *comment, ...)
135 va_start (ap, comment);
137 #ifdef ASM_OUTPUT_DWARF_OFFSET
138 ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label, base);
140 dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
143 if (flag_debug_asm && comment)
145 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
146 vfprintf (asm_out_file, comment, ap);
148 fputc ('\n', asm_out_file);
155 /* Output a self-relative reference to a label, possibly in a
156 different section or object file. */
159 dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED,
160 const char *label ATTRIBUTE_UNUSED,
161 const char *comment, ...)
165 va_start (ap, comment);
167 #ifdef ASM_OUTPUT_DWARF_PCREL
168 ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label);
170 dw2_assemble_integer (size,
171 gen_rtx_MINUS (Pmode,
172 gen_rtx_SYMBOL_REF (Pmode, label),
176 if (flag_debug_asm && comment)
178 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
179 vfprintf (asm_out_file, comment, ap);
181 fputc ('\n', asm_out_file);
187 /* Output an absolute reference to a label. */
190 dw2_asm_output_addr (int size, const char *label,
191 const char *comment, ...)
195 va_start (ap, comment);
197 dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
199 if (flag_debug_asm && comment)
201 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
202 vfprintf (asm_out_file, comment, ap);
204 fputc ('\n', asm_out_file);
209 /* Similar, but use an RTX expression instead of a text label. */
212 dw2_asm_output_addr_rtx (int size, rtx addr,
213 const char *comment, ...)
217 va_start (ap, comment);
219 dw2_assemble_integer (size, addr);
221 if (flag_debug_asm && comment)
223 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
224 vfprintf (asm_out_file, comment, ap);
226 fputc ('\n', asm_out_file);
231 /* Output the first ORIG_LEN characters of STR as a string.
232 If ORIG_LEN is equal to -1, ignore this parameter and output
233 the entire STR instead.
234 If COMMENT is not NULL and comments in the debug information
235 have been requested by the user, append the given COMMENT
236 to the generated output. */
239 dw2_asm_output_nstring (const char *str, size_t orig_len,
240 const char *comment, ...)
245 va_start (ap, comment);
249 if (len == (size_t) -1)
252 if (flag_debug_asm && comment)
254 fputs ("\t.ascii \"", asm_out_file);
255 for (i = 0; i < len; i++)
258 if (c == '\"' || c == '\\')
259 fputc ('\\', asm_out_file);
261 fputc (c, asm_out_file);
263 fprintf (asm_out_file, "\\%o", c);
265 fprintf (asm_out_file, "\\0\"\t%s ", ASM_COMMENT_START);
266 vfprintf (asm_out_file, comment, ap);
267 fputc ('\n', asm_out_file);
271 /* If an explicit length was given, we can't assume there
272 is a null termination in the string buffer. */
273 if (orig_len == (size_t) -1)
275 ASM_OUTPUT_ASCII (asm_out_file, str, len);
276 if (orig_len != (size_t) -1)
277 assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1);
284 /* Return the size of an unsigned LEB128 quantity. */
287 size_of_uleb128 (unsigned HOST_WIDE_INT value)
301 /* Return the size of a signed LEB128 quantity. */
304 size_of_sleb128 (HOST_WIDE_INT value)
310 byte = (value & 0x7f);
314 while (!((value == 0 && (byte & 0x40) == 0)
315 || (value == -1 && (byte & 0x40) != 0)));
320 /* Given an encoding, return the number of bytes the format occupies.
321 This is only defined for fixed-size encodings, and so does not
325 size_of_encoded_value (int encoding)
327 if (encoding == DW_EH_PE_omit)
330 switch (encoding & 0x07)
332 case DW_EH_PE_absptr:
333 return POINTER_SIZE / BITS_PER_UNIT;
334 case DW_EH_PE_udata2:
336 case DW_EH_PE_udata4:
338 case DW_EH_PE_udata8:
345 /* Yield a name for a given pointer encoding. */
348 eh_data_format_name (int format)
350 #if HAVE_DESIGNATED_INITIALIZERS
351 #define S(p, v) [p] = v,
353 #define S(p, v) case p: return v;
356 #if HAVE_DESIGNATED_INITIALIZERS
357 __extension__ static const char * const format_names[256] = {
362 S(DW_EH_PE_absptr, "absolute")
363 S(DW_EH_PE_omit, "omit")
364 S(DW_EH_PE_aligned, "aligned absolute")
366 S(DW_EH_PE_uleb128, "uleb128")
367 S(DW_EH_PE_udata2, "udata2")
368 S(DW_EH_PE_udata4, "udata4")
369 S(DW_EH_PE_udata8, "udata8")
370 S(DW_EH_PE_sleb128, "sleb128")
371 S(DW_EH_PE_sdata2, "sdata2")
372 S(DW_EH_PE_sdata4, "sdata4")
373 S(DW_EH_PE_sdata8, "sdata8")
375 S(DW_EH_PE_absptr | DW_EH_PE_pcrel, "pcrel")
376 S(DW_EH_PE_uleb128 | DW_EH_PE_pcrel, "pcrel uleb128")
377 S(DW_EH_PE_udata2 | DW_EH_PE_pcrel, "pcrel udata2")
378 S(DW_EH_PE_udata4 | DW_EH_PE_pcrel, "pcrel udata4")
379 S(DW_EH_PE_udata8 | DW_EH_PE_pcrel, "pcrel udata8")
380 S(DW_EH_PE_sleb128 | DW_EH_PE_pcrel, "pcrel sleb128")
381 S(DW_EH_PE_sdata2 | DW_EH_PE_pcrel, "pcrel sdata2")
382 S(DW_EH_PE_sdata4 | DW_EH_PE_pcrel, "pcrel sdata4")
383 S(DW_EH_PE_sdata8 | DW_EH_PE_pcrel, "pcrel sdata8")
385 S(DW_EH_PE_absptr | DW_EH_PE_textrel, "textrel")
386 S(DW_EH_PE_uleb128 | DW_EH_PE_textrel, "textrel uleb128")
387 S(DW_EH_PE_udata2 | DW_EH_PE_textrel, "textrel udata2")
388 S(DW_EH_PE_udata4 | DW_EH_PE_textrel, "textrel udata4")
389 S(DW_EH_PE_udata8 | DW_EH_PE_textrel, "textrel udata8")
390 S(DW_EH_PE_sleb128 | DW_EH_PE_textrel, "textrel sleb128")
391 S(DW_EH_PE_sdata2 | DW_EH_PE_textrel, "textrel sdata2")
392 S(DW_EH_PE_sdata4 | DW_EH_PE_textrel, "textrel sdata4")
393 S(DW_EH_PE_sdata8 | DW_EH_PE_textrel, "textrel sdata8")
395 S(DW_EH_PE_absptr | DW_EH_PE_datarel, "datarel")
396 S(DW_EH_PE_uleb128 | DW_EH_PE_datarel, "datarel uleb128")
397 S(DW_EH_PE_udata2 | DW_EH_PE_datarel, "datarel udata2")
398 S(DW_EH_PE_udata4 | DW_EH_PE_datarel, "datarel udata4")
399 S(DW_EH_PE_udata8 | DW_EH_PE_datarel, "datarel udata8")
400 S(DW_EH_PE_sleb128 | DW_EH_PE_datarel, "datarel sleb128")
401 S(DW_EH_PE_sdata2 | DW_EH_PE_datarel, "datarel sdata2")
402 S(DW_EH_PE_sdata4 | DW_EH_PE_datarel, "datarel sdata4")
403 S(DW_EH_PE_sdata8 | DW_EH_PE_datarel, "datarel sdata8")
405 S(DW_EH_PE_absptr | DW_EH_PE_funcrel, "funcrel")
406 S(DW_EH_PE_uleb128 | DW_EH_PE_funcrel, "funcrel uleb128")
407 S(DW_EH_PE_udata2 | DW_EH_PE_funcrel, "funcrel udata2")
408 S(DW_EH_PE_udata4 | DW_EH_PE_funcrel, "funcrel udata4")
409 S(DW_EH_PE_udata8 | DW_EH_PE_funcrel, "funcrel udata8")
410 S(DW_EH_PE_sleb128 | DW_EH_PE_funcrel, "funcrel sleb128")
411 S(DW_EH_PE_sdata2 | DW_EH_PE_funcrel, "funcrel sdata2")
412 S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4")
413 S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8")
415 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel,
417 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel,
418 "indirect pcrel uleb128")
419 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_pcrel,
420 "indirect pcrel udata2")
421 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_pcrel,
422 "indirect pcrel udata4")
423 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_pcrel,
424 "indirect pcrel udata8")
425 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_pcrel,
426 "indirect pcrel sleb128")
427 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_pcrel,
428 "indirect pcrel sdata2")
429 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_pcrel,
430 "indirect pcrel sdata4")
431 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_pcrel,
432 "indirect pcrel sdata8")
434 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_textrel,
436 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_textrel,
437 "indirect textrel uleb128")
438 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_textrel,
439 "indirect textrel udata2")
440 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_textrel,
441 "indirect textrel udata4")
442 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_textrel,
443 "indirect textrel udata8")
444 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_textrel,
445 "indirect textrel sleb128")
446 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_textrel,
447 "indirect textrel sdata2")
448 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_textrel,
449 "indirect textrel sdata4")
450 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_textrel,
451 "indirect textrel sdata8")
453 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_datarel,
455 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_datarel,
456 "indirect datarel uleb128")
457 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_datarel,
458 "indirect datarel udata2")
459 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_datarel,
460 "indirect datarel udata4")
461 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_datarel,
462 "indirect datarel udata8")
463 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_datarel,
464 "indirect datarel sleb128")
465 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_datarel,
466 "indirect datarel sdata2")
467 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_datarel,
468 "indirect datarel sdata4")
469 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_datarel,
470 "indirect datarel sdata8")
472 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_funcrel,
474 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_funcrel,
475 "indirect funcrel uleb128")
476 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_funcrel,
477 "indirect funcrel udata2")
478 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_funcrel,
479 "indirect funcrel udata4")
480 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_funcrel,
481 "indirect funcrel udata8")
482 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_funcrel,
483 "indirect funcrel sleb128")
484 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_funcrel,
485 "indirect funcrel sdata2")
486 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_funcrel,
487 "indirect funcrel sdata4")
488 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_funcrel,
489 "indirect funcrel sdata8")
491 #if HAVE_DESIGNATED_INITIALIZERS
494 gcc_assert (format >= 0 && format < 0x100 && format_names[format]);
496 return format_names[format];
503 /* Output an unsigned LEB128 quantity. */
506 dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value,
507 const char *comment, ...)
511 va_start (ap, comment);
513 #ifdef HAVE_AS_LEB128
514 fprintf (asm_out_file, "\t.uleb128 " HOST_WIDE_INT_PRINT_HEX , value);
516 if (flag_debug_asm && comment)
518 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
519 vfprintf (asm_out_file, comment, ap);
523 unsigned HOST_WIDE_INT work = value;
524 const char *byte_op = targetm.asm_out.byte_op;
527 fputs (byte_op, asm_out_file);
530 int byte = (work & 0x7f);
533 /* More bytes to follow. */
538 fprintf (asm_out_file, "0x%x", byte);
540 fputc (',', asm_out_file);
543 assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
549 fprintf (asm_out_file, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX,
550 ASM_COMMENT_START, value);
553 fputs ("; ", asm_out_file);
554 vfprintf (asm_out_file, comment, ap);
559 fputc ('\n', asm_out_file);
564 /* Output a signed LEB128 quantity. */
567 dw2_asm_output_data_sleb128 (HOST_WIDE_INT value,
568 const char *comment, ...)
572 va_start (ap, comment);
574 #ifdef HAVE_AS_LEB128
575 fprintf (asm_out_file, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC, value);
577 if (flag_debug_asm && comment)
579 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
580 vfprintf (asm_out_file, comment, ap);
584 HOST_WIDE_INT work = value;
586 const char *byte_op = targetm.asm_out.byte_op;
589 fputs (byte_op, asm_out_file);
592 byte = (work & 0x7f);
593 /* arithmetic shift */
595 more = !((work == 0 && (byte & 0x40) == 0)
596 || (work == -1 && (byte & 0x40) != 0));
602 fprintf (asm_out_file, "0x%x", byte);
604 fputc (',', asm_out_file);
607 assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
613 fprintf (asm_out_file, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC,
614 ASM_COMMENT_START, value);
617 fputs ("; ", asm_out_file);
618 vfprintf (asm_out_file, comment, ap);
623 fputc ('\n', asm_out_file);
629 dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
630 const char *lab2 ATTRIBUTE_UNUSED,
631 const char *comment, ...)
635 va_start (ap, comment);
637 #ifdef HAVE_AS_LEB128
638 fputs ("\t.uleb128 ", asm_out_file);
639 assemble_name (asm_out_file, lab1);
640 fputc ('-', asm_out_file);
641 assemble_name (asm_out_file, lab2);
646 if (flag_debug_asm && comment)
648 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
649 vfprintf (asm_out_file, comment, ap);
651 fputc ('\n', asm_out_file);
659 dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED,
660 const char *lab2 ATTRIBUTE_UNUSED,
661 const char *comment, ...)
665 va_start (ap, comment);
667 #ifdef HAVE_AS_LEB128
668 fputs ("\t.sleb128 ", asm_out_file);
669 assemble_name (asm_out_file, lab1);
670 fputc ('-', asm_out_file);
671 assemble_name (asm_out_file, lab2);
676 if (flag_debug_asm && comment)
678 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
679 vfprintf (asm_out_file, comment, ap);
681 fputc ('\n', asm_out_file);
687 static rtx dw2_force_const_mem (rtx, bool);
688 static int dw2_output_indirect_constant_1 (splay_tree_node, void *);
690 static GTY((param1_is (char *), param2_is (tree))) splay_tree indirect_pool;
692 static GTY(()) int dw2_const_labelno;
694 #if defined(HAVE_GAS_HIDDEN) && defined(SUPPORTS_ONE_ONLY)
695 # define USE_LINKONCE_INDIRECT 1
697 # define USE_LINKONCE_INDIRECT 0
700 /* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
701 memory. Differs from force_const_mem in that a single pool is used for
702 the entire unit of translation, and the memory is not guaranteed to be
703 "near" the function in any interesting sense. PUBLIC controls whether
704 the symbol can be shared across the entire application (or DSO). */
707 dw2_force_const_mem (rtx x, bool public)
709 splay_tree_node node;
714 indirect_pool = splay_tree_new_ggc (splay_tree_compare_pointers);
716 gcc_assert (GET_CODE (x) == SYMBOL_REF);
718 str = targetm.strip_name_encoding (XSTR (x, 0));
719 node = splay_tree_lookup (indirect_pool, (splay_tree_key) str);
721 decl = (tree) node->value;
726 if (public && USE_LINKONCE_INDIRECT)
728 char *ref_name = alloca (strlen (str) + sizeof "DW.ref.");
730 sprintf (ref_name, "DW.ref.%s", str);
731 id = get_identifier (ref_name);
732 decl = build_decl (VAR_DECL, id, ptr_type_node);
733 DECL_ARTIFICIAL (decl) = 1;
734 DECL_IGNORED_P (decl) = 1;
735 TREE_PUBLIC (decl) = 1;
736 DECL_INITIAL (decl) = decl;
737 make_decl_one_only (decl);
743 ASM_GENERATE_INTERNAL_LABEL (label, "LDFCM", dw2_const_labelno);
745 id = get_identifier (label);
746 decl = build_decl (VAR_DECL, id, ptr_type_node);
747 DECL_ARTIFICIAL (decl) = 1;
748 DECL_IGNORED_P (decl) = 1;
749 TREE_STATIC (decl) = 1;
750 DECL_INITIAL (decl) = decl;
753 id = maybe_get_identifier (str);
755 TREE_SYMBOL_REFERENCED (id) = 1;
757 splay_tree_insert (indirect_pool, (splay_tree_key) str,
758 (splay_tree_value) decl);
761 return XEXP (DECL_RTL (decl), 0);
764 /* A helper function for dw2_output_indirect_constants called through
765 splay_tree_foreach. Emit one queued constant to memory. */
768 dw2_output_indirect_constant_1 (splay_tree_node node,
769 void *data ATTRIBUTE_UNUSED)
775 sym = (const char *) node->key;
776 decl = (tree) node->value;
777 sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
778 if (TREE_PUBLIC (decl) && USE_LINKONCE_INDIRECT)
779 fprintf (asm_out_file, "\t.hidden %sDW.ref.%s\n", user_label_prefix, sym);
780 assemble_variable (decl, 1, 1, 1);
781 assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
786 /* Emit the constants queued through dw2_force_const_mem. */
789 dw2_output_indirect_constants (void)
792 splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL);
795 /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed.
796 If PUBLIC is set and the encoding is DW_EH_PE_indirect, the indirect
797 reference is shared across the entire application (or DSO). */
800 dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr, bool public,
801 const char *comment, ...)
806 va_start (ap, comment);
808 size = size_of_encoded_value (encoding);
810 if (encoding == DW_EH_PE_aligned)
812 assemble_align (POINTER_SIZE);
813 assemble_integer (addr, size, POINTER_SIZE, 1);
817 /* NULL is _always_ represented as a plain zero, as is 1 for Ada's
819 if (addr == const0_rtx || addr == const1_rtx)
820 assemble_integer (addr, size, BITS_PER_UNIT, 1);
824 /* Allow the target first crack at emitting this. Some of the
825 special relocations require special directives instead of
826 just ".4byte" or whatever. */
827 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
828 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file, encoding, size,
832 /* Indirection is used to get dynamic relocations out of a
833 read-only section. */
834 if (encoding & DW_EH_PE_indirect)
836 /* It is very tempting to use force_const_mem so that we share data
837 with the normal constant pool. However, we've already emitted
838 the constant pool for this function. Moreover, we'd like to
839 share these constants across the entire unit of translation and
840 even, if possible, across the entire application (or DSO). */
841 addr = dw2_force_const_mem (addr, public);
842 encoding &= ~DW_EH_PE_indirect;
846 switch (encoding & 0xF0)
848 case DW_EH_PE_absptr:
849 dw2_assemble_integer (size, addr);
853 gcc_assert (GET_CODE (addr) == SYMBOL_REF);
854 #ifdef ASM_OUTPUT_DWARF_PCREL
855 ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, XSTR (addr, 0));
857 dw2_assemble_integer (size, gen_rtx_MINUS (Pmode, addr, pc_rtx));
862 /* Other encodings should have been handled by
863 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */
867 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
872 if (flag_debug_asm && comment)
874 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
875 vfprintf (asm_out_file, comment, ap);
877 fputc ('\n', asm_out_file);
882 #include "gt-dwarf2asm.h"