1 /* Dwarf2 assembler output helper routines.
2 Copyright (C) 2001-2015 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 3, 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 COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
29 #include "double-int.h"
37 #include "stringpool.h"
42 #include "dwarf2asm.h"
49 /* Output an unaligned integer with the given value and size. Prefer not
50 to print a newline, since the caller may want to add a comment. */
53 dw2_assemble_integer (int size
, rtx x
)
55 const char *op
= integer_asm_op (size
, FALSE
);
59 fputs (op
, asm_out_file
);
61 fprint_whex (asm_out_file
, (unsigned HOST_WIDE_INT
) INTVAL (x
));
63 output_addr_const (asm_out_file
, x
);
66 assemble_integer (x
, size
, BITS_PER_UNIT
, 1);
70 /* Output a value of a given size in target byte order. */
73 dw2_asm_output_data_raw (int size
, unsigned HOST_WIDE_INT value
)
75 unsigned char bytes
[8];
78 for (i
= 0; i
< 8; ++i
)
80 bytes
[i
] = value
& 0xff;
86 for (i
= size
- 1; i
> 0; --i
)
87 fprintf (asm_out_file
, "%#x,", bytes
[i
]);
88 fprintf (asm_out_file
, "%#x", bytes
[0]);
92 for (i
= 0; i
< size
- 1; ++i
)
93 fprintf (asm_out_file
, "%#x,", bytes
[i
]);
94 fprintf (asm_out_file
, "%#x", bytes
[i
]);
98 /* Output an immediate constant in a given SIZE in bytes. */
101 dw2_asm_output_data (int size
, unsigned HOST_WIDE_INT value
,
102 const char *comment
, ...)
105 const char *op
= integer_asm_op (size
, FALSE
);
107 va_start (ap
, comment
);
109 if (size
* 8 < HOST_BITS_PER_WIDE_INT
)
110 value
&= ~(~(unsigned HOST_WIDE_INT
) 0 << (size
* 8));
114 fputs (op
, asm_out_file
);
115 fprint_whex (asm_out_file
, value
);
118 assemble_integer (GEN_INT (value
), size
, BITS_PER_UNIT
, 1);
120 if (flag_debug_asm
&& comment
)
122 fputs ("\t" ASM_COMMENT_START
" ", asm_out_file
);
123 vfprintf (asm_out_file
, comment
, ap
);
125 putc ('\n', asm_out_file
);
130 /* Output the difference between two symbols in a given size. */
131 /* ??? There appear to be assemblers that do not like such
132 subtraction, but do support ASM_SET_OP. It's unfortunately
133 impossible to do here, since the ASM_SET_OP for the difference
134 symbol must appear after both symbols are defined. */
137 dw2_asm_output_delta (int size
, const char *lab1
, const char *lab2
,
138 const char *comment
, ...)
142 va_start (ap
, comment
);
144 #ifdef ASM_OUTPUT_DWARF_DELTA
145 ASM_OUTPUT_DWARF_DELTA (asm_out_file
, size
, lab1
, lab2
);
147 dw2_assemble_integer (size
,
148 gen_rtx_MINUS (Pmode
,
149 gen_rtx_SYMBOL_REF (Pmode
, lab1
),
150 gen_rtx_SYMBOL_REF (Pmode
, lab2
)));
152 if (flag_debug_asm
&& comment
)
154 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
155 vfprintf (asm_out_file
, comment
, ap
);
157 fputc ('\n', asm_out_file
);
162 #ifdef ASM_OUTPUT_DWARF_VMS_DELTA
163 /* Output the difference between two symbols in instruction units
167 dw2_asm_output_vms_delta (int size ATTRIBUTE_UNUSED
,
168 const char *lab1
, const char *lab2
,
169 const char *comment
, ...)
173 va_start (ap
, comment
);
175 ASM_OUTPUT_DWARF_VMS_DELTA (asm_out_file
, size
, lab1
, lab2
);
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 a section-relative reference to a LABEL, which was placed in
188 BASE. In general this can only be done for debugging symbols.
189 E.g. on most targets with the GNU linker, this is accomplished with
190 a direct reference and the knowledge that the debugging section
191 will be placed at VMA 0. Some targets have special relocations for
192 this that we must use. */
195 dw2_asm_output_offset (int size
, const char *label
,
196 section
*base ATTRIBUTE_UNUSED
,
197 const char *comment
, ...)
201 va_start (ap
, comment
);
203 #ifdef ASM_OUTPUT_DWARF_OFFSET
204 ASM_OUTPUT_DWARF_OFFSET (asm_out_file
, size
, label
, base
);
206 dw2_assemble_integer (size
, gen_rtx_SYMBOL_REF (Pmode
, label
));
209 if (flag_debug_asm
&& comment
)
211 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
212 vfprintf (asm_out_file
, comment
, ap
);
214 fputc ('\n', asm_out_file
);
221 /* Output a self-relative reference to a label, possibly in a
222 different section or object file. */
225 dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED
,
226 const char *label ATTRIBUTE_UNUSED
,
227 const char *comment
, ...)
231 va_start (ap
, comment
);
233 #ifdef ASM_OUTPUT_DWARF_PCREL
234 ASM_OUTPUT_DWARF_PCREL (asm_out_file
, size
, label
);
236 dw2_assemble_integer (size
,
237 gen_rtx_MINUS (Pmode
,
238 gen_rtx_SYMBOL_REF (Pmode
, label
),
242 if (flag_debug_asm
&& comment
)
244 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
245 vfprintf (asm_out_file
, comment
, ap
);
247 fputc ('\n', asm_out_file
);
253 /* Output an absolute reference to a label. */
256 dw2_asm_output_addr (int size
, const char *label
,
257 const char *comment
, ...)
261 va_start (ap
, comment
);
263 dw2_assemble_integer (size
, gen_rtx_SYMBOL_REF (Pmode
, label
));
265 if (flag_debug_asm
&& comment
)
267 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
268 vfprintf (asm_out_file
, comment
, ap
);
270 fputc ('\n', asm_out_file
);
275 /* Similar, but use an RTX expression instead of a text label. */
278 dw2_asm_output_addr_rtx (int size
, rtx addr
,
279 const char *comment
, ...)
283 va_start (ap
, comment
);
285 dw2_assemble_integer (size
, addr
);
287 if (flag_debug_asm
&& comment
)
289 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
290 vfprintf (asm_out_file
, comment
, ap
);
292 fputc ('\n', asm_out_file
);
297 /* Output the first ORIG_LEN characters of STR as a string.
298 If ORIG_LEN is equal to -1, ignore this parameter and output
299 the entire STR instead.
300 If COMMENT is not NULL and comments in the debug information
301 have been requested by the user, append the given COMMENT
302 to the generated output. */
305 dw2_asm_output_nstring (const char *str
, size_t orig_len
,
306 const char *comment
, ...)
311 va_start (ap
, comment
);
315 if (len
== (size_t) -1)
318 if (flag_debug_asm
&& comment
)
320 fputs ("\t.ascii \"", asm_out_file
);
321 for (i
= 0; i
< len
; i
++)
324 if (c
== '\"' || c
== '\\')
325 fputc ('\\', asm_out_file
);
327 fputc (c
, asm_out_file
);
329 fprintf (asm_out_file
, "\\%o", c
);
331 fprintf (asm_out_file
, "\\0\"\t%s ", ASM_COMMENT_START
);
332 vfprintf (asm_out_file
, comment
, ap
);
333 fputc ('\n', asm_out_file
);
337 /* If an explicit length was given, we can't assume there
338 is a null termination in the string buffer. */
339 if (orig_len
== (size_t) -1)
341 ASM_OUTPUT_ASCII (asm_out_file
, str
, len
);
342 if (orig_len
!= (size_t) -1)
343 assemble_integer (const0_rtx
, 1, BITS_PER_UNIT
, 1);
350 /* Return the size of an unsigned LEB128 quantity. */
353 size_of_uleb128 (unsigned HOST_WIDE_INT value
)
367 /* Return the size of a signed LEB128 quantity. */
370 size_of_sleb128 (HOST_WIDE_INT value
)
376 byte
= (value
& 0x7f);
380 while (!((value
== 0 && (byte
& 0x40) == 0)
381 || (value
== -1 && (byte
& 0x40) != 0)));
386 /* Given an encoding, return the number of bytes the format occupies.
387 This is only defined for fixed-size encodings, and so does not
391 size_of_encoded_value (int encoding
)
393 if (encoding
== DW_EH_PE_omit
)
396 switch (encoding
& 0x07)
398 case DW_EH_PE_absptr
:
399 return POINTER_SIZE_UNITS
;
400 case DW_EH_PE_udata2
:
402 case DW_EH_PE_udata4
:
404 case DW_EH_PE_udata8
:
411 /* Yield a name for a given pointer encoding. */
414 eh_data_format_name (int format
)
416 #if HAVE_DESIGNATED_INITIALIZERS
417 #define S(p, v) [p] = v,
419 #define S(p, v) case p: return v;
422 #if HAVE_DESIGNATED_INITIALIZERS
423 __extension__
static const char * const format_names
[256] = {
428 S(DW_EH_PE_absptr
, "absolute")
429 S(DW_EH_PE_omit
, "omit")
430 S(DW_EH_PE_aligned
, "aligned absolute")
432 S(DW_EH_PE_uleb128
, "uleb128")
433 S(DW_EH_PE_udata2
, "udata2")
434 S(DW_EH_PE_udata4
, "udata4")
435 S(DW_EH_PE_udata8
, "udata8")
436 S(DW_EH_PE_sleb128
, "sleb128")
437 S(DW_EH_PE_sdata2
, "sdata2")
438 S(DW_EH_PE_sdata4
, "sdata4")
439 S(DW_EH_PE_sdata8
, "sdata8")
441 S(DW_EH_PE_absptr
| DW_EH_PE_pcrel
, "pcrel")
442 S(DW_EH_PE_uleb128
| DW_EH_PE_pcrel
, "pcrel uleb128")
443 S(DW_EH_PE_udata2
| DW_EH_PE_pcrel
, "pcrel udata2")
444 S(DW_EH_PE_udata4
| DW_EH_PE_pcrel
, "pcrel udata4")
445 S(DW_EH_PE_udata8
| DW_EH_PE_pcrel
, "pcrel udata8")
446 S(DW_EH_PE_sleb128
| DW_EH_PE_pcrel
, "pcrel sleb128")
447 S(DW_EH_PE_sdata2
| DW_EH_PE_pcrel
, "pcrel sdata2")
448 S(DW_EH_PE_sdata4
| DW_EH_PE_pcrel
, "pcrel sdata4")
449 S(DW_EH_PE_sdata8
| DW_EH_PE_pcrel
, "pcrel sdata8")
451 S(DW_EH_PE_absptr
| DW_EH_PE_textrel
, "textrel")
452 S(DW_EH_PE_uleb128
| DW_EH_PE_textrel
, "textrel uleb128")
453 S(DW_EH_PE_udata2
| DW_EH_PE_textrel
, "textrel udata2")
454 S(DW_EH_PE_udata4
| DW_EH_PE_textrel
, "textrel udata4")
455 S(DW_EH_PE_udata8
| DW_EH_PE_textrel
, "textrel udata8")
456 S(DW_EH_PE_sleb128
| DW_EH_PE_textrel
, "textrel sleb128")
457 S(DW_EH_PE_sdata2
| DW_EH_PE_textrel
, "textrel sdata2")
458 S(DW_EH_PE_sdata4
| DW_EH_PE_textrel
, "textrel sdata4")
459 S(DW_EH_PE_sdata8
| DW_EH_PE_textrel
, "textrel sdata8")
461 S(DW_EH_PE_absptr
| DW_EH_PE_datarel
, "datarel")
462 S(DW_EH_PE_uleb128
| DW_EH_PE_datarel
, "datarel uleb128")
463 S(DW_EH_PE_udata2
| DW_EH_PE_datarel
, "datarel udata2")
464 S(DW_EH_PE_udata4
| DW_EH_PE_datarel
, "datarel udata4")
465 S(DW_EH_PE_udata8
| DW_EH_PE_datarel
, "datarel udata8")
466 S(DW_EH_PE_sleb128
| DW_EH_PE_datarel
, "datarel sleb128")
467 S(DW_EH_PE_sdata2
| DW_EH_PE_datarel
, "datarel sdata2")
468 S(DW_EH_PE_sdata4
| DW_EH_PE_datarel
, "datarel sdata4")
469 S(DW_EH_PE_sdata8
| DW_EH_PE_datarel
, "datarel sdata8")
471 S(DW_EH_PE_absptr
| DW_EH_PE_funcrel
, "funcrel")
472 S(DW_EH_PE_uleb128
| DW_EH_PE_funcrel
, "funcrel uleb128")
473 S(DW_EH_PE_udata2
| DW_EH_PE_funcrel
, "funcrel udata2")
474 S(DW_EH_PE_udata4
| DW_EH_PE_funcrel
, "funcrel udata4")
475 S(DW_EH_PE_udata8
| DW_EH_PE_funcrel
, "funcrel udata8")
476 S(DW_EH_PE_sleb128
| DW_EH_PE_funcrel
, "funcrel sleb128")
477 S(DW_EH_PE_sdata2
| DW_EH_PE_funcrel
, "funcrel sdata2")
478 S(DW_EH_PE_sdata4
| DW_EH_PE_funcrel
, "funcrel sdata4")
479 S(DW_EH_PE_sdata8
| DW_EH_PE_funcrel
, "funcrel sdata8")
481 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
, "indirect absolute")
483 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_pcrel
,
485 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_pcrel
,
486 "indirect pcrel uleb128")
487 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_pcrel
,
488 "indirect pcrel udata2")
489 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_pcrel
,
490 "indirect pcrel udata4")
491 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_pcrel
,
492 "indirect pcrel udata8")
493 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_pcrel
,
494 "indirect pcrel sleb128")
495 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_pcrel
,
496 "indirect pcrel sdata2")
497 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_pcrel
,
498 "indirect pcrel sdata4")
499 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_pcrel
,
500 "indirect pcrel sdata8")
502 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_textrel
,
504 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_textrel
,
505 "indirect textrel uleb128")
506 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_textrel
,
507 "indirect textrel udata2")
508 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_textrel
,
509 "indirect textrel udata4")
510 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_textrel
,
511 "indirect textrel udata8")
512 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_textrel
,
513 "indirect textrel sleb128")
514 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_textrel
,
515 "indirect textrel sdata2")
516 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_textrel
,
517 "indirect textrel sdata4")
518 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_textrel
,
519 "indirect textrel sdata8")
521 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_datarel
,
523 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_datarel
,
524 "indirect datarel uleb128")
525 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_datarel
,
526 "indirect datarel udata2")
527 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_datarel
,
528 "indirect datarel udata4")
529 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_datarel
,
530 "indirect datarel udata8")
531 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_datarel
,
532 "indirect datarel sleb128")
533 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_datarel
,
534 "indirect datarel sdata2")
535 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_datarel
,
536 "indirect datarel sdata4")
537 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_datarel
,
538 "indirect datarel sdata8")
540 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_funcrel
,
542 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_funcrel
,
543 "indirect funcrel uleb128")
544 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_funcrel
,
545 "indirect funcrel udata2")
546 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_funcrel
,
547 "indirect funcrel udata4")
548 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_funcrel
,
549 "indirect funcrel udata8")
550 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_funcrel
,
551 "indirect funcrel sleb128")
552 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_funcrel
,
553 "indirect funcrel sdata2")
554 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_funcrel
,
555 "indirect funcrel sdata4")
556 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_funcrel
,
557 "indirect funcrel sdata8")
559 #if HAVE_DESIGNATED_INITIALIZERS
562 gcc_assert (format
>= 0 && format
< 0x100 && format_names
[format
]);
564 return format_names
[format
];
571 /* Output an unsigned LEB128 quantity, but only the byte values. */
574 dw2_asm_output_data_uleb128_raw (unsigned HOST_WIDE_INT value
)
578 int byte
= (value
& 0x7f);
581 /* More bytes to follow. */
584 fprintf (asm_out_file
, "%#x", byte
);
587 fputc (',', asm_out_file
);
591 /* Output an unsigned LEB128 quantity. */
594 dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value
,
595 const char *comment
, ...)
599 va_start (ap
, comment
);
601 #ifdef HAVE_AS_LEB128
602 fputs ("\t.uleb128 ", asm_out_file
);
603 fprint_whex (asm_out_file
, value
);
605 if (flag_debug_asm
&& comment
)
607 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
608 vfprintf (asm_out_file
, comment
, ap
);
612 unsigned HOST_WIDE_INT work
= value
;
613 const char *byte_op
= targetm
.asm_out
.byte_op
;
616 fputs (byte_op
, asm_out_file
);
619 int byte
= (work
& 0x7f);
622 /* More bytes to follow. */
627 fprintf (asm_out_file
, "%#x", byte
);
629 fputc (',', asm_out_file
);
632 assemble_integer (GEN_INT (byte
), 1, BITS_PER_UNIT
, 1);
638 fprintf (asm_out_file
, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX
,
639 ASM_COMMENT_START
, value
);
642 fputs ("; ", asm_out_file
);
643 vfprintf (asm_out_file
, comment
, ap
);
648 putc ('\n', asm_out_file
);
653 /* Output an signed LEB128 quantity, but only the byte values. */
656 dw2_asm_output_data_sleb128_raw (HOST_WIDE_INT value
)
662 byte
= (value
& 0x7f);
664 more
= !((value
== 0 && (byte
& 0x40) == 0)
665 || (value
== -1 && (byte
& 0x40) != 0));
669 fprintf (asm_out_file
, "%#x", byte
);
672 fputc (',', asm_out_file
);
676 /* Output a signed LEB128 quantity. */
679 dw2_asm_output_data_sleb128 (HOST_WIDE_INT value
,
680 const char *comment
, ...)
684 va_start (ap
, comment
);
686 #ifdef HAVE_AS_LEB128
687 fprintf (asm_out_file
, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC
, value
);
689 if (flag_debug_asm
&& comment
)
691 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
692 vfprintf (asm_out_file
, comment
, ap
);
696 HOST_WIDE_INT work
= value
;
698 const char *byte_op
= targetm
.asm_out
.byte_op
;
701 fputs (byte_op
, asm_out_file
);
704 byte
= (work
& 0x7f);
705 /* arithmetic shift */
707 more
= !((work
== 0 && (byte
& 0x40) == 0)
708 || (work
== -1 && (byte
& 0x40) != 0));
714 fprintf (asm_out_file
, "%#x", byte
);
716 fputc (',', asm_out_file
);
719 assemble_integer (GEN_INT (byte
), 1, BITS_PER_UNIT
, 1);
725 fprintf (asm_out_file
, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC
,
726 ASM_COMMENT_START
, value
);
729 fputs ("; ", asm_out_file
);
730 vfprintf (asm_out_file
, comment
, ap
);
735 fputc ('\n', asm_out_file
);
741 dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED
,
742 const char *lab2 ATTRIBUTE_UNUSED
,
743 const char *comment
, ...)
747 va_start (ap
, comment
);
749 #ifdef HAVE_AS_LEB128
750 fputs ("\t.uleb128 ", asm_out_file
);
751 assemble_name (asm_out_file
, lab1
);
752 putc ('-', asm_out_file
);
753 assemble_name (asm_out_file
, lab2
);
758 if (flag_debug_asm
&& comment
)
760 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
761 vfprintf (asm_out_file
, comment
, ap
);
763 fputc ('\n', asm_out_file
);
771 dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED
,
772 const char *lab2 ATTRIBUTE_UNUSED
,
773 const char *comment
, ...)
777 va_start (ap
, comment
);
779 #ifdef HAVE_AS_LEB128
780 fputs ("\t.sleb128 ", asm_out_file
);
781 assemble_name (asm_out_file
, lab1
);
782 putc ('-', asm_out_file
);
783 assemble_name (asm_out_file
, lab2
);
788 if (flag_debug_asm
&& comment
)
790 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
791 vfprintf (asm_out_file
, comment
, ap
);
793 fputc ('\n', asm_out_file
);
799 static GTY(()) hash_map
<const char *, tree
> *indirect_pool
;
801 static GTY(()) int dw2_const_labelno
;
803 #if defined(HAVE_GAS_HIDDEN)
804 # define USE_LINKONCE_INDIRECT (SUPPORTS_ONE_ONLY)
806 # define USE_LINKONCE_INDIRECT 0
809 /* Compare two std::pair<const char *, tree> by their first element.
811 >0 to indicate whether K1 is less than, equal to, or greater than
815 compare_strings (const void *a
, const void *b
)
817 const char *s1
= ((const std::pair
<const char *, tree
> *) a
)->first
;
818 const char *s2
= ((const std::pair
<const char *, tree
> *) b
)->first
;
824 ret
= strcmp (s1
, s2
);
826 /* The strings are always those from IDENTIFIER_NODEs, and,
827 therefore, we should never have two copies of the same
834 /* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
835 memory. Differs from force_const_mem in that a single pool is used for
836 the entire unit of translation, and the memory is not guaranteed to be
837 "near" the function in any interesting sense. IS_PUBLIC controls whether
838 the symbol can be shared across the entire application (or DSO). */
841 dw2_force_const_mem (rtx x
, bool is_public
)
847 indirect_pool
= hash_map
<const char *, tree
>::create_ggc (64);
849 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
852 tree
*slot
= indirect_pool
->get (key
);
858 const char *str
= targetm
.strip_name_encoding (key
);
860 if (is_public
&& USE_LINKONCE_INDIRECT
)
862 char *ref_name
= XALLOCAVEC (char, strlen (str
) + sizeof "DW.ref.");
864 sprintf (ref_name
, "DW.ref.%s", str
);
865 gcc_assert (!maybe_get_identifier (ref_name
));
866 decl_id
= get_identifier (ref_name
);
867 TREE_PUBLIC (decl_id
) = 1;
873 ASM_GENERATE_INTERNAL_LABEL (label
, "LDFCM", dw2_const_labelno
);
875 gcc_assert (!maybe_get_identifier (label
));
876 decl_id
= get_identifier (label
);
879 id
= maybe_get_identifier (str
);
881 TREE_SYMBOL_REFERENCED (id
) = 1;
883 indirect_pool
->put (key
, decl_id
);
886 return gen_rtx_SYMBOL_REF (Pmode
, IDENTIFIER_POINTER (decl_id
));
889 /* A helper function for dw2_output_indirect_constants. Emit one queued
890 constant to memory. */
893 dw2_output_indirect_constant_1 (const char *sym
, tree id
)
898 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, id
, ptr_type_node
);
899 SET_DECL_ASSEMBLER_NAME (decl
, id
);
900 DECL_ARTIFICIAL (decl
) = 1;
901 DECL_IGNORED_P (decl
) = 1;
902 DECL_INITIAL (decl
) = decl
;
903 TREE_READONLY (decl
) = 1;
904 TREE_STATIC (decl
) = 1;
906 if (TREE_PUBLIC (id
))
908 TREE_PUBLIC (decl
) = 1;
909 make_decl_one_only (decl
, DECL_ASSEMBLER_NAME (decl
));
910 if (USE_LINKONCE_INDIRECT
)
911 DECL_VISIBILITY (decl
) = VISIBILITY_HIDDEN
;
914 sym_ref
= gen_rtx_SYMBOL_REF (Pmode
, sym
);
915 assemble_variable (decl
, 1, 1, 1);
916 assemble_integer (sym_ref
, POINTER_SIZE_UNITS
, POINTER_SIZE
, 1);
921 /* Emit the constants queued through dw2_force_const_mem. */
924 dw2_output_indirect_constants (void)
929 auto_vec
<std::pair
<const char *, tree
> > temp (indirect_pool
->elements ());
930 for (hash_map
<const char *, tree
>::iterator iter
= indirect_pool
->begin ();
931 iter
!= indirect_pool
->end (); ++iter
)
932 temp
.quick_push (*iter
);
934 temp
.qsort (compare_strings
);
936 for (unsigned int i
= 0; i
< temp
.length (); i
++)
937 dw2_output_indirect_constant_1 (temp
[i
].first
, temp
[i
].second
);
940 /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed.
941 If PUBLIC is set and the encoding is DW_EH_PE_indirect, the indirect
942 reference is shared across the entire application (or DSO). */
945 dw2_asm_output_encoded_addr_rtx (int encoding
, rtx addr
, bool is_public
,
946 const char *comment
, ...)
951 va_start (ap
, comment
);
953 size
= size_of_encoded_value (encoding
);
955 if (encoding
== DW_EH_PE_aligned
)
957 assemble_align (POINTER_SIZE
);
958 assemble_integer (addr
, size
, POINTER_SIZE
, 1);
963 /* NULL is _always_ represented as a plain zero, as is 1 for Ada's
965 if (addr
== const0_rtx
|| addr
== const1_rtx
)
966 assemble_integer (addr
, size
, BITS_PER_UNIT
, 1);
970 /* Allow the target first crack at emitting this. Some of the
971 special relocations require special directives instead of
972 just ".4byte" or whatever. */
973 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
974 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file
, encoding
, size
,
978 /* Indirection is used to get dynamic relocations out of a
979 read-only section. */
980 if (encoding
& DW_EH_PE_indirect
)
982 /* It is very tempting to use force_const_mem so that we share data
983 with the normal constant pool. However, we've already emitted
984 the constant pool for this function. Moreover, we'd like to
985 share these constants across the entire unit of translation and
986 even, if possible, across the entire application (or DSO). */
987 addr
= dw2_force_const_mem (addr
, is_public
);
988 encoding
&= ~DW_EH_PE_indirect
;
992 switch (encoding
& 0xF0)
994 case DW_EH_PE_absptr
:
995 dw2_assemble_integer (size
, addr
);
999 gcc_assert (GET_CODE (addr
) == SYMBOL_REF
);
1000 #ifdef ASM_OUTPUT_DWARF_PCREL
1001 ASM_OUTPUT_DWARF_PCREL (asm_out_file
, size
, XSTR (addr
, 0));
1003 dw2_assemble_integer (size
, gen_rtx_MINUS (Pmode
, addr
, pc_rtx
));
1008 /* Other encodings should have been handled by
1009 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */
1013 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
1018 if (flag_debug_asm
&& comment
)
1020 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
1021 vfprintf (asm_out_file
, comment
, ap
);
1023 fputc ('\n', asm_out_file
);
1028 #include "gt-dwarf2asm.h"