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 "stringpool.h"
34 #include "dwarf2asm.h"
39 /* Output an unaligned integer with the given value and size. Prefer not
40 to print a newline, since the caller may want to add a comment. */
43 dw2_assemble_integer (int size
, rtx x
)
45 const char *op
= integer_asm_op (size
, FALSE
);
49 fputs (op
, asm_out_file
);
51 fprint_whex (asm_out_file
, (unsigned HOST_WIDE_INT
) INTVAL (x
));
53 output_addr_const (asm_out_file
, x
);
56 assemble_integer (x
, size
, BITS_PER_UNIT
, 1);
60 /* Output a value of a given size in target byte order. */
63 dw2_asm_output_data_raw (int size
, unsigned HOST_WIDE_INT value
)
65 unsigned char bytes
[8];
68 for (i
= 0; i
< 8; ++i
)
70 bytes
[i
] = value
& 0xff;
76 for (i
= size
- 1; i
> 0; --i
)
77 fprintf (asm_out_file
, "%#x,", bytes
[i
]);
78 fprintf (asm_out_file
, "%#x", bytes
[0]);
82 for (i
= 0; i
< size
- 1; ++i
)
83 fprintf (asm_out_file
, "%#x,", bytes
[i
]);
84 fprintf (asm_out_file
, "%#x", bytes
[i
]);
88 /* Output an immediate constant in a given SIZE in bytes. */
91 dw2_asm_output_data (int size
, unsigned HOST_WIDE_INT value
,
92 const char *comment
, ...)
95 const char *op
= integer_asm_op (size
, FALSE
);
97 va_start (ap
, comment
);
99 if (size
* 8 < HOST_BITS_PER_WIDE_INT
)
100 value
&= ~(~(unsigned HOST_WIDE_INT
) 0 << (size
* 8));
104 fputs (op
, asm_out_file
);
105 fprint_whex (asm_out_file
, value
);
108 assemble_integer (GEN_INT (value
), size
, BITS_PER_UNIT
, 1);
110 if (flag_debug_asm
&& comment
)
112 fputs ("\t" ASM_COMMENT_START
" ", asm_out_file
);
113 vfprintf (asm_out_file
, comment
, ap
);
115 putc ('\n', asm_out_file
);
120 /* Output the difference between two symbols in a given size. */
121 /* ??? There appear to be assemblers that do not like such
122 subtraction, but do support ASM_SET_OP. It's unfortunately
123 impossible to do here, since the ASM_SET_OP for the difference
124 symbol must appear after both symbols are defined. */
127 dw2_asm_output_delta (int size
, const char *lab1
, const char *lab2
,
128 const char *comment
, ...)
132 va_start (ap
, comment
);
134 #ifdef ASM_OUTPUT_DWARF_DELTA
135 ASM_OUTPUT_DWARF_DELTA (asm_out_file
, size
, lab1
, lab2
);
137 dw2_assemble_integer (size
,
138 gen_rtx_MINUS (Pmode
,
139 gen_rtx_SYMBOL_REF (Pmode
, lab1
),
140 gen_rtx_SYMBOL_REF (Pmode
, lab2
)));
142 if (flag_debug_asm
&& comment
)
144 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
145 vfprintf (asm_out_file
, comment
, ap
);
147 fputc ('\n', asm_out_file
);
152 #ifdef ASM_OUTPUT_DWARF_VMS_DELTA
153 /* Output the difference between two symbols in instruction units
157 dw2_asm_output_vms_delta (int size ATTRIBUTE_UNUSED
,
158 const char *lab1
, const char *lab2
,
159 const char *comment
, ...)
163 va_start (ap
, comment
);
165 ASM_OUTPUT_DWARF_VMS_DELTA (asm_out_file
, size
, lab1
, lab2
);
166 if (flag_debug_asm
&& comment
)
168 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
169 vfprintf (asm_out_file
, comment
, ap
);
171 fputc ('\n', asm_out_file
);
177 /* Output a section-relative reference to a LABEL, which was placed in
178 BASE. In general this can only be done for debugging symbols.
179 E.g. on most targets with the GNU linker, this is accomplished with
180 a direct reference and the knowledge that the debugging section
181 will be placed at VMA 0. Some targets have special relocations for
182 this that we must use. */
185 dw2_asm_output_offset (int size
, const char *label
,
186 section
*base ATTRIBUTE_UNUSED
,
187 const char *comment
, ...)
191 va_start (ap
, comment
);
193 #ifdef ASM_OUTPUT_DWARF_OFFSET
194 ASM_OUTPUT_DWARF_OFFSET (asm_out_file
, size
, label
, base
);
196 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
);
211 /* Output a self-relative reference to a label, possibly in a
212 different section or object file. */
215 dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED
,
216 const char *label ATTRIBUTE_UNUSED
,
217 const char *comment
, ...)
221 va_start (ap
, comment
);
223 #ifdef ASM_OUTPUT_DWARF_PCREL
224 ASM_OUTPUT_DWARF_PCREL (asm_out_file
, size
, label
);
226 dw2_assemble_integer (size
,
227 gen_rtx_MINUS (Pmode
,
228 gen_rtx_SYMBOL_REF (Pmode
, label
),
232 if (flag_debug_asm
&& comment
)
234 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
235 vfprintf (asm_out_file
, comment
, ap
);
237 fputc ('\n', asm_out_file
);
243 /* Output an absolute reference to a label. */
246 dw2_asm_output_addr (int size
, const char *label
,
247 const char *comment
, ...)
251 va_start (ap
, comment
);
253 dw2_assemble_integer (size
, gen_rtx_SYMBOL_REF (Pmode
, label
));
255 if (flag_debug_asm
&& comment
)
257 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
258 vfprintf (asm_out_file
, comment
, ap
);
260 fputc ('\n', asm_out_file
);
265 /* Similar, but use an RTX expression instead of a text label. */
268 dw2_asm_output_addr_rtx (int size
, rtx addr
,
269 const char *comment
, ...)
273 va_start (ap
, comment
);
275 dw2_assemble_integer (size
, addr
);
277 if (flag_debug_asm
&& comment
)
279 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
280 vfprintf (asm_out_file
, comment
, ap
);
282 fputc ('\n', asm_out_file
);
287 /* Output the first ORIG_LEN characters of STR as a string.
288 If ORIG_LEN is equal to -1, ignore this parameter and output
289 the entire STR instead.
290 If COMMENT is not NULL and comments in the debug information
291 have been requested by the user, append the given COMMENT
292 to the generated output. */
295 dw2_asm_output_nstring (const char *str
, size_t orig_len
,
296 const char *comment
, ...)
301 va_start (ap
, comment
);
305 if (len
== (size_t) -1)
308 if (flag_debug_asm
&& comment
)
310 fputs ("\t.ascii \"", asm_out_file
);
311 for (i
= 0; i
< len
; i
++)
314 if (c
== '\"' || c
== '\\')
315 fputc ('\\', asm_out_file
);
317 fputc (c
, asm_out_file
);
319 fprintf (asm_out_file
, "\\%o", c
);
321 fprintf (asm_out_file
, "\\0\"\t%s ", ASM_COMMENT_START
);
322 vfprintf (asm_out_file
, comment
, ap
);
323 fputc ('\n', asm_out_file
);
327 /* If an explicit length was given, we can't assume there
328 is a null termination in the string buffer. */
329 if (orig_len
== (size_t) -1)
331 ASM_OUTPUT_ASCII (asm_out_file
, str
, len
);
332 if (orig_len
!= (size_t) -1)
333 assemble_integer (const0_rtx
, 1, BITS_PER_UNIT
, 1);
340 /* Return the size of an unsigned LEB128 quantity. */
343 size_of_uleb128 (unsigned HOST_WIDE_INT value
)
357 /* Return the size of a signed LEB128 quantity. */
360 size_of_sleb128 (HOST_WIDE_INT value
)
366 byte
= (value
& 0x7f);
370 while (!((value
== 0 && (byte
& 0x40) == 0)
371 || (value
== -1 && (byte
& 0x40) != 0)));
376 /* Given an encoding, return the number of bytes the format occupies.
377 This is only defined for fixed-size encodings, and so does not
381 size_of_encoded_value (int encoding
)
383 if (encoding
== DW_EH_PE_omit
)
386 switch (encoding
& 0x07)
388 case DW_EH_PE_absptr
:
389 return POINTER_SIZE_UNITS
;
390 case DW_EH_PE_udata2
:
392 case DW_EH_PE_udata4
:
394 case DW_EH_PE_udata8
:
401 /* Yield a name for a given pointer encoding. */
404 eh_data_format_name (int format
)
406 #if HAVE_DESIGNATED_INITIALIZERS
407 #define S(p, v) [p] = v,
409 #define S(p, v) case p: return v;
412 #if HAVE_DESIGNATED_INITIALIZERS
413 __extension__
static const char * const format_names
[256] = {
418 S(DW_EH_PE_absptr
, "absolute")
419 S(DW_EH_PE_omit
, "omit")
420 S(DW_EH_PE_aligned
, "aligned absolute")
422 S(DW_EH_PE_uleb128
, "uleb128")
423 S(DW_EH_PE_udata2
, "udata2")
424 S(DW_EH_PE_udata4
, "udata4")
425 S(DW_EH_PE_udata8
, "udata8")
426 S(DW_EH_PE_sleb128
, "sleb128")
427 S(DW_EH_PE_sdata2
, "sdata2")
428 S(DW_EH_PE_sdata4
, "sdata4")
429 S(DW_EH_PE_sdata8
, "sdata8")
431 S(DW_EH_PE_absptr
| DW_EH_PE_pcrel
, "pcrel")
432 S(DW_EH_PE_uleb128
| DW_EH_PE_pcrel
, "pcrel uleb128")
433 S(DW_EH_PE_udata2
| DW_EH_PE_pcrel
, "pcrel udata2")
434 S(DW_EH_PE_udata4
| DW_EH_PE_pcrel
, "pcrel udata4")
435 S(DW_EH_PE_udata8
| DW_EH_PE_pcrel
, "pcrel udata8")
436 S(DW_EH_PE_sleb128
| DW_EH_PE_pcrel
, "pcrel sleb128")
437 S(DW_EH_PE_sdata2
| DW_EH_PE_pcrel
, "pcrel sdata2")
438 S(DW_EH_PE_sdata4
| DW_EH_PE_pcrel
, "pcrel sdata4")
439 S(DW_EH_PE_sdata8
| DW_EH_PE_pcrel
, "pcrel sdata8")
441 S(DW_EH_PE_absptr
| DW_EH_PE_textrel
, "textrel")
442 S(DW_EH_PE_uleb128
| DW_EH_PE_textrel
, "textrel uleb128")
443 S(DW_EH_PE_udata2
| DW_EH_PE_textrel
, "textrel udata2")
444 S(DW_EH_PE_udata4
| DW_EH_PE_textrel
, "textrel udata4")
445 S(DW_EH_PE_udata8
| DW_EH_PE_textrel
, "textrel udata8")
446 S(DW_EH_PE_sleb128
| DW_EH_PE_textrel
, "textrel sleb128")
447 S(DW_EH_PE_sdata2
| DW_EH_PE_textrel
, "textrel sdata2")
448 S(DW_EH_PE_sdata4
| DW_EH_PE_textrel
, "textrel sdata4")
449 S(DW_EH_PE_sdata8
| DW_EH_PE_textrel
, "textrel sdata8")
451 S(DW_EH_PE_absptr
| DW_EH_PE_datarel
, "datarel")
452 S(DW_EH_PE_uleb128
| DW_EH_PE_datarel
, "datarel uleb128")
453 S(DW_EH_PE_udata2
| DW_EH_PE_datarel
, "datarel udata2")
454 S(DW_EH_PE_udata4
| DW_EH_PE_datarel
, "datarel udata4")
455 S(DW_EH_PE_udata8
| DW_EH_PE_datarel
, "datarel udata8")
456 S(DW_EH_PE_sleb128
| DW_EH_PE_datarel
, "datarel sleb128")
457 S(DW_EH_PE_sdata2
| DW_EH_PE_datarel
, "datarel sdata2")
458 S(DW_EH_PE_sdata4
| DW_EH_PE_datarel
, "datarel sdata4")
459 S(DW_EH_PE_sdata8
| DW_EH_PE_datarel
, "datarel sdata8")
461 S(DW_EH_PE_absptr
| DW_EH_PE_funcrel
, "funcrel")
462 S(DW_EH_PE_uleb128
| DW_EH_PE_funcrel
, "funcrel uleb128")
463 S(DW_EH_PE_udata2
| DW_EH_PE_funcrel
, "funcrel udata2")
464 S(DW_EH_PE_udata4
| DW_EH_PE_funcrel
, "funcrel udata4")
465 S(DW_EH_PE_udata8
| DW_EH_PE_funcrel
, "funcrel udata8")
466 S(DW_EH_PE_sleb128
| DW_EH_PE_funcrel
, "funcrel sleb128")
467 S(DW_EH_PE_sdata2
| DW_EH_PE_funcrel
, "funcrel sdata2")
468 S(DW_EH_PE_sdata4
| DW_EH_PE_funcrel
, "funcrel sdata4")
469 S(DW_EH_PE_sdata8
| DW_EH_PE_funcrel
, "funcrel sdata8")
471 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
, "indirect absolute")
473 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_pcrel
,
475 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_pcrel
,
476 "indirect pcrel uleb128")
477 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_pcrel
,
478 "indirect pcrel udata2")
479 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_pcrel
,
480 "indirect pcrel udata4")
481 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_pcrel
,
482 "indirect pcrel udata8")
483 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_pcrel
,
484 "indirect pcrel sleb128")
485 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_pcrel
,
486 "indirect pcrel sdata2")
487 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_pcrel
,
488 "indirect pcrel sdata4")
489 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_pcrel
,
490 "indirect pcrel sdata8")
492 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_textrel
,
494 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_textrel
,
495 "indirect textrel uleb128")
496 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_textrel
,
497 "indirect textrel udata2")
498 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_textrel
,
499 "indirect textrel udata4")
500 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_textrel
,
501 "indirect textrel udata8")
502 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_textrel
,
503 "indirect textrel sleb128")
504 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_textrel
,
505 "indirect textrel sdata2")
506 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_textrel
,
507 "indirect textrel sdata4")
508 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_textrel
,
509 "indirect textrel sdata8")
511 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_datarel
,
513 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_datarel
,
514 "indirect datarel uleb128")
515 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_datarel
,
516 "indirect datarel udata2")
517 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_datarel
,
518 "indirect datarel udata4")
519 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_datarel
,
520 "indirect datarel udata8")
521 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_datarel
,
522 "indirect datarel sleb128")
523 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_datarel
,
524 "indirect datarel sdata2")
525 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_datarel
,
526 "indirect datarel sdata4")
527 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_datarel
,
528 "indirect datarel sdata8")
530 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_funcrel
,
532 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_funcrel
,
533 "indirect funcrel uleb128")
534 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_funcrel
,
535 "indirect funcrel udata2")
536 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_funcrel
,
537 "indirect funcrel udata4")
538 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_funcrel
,
539 "indirect funcrel udata8")
540 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_funcrel
,
541 "indirect funcrel sleb128")
542 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_funcrel
,
543 "indirect funcrel sdata2")
544 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_funcrel
,
545 "indirect funcrel sdata4")
546 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_funcrel
,
547 "indirect funcrel sdata8")
549 #if HAVE_DESIGNATED_INITIALIZERS
552 gcc_assert (format
>= 0 && format
< 0x100 && format_names
[format
]);
554 return format_names
[format
];
561 /* Output an unsigned LEB128 quantity, but only the byte values. */
564 dw2_asm_output_data_uleb128_raw (unsigned HOST_WIDE_INT value
)
568 int byte
= (value
& 0x7f);
571 /* More bytes to follow. */
574 fprintf (asm_out_file
, "%#x", byte
);
577 fputc (',', asm_out_file
);
581 /* Output an unsigned LEB128 quantity. */
584 dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value
,
585 const char *comment
, ...)
589 va_start (ap
, comment
);
591 #ifdef HAVE_AS_LEB128
592 fputs ("\t.uleb128 ", asm_out_file
);
593 fprint_whex (asm_out_file
, value
);
595 if (flag_debug_asm
&& comment
)
597 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
598 vfprintf (asm_out_file
, comment
, ap
);
602 unsigned HOST_WIDE_INT work
= value
;
603 const char *byte_op
= targetm
.asm_out
.byte_op
;
606 fputs (byte_op
, asm_out_file
);
609 int byte
= (work
& 0x7f);
612 /* More bytes to follow. */
617 fprintf (asm_out_file
, "%#x", byte
);
619 fputc (',', asm_out_file
);
622 assemble_integer (GEN_INT (byte
), 1, BITS_PER_UNIT
, 1);
628 fprintf (asm_out_file
, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX
,
629 ASM_COMMENT_START
, value
);
632 fputs ("; ", asm_out_file
);
633 vfprintf (asm_out_file
, comment
, ap
);
638 putc ('\n', asm_out_file
);
643 /* Output an signed LEB128 quantity, but only the byte values. */
646 dw2_asm_output_data_sleb128_raw (HOST_WIDE_INT value
)
652 byte
= (value
& 0x7f);
654 more
= !((value
== 0 && (byte
& 0x40) == 0)
655 || (value
== -1 && (byte
& 0x40) != 0));
659 fprintf (asm_out_file
, "%#x", byte
);
662 fputc (',', asm_out_file
);
666 /* Output a signed LEB128 quantity. */
669 dw2_asm_output_data_sleb128 (HOST_WIDE_INT value
,
670 const char *comment
, ...)
674 va_start (ap
, comment
);
676 #ifdef HAVE_AS_LEB128
677 fprintf (asm_out_file
, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC
, value
);
679 if (flag_debug_asm
&& comment
)
681 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
682 vfprintf (asm_out_file
, comment
, ap
);
686 HOST_WIDE_INT work
= value
;
688 const char *byte_op
= targetm
.asm_out
.byte_op
;
691 fputs (byte_op
, asm_out_file
);
694 byte
= (work
& 0x7f);
695 /* arithmetic shift */
697 more
= !((work
== 0 && (byte
& 0x40) == 0)
698 || (work
== -1 && (byte
& 0x40) != 0));
704 fprintf (asm_out_file
, "%#x", byte
);
706 fputc (',', asm_out_file
);
709 assemble_integer (GEN_INT (byte
), 1, BITS_PER_UNIT
, 1);
715 fprintf (asm_out_file
, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC
,
716 ASM_COMMENT_START
, value
);
719 fputs ("; ", asm_out_file
);
720 vfprintf (asm_out_file
, comment
, ap
);
725 fputc ('\n', asm_out_file
);
731 dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED
,
732 const char *lab2 ATTRIBUTE_UNUSED
,
733 const char *comment
, ...)
737 va_start (ap
, comment
);
739 #ifdef HAVE_AS_LEB128
740 fputs ("\t.uleb128 ", asm_out_file
);
741 assemble_name (asm_out_file
, lab1
);
742 putc ('-', asm_out_file
);
743 assemble_name (asm_out_file
, lab2
);
748 if (flag_debug_asm
&& comment
)
750 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
751 vfprintf (asm_out_file
, comment
, ap
);
753 fputc ('\n', asm_out_file
);
761 dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED
,
762 const char *lab2 ATTRIBUTE_UNUSED
,
763 const char *comment
, ...)
767 va_start (ap
, comment
);
769 #ifdef HAVE_AS_LEB128
770 fputs ("\t.sleb128 ", asm_out_file
);
771 assemble_name (asm_out_file
, lab1
);
772 putc ('-', asm_out_file
);
773 assemble_name (asm_out_file
, lab2
);
778 if (flag_debug_asm
&& comment
)
780 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
781 vfprintf (asm_out_file
, comment
, ap
);
783 fputc ('\n', asm_out_file
);
789 static GTY(()) hash_map
<const char *, tree
> *indirect_pool
;
791 static GTY(()) int dw2_const_labelno
;
793 #if defined(HAVE_GAS_HIDDEN)
794 # define USE_LINKONCE_INDIRECT (SUPPORTS_ONE_ONLY)
796 # define USE_LINKONCE_INDIRECT 0
799 /* Compare two std::pair<const char *, tree> by their first element.
801 >0 to indicate whether K1 is less than, equal to, or greater than
805 compare_strings (const void *a
, const void *b
)
807 const char *s1
= ((const std::pair
<const char *, tree
> *) a
)->first
;
808 const char *s2
= ((const std::pair
<const char *, tree
> *) b
)->first
;
814 ret
= strcmp (s1
, s2
);
816 /* The strings are always those from IDENTIFIER_NODEs, and,
817 therefore, we should never have two copies of the same
824 /* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
825 memory. Differs from force_const_mem in that a single pool is used for
826 the entire unit of translation, and the memory is not guaranteed to be
827 "near" the function in any interesting sense. IS_PUBLIC controls whether
828 the symbol can be shared across the entire application (or DSO). */
831 dw2_force_const_mem (rtx x
, bool is_public
)
837 indirect_pool
= hash_map
<const char *, tree
>::create_ggc (64);
839 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
842 tree
*slot
= indirect_pool
->get (key
);
848 const char *str
= targetm
.strip_name_encoding (key
);
850 if (is_public
&& USE_LINKONCE_INDIRECT
)
852 char *ref_name
= XALLOCAVEC (char, strlen (str
) + sizeof "DW.ref.");
854 sprintf (ref_name
, "DW.ref.%s", str
);
855 gcc_assert (!maybe_get_identifier (ref_name
));
856 decl_id
= get_identifier (ref_name
);
857 TREE_PUBLIC (decl_id
) = 1;
863 ASM_GENERATE_INTERNAL_LABEL (label
, "LDFCM", dw2_const_labelno
);
865 gcc_assert (!maybe_get_identifier (label
));
866 decl_id
= get_identifier (label
);
869 id
= maybe_get_identifier (str
);
871 TREE_SYMBOL_REFERENCED (id
) = 1;
873 indirect_pool
->put (key
, decl_id
);
876 return gen_rtx_SYMBOL_REF (Pmode
, IDENTIFIER_POINTER (decl_id
));
879 /* A helper function for dw2_output_indirect_constants. Emit one queued
880 constant to memory. */
883 dw2_output_indirect_constant_1 (const char *sym
, tree id
)
888 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, id
, ptr_type_node
);
889 SET_DECL_ASSEMBLER_NAME (decl
, id
);
890 DECL_ARTIFICIAL (decl
) = 1;
891 DECL_IGNORED_P (decl
) = 1;
892 DECL_INITIAL (decl
) = decl
;
893 TREE_READONLY (decl
) = 1;
894 TREE_STATIC (decl
) = 1;
896 if (TREE_PUBLIC (id
))
898 TREE_PUBLIC (decl
) = 1;
899 make_decl_one_only (decl
, DECL_ASSEMBLER_NAME (decl
));
900 if (USE_LINKONCE_INDIRECT
)
901 DECL_VISIBILITY (decl
) = VISIBILITY_HIDDEN
;
904 sym_ref
= gen_rtx_SYMBOL_REF (Pmode
, sym
);
905 assemble_variable (decl
, 1, 1, 1);
906 assemble_integer (sym_ref
, POINTER_SIZE_UNITS
, POINTER_SIZE
, 1);
911 /* Emit the constants queued through dw2_force_const_mem. */
914 dw2_output_indirect_constants (void)
919 auto_vec
<std::pair
<const char *, tree
> > temp (indirect_pool
->elements ());
920 for (hash_map
<const char *, tree
>::iterator iter
= indirect_pool
->begin ();
921 iter
!= indirect_pool
->end (); ++iter
)
922 temp
.quick_push (*iter
);
924 temp
.qsort (compare_strings
);
926 for (unsigned int i
= 0; i
< temp
.length (); i
++)
927 dw2_output_indirect_constant_1 (temp
[i
].first
, temp
[i
].second
);
930 /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed.
931 If PUBLIC is set and the encoding is DW_EH_PE_indirect, the indirect
932 reference is shared across the entire application (or DSO). */
935 dw2_asm_output_encoded_addr_rtx (int encoding
, rtx addr
, bool is_public
,
936 const char *comment
, ...)
941 va_start (ap
, comment
);
943 size
= size_of_encoded_value (encoding
);
945 if (encoding
== DW_EH_PE_aligned
)
947 assemble_align (POINTER_SIZE
);
948 assemble_integer (addr
, size
, POINTER_SIZE
, 1);
953 /* NULL is _always_ represented as a plain zero, as is 1 for Ada's
955 if (addr
== const0_rtx
|| addr
== const1_rtx
)
956 assemble_integer (addr
, size
, BITS_PER_UNIT
, 1);
960 /* Allow the target first crack at emitting this. Some of the
961 special relocations require special directives instead of
962 just ".4byte" or whatever. */
963 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
964 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file
, encoding
, size
,
968 /* Indirection is used to get dynamic relocations out of a
969 read-only section. */
970 if (encoding
& DW_EH_PE_indirect
)
972 /* It is very tempting to use force_const_mem so that we share data
973 with the normal constant pool. However, we've already emitted
974 the constant pool for this function. Moreover, we'd like to
975 share these constants across the entire unit of translation and
976 even, if possible, across the entire application (or DSO). */
977 addr
= dw2_force_const_mem (addr
, is_public
);
978 encoding
&= ~DW_EH_PE_indirect
;
982 switch (encoding
& 0xF0)
984 case DW_EH_PE_absptr
:
985 dw2_assemble_integer (size
, addr
);
989 gcc_assert (GET_CODE (addr
) == SYMBOL_REF
);
990 #ifdef ASM_OUTPUT_DWARF_PCREL
991 ASM_OUTPUT_DWARF_PCREL (asm_out_file
, size
, XSTR (addr
, 0));
993 dw2_assemble_integer (size
, gen_rtx_MINUS (Pmode
, addr
, pc_rtx
));
998 /* Other encodings should have been handled by
999 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */
1003 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
1008 if (flag_debug_asm
&& comment
)
1010 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
1011 vfprintf (asm_out_file
, comment
, ap
);
1013 fputc ('\n', asm_out_file
);
1018 #include "gt-dwarf2asm.h"