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 #ifndef ANSI_PROTOTYPES
89 unsigned HOST_WIDE_INT value
;
94 VA_START (ap
, comment
);
96 #ifndef ANSI_PROTOTYPES
97 size
= va_arg (ap
, int);
98 value
= va_arg (ap
, unsigned HOST_WIDE_INT
);
99 comment
= va_arg (ap
, const char *);
102 if (size
* 8 < HOST_BITS_PER_WIDE_INT
)
103 value
&= ~(~(unsigned HOST_WIDE_INT
)0 << (size
* 8));
105 #ifdef UNALIGNED_INT_ASM_OP
106 fputs (unaligned_integer_asm_op (size
), asm_out_file
);
107 fprintf (asm_out_file
, HOST_WIDE_INT_PRINT_HEX
, value
);
109 assemble_integer (GEN_INT (value
), size
, BITS_PER_UNIT
, 1);
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 the difference between two symbols in a given size. */
123 /* ??? There appear to be assemblers that do not like such
124 subtraction, but do support ASM_SET_OP. It's unfortunately
125 impossible to do here, since the ASM_SET_OP for the difference
126 symbol must appear after both symbols are defined. */
129 dw2_asm_output_delta
VPARAMS ((int size
, const char *lab1
, const char *lab2
,
130 const char *comment
, ...))
132 #ifndef ANSI_PROTOTYPES
134 const char *lab1
, *lab2
;
139 VA_START (ap
, comment
);
141 #ifndef ANSI_PROTOTYPES
142 size
= va_arg (ap
, int);
143 lab1
= va_arg (ap
, const char *);
144 lab2
= va_arg (ap
, const char *);
145 comment
= va_arg (ap
, const char *);
148 #ifdef UNALIGNED_INT_ASM_OP
149 fputs (unaligned_integer_asm_op (size
), asm_out_file
);
150 assemble_name (asm_out_file
, lab1
);
151 fputc ('-', asm_out_file
);
152 assemble_name (asm_out_file
, lab2
);
154 assemble_integer (gen_rtx_MINUS (Pmode
, gen_rtx_SYMBOL_REF (Pmode
, lab1
),
155 gen_rtx_SYMBOL_REF (Pmode
, lab2
)),
156 size
, BITS_PER_UNIT
, 1);
159 if (flag_debug_asm
&& comment
)
161 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
162 vfprintf (asm_out_file
, comment
, ap
);
164 fputc ('\n', asm_out_file
);
169 /* Output a section-relative reference to a label. In general this
170 can only be done for debugging symbols. E.g. on most targets with
171 the GNU linker, this is accomplished with a direct reference and
172 the knowledge that the debugging section will be placed at VMA 0.
173 Some targets have special relocations for this that we must use. */
176 dw2_asm_output_offset
VPARAMS ((int size
, const char *label
,
177 const char *comment
, ...))
179 #ifndef ANSI_PROTOTYPES
186 VA_START (ap
, comment
);
188 #ifndef ANSI_PROTOTYPES
189 size
= va_arg (ap
, int);
190 label
= va_arg (ap
, const char *);
191 comment
= va_arg (ap
, const char *);
194 #ifdef ASM_OUTPUT_DWARF_OFFSET
195 ASM_OUTPUT_DWARF_OFFSET (asm_out_file
, size
, label
);
197 #ifdef UNALIGNED_INT_ASM_OP
198 fputs (unaligned_integer_asm_op (size
), asm_out_file
);
199 assemble_name (asm_out_file
, label
);
201 assemble_integer (gen_rtx_SYMBOL_REF (Pmode
, label
), size
, BITS_PER_UNIT
, 1);
205 if (flag_debug_asm
&& comment
)
207 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
208 vfprintf (asm_out_file
, comment
, ap
);
210 fputc ('\n', asm_out_file
);
215 /* Output a self-relative reference to a label, possibly in a
216 different section or object file. */
219 dw2_asm_output_pcrel
VPARAMS ((int size
, const char *label
,
220 const char *comment
, ...))
222 #ifndef ANSI_PROTOTYPES
229 VA_START (ap
, comment
);
231 #ifndef ANSI_PROTOTYPES
232 size
= va_arg (ap
, int);
233 label
= va_arg (ap
, const char *);
234 comment
= va_arg (ap
, const char *);
237 #ifdef ASM_OUTPUT_DWARF_PCREL
238 ASM_OUTPUT_DWARF_PCREL (asm_out_file
, size
, label
);
240 #ifdef UNALIGNED_INT_ASM_OP
241 fputs (unaligned_integer_asm_op (size
), asm_out_file
);
242 assemble_name (asm_out_file
, label
);
243 fputc ('-', asm_out_file
);
244 fputc ('.', asm_out_file
);
250 if (flag_debug_asm
&& comment
)
252 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
253 vfprintf (asm_out_file
, comment
, ap
);
255 fputc ('\n', asm_out_file
);
260 /* Output an absolute reference to a label. */
263 dw2_asm_output_addr
VPARAMS ((int size
, const char *label
,
264 const char *comment
, ...))
266 #ifndef ANSI_PROTOTYPES
273 VA_START (ap
, comment
);
275 #ifndef ANSI_PROTOTYPES
276 size
= va_arg (ap
, int);
277 label
= va_arg (ap
, const char *);
278 comment
= va_arg (ap
, const char *);
281 #ifdef UNALIGNED_INT_ASM_OP
282 fputs (unaligned_integer_asm_op (size
), asm_out_file
);
283 assemble_name (asm_out_file
, label
);
285 assemble_integer (gen_rtx_SYMBOL_REF (Pmode
, label
), size
, BITS_PER_UNIT
, 1);
288 if (flag_debug_asm
&& comment
)
290 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
291 vfprintf (asm_out_file
, comment
, ap
);
293 fputc ('\n', asm_out_file
);
298 /* Similar, but use an RTX expression instead of a text label. */
301 dw2_asm_output_addr_rtx
VPARAMS ((int size
, rtx addr
,
302 const char *comment
, ...))
304 #ifndef ANSI_PROTOTYPES
311 VA_START (ap
, comment
);
313 #ifndef ANSI_PROTOTYPES
314 size
= va_arg (ap
, int);
315 addr
= va_arg (ap
, rtx
);
316 comment
= va_arg (ap
, const char *);
319 #ifdef UNALIGNED_INT_ASM_OP
320 fputs (unaligned_integer_asm_op (size
), asm_out_file
);
321 output_addr_const (asm_out_file
, addr
);
323 assemble_integer (addr
, size
, BITS_PER_UNIT
, 1);
326 if (flag_debug_asm
&& comment
)
328 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
329 vfprintf (asm_out_file
, comment
, ap
);
331 fputc ('\n', asm_out_file
);
337 dw2_asm_output_nstring
VPARAMS ((const char *str
, size_t orig_len
,
338 const char *comment
, ...))
340 #ifndef ANSI_PROTOTYPES
346 size_t i
, len
= orig_len
;
348 VA_START (ap
, comment
);
350 #ifndef ANSI_PROTOTYPES
351 str
= va_arg (ap
, const char *);
352 len
= va_arg (ap
, size_t);
353 comment
= va_arg (ap
, const char *);
356 if (len
== (size_t) -1)
359 if (flag_debug_asm
&& comment
)
361 fputs ("\t.ascii \"", asm_out_file
);
362 for (i
= 0; i
< len
; i
++)
365 if (c
== '\"' || c
== '\\')
366 fputc ('\\', asm_out_file
);
368 fputc (c
, asm_out_file
);
370 fprintf (asm_out_file
, "\\%o", c
);
372 fprintf (asm_out_file
, "\\0\"\t%s ", ASM_COMMENT_START
);
373 vfprintf (asm_out_file
, comment
, ap
);
374 fputc ('\n', asm_out_file
);
378 /* If an explicit length was given, we can't assume there
379 is a null termination in the string buffer. */
380 if (orig_len
== (size_t) -1)
382 ASM_OUTPUT_ASCII (asm_out_file
, str
, len
);
383 if (orig_len
!= (size_t) -1)
384 fprintf (asm_out_file
, "%s0\n", ASM_BYTE_OP
);
391 /* Return the size of an unsigned LEB128 quantity. */
394 size_of_uleb128 (value
)
395 unsigned HOST_WIDE_INT value
;
401 byte
= (value
& 0x7f);
410 /* Return the size of a signed LEB128 quantity. */
413 size_of_sleb128 (value
)
420 byte
= (value
& 0x7f);
424 while (!((value
== 0 && (byte
& 0x40) == 0)
425 || (value
== -1 && (byte
& 0x40) != 0)));
430 /* Given an encoding, return the number of bytes the format occupies.
431 This is only defined for fixed-size encodings, and so does not
435 size_of_encoded_value (encoding
)
438 if (encoding
== DW_EH_PE_omit
)
441 switch (encoding
& 0x07)
443 case DW_EH_PE_absptr
:
444 return POINTER_SIZE
/ BITS_PER_UNIT
;
445 case DW_EH_PE_udata2
:
447 case DW_EH_PE_udata4
:
449 case DW_EH_PE_udata8
:
455 /* Yield a name for a given pointer encoding. */
458 eh_data_format_name (format
)
461 #if HAVE_DESIGNATED_INITIALIZERS
462 #define S(p, v) [p] = v,
464 #define S(p, v) case p: return v;
467 #if HAVE_DESIGNATED_INITIALIZERS
468 __extension__
static const char * const format_names
[256] = {
473 S(DW_EH_PE_absptr
, "absolute")
474 S(DW_EH_PE_omit
, "omit")
475 S(DW_EH_PE_aligned
, "aligned absolute")
477 S(DW_EH_PE_uleb128
, "uleb128")
478 S(DW_EH_PE_udata2
, "udata2")
479 S(DW_EH_PE_udata4
, "udata4")
480 S(DW_EH_PE_udata8
, "udata8")
481 S(DW_EH_PE_sleb128
, "sleb128")
482 S(DW_EH_PE_sdata2
, "sdata2")
483 S(DW_EH_PE_sdata4
, "sdata4")
484 S(DW_EH_PE_sdata8
, "sdata8")
486 S(DW_EH_PE_absptr
| DW_EH_PE_pcrel
, "pcrel")
487 S(DW_EH_PE_uleb128
| DW_EH_PE_pcrel
, "pcrel uleb128")
488 S(DW_EH_PE_udata2
| DW_EH_PE_pcrel
, "pcrel udata2")
489 S(DW_EH_PE_udata4
| DW_EH_PE_pcrel
, "pcrel udata4")
490 S(DW_EH_PE_udata8
| DW_EH_PE_pcrel
, "pcrel udata8")
491 S(DW_EH_PE_sleb128
| DW_EH_PE_pcrel
, "pcrel sleb128")
492 S(DW_EH_PE_sdata2
| DW_EH_PE_pcrel
, "pcrel sdata2")
493 S(DW_EH_PE_sdata4
| DW_EH_PE_pcrel
, "pcrel sdata4")
494 S(DW_EH_PE_sdata8
| DW_EH_PE_pcrel
, "pcrel sdata8")
496 S(DW_EH_PE_absptr
| DW_EH_PE_textrel
, "textrel")
497 S(DW_EH_PE_uleb128
| DW_EH_PE_textrel
, "textrel uleb128")
498 S(DW_EH_PE_udata2
| DW_EH_PE_textrel
, "textrel udata2")
499 S(DW_EH_PE_udata4
| DW_EH_PE_textrel
, "textrel udata4")
500 S(DW_EH_PE_udata8
| DW_EH_PE_textrel
, "textrel udata8")
501 S(DW_EH_PE_sleb128
| DW_EH_PE_textrel
, "textrel sleb128")
502 S(DW_EH_PE_sdata2
| DW_EH_PE_textrel
, "textrel sdata2")
503 S(DW_EH_PE_sdata4
| DW_EH_PE_textrel
, "textrel sdata4")
504 S(DW_EH_PE_sdata8
| DW_EH_PE_textrel
, "textrel sdata8")
506 S(DW_EH_PE_absptr
| DW_EH_PE_datarel
, "datarel")
507 S(DW_EH_PE_uleb128
| DW_EH_PE_datarel
, "datarel uleb128")
508 S(DW_EH_PE_udata2
| DW_EH_PE_datarel
, "datarel udata2")
509 S(DW_EH_PE_udata4
| DW_EH_PE_datarel
, "datarel udata4")
510 S(DW_EH_PE_udata8
| DW_EH_PE_datarel
, "datarel udata8")
511 S(DW_EH_PE_sleb128
| DW_EH_PE_datarel
, "datarel sleb128")
512 S(DW_EH_PE_sdata2
| DW_EH_PE_datarel
, "datarel sdata2")
513 S(DW_EH_PE_sdata4
| DW_EH_PE_datarel
, "datarel sdata4")
514 S(DW_EH_PE_sdata8
| DW_EH_PE_datarel
, "datarel sdata8")
516 S(DW_EH_PE_absptr
| DW_EH_PE_funcrel
, "funcrel")
517 S(DW_EH_PE_uleb128
| DW_EH_PE_funcrel
, "funcrel uleb128")
518 S(DW_EH_PE_udata2
| DW_EH_PE_funcrel
, "funcrel udata2")
519 S(DW_EH_PE_udata4
| DW_EH_PE_funcrel
, "funcrel udata4")
520 S(DW_EH_PE_udata8
| DW_EH_PE_funcrel
, "funcrel udata8")
521 S(DW_EH_PE_sleb128
| DW_EH_PE_funcrel
, "funcrel sleb128")
522 S(DW_EH_PE_sdata2
| DW_EH_PE_funcrel
, "funcrel sdata2")
523 S(DW_EH_PE_sdata4
| DW_EH_PE_funcrel
, "funcrel sdata4")
524 S(DW_EH_PE_sdata8
| DW_EH_PE_funcrel
, "funcrel sdata8")
526 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_pcrel
,
528 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_pcrel
,
529 "indirect pcrel uleb128")
530 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_pcrel
,
531 "indirect pcrel udata2")
532 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_pcrel
,
533 "indirect pcrel udata4")
534 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_pcrel
,
535 "indirect pcrel udata8")
536 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_pcrel
,
537 "indirect pcrel sleb128")
538 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_pcrel
,
539 "indirect pcrel sdata2")
540 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_pcrel
,
541 "indirect pcrel sdata4")
542 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_pcrel
,
543 "indirect pcrel sdata8")
545 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_textrel
,
547 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_textrel
,
548 "indirect textrel uleb128")
549 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_textrel
,
550 "indirect textrel udata2")
551 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_textrel
,
552 "indirect textrel udata4")
553 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_textrel
,
554 "indirect textrel udata8")
555 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_textrel
,
556 "indirect textrel sleb128")
557 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_textrel
,
558 "indirect textrel sdata2")
559 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_textrel
,
560 "indirect textrel sdata4")
561 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_textrel
,
562 "indirect textrel sdata8")
564 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_datarel
,
566 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_datarel
,
567 "indirect datarel uleb128")
568 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_datarel
,
569 "indirect datarel udata2")
570 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_datarel
,
571 "indirect datarel udata4")
572 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_datarel
,
573 "indirect datarel udata8")
574 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_datarel
,
575 "indirect datarel sleb128")
576 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_datarel
,
577 "indirect datarel sdata2")
578 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_datarel
,
579 "indirect datarel sdata4")
580 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_datarel
,
581 "indirect datarel sdata8")
583 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_funcrel
,
585 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_funcrel
,
586 "indirect funcrel uleb128")
587 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_funcrel
,
588 "indirect funcrel udata2")
589 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_funcrel
,
590 "indirect funcrel udata4")
591 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_funcrel
,
592 "indirect funcrel udata8")
593 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_funcrel
,
594 "indirect funcrel sleb128")
595 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_funcrel
,
596 "indirect funcrel sdata2")
597 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_funcrel
,
598 "indirect funcrel sdata4")
599 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_funcrel
,
600 "indirect funcrel sdata8")
602 #if HAVE_DESIGNATED_INITIALIZERS
605 if (format
< 0 || format
> 0xff || format_names
[format
] == NULL
)
607 return format_names
[format
];
614 /* Output an unsigned LEB128 quantity. */
617 dw2_asm_output_data_uleb128
VPARAMS ((unsigned HOST_WIDE_INT value
,
618 const char *comment
, ...))
620 #ifndef ANSI_PROTOTYPES
621 unsigned HOST_WIDE_INT value
;
626 VA_START (ap
, comment
);
628 #ifndef ANSI_PROTOTYPES
629 value
= va_arg (ap
, unsigned HOST_WIDE_INT
);
630 comment
= va_arg (ap
, const char *);
633 #ifdef HAVE_AS_LEB128
634 fputs ("\t.uleb128 ", asm_out_file
);
635 fprintf (asm_out_file
, HOST_WIDE_INT_PRINT_HEX
, value
);
637 if (flag_debug_asm
&& comment
)
639 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
640 vfprintf (asm_out_file
, comment
, ap
);
644 unsigned HOST_WIDE_INT work
= value
;
646 fputs (ASM_BYTE_OP
, asm_out_file
);
649 int byte
= (work
& 0x7f);
652 /* More bytes to follow. */
655 fprintf (asm_out_file
, "0x%x", byte
);
657 fputc (',', asm_out_file
);
663 fprintf (asm_out_file
, "\t%s uleb128 ", ASM_COMMENT_START
);
664 fprintf (asm_out_file
, HOST_WIDE_INT_PRINT_HEX
, value
);
667 fputs ("; ", asm_out_file
);
668 vfprintf (asm_out_file
, comment
, ap
);
673 fputc ('\n', asm_out_file
);
678 /* Output an signed LEB128 quantity. */
681 dw2_asm_output_data_sleb128
VPARAMS ((HOST_WIDE_INT value
,
682 const char *comment
, ...))
684 #ifndef ANSI_PROTOTYPES
690 VA_START (ap
, comment
);
692 #ifndef ANSI_PROTOTYPES
693 value
= va_arg (ap
, HOST_WIDE_INT
);
694 comment
= va_arg (ap
, const char *);
697 #ifdef HAVE_AS_LEB128
698 fputs ("\t.sleb128 ", asm_out_file
);
699 fprintf (asm_out_file
, HOST_WIDE_INT_PRINT_DEC
, value
);
701 if (flag_debug_asm
&& comment
)
703 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
704 vfprintf (asm_out_file
, comment
, ap
);
708 HOST_WIDE_INT work
= value
;
711 fputs (ASM_BYTE_OP
, asm_out_file
);
714 byte
= (work
& 0x7f);
715 /* arithmetic shift */
717 more
= !((work
== 0 && (byte
& 0x40) == 0)
718 || (work
== -1 && (byte
& 0x40) != 0));
722 fprintf (asm_out_file
, "0x%x", byte
);
724 fputc (',', asm_out_file
);
730 fprintf (asm_out_file
, "\t%s sleb128 ", ASM_COMMENT_START
);
731 fprintf (asm_out_file
, HOST_WIDE_INT_PRINT_DEC
, value
);
734 fputs ("; ", asm_out_file
);
735 vfprintf (asm_out_file
, comment
, ap
);
740 fputc ('\n', asm_out_file
);
746 dw2_asm_output_delta_uleb128
VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED
,
747 const char *lab2 ATTRIBUTE_UNUSED
,
748 const char *comment
, ...))
750 #ifndef ANSI_PROTOTYPES
751 const char *lab1
, *lab2
;
756 VA_START (ap
, comment
);
758 #ifndef ANSI_PROTOTYPES
759 lab1
= va_arg (ap
, const char *);
760 lab2
= va_arg (ap
, const char *);
761 comment
= va_arg (ap
, const char *);
764 #ifdef HAVE_AS_LEB128
765 fputs ("\t.uleb128 ", asm_out_file
);
766 assemble_name (asm_out_file
, lab1
);
767 fputc ('-', asm_out_file
);
768 assemble_name (asm_out_file
, lab2
);
773 if (flag_debug_asm
&& comment
)
775 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
776 vfprintf (asm_out_file
, comment
, ap
);
778 fputc ('\n', asm_out_file
);
784 dw2_asm_output_delta_sleb128
VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED
,
785 const char *lab2 ATTRIBUTE_UNUSED
,
786 const char *comment
, ...))
788 #ifndef ANSI_PROTOTYPES
789 const char *lab1
, *lab2
;
794 VA_START (ap
, comment
);
796 #ifndef ANSI_PROTOTYPES
797 lab1
= va_arg (ap
, const char *);
798 lab2
= va_arg (ap
, const char *);
799 comment
= va_arg (ap
, const char *);
802 #ifdef HAVE_AS_LEB128
803 fputs ("\t.sleb128 ", asm_out_file
);
804 assemble_name (asm_out_file
, lab1
);
805 fputc ('-', asm_out_file
);
806 assemble_name (asm_out_file
, lab2
);
811 if (flag_debug_asm
&& comment
)
813 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
814 vfprintf (asm_out_file
, comment
, ap
);
816 fputc ('\n', asm_out_file
);
821 static rtx dw2_force_const_mem
PARAMS ((rtx
));
822 static int dw2_output_indirect_constant_1
PARAMS ((splay_tree_node
, void *));
824 static splay_tree indirect_pool
;
826 /* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
827 memory. Differs from force_const_mem in that a single pool is used for
828 the entire unit of translation, and the memory is not guaranteed to be
829 "near" the function in any interesting sense. */
832 dw2_force_const_mem (x
)
835 splay_tree_node node
;
836 const char *const_sym
;
839 indirect_pool
= splay_tree_new (splay_tree_compare_pointers
, NULL
, NULL
);
841 if (GET_CODE (x
) != SYMBOL_REF
)
843 node
= splay_tree_lookup (indirect_pool
, (splay_tree_key
) XSTR (x
, 0));
845 const_sym
= (const char *) node
->value
;
848 extern int const_labelno
;
852 ASM_GENERATE_INTERNAL_LABEL (label
, "LC", const_labelno
);
854 const_sym
= ggc_strdup (label
);
856 id
= maybe_get_identifier (XSTR (x
, 0));
858 TREE_SYMBOL_REFERENCED (id
) = 1;
860 splay_tree_insert (indirect_pool
, (splay_tree_key
) XSTR (x
, 0),
861 (splay_tree_value
) const_sym
);
864 return gen_rtx_SYMBOL_REF (Pmode
, const_sym
);
867 /* A helper function for dw2_output_indirect_constants called through
868 splay_tree_foreach. Emit one queued constant to memory. */
871 dw2_output_indirect_constant_1 (node
, data
)
872 splay_tree_node node
;
873 void* data ATTRIBUTE_UNUSED
;
875 const char *label
, *sym
;
878 label
= (const char *) node
->value
;
879 sym
= (const char *) node
->key
;
880 sym_ref
= gen_rtx_SYMBOL_REF (Pmode
, sym
);
882 ASM_OUTPUT_LABEL (asm_out_file
, label
);
883 assemble_integer (sym_ref
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
888 /* Emit the constants queued through dw2_force_const_mem. */
891 dw2_output_indirect_constants ()
896 /* Assume that the whole reason we're emitting these symbol references
897 indirectly is that they contain dynamic relocations, and are thus
898 read-write. If there was no possibility of a dynamic relocation, we
899 might as well have used a direct relocation. */
902 /* Everything we're emitting is a pointer. Align appropriately. */
903 assemble_align (POINTER_SIZE
);
905 splay_tree_foreach (indirect_pool
, dw2_output_indirect_constant_1
, NULL
);
908 /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed. */
911 dw2_asm_output_encoded_addr_rtx
VPARAMS ((int encoding
,
913 const char *comment
, ...))
915 #ifndef ANSI_PROTOTYPES
923 VA_START (ap
, comment
);
925 #ifndef ANSI_PROTOTYPES
926 encoding
= va_arg (ap
, int);
927 addr
= va_arg (ap
, rtx
);
928 comment
= va_arg (ap
, const char *);
931 size
= size_of_encoded_value (encoding
);
933 if (encoding
== DW_EH_PE_aligned
)
935 assemble_align (POINTER_SIZE
);
936 encoding
= DW_EH_PE_absptr
;
939 /* NULL is _always_ represented as a plain zero. */
940 if (addr
== const0_rtx
)
941 assemble_integer (addr
, size
, BITS_PER_UNIT
, 1);
945 /* Allow the target first crack at emitting this. Some of the
946 special relocations require special directives instead of
947 just ".4byte" or whatever. */
948 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
949 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file
, encoding
, size
,
953 /* Indirection is used to get dynamic relocations out of a
954 read-only section. */
955 if (encoding
& DW_EH_PE_indirect
)
957 /* It is very tempting to use force_const_mem so that we share data
958 with the normal constant pool. However, we've already emitted
959 the constant pool for this function. Moreover, we'd like to
960 share these constants across the entire unit of translation,
961 or better, across the entire application (or DSO). */
962 addr
= dw2_force_const_mem (addr
);
963 encoding
&= ~DW_EH_PE_indirect
;
967 switch (encoding
& 0xF0)
969 case DW_EH_PE_absptr
:
970 #ifdef UNALIGNED_INT_ASM_OP
971 fputs (unaligned_integer_asm_op (size
), asm_out_file
);
972 output_addr_const (asm_out_file
, addr
);
974 assemble_integer (addr
, size
, BITS_PER_UNIT
, 1);
979 if (GET_CODE (addr
) != SYMBOL_REF
)
981 #ifdef ASM_OUTPUT_DWARF_PCREL
982 ASM_OUTPUT_DWARF_PCREL (asm_out_file
, size
, XSTR (addr
, 0));
984 #ifdef UNALIGNED_INT_ASM_OP
985 fputs (unaligned_integer_asm_op (size
), asm_out_file
);
986 assemble_name (asm_out_file
, XSTR (addr
, 0));
987 fputc ('-', asm_out_file
);
988 fputc ('.', asm_out_file
);
996 /* Other encodings should have been handled by
997 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */
1001 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
1006 if (flag_debug_asm
&& comment
)
1008 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
1009 vfprintf (asm_out_file
, comment
, ap
);
1011 fputc ('\n', asm_out_file
);