1 /* Dwarf2 assembler output helper routines.
2 Copyright (C) 2001 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
28 #include "dwarf2asm.h"
30 #include "splay-tree.h"
35 /* How to start an assembler comment. */
36 #ifndef ASM_COMMENT_START
37 #define ASM_COMMENT_START ";#"
40 /* We don't have unaligned support, let's hope the normal output works for
41 .debug_frame. But we know it won't work for .debug_info. */
42 #if !defined(UNALIGNED_INT_ASM_OP) && defined(DWARF2_DEBUGGING_INFO)
43 #error DWARF2_DEBUGGING_INFO requires UNALIGNED_INT_ASM_OP.
47 /* Despite the fact that assemble_integer handles unaligned data,
48 continue emitting things by hand when possible, since that makes
49 the assembler commentary come out prettier. */
50 #ifdef UNALIGNED_INT_ASM_OP
51 static const char * unaligned_integer_asm_op PARAMS ((int));
53 static inline const char *
54 unaligned_integer_asm_op (size)
64 op = UNALIGNED_SHORT_ASM_OP;
67 op = UNALIGNED_INT_ASM_OP;
70 #ifdef UNALIGNED_DOUBLE_INT_ASM_OP
71 op = UNALIGNED_DOUBLE_INT_ASM_OP;
79 #endif /* UNALIGNED_INT_ASM_OP */
81 /* Output an immediate constant in a given size. */
84 dw2_asm_output_data VPARAMS ((int size, unsigned HOST_WIDE_INT value,
85 const char *comment, ...))
87 VA_OPEN (ap, comment);
88 VA_FIXEDARG (ap, int, size);
89 VA_FIXEDARG (ap, unsigned HOST_WIDE_INT, value);
90 VA_FIXEDARG (ap, const char *, comment);
92 if (size * 8 < HOST_BITS_PER_WIDE_INT)
93 value &= ~(~(unsigned HOST_WIDE_INT)0 << (size * 8));
95 #ifdef UNALIGNED_INT_ASM_OP
96 fputs (unaligned_integer_asm_op (size), asm_out_file);
97 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
99 assemble_integer (GEN_INT (value), size, BITS_PER_UNIT, 1);
102 if (flag_debug_asm && comment)
104 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
105 vfprintf (asm_out_file, comment, ap);
107 fputc ('\n', asm_out_file);
112 /* Output the difference between two symbols in a given size. */
113 /* ??? There appear to be assemblers that do not like such
114 subtraction, but do support ASM_SET_OP. It's unfortunately
115 impossible to do here, since the ASM_SET_OP for the difference
116 symbol must appear after both symbols are defined. */
119 dw2_asm_output_delta VPARAMS ((int size, const char *lab1, const char *lab2,
120 const char *comment, ...))
122 VA_OPEN (ap, comment);
123 VA_FIXEDARG (ap, int, size);
124 VA_FIXEDARG (ap, const char *, lab1);
125 VA_FIXEDARG (ap, const char *, lab2);
126 VA_FIXEDARG (ap, const char *, comment);
128 #ifdef UNALIGNED_INT_ASM_OP
129 fputs (unaligned_integer_asm_op (size), asm_out_file);
130 assemble_name (asm_out_file, lab1);
131 fputc ('-', asm_out_file);
132 assemble_name (asm_out_file, lab2);
134 assemble_integer (gen_rtx_MINUS (Pmode, gen_rtx_SYMBOL_REF (Pmode, lab1),
135 gen_rtx_SYMBOL_REF (Pmode, lab2)),
136 size, BITS_PER_UNIT, 1);
139 if (flag_debug_asm && comment)
141 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
142 vfprintf (asm_out_file, comment, ap);
144 fputc ('\n', asm_out_file);
149 /* Output a section-relative reference to a label. In general this
150 can only be done for debugging symbols. E.g. on most targets with
151 the GNU linker, this is accomplished with a direct reference and
152 the knowledge that the debugging section will be placed at VMA 0.
153 Some targets have special relocations for this that we must use. */
156 dw2_asm_output_offset VPARAMS ((int size, const char *label,
157 const char *comment, ...))
159 VA_OPEN (ap, comment);
160 VA_FIXEDARG (ap, int, size);
161 VA_FIXEDARG (ap, const char *, label);
162 VA_FIXEDARG (ap, const char *, comment);
164 #ifdef ASM_OUTPUT_DWARF_OFFSET
165 ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label);
167 #ifdef UNALIGNED_INT_ASM_OP
168 fputs (unaligned_integer_asm_op (size), asm_out_file);
169 assemble_name (asm_out_file, label);
171 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, label), size, BITS_PER_UNIT, 1);
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 a self-relative reference to a label, possibly in a
186 different section or object file. */
189 dw2_asm_output_pcrel VPARAMS ((int size, const char *label,
190 const char *comment, ...))
192 VA_OPEN (ap, comment);
193 VA_FIXEDARG (ap, int, size);
194 VA_FIXEDARG (ap, const char *, label);
195 VA_FIXEDARG (ap, const char *, comment);
197 #ifdef ASM_OUTPUT_DWARF_PCREL
198 ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label);
200 #ifdef UNALIGNED_INT_ASM_OP
201 fputs (unaligned_integer_asm_op (size), asm_out_file);
202 assemble_name (asm_out_file, label);
203 fputc ('-', asm_out_file);
204 fputc ('.', asm_out_file);
210 if (flag_debug_asm && comment)
212 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
213 vfprintf (asm_out_file, comment, ap);
215 fputc ('\n', asm_out_file);
220 /* Output an absolute reference to a label. */
223 dw2_asm_output_addr VPARAMS ((int size, const char *label,
224 const char *comment, ...))
226 VA_OPEN (ap, comment);
227 VA_FIXEDARG (ap, int, size);
228 VA_FIXEDARG (ap, const char *, label);
229 VA_FIXEDARG (ap, const char *, comment);
231 #ifdef UNALIGNED_INT_ASM_OP
232 fputs (unaligned_integer_asm_op (size), asm_out_file);
233 assemble_name (asm_out_file, label);
235 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, label), size, BITS_PER_UNIT, 1);
238 if (flag_debug_asm && comment)
240 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
241 vfprintf (asm_out_file, comment, ap);
243 fputc ('\n', asm_out_file);
248 /* Similar, but use an RTX expression instead of a text label. */
251 dw2_asm_output_addr_rtx VPARAMS ((int size, rtx addr,
252 const char *comment, ...))
254 VA_OPEN (ap, comment);
255 VA_FIXEDARG (ap, int, size);
256 VA_FIXEDARG (ap, rtx, addr);
257 VA_FIXEDARG (ap, const char *, comment);
259 #ifdef UNALIGNED_INT_ASM_OP
260 fputs (unaligned_integer_asm_op (size), asm_out_file);
261 output_addr_const (asm_out_file, addr);
263 assemble_integer (addr, size, BITS_PER_UNIT, 1);
266 if (flag_debug_asm && comment)
268 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
269 vfprintf (asm_out_file, comment, ap);
271 fputc ('\n', asm_out_file);
277 dw2_asm_output_nstring VPARAMS ((const char *str, size_t orig_len,
278 const char *comment, ...))
282 VA_OPEN (ap, comment);
283 VA_FIXEDARG (ap, const char *, str);
284 VA_FIXEDARG (ap, size_t, orig_len);
285 VA_FIXEDARG (ap, const char *, comment);
289 if (len == (size_t) -1)
292 if (flag_debug_asm && comment)
294 fputs ("\t.ascii \"", asm_out_file);
295 for (i = 0; i < len; i++)
298 if (c == '\"' || c == '\\')
299 fputc ('\\', asm_out_file);
301 fputc (c, asm_out_file);
303 fprintf (asm_out_file, "\\%o", c);
305 fprintf (asm_out_file, "\\0\"\t%s ", ASM_COMMENT_START);
306 vfprintf (asm_out_file, comment, ap);
307 fputc ('\n', asm_out_file);
311 /* If an explicit length was given, we can't assume there
312 is a null termination in the string buffer. */
313 if (orig_len == (size_t) -1)
315 ASM_OUTPUT_ASCII (asm_out_file, str, len);
316 if (orig_len != (size_t) -1)
317 fprintf (asm_out_file, "%s0\n", ASM_BYTE_OP);
324 /* Return the size of an unsigned LEB128 quantity. */
327 size_of_uleb128 (value)
328 unsigned HOST_WIDE_INT value;
334 byte = (value & 0x7f);
343 /* Return the size of a signed LEB128 quantity. */
346 size_of_sleb128 (value)
353 byte = (value & 0x7f);
357 while (!((value == 0 && (byte & 0x40) == 0)
358 || (value == -1 && (byte & 0x40) != 0)));
363 /* Given an encoding, return the number of bytes the format occupies.
364 This is only defined for fixed-size encodings, and so does not
368 size_of_encoded_value (encoding)
371 if (encoding == DW_EH_PE_omit)
374 switch (encoding & 0x07)
376 case DW_EH_PE_absptr:
377 return POINTER_SIZE / BITS_PER_UNIT;
378 case DW_EH_PE_udata2:
380 case DW_EH_PE_udata4:
382 case DW_EH_PE_udata8:
388 /* Yield a name for a given pointer encoding. */
391 eh_data_format_name (format)
394 #if HAVE_DESIGNATED_INITIALIZERS
395 #define S(p, v) [p] = v,
397 #define S(p, v) case p: return v;
400 #if HAVE_DESIGNATED_INITIALIZERS
401 __extension__ static const char * const format_names[256] = {
406 S(DW_EH_PE_absptr, "absolute")
407 S(DW_EH_PE_omit, "omit")
408 S(DW_EH_PE_aligned, "aligned absolute")
410 S(DW_EH_PE_uleb128, "uleb128")
411 S(DW_EH_PE_udata2, "udata2")
412 S(DW_EH_PE_udata4, "udata4")
413 S(DW_EH_PE_udata8, "udata8")
414 S(DW_EH_PE_sleb128, "sleb128")
415 S(DW_EH_PE_sdata2, "sdata2")
416 S(DW_EH_PE_sdata4, "sdata4")
417 S(DW_EH_PE_sdata8, "sdata8")
419 S(DW_EH_PE_absptr | DW_EH_PE_pcrel, "pcrel")
420 S(DW_EH_PE_uleb128 | DW_EH_PE_pcrel, "pcrel uleb128")
421 S(DW_EH_PE_udata2 | DW_EH_PE_pcrel, "pcrel udata2")
422 S(DW_EH_PE_udata4 | DW_EH_PE_pcrel, "pcrel udata4")
423 S(DW_EH_PE_udata8 | DW_EH_PE_pcrel, "pcrel udata8")
424 S(DW_EH_PE_sleb128 | DW_EH_PE_pcrel, "pcrel sleb128")
425 S(DW_EH_PE_sdata2 | DW_EH_PE_pcrel, "pcrel sdata2")
426 S(DW_EH_PE_sdata4 | DW_EH_PE_pcrel, "pcrel sdata4")
427 S(DW_EH_PE_sdata8 | DW_EH_PE_pcrel, "pcrel sdata8")
429 S(DW_EH_PE_absptr | DW_EH_PE_textrel, "textrel")
430 S(DW_EH_PE_uleb128 | DW_EH_PE_textrel, "textrel uleb128")
431 S(DW_EH_PE_udata2 | DW_EH_PE_textrel, "textrel udata2")
432 S(DW_EH_PE_udata4 | DW_EH_PE_textrel, "textrel udata4")
433 S(DW_EH_PE_udata8 | DW_EH_PE_textrel, "textrel udata8")
434 S(DW_EH_PE_sleb128 | DW_EH_PE_textrel, "textrel sleb128")
435 S(DW_EH_PE_sdata2 | DW_EH_PE_textrel, "textrel sdata2")
436 S(DW_EH_PE_sdata4 | DW_EH_PE_textrel, "textrel sdata4")
437 S(DW_EH_PE_sdata8 | DW_EH_PE_textrel, "textrel sdata8")
439 S(DW_EH_PE_absptr | DW_EH_PE_datarel, "datarel")
440 S(DW_EH_PE_uleb128 | DW_EH_PE_datarel, "datarel uleb128")
441 S(DW_EH_PE_udata2 | DW_EH_PE_datarel, "datarel udata2")
442 S(DW_EH_PE_udata4 | DW_EH_PE_datarel, "datarel udata4")
443 S(DW_EH_PE_udata8 | DW_EH_PE_datarel, "datarel udata8")
444 S(DW_EH_PE_sleb128 | DW_EH_PE_datarel, "datarel sleb128")
445 S(DW_EH_PE_sdata2 | DW_EH_PE_datarel, "datarel sdata2")
446 S(DW_EH_PE_sdata4 | DW_EH_PE_datarel, "datarel sdata4")
447 S(DW_EH_PE_sdata8 | DW_EH_PE_datarel, "datarel sdata8")
449 S(DW_EH_PE_absptr | DW_EH_PE_funcrel, "funcrel")
450 S(DW_EH_PE_uleb128 | DW_EH_PE_funcrel, "funcrel uleb128")
451 S(DW_EH_PE_udata2 | DW_EH_PE_funcrel, "funcrel udata2")
452 S(DW_EH_PE_udata4 | DW_EH_PE_funcrel, "funcrel udata4")
453 S(DW_EH_PE_udata8 | DW_EH_PE_funcrel, "funcrel udata8")
454 S(DW_EH_PE_sleb128 | DW_EH_PE_funcrel, "funcrel sleb128")
455 S(DW_EH_PE_sdata2 | DW_EH_PE_funcrel, "funcrel sdata2")
456 S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4")
457 S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8")
459 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel,
461 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel,
462 "indirect pcrel uleb128")
463 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_pcrel,
464 "indirect pcrel udata2")
465 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_pcrel,
466 "indirect pcrel udata4")
467 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_pcrel,
468 "indirect pcrel udata8")
469 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_pcrel,
470 "indirect pcrel sleb128")
471 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_pcrel,
472 "indirect pcrel sdata2")
473 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_pcrel,
474 "indirect pcrel sdata4")
475 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_pcrel,
476 "indirect pcrel sdata8")
478 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_textrel,
480 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_textrel,
481 "indirect textrel uleb128")
482 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_textrel,
483 "indirect textrel udata2")
484 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_textrel,
485 "indirect textrel udata4")
486 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_textrel,
487 "indirect textrel udata8")
488 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_textrel,
489 "indirect textrel sleb128")
490 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_textrel,
491 "indirect textrel sdata2")
492 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_textrel,
493 "indirect textrel sdata4")
494 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_textrel,
495 "indirect textrel sdata8")
497 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_datarel,
499 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_datarel,
500 "indirect datarel uleb128")
501 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_datarel,
502 "indirect datarel udata2")
503 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_datarel,
504 "indirect datarel udata4")
505 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_datarel,
506 "indirect datarel udata8")
507 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_datarel,
508 "indirect datarel sleb128")
509 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_datarel,
510 "indirect datarel sdata2")
511 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_datarel,
512 "indirect datarel sdata4")
513 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_datarel,
514 "indirect datarel sdata8")
516 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_funcrel,
518 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_funcrel,
519 "indirect funcrel uleb128")
520 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_funcrel,
521 "indirect funcrel udata2")
522 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_funcrel,
523 "indirect funcrel udata4")
524 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_funcrel,
525 "indirect funcrel udata8")
526 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_funcrel,
527 "indirect funcrel sleb128")
528 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_funcrel,
529 "indirect funcrel sdata2")
530 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_funcrel,
531 "indirect funcrel sdata4")
532 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_funcrel,
533 "indirect funcrel sdata8")
535 #if HAVE_DESIGNATED_INITIALIZERS
538 if (format < 0 || format > 0xff || format_names[format] == NULL)
540 return format_names[format];
547 /* Output an unsigned LEB128 quantity. */
550 dw2_asm_output_data_uleb128 VPARAMS ((unsigned HOST_WIDE_INT value,
551 const char *comment, ...))
553 VA_OPEN (ap, comment);
554 VA_FIXEDARG (ap, unsigned HOST_WIDE_INT, value);
555 VA_FIXEDARG (ap, const char *, comment);
557 #ifdef HAVE_AS_LEB128
558 fputs ("\t.uleb128 ", asm_out_file);
559 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
561 if (flag_debug_asm && comment)
563 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
564 vfprintf (asm_out_file, comment, ap);
568 unsigned HOST_WIDE_INT work = value;
570 fputs (ASM_BYTE_OP, asm_out_file);
573 int byte = (work & 0x7f);
576 /* More bytes to follow. */
579 fprintf (asm_out_file, "0x%x", byte);
581 fputc (',', asm_out_file);
587 fprintf (asm_out_file, "\t%s uleb128 ", ASM_COMMENT_START);
588 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
591 fputs ("; ", asm_out_file);
592 vfprintf (asm_out_file, comment, ap);
597 fputc ('\n', asm_out_file);
602 /* Output an signed LEB128 quantity. */
605 dw2_asm_output_data_sleb128 VPARAMS ((HOST_WIDE_INT value,
606 const char *comment, ...))
608 VA_OPEN (ap, comment);
609 VA_FIXEDARG (ap, HOST_WIDE_INT, value);
610 VA_FIXEDARG (ap, const char *, comment);
612 #ifdef HAVE_AS_LEB128
613 fputs ("\t.sleb128 ", asm_out_file);
614 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, value);
616 if (flag_debug_asm && comment)
618 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
619 vfprintf (asm_out_file, comment, ap);
623 HOST_WIDE_INT work = value;
626 fputs (ASM_BYTE_OP, asm_out_file);
629 byte = (work & 0x7f);
630 /* arithmetic shift */
632 more = !((work == 0 && (byte & 0x40) == 0)
633 || (work == -1 && (byte & 0x40) != 0));
637 fprintf (asm_out_file, "0x%x", byte);
639 fputc (',', asm_out_file);
645 fprintf (asm_out_file, "\t%s sleb128 ", ASM_COMMENT_START);
646 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, value);
649 fputs ("; ", asm_out_file);
650 vfprintf (asm_out_file, comment, ap);
655 fputc ('\n', asm_out_file);
661 dw2_asm_output_delta_uleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
662 const char *lab2 ATTRIBUTE_UNUSED,
663 const char *comment, ...))
665 VA_OPEN (ap, comment);
666 VA_FIXEDARG (ap, const char *, lab1);
667 VA_FIXEDARG (ap, const char *, lab2);
668 VA_FIXEDARG (ap, const char *, comment);
670 #ifdef HAVE_AS_LEB128
671 fputs ("\t.uleb128 ", asm_out_file);
672 assemble_name (asm_out_file, lab1);
673 fputc ('-', asm_out_file);
674 assemble_name (asm_out_file, lab2);
679 if (flag_debug_asm && comment)
681 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
682 vfprintf (asm_out_file, comment, ap);
684 fputc ('\n', asm_out_file);
690 dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
691 const char *lab2 ATTRIBUTE_UNUSED,
692 const char *comment, ...))
694 VA_OPEN (ap, comment);
695 VA_FIXEDARG (ap, const char *, lab1);
696 VA_FIXEDARG (ap, const char *, lab2);
697 VA_FIXEDARG (ap, const char *, comment);
699 #ifdef HAVE_AS_LEB128
700 fputs ("\t.sleb128 ", asm_out_file);
701 assemble_name (asm_out_file, lab1);
702 fputc ('-', asm_out_file);
703 assemble_name (asm_out_file, lab2);
708 if (flag_debug_asm && comment)
710 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
711 vfprintf (asm_out_file, comment, ap);
713 fputc ('\n', asm_out_file);
718 static rtx dw2_force_const_mem PARAMS ((rtx));
719 static int dw2_output_indirect_constant_1 PARAMS ((splay_tree_node, void *));
721 static splay_tree indirect_pool;
723 /* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
724 memory. Differs from force_const_mem in that a single pool is used for
725 the entire unit of translation, and the memory is not guaranteed to be
726 "near" the function in any interesting sense. */
729 dw2_force_const_mem (x)
732 splay_tree_node node;
733 const char *const_sym;
736 indirect_pool = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
738 if (GET_CODE (x) != SYMBOL_REF)
740 node = splay_tree_lookup (indirect_pool, (splay_tree_key) XSTR (x, 0));
742 const_sym = (const char *) node->value;
745 extern int const_labelno;
749 ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
751 const_sym = ggc_strdup (label);
753 id = maybe_get_identifier (XSTR (x, 0));
755 TREE_SYMBOL_REFERENCED (id) = 1;
757 splay_tree_insert (indirect_pool, (splay_tree_key) XSTR (x, 0),
758 (splay_tree_value) const_sym);
761 return gen_rtx_SYMBOL_REF (Pmode, const_sym);
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 (node, data)
769 splay_tree_node node;
770 void* data ATTRIBUTE_UNUSED;
772 const char *label, *sym;
775 label = (const char *) node->value;
776 sym = (const char *) node->key;
777 sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
779 ASM_OUTPUT_LABEL (asm_out_file, label);
780 assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
785 /* Emit the constants queued through dw2_force_const_mem. */
788 dw2_output_indirect_constants ()
793 /* Assume that the whole reason we're emitting these symbol references
794 indirectly is that they contain dynamic relocations, and are thus
795 read-write. If there was no possibility of a dynamic relocation, we
796 might as well have used a direct relocation. */
799 /* Everything we're emitting is a pointer. Align appropriately. */
800 assemble_align (POINTER_SIZE);
802 splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL);
805 /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed. */
808 dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding,
810 const char *comment, ...))
814 VA_OPEN (ap, comment);
815 VA_FIXEDARG (ap, int, encoding);
816 VA_FIXEDARG (ap, rtx, addr);
817 VA_FIXEDARG (ap, const char *, comment);
819 size = size_of_encoded_value (encoding);
821 if (encoding == DW_EH_PE_aligned)
823 assemble_align (POINTER_SIZE);
824 assemble_integer (addr, size, POINTER_SIZE, 1);
828 /* NULL is _always_ represented as a plain zero. */
829 if (addr == const0_rtx)
830 assemble_integer (addr, size, BITS_PER_UNIT, 1);
834 /* Allow the target first crack at emitting this. Some of the
835 special relocations require special directives instead of
836 just ".4byte" or whatever. */
837 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
838 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file, encoding, size,
842 /* Indirection is used to get dynamic relocations out of a
843 read-only section. */
844 if (encoding & DW_EH_PE_indirect)
846 /* It is very tempting to use force_const_mem so that we share data
847 with the normal constant pool. However, we've already emitted
848 the constant pool for this function. Moreover, we'd like to
849 share these constants across the entire unit of translation,
850 or better, across the entire application (or DSO). */
851 addr = dw2_force_const_mem (addr);
852 encoding &= ~DW_EH_PE_indirect;
856 switch (encoding & 0xF0)
858 case DW_EH_PE_absptr:
859 #ifdef UNALIGNED_INT_ASM_OP
860 fputs (unaligned_integer_asm_op (size), asm_out_file);
861 output_addr_const (asm_out_file, addr);
863 assemble_integer (addr, size, BITS_PER_UNIT, 1);
868 if (GET_CODE (addr) != SYMBOL_REF)
870 #ifdef ASM_OUTPUT_DWARF_PCREL
871 ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, XSTR (addr, 0));
873 #ifdef UNALIGNED_INT_ASM_OP
874 fputs (unaligned_integer_asm_op (size), asm_out_file);
875 assemble_name (asm_out_file, XSTR (addr, 0));
876 fputc ('-', asm_out_file);
877 fputc ('.', asm_out_file);
885 /* Other encodings should have been handled by
886 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */
890 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
895 if (flag_debug_asm && comment)
897 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
898 vfprintf (asm_out_file, comment, ap);
900 fputc ('\n', asm_out_file);