1 /* Dwarf2 assembler output helper routines.
2 Copyright (C) 2001, 2002 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, 59 Temple Place - Suite 330, 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 (size
, x
)
52 const char *op
= integer_asm_op (size
, FALSE
);
56 fputs (op
, asm_out_file
);
57 if (GET_CODE (x
) == CONST_INT
)
58 fprintf (asm_out_file
, HOST_WIDE_INT_PRINT_HEX
, INTVAL (x
));
60 output_addr_const (asm_out_file
, x
);
63 assemble_integer (x
, size
, BITS_PER_UNIT
, 1);
67 /* Output an immediate constant in a given size. */
70 dw2_asm_output_data (int size
, unsigned HOST_WIDE_INT value
,
71 const char *comment
, ...)
75 va_start (ap
, comment
);
77 if (size
* 8 < HOST_BITS_PER_WIDE_INT
)
78 value
&= ~(~(unsigned HOST_WIDE_INT
) 0 << (size
* 8));
80 dw2_assemble_integer (size
, GEN_INT (value
));
82 if (flag_debug_asm
&& comment
)
84 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
85 vfprintf (asm_out_file
, comment
, ap
);
87 fputc ('\n', asm_out_file
);
92 /* Output the difference between two symbols in a given size. */
93 /* ??? There appear to be assemblers that do not like such
94 subtraction, but do support ASM_SET_OP. It's unfortunately
95 impossible to do here, since the ASM_SET_OP for the difference
96 symbol must appear after both symbols are defined. */
99 dw2_asm_output_delta (int size
, const char *lab1
, const char *lab2
,
100 const char *comment
, ...)
104 va_start (ap
, comment
);
106 #ifdef ASM_OUTPUT_DWARF_DELTA
107 ASM_OUTPUT_DWARF_DELTA (asm_out_file
, size
, lab1
, lab2
);
109 dw2_assemble_integer (size
,
110 gen_rtx_MINUS (Pmode
,
111 gen_rtx_SYMBOL_REF (Pmode
, lab1
),
112 gen_rtx_SYMBOL_REF (Pmode
, lab2
)));
114 if (flag_debug_asm
&& comment
)
116 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
117 vfprintf (asm_out_file
, comment
, ap
);
119 fputc ('\n', asm_out_file
);
124 /* Output a section-relative reference to a label. In general this
125 can only be done for debugging symbols. E.g. on most targets with
126 the GNU linker, this is accomplished with a direct reference and
127 the knowledge that the debugging section will be placed at VMA 0.
128 Some targets have special relocations for this that we must use. */
131 dw2_asm_output_offset (int size
, const char *label
,
132 const char *comment
, ...)
136 va_start (ap
, comment
);
138 #ifdef ASM_OUTPUT_DWARF_OFFSET
139 ASM_OUTPUT_DWARF_OFFSET (asm_out_file
, size
, label
);
141 dw2_assemble_integer (size
, gen_rtx_SYMBOL_REF (Pmode
, label
));
144 if (flag_debug_asm
&& comment
)
146 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
147 vfprintf (asm_out_file
, comment
, ap
);
149 fputc ('\n', asm_out_file
);
154 /* Output a self-relative reference to a label, possibly in a
155 different section or object file. */
158 dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED
,
159 const char *label ATTRIBUTE_UNUSED
,
160 const char *comment
, ...)
164 va_start (ap
, comment
);
166 #ifdef ASM_OUTPUT_DWARF_PCREL
167 ASM_OUTPUT_DWARF_PCREL (asm_out_file
, size
, label
);
169 dw2_assemble_integer (size
,
170 gen_rtx_MINUS (Pmode
,
171 gen_rtx_SYMBOL_REF (Pmode
, label
),
175 if (flag_debug_asm
&& comment
)
177 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
178 vfprintf (asm_out_file
, comment
, ap
);
180 fputc ('\n', asm_out_file
);
185 /* Output an absolute reference to a label. */
188 dw2_asm_output_addr (int size
, const char *label
,
189 const char *comment
, ...)
193 va_start (ap
, comment
);
195 dw2_assemble_integer (size
, gen_rtx_SYMBOL_REF (Pmode
, label
));
197 if (flag_debug_asm
&& comment
)
199 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
200 vfprintf (asm_out_file
, comment
, ap
);
202 fputc ('\n', asm_out_file
);
207 /* Similar, but use an RTX expression instead of a text label. */
210 dw2_asm_output_addr_rtx (int size
, rtx addr
,
211 const char *comment
, ...)
215 va_start (ap
, comment
);
217 dw2_assemble_integer (size
, addr
);
219 if (flag_debug_asm
&& comment
)
221 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
222 vfprintf (asm_out_file
, comment
, ap
);
224 fputc ('\n', asm_out_file
);
230 dw2_asm_output_nstring (const char *str
, size_t orig_len
,
231 const char *comment
, ...)
236 va_start (ap
, comment
);
240 if (len
== (size_t) -1)
243 if (flag_debug_asm
&& comment
)
245 fputs ("\t.ascii \"", asm_out_file
);
246 for (i
= 0; i
< len
; i
++)
249 if (c
== '\"' || c
== '\\')
250 fputc ('\\', asm_out_file
);
252 fputc (c
, asm_out_file
);
254 fprintf (asm_out_file
, "\\%o", c
);
256 fprintf (asm_out_file
, "\\0\"\t%s ", ASM_COMMENT_START
);
257 vfprintf (asm_out_file
, comment
, ap
);
258 fputc ('\n', asm_out_file
);
262 /* If an explicit length was given, we can't assume there
263 is a null termination in the string buffer. */
264 if (orig_len
== (size_t) -1)
266 ASM_OUTPUT_ASCII (asm_out_file
, str
, len
);
267 if (orig_len
!= (size_t) -1)
268 assemble_integer (const0_rtx
, 1, BITS_PER_UNIT
, 1);
275 /* Return the size of an unsigned LEB128 quantity. */
278 size_of_uleb128 (value
)
279 unsigned HOST_WIDE_INT value
;
293 /* Return the size of a signed LEB128 quantity. */
296 size_of_sleb128 (value
)
303 byte
= (value
& 0x7f);
307 while (!((value
== 0 && (byte
& 0x40) == 0)
308 || (value
== -1 && (byte
& 0x40) != 0)));
313 /* Given an encoding, return the number of bytes the format occupies.
314 This is only defined for fixed-size encodings, and so does not
318 size_of_encoded_value (encoding
)
321 if (encoding
== DW_EH_PE_omit
)
324 switch (encoding
& 0x07)
326 case DW_EH_PE_absptr
:
327 return POINTER_SIZE
/ BITS_PER_UNIT
;
328 case DW_EH_PE_udata2
:
330 case DW_EH_PE_udata4
:
332 case DW_EH_PE_udata8
:
338 /* Yield a name for a given pointer encoding. */
341 eh_data_format_name (format
)
344 #if HAVE_DESIGNATED_INITIALIZERS
345 #define S(p, v) [p] = v,
347 #define S(p, v) case p: return v;
350 #if HAVE_DESIGNATED_INITIALIZERS
351 __extension__
static const char * const format_names
[256] = {
356 S(DW_EH_PE_absptr
, "absolute")
357 S(DW_EH_PE_omit
, "omit")
358 S(DW_EH_PE_aligned
, "aligned absolute")
360 S(DW_EH_PE_uleb128
, "uleb128")
361 S(DW_EH_PE_udata2
, "udata2")
362 S(DW_EH_PE_udata4
, "udata4")
363 S(DW_EH_PE_udata8
, "udata8")
364 S(DW_EH_PE_sleb128
, "sleb128")
365 S(DW_EH_PE_sdata2
, "sdata2")
366 S(DW_EH_PE_sdata4
, "sdata4")
367 S(DW_EH_PE_sdata8
, "sdata8")
369 S(DW_EH_PE_absptr
| DW_EH_PE_pcrel
, "pcrel")
370 S(DW_EH_PE_uleb128
| DW_EH_PE_pcrel
, "pcrel uleb128")
371 S(DW_EH_PE_udata2
| DW_EH_PE_pcrel
, "pcrel udata2")
372 S(DW_EH_PE_udata4
| DW_EH_PE_pcrel
, "pcrel udata4")
373 S(DW_EH_PE_udata8
| DW_EH_PE_pcrel
, "pcrel udata8")
374 S(DW_EH_PE_sleb128
| DW_EH_PE_pcrel
, "pcrel sleb128")
375 S(DW_EH_PE_sdata2
| DW_EH_PE_pcrel
, "pcrel sdata2")
376 S(DW_EH_PE_sdata4
| DW_EH_PE_pcrel
, "pcrel sdata4")
377 S(DW_EH_PE_sdata8
| DW_EH_PE_pcrel
, "pcrel sdata8")
379 S(DW_EH_PE_absptr
| DW_EH_PE_textrel
, "textrel")
380 S(DW_EH_PE_uleb128
| DW_EH_PE_textrel
, "textrel uleb128")
381 S(DW_EH_PE_udata2
| DW_EH_PE_textrel
, "textrel udata2")
382 S(DW_EH_PE_udata4
| DW_EH_PE_textrel
, "textrel udata4")
383 S(DW_EH_PE_udata8
| DW_EH_PE_textrel
, "textrel udata8")
384 S(DW_EH_PE_sleb128
| DW_EH_PE_textrel
, "textrel sleb128")
385 S(DW_EH_PE_sdata2
| DW_EH_PE_textrel
, "textrel sdata2")
386 S(DW_EH_PE_sdata4
| DW_EH_PE_textrel
, "textrel sdata4")
387 S(DW_EH_PE_sdata8
| DW_EH_PE_textrel
, "textrel sdata8")
389 S(DW_EH_PE_absptr
| DW_EH_PE_datarel
, "datarel")
390 S(DW_EH_PE_uleb128
| DW_EH_PE_datarel
, "datarel uleb128")
391 S(DW_EH_PE_udata2
| DW_EH_PE_datarel
, "datarel udata2")
392 S(DW_EH_PE_udata4
| DW_EH_PE_datarel
, "datarel udata4")
393 S(DW_EH_PE_udata8
| DW_EH_PE_datarel
, "datarel udata8")
394 S(DW_EH_PE_sleb128
| DW_EH_PE_datarel
, "datarel sleb128")
395 S(DW_EH_PE_sdata2
| DW_EH_PE_datarel
, "datarel sdata2")
396 S(DW_EH_PE_sdata4
| DW_EH_PE_datarel
, "datarel sdata4")
397 S(DW_EH_PE_sdata8
| DW_EH_PE_datarel
, "datarel sdata8")
399 S(DW_EH_PE_absptr
| DW_EH_PE_funcrel
, "funcrel")
400 S(DW_EH_PE_uleb128
| DW_EH_PE_funcrel
, "funcrel uleb128")
401 S(DW_EH_PE_udata2
| DW_EH_PE_funcrel
, "funcrel udata2")
402 S(DW_EH_PE_udata4
| DW_EH_PE_funcrel
, "funcrel udata4")
403 S(DW_EH_PE_udata8
| DW_EH_PE_funcrel
, "funcrel udata8")
404 S(DW_EH_PE_sleb128
| DW_EH_PE_funcrel
, "funcrel sleb128")
405 S(DW_EH_PE_sdata2
| DW_EH_PE_funcrel
, "funcrel sdata2")
406 S(DW_EH_PE_sdata4
| DW_EH_PE_funcrel
, "funcrel sdata4")
407 S(DW_EH_PE_sdata8
| DW_EH_PE_funcrel
, "funcrel sdata8")
409 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_pcrel
,
411 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_pcrel
,
412 "indirect pcrel uleb128")
413 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_pcrel
,
414 "indirect pcrel udata2")
415 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_pcrel
,
416 "indirect pcrel udata4")
417 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_pcrel
,
418 "indirect pcrel udata8")
419 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_pcrel
,
420 "indirect pcrel sleb128")
421 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_pcrel
,
422 "indirect pcrel sdata2")
423 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_pcrel
,
424 "indirect pcrel sdata4")
425 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_pcrel
,
426 "indirect pcrel sdata8")
428 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_textrel
,
430 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_textrel
,
431 "indirect textrel uleb128")
432 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_textrel
,
433 "indirect textrel udata2")
434 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_textrel
,
435 "indirect textrel udata4")
436 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_textrel
,
437 "indirect textrel udata8")
438 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_textrel
,
439 "indirect textrel sleb128")
440 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_textrel
,
441 "indirect textrel sdata2")
442 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_textrel
,
443 "indirect textrel sdata4")
444 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_textrel
,
445 "indirect textrel sdata8")
447 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_datarel
,
449 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_datarel
,
450 "indirect datarel uleb128")
451 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_datarel
,
452 "indirect datarel udata2")
453 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_datarel
,
454 "indirect datarel udata4")
455 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_datarel
,
456 "indirect datarel udata8")
457 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_datarel
,
458 "indirect datarel sleb128")
459 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_datarel
,
460 "indirect datarel sdata2")
461 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_datarel
,
462 "indirect datarel sdata4")
463 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_datarel
,
464 "indirect datarel sdata8")
466 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_funcrel
,
468 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_funcrel
,
469 "indirect funcrel uleb128")
470 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_funcrel
,
471 "indirect funcrel udata2")
472 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_funcrel
,
473 "indirect funcrel udata4")
474 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_funcrel
,
475 "indirect funcrel udata8")
476 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_funcrel
,
477 "indirect funcrel sleb128")
478 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_funcrel
,
479 "indirect funcrel sdata2")
480 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_funcrel
,
481 "indirect funcrel sdata4")
482 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_funcrel
,
483 "indirect funcrel sdata8")
485 #if HAVE_DESIGNATED_INITIALIZERS
488 if (format
< 0 || format
> 0xff || format_names
[format
] == NULL
)
490 return format_names
[format
];
497 /* Output an unsigned LEB128 quantity. */
500 dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value
,
501 const char *comment
, ...)
505 va_start (ap
, comment
);
507 #ifdef HAVE_AS_LEB128
508 fprintf (asm_out_file
, "\t.uleb128 " HOST_WIDE_INT_PRINT_HEX
, value
);
510 if (flag_debug_asm
&& comment
)
512 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
513 vfprintf (asm_out_file
, comment
, ap
);
517 unsigned HOST_WIDE_INT work
= value
;
518 const char *byte_op
= targetm
.asm_out
.byte_op
;
521 fputs (byte_op
, asm_out_file
);
524 int byte
= (work
& 0x7f);
527 /* More bytes to follow. */
532 fprintf (asm_out_file
, "0x%x", byte
);
534 fputc (',', asm_out_file
);
537 assemble_integer (GEN_INT (byte
), 1, BITS_PER_UNIT
, 1);
543 fprintf (asm_out_file
, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX
,
544 ASM_COMMENT_START
, value
);
547 fputs ("; ", asm_out_file
);
548 vfprintf (asm_out_file
, comment
, ap
);
553 fputc ('\n', asm_out_file
);
558 /* Output a signed LEB128 quantity. */
561 dw2_asm_output_data_sleb128 (HOST_WIDE_INT value
,
562 const char *comment
, ...)
566 va_start (ap
, comment
);
568 #ifdef HAVE_AS_LEB128
569 fprintf (asm_out_file
, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC
, value
);
571 if (flag_debug_asm
&& comment
)
573 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
574 vfprintf (asm_out_file
, comment
, ap
);
578 HOST_WIDE_INT work
= value
;
580 const char *byte_op
= targetm
.asm_out
.byte_op
;
583 fputs (byte_op
, asm_out_file
);
586 byte
= (work
& 0x7f);
587 /* arithmetic shift */
589 more
= !((work
== 0 && (byte
& 0x40) == 0)
590 || (work
== -1 && (byte
& 0x40) != 0));
596 fprintf (asm_out_file
, "0x%x", byte
);
598 fputc (',', asm_out_file
);
601 assemble_integer (GEN_INT (byte
), 1, BITS_PER_UNIT
, 1);
607 fprintf (asm_out_file
, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC
,
608 ASM_COMMENT_START
, value
);
611 fputs ("; ", asm_out_file
);
612 vfprintf (asm_out_file
, comment
, ap
);
617 fputc ('\n', asm_out_file
);
623 dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED
,
624 const char *lab2 ATTRIBUTE_UNUSED
,
625 const char *comment
, ...)
629 va_start (ap
, comment
);
631 #ifdef HAVE_AS_LEB128
632 fputs ("\t.uleb128 ", asm_out_file
);
633 assemble_name (asm_out_file
, lab1
);
634 fputc ('-', asm_out_file
);
635 assemble_name (asm_out_file
, lab2
);
640 if (flag_debug_asm
&& comment
)
642 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
643 vfprintf (asm_out_file
, comment
, ap
);
645 fputc ('\n', asm_out_file
);
651 dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED
,
652 const char *lab2 ATTRIBUTE_UNUSED
,
653 const char *comment
, ...)
657 va_start (ap
, comment
);
659 #ifdef HAVE_AS_LEB128
660 fputs ("\t.sleb128 ", asm_out_file
);
661 assemble_name (asm_out_file
, lab1
);
662 fputc ('-', asm_out_file
);
663 assemble_name (asm_out_file
, lab2
);
668 if (flag_debug_asm
&& comment
)
670 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
671 vfprintf (asm_out_file
, comment
, ap
);
673 fputc ('\n', asm_out_file
);
678 static rtx dw2_force_const_mem
PARAMS ((rtx
));
679 static int dw2_output_indirect_constant_1
PARAMS ((splay_tree_node
, void *));
681 static GTY((param1_is (char *), param2_is (tree
))) splay_tree indirect_pool
;
683 static GTY(()) int dw2_const_labelno
;
685 #if defined(HAVE_GAS_HIDDEN) && defined(SUPPORTS_ONE_ONLY)
686 # define USE_LINKONCE_INDIRECT 1
688 # define USE_LINKONCE_INDIRECT 0
691 /* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
692 memory. Differs from force_const_mem in that a single pool is used for
693 the entire unit of translation, and the memory is not guaranteed to be
694 "near" the function in any interesting sense. */
697 dw2_force_const_mem (x
)
700 splay_tree_node node
;
705 indirect_pool
= splay_tree_new_ggc (splay_tree_compare_pointers
);
707 if (GET_CODE (x
) != SYMBOL_REF
)
710 str
= (* targetm
.strip_name_encoding
) (XSTR (x
, 0));
711 node
= splay_tree_lookup (indirect_pool
, (splay_tree_key
) str
);
713 decl
= (tree
) node
->value
;
718 if (USE_LINKONCE_INDIRECT
)
720 char *ref_name
= alloca (strlen (str
) + sizeof "DW.ref.");
722 sprintf (ref_name
, "DW.ref.%s", str
);
723 id
= get_identifier (ref_name
);
724 decl
= build_decl (VAR_DECL
, id
, ptr_type_node
);
725 DECL_ARTIFICIAL (decl
) = 1;
726 TREE_PUBLIC (decl
) = 1;
727 DECL_INITIAL (decl
) = decl
;
728 make_decl_one_only (decl
);
734 ASM_GENERATE_INTERNAL_LABEL (label
, "LDFCM", dw2_const_labelno
);
736 id
= get_identifier (label
);
737 decl
= build_decl (VAR_DECL
, id
, ptr_type_node
);
738 DECL_ARTIFICIAL (decl
) = 1;
739 TREE_STATIC (decl
) = 1;
740 DECL_INITIAL (decl
) = decl
;
743 id
= maybe_get_identifier (str
);
745 TREE_SYMBOL_REFERENCED (id
) = 1;
747 splay_tree_insert (indirect_pool
, (splay_tree_key
) str
,
748 (splay_tree_value
) decl
);
751 return XEXP (DECL_RTL (decl
), 0);
754 /* A helper function for dw2_output_indirect_constants called through
755 splay_tree_foreach. Emit one queued constant to memory. */
758 dw2_output_indirect_constant_1 (node
, data
)
759 splay_tree_node node
;
760 void* data ATTRIBUTE_UNUSED
;
765 sym
= (const char *) node
->key
;
766 sym_ref
= gen_rtx_SYMBOL_REF (Pmode
, sym
);
767 if (USE_LINKONCE_INDIRECT
)
768 fprintf (asm_out_file
, "\t.hidden DW.ref.%s\n", sym
);
769 assemble_variable ((tree
) node
->value
, 1, 1, 1);
770 assemble_integer (sym_ref
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
775 /* Emit the constants queued through dw2_force_const_mem. */
778 dw2_output_indirect_constants ()
781 splay_tree_foreach (indirect_pool
, dw2_output_indirect_constant_1
, NULL
);
784 /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed. */
787 dw2_asm_output_encoded_addr_rtx (int encoding
, rtx addr
,
788 const char *comment
, ...)
793 va_start (ap
, comment
);
795 size
= size_of_encoded_value (encoding
);
797 if (encoding
== DW_EH_PE_aligned
)
799 assemble_align (POINTER_SIZE
);
800 assemble_integer (addr
, size
, POINTER_SIZE
, 1);
804 /* NULL is _always_ represented as a plain zero, as is 1 for Ada's
806 if (addr
== const0_rtx
|| addr
== const1_rtx
)
807 assemble_integer (addr
, size
, BITS_PER_UNIT
, 1);
811 /* Allow the target first crack at emitting this. Some of the
812 special relocations require special directives instead of
813 just ".4byte" or whatever. */
814 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
815 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file
, encoding
, size
,
819 /* Indirection is used to get dynamic relocations out of a
820 read-only section. */
821 if (encoding
& DW_EH_PE_indirect
)
823 /* It is very tempting to use force_const_mem so that we share data
824 with the normal constant pool. However, we've already emitted
825 the constant pool for this function. Moreover, we'd like to
826 share these constants across the entire unit of translation,
827 or better, across the entire application (or DSO). */
828 addr
= dw2_force_const_mem (addr
);
829 encoding
&= ~DW_EH_PE_indirect
;
833 switch (encoding
& 0xF0)
835 case DW_EH_PE_absptr
:
836 dw2_assemble_integer (size
, addr
);
840 if (GET_CODE (addr
) != SYMBOL_REF
)
842 #ifdef ASM_OUTPUT_DWARF_PCREL
843 ASM_OUTPUT_DWARF_PCREL (asm_out_file
, size
, XSTR (addr
, 0));
845 dw2_assemble_integer (size
, gen_rtx_MINUS (Pmode
, addr
, pc_rtx
));
850 /* Other encodings should have been handled by
851 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */
855 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
860 if (flag_debug_asm
&& comment
)
862 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
863 vfprintf (asm_out_file
, comment
, ap
);
865 fputc ('\n', asm_out_file
);
870 #include "gt-dwarf2asm.h"