]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/dwarf2asm.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / dwarf2asm.cc
CommitLineData
2e4b9b8c 1/* Dwarf2 assembler output helper routines.
a945c346 2 Copyright (C) 2001-2024 Free Software Foundation, Inc.
2e4b9b8c 3
1322177d 4This file is part of GCC.
2e4b9b8c 5
1322177d
LB
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
1322177d 9version.
2e4b9b8c 10
1322177d
LB
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
2e4b9b8c
RH
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
2e4b9b8c
RH
19
20
21#include "config.h"
22#include "system.h"
4977bab6 23#include "coretypes.h"
957060b5
AM
24#include "target.h"
25#include "rtl.h"
2a1ee410 26#include "tree.h"
4d0cdd0c 27#include "memmodel.h"
957060b5 28#include "tm_p.h"
d8a2d370
DN
29#include "stringpool.h"
30#include "varasm.h"
2e4b9b8c
RH
31#include "output.h"
32#include "dwarf2asm.h"
a80b0574 33#include "dwarf2.h"
7180b1a6
RB
34#include "function.h"
35#include "emit-rtl.h"
90841d43 36#include "fold-const.h"
2e4b9b8c 37
7abcdb06
ML
38#ifndef XCOFF_DEBUGGING_INFO
39#define XCOFF_DEBUGGING_INFO 0
40#endif
41
2e4b9b8c 42\f
301d03af
RS
43/* Output an unaligned integer with the given value and size. Prefer not
44 to print a newline, since the caller may want to add a comment. */
45
46void
7080f735 47dw2_assemble_integer (int size, rtx x)
2e4b9b8c 48{
6e44c09b 49 if (size == 2 * (int) DWARF2_ADDR_SIZE && !CONST_SCALAR_INT_P (x))
74237316
JJ
50 {
51 /* On 32-bit targets with -gdwarf64, DImode values with
52 relocations usually result in assembler errors. Assume
53 all such values are positive and emit the relocation only
54 in the least significant half. */
e9ba2ccf 55 const char *op = integer_asm_op (DWARF2_ADDR_SIZE, false);
74237316
JJ
56 if (BYTES_BIG_ENDIAN)
57 {
58 if (op)
59 {
60 fputs (op, asm_out_file);
61 fprint_whex (asm_out_file, 0);
62 fputs (", ", asm_out_file);
63 output_addr_const (asm_out_file, x);
64 }
65 else
66 {
67 assemble_integer (const0_rtx, DWARF2_ADDR_SIZE,
68 BITS_PER_UNIT, 1);
69 putc ('\n', asm_out_file);
70 assemble_integer (x, DWARF2_ADDR_SIZE,
71 BITS_PER_UNIT, 1);
72 }
73 }
74 else
75 {
76 if (op)
77 {
78 fputs (op, asm_out_file);
79 output_addr_const (asm_out_file, x);
80 fputs (", ", asm_out_file);
81 fprint_whex (asm_out_file, 0);
82 }
83 else
84 {
85 assemble_integer (x, DWARF2_ADDR_SIZE,
86 BITS_PER_UNIT, 1);
87 putc ('\n', asm_out_file);
88 assemble_integer (const0_rtx, DWARF2_ADDR_SIZE,
89 BITS_PER_UNIT, 1);
90 }
91 }
92 return;
93 }
94
e9ba2ccf 95 const char *op = integer_asm_op (size, false);
301d03af
RS
96
97 if (op)
2e4b9b8c 98 {
301d03af 99 fputs (op, asm_out_file);
481683e1 100 if (CONST_INT_P (x))
5e3929ed 101 fprint_whex (asm_out_file, (unsigned HOST_WIDE_INT) INTVAL (x));
301d03af
RS
102 else
103 output_addr_const (asm_out_file, x);
2e4b9b8c 104 }
301d03af
RS
105 else
106 assemble_integer (x, size, BITS_PER_UNIT, 1);
2e4b9b8c 107}
3a538a66 108
2e4b9b8c 109
d4ea4622
RH
110/* Output a value of a given size in target byte order. */
111
112void
113dw2_asm_output_data_raw (int size, unsigned HOST_WIDE_INT value)
114{
115 unsigned char bytes[8];
116 int i;
117
118 for (i = 0; i < 8; ++i)
119 {
120 bytes[i] = value & 0xff;
121 value >>= 8;
122 }
123
124 if (BYTES_BIG_ENDIAN)
125 {
126 for (i = size - 1; i > 0; --i)
a3f1cee4
UB
127 fprintf (asm_out_file, "%#x,", bytes[i]);
128 fprintf (asm_out_file, "%#x", bytes[0]);
d4ea4622
RH
129 }
130 else
131 {
132 for (i = 0; i < size - 1; ++i)
a3f1cee4
UB
133 fprintf (asm_out_file, "%#x,", bytes[i]);
134 fprintf (asm_out_file, "%#x", bytes[i]);
d4ea4622
RH
135 }
136}
137
105f48ae 138/* Output an immediate constant in a given SIZE in bytes. */
8e7fa2c8 139
2e4b9b8c 140void
e34d07f2
KG
141dw2_asm_output_data (int size, unsigned HOST_WIDE_INT value,
142 const char *comment, ...)
2e4b9b8c 143{
e34d07f2 144 va_list ap;
e9ba2ccf 145 const char *op = integer_asm_op (size, false);
7080f735 146
e34d07f2 147 va_start (ap, comment);
2e4b9b8c 148
da6af203 149 if (size * 8 < HOST_BITS_PER_WIDE_INT)
dd4786fe 150 value &= ~(HOST_WIDE_INT_M1U << (size * 8));
da6af203 151
d61772b2 152 if (op)
5e3929ed
DA
153 {
154 fputs (op, asm_out_file);
155 fprint_whex (asm_out_file, value);
156 }
d61772b2
GK
157 else
158 assemble_integer (GEN_INT (value), size, BITS_PER_UNIT, 1);
2e4b9b8c
RH
159
160 if (flag_debug_asm && comment)
161 {
5e3929ed 162 fputs ("\t" ASM_COMMENT_START " ", asm_out_file);
2e4b9b8c
RH
163 vfprintf (asm_out_file, comment, ap);
164 }
5e3929ed 165 putc ('\n', asm_out_file);
2e4b9b8c 166
e34d07f2 167 va_end (ap);
2e4b9b8c
RH
168}
169
8e7fa2c8
RH
170/* Output the difference between two symbols in a given size. */
171/* ??? There appear to be assemblers that do not like such
172 subtraction, but do support ASM_SET_OP. It's unfortunately
173 impossible to do here, since the ASM_SET_OP for the difference
174 symbol must appear after both symbols are defined. */
175
2e4b9b8c 176void
e34d07f2
KG
177dw2_asm_output_delta (int size, const char *lab1, const char *lab2,
178 const char *comment, ...)
2e4b9b8c 179{
e34d07f2 180 va_list ap;
7080f735 181
e34d07f2 182 va_start (ap, comment);
2e4b9b8c 183
7606e68f
SS
184#ifdef ASM_OUTPUT_DWARF_DELTA
185 ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2);
186#else
301d03af
RS
187 dw2_assemble_integer (size,
188 gen_rtx_MINUS (Pmode,
189 gen_rtx_SYMBOL_REF (Pmode, lab1),
190 gen_rtx_SYMBOL_REF (Pmode, lab2)));
7606e68f 191#endif
2e4b9b8c
RH
192 if (flag_debug_asm && comment)
193 {
194 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
195 vfprintf (asm_out_file, comment, ap);
196 }
197 fputc ('\n', asm_out_file);
198
e34d07f2 199 va_end (ap);
2e4b9b8c
RH
200}
201
2cea0398 202#ifdef ASM_OUTPUT_DWARF_VMS_DELTA
67ad2ae7
DR
203/* Output the difference between two symbols in instruction units
204 in a given size. */
205
206void
207dw2_asm_output_vms_delta (int size ATTRIBUTE_UNUSED,
208 const char *lab1, const char *lab2,
209 const char *comment, ...)
210{
211 va_list ap;
212
213 va_start (ap, comment);
214
67ad2ae7
DR
215 ASM_OUTPUT_DWARF_VMS_DELTA (asm_out_file, size, lab1, lab2);
216 if (flag_debug_asm && comment)
217 {
218 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
219 vfprintf (asm_out_file, comment, ap);
220 }
221 fputc ('\n', asm_out_file);
67ad2ae7
DR
222
223 va_end (ap);
224}
2cea0398 225#endif
67ad2ae7 226
192d0f89
GK
227/* Output a section-relative reference to a LABEL, which was placed in
228 BASE. In general this can only be done for debugging symbols.
229 E.g. on most targets with the GNU linker, this is accomplished with
230 a direct reference and the knowledge that the debugging section
231 will be placed at VMA 0. Some targets have special relocations for
232 this that we must use. */
8e7fa2c8 233
2e4b9b8c 234void
79252435
SB
235dw2_asm_output_offset (int size, const char *label,
236 section *base ATTRIBUTE_UNUSED,
e34d07f2 237 const char *comment, ...)
2e4b9b8c 238{
e34d07f2 239 va_list ap;
7080f735 240
e34d07f2 241 va_start (ap, comment);
2e4b9b8c 242
8e7fa2c8 243#ifdef ASM_OUTPUT_DWARF_OFFSET
7180b1a6 244 ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label, 0, base);
8e7fa2c8 245#else
301d03af 246 dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
2e4b9b8c
RH
247#endif
248
249 if (flag_debug_asm && comment)
250 {
251 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
252 vfprintf (asm_out_file, comment, ap);
253 }
254 fputc ('\n', asm_out_file);
255
e34d07f2 256 va_end (ap);
2e4b9b8c
RH
257}
258
7180b1a6
RB
259void
260dw2_asm_output_offset (int size, const char *label, HOST_WIDE_INT offset,
261 section *base ATTRIBUTE_UNUSED,
262 const char *comment, ...)
263{
264 va_list ap;
265
266 va_start (ap, comment);
267
268#ifdef ASM_OUTPUT_DWARF_OFFSET
269 ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label, offset, base);
270#else
271 dw2_assemble_integer (size, gen_rtx_PLUS (Pmode,
272 gen_rtx_SYMBOL_REF (Pmode, label),
273 gen_int_mode (offset, Pmode)));
274#endif
275
276 if (flag_debug_asm && comment)
277 {
278 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
279 vfprintf (asm_out_file, comment, ap);
280 }
281 fputc ('\n', asm_out_file);
282
283 va_end (ap);
284}
285
c8f4fe99
BE
286#if 0
287
8e7fa2c8
RH
288/* Output a self-relative reference to a label, possibly in a
289 different section or object file. */
290
2e4b9b8c 291void
e34d07f2
KG
292dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED,
293 const char *label ATTRIBUTE_UNUSED,
294 const char *comment, ...)
2e4b9b8c 295{
e34d07f2 296 va_list ap;
7080f735 297
e34d07f2 298 va_start (ap, comment);
2e4b9b8c 299
8e7fa2c8
RH
300#ifdef ASM_OUTPUT_DWARF_PCREL
301 ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label);
302#else
301d03af
RS
303 dw2_assemble_integer (size,
304 gen_rtx_MINUS (Pmode,
305 gen_rtx_SYMBOL_REF (Pmode, label),
306 pc_rtx));
8e7fa2c8
RH
307#endif
308
309 if (flag_debug_asm && comment)
310 {
311 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
312 vfprintf (asm_out_file, comment, ap);
313 }
314 fputc ('\n', asm_out_file);
315
e34d07f2 316 va_end (ap);
8e7fa2c8 317}
c8f4fe99 318#endif /* 0 */
8e7fa2c8
RH
319
320/* Output an absolute reference to a label. */
321
322void
e34d07f2
KG
323dw2_asm_output_addr (int size, const char *label,
324 const char *comment, ...)
8e7fa2c8 325{
e34d07f2 326 va_list ap;
7080f735 327
e34d07f2 328 va_start (ap, comment);
8e7fa2c8 329
301d03af 330 dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
2e4b9b8c
RH
331
332 if (flag_debug_asm && comment)
333 {
334 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
335 vfprintf (asm_out_file, comment, ap);
336 }
337 fputc ('\n', asm_out_file);
338
e34d07f2 339 va_end (ap);
2e4b9b8c
RH
340}
341
8e7fa2c8
RH
342/* Similar, but use an RTX expression instead of a text label. */
343
2e4b9b8c 344void
e34d07f2
KG
345dw2_asm_output_addr_rtx (int size, rtx addr,
346 const char *comment, ...)
2e4b9b8c 347{
e34d07f2 348 va_list ap;
7080f735 349
e34d07f2 350 va_start (ap, comment);
2e4b9b8c 351
301d03af 352 dw2_assemble_integer (size, addr);
2e4b9b8c
RH
353
354 if (flag_debug_asm && comment)
355 {
356 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
357 vfprintf (asm_out_file, comment, ap);
358 }
359 fputc ('\n', asm_out_file);
360
e34d07f2 361 va_end (ap);
2e4b9b8c
RH
362}
363
1e290ba1
JB
364/* Output the first ORIG_LEN characters of STR as a string.
365 If ORIG_LEN is equal to -1, ignore this parameter and output
366 the entire STR instead.
367 If COMMENT is not NULL and comments in the debug information
368 have been requested by the user, append the given COMMENT
369 to the generated output. */
b8698a0f 370
2e4b9b8c 371void
e34d07f2
KG
372dw2_asm_output_nstring (const char *str, size_t orig_len,
373 const char *comment, ...)
2e4b9b8c 374{
7a75edb7 375 size_t i, len;
e34d07f2 376 va_list ap;
2e4b9b8c 377
e34d07f2 378 va_start (ap, comment);
2e4b9b8c 379
7a75edb7 380 len = orig_len;
2e4b9b8c
RH
381
382 if (len == (size_t) -1)
383 len = strlen (str);
384
385 if (flag_debug_asm && comment)
386 {
7abcdb06
ML
387 if (XCOFF_DEBUGGING_INFO)
388 fputs ("\t.byte \"", asm_out_file);
389 else
390 fputs ("\t.ascii \"", asm_out_file);
51fbbb92 391
2e4b9b8c
RH
392 for (i = 0; i < len; i++)
393 {
394 int c = str[i];
7e78cfda 395 if (c == '\"')
7abcdb06 396 fputc (XCOFF_DEBUGGING_INFO ? '\"' : '\\', asm_out_file);
7e78cfda 397 else if (c == '\\')
2e4b9b8c 398 fputc ('\\', asm_out_file);
c3284718 399 if (ISPRINT (c))
2e4b9b8c
RH
400 fputc (c, asm_out_file);
401 else
402 fprintf (asm_out_file, "\\%o", c);
403 }
404 fprintf (asm_out_file, "\\0\"\t%s ", ASM_COMMENT_START);
405 vfprintf (asm_out_file, comment, ap);
406 fputc ('\n', asm_out_file);
407 }
408 else
409 {
410 /* If an explicit length was given, we can't assume there
411 is a null termination in the string buffer. */
412 if (orig_len == (size_t) -1)
413 len += 1;
414 ASM_OUTPUT_ASCII (asm_out_file, str, len);
415 if (orig_len != (size_t) -1)
301d03af 416 assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1);
2e4b9b8c
RH
417 }
418
e34d07f2 419 va_end (ap);
2e4b9b8c
RH
420}
421\f
422
423/* Return the size of an unsigned LEB128 quantity. */
424
425int
7080f735 426size_of_uleb128 (unsigned HOST_WIDE_INT value)
2e4b9b8c 427{
4977bab6 428 int size = 0;
2e4b9b8c
RH
429
430 do
431 {
2e4b9b8c
RH
432 value >>= 7;
433 size += 1;
434 }
435 while (value != 0);
436
437 return size;
438}
439
440/* Return the size of a signed LEB128 quantity. */
441
442int
7080f735 443size_of_sleb128 (HOST_WIDE_INT value)
2e4b9b8c
RH
444{
445 int size = 0, byte;
446
447 do
448 {
449 byte = (value & 0x7f);
450 value >>= 7;
451 size += 1;
452 }
453 while (!((value == 0 && (byte & 0x40) == 0)
454 || (value == -1 && (byte & 0x40) != 0)));
455
456 return size;
457}
458
b627d6fe 459/* Given an encoding, return the number of bytes the format occupies.
3a538a66 460 This is only defined for fixed-size encodings, and so does not
b627d6fe
RH
461 include leb128. */
462
463int
7080f735 464size_of_encoded_value (int encoding)
b627d6fe
RH
465{
466 if (encoding == DW_EH_PE_omit)
467 return 0;
468
469 switch (encoding & 0x07)
470 {
471 case DW_EH_PE_absptr:
50b6ee8b 472 return POINTER_SIZE_UNITS;
b627d6fe
RH
473 case DW_EH_PE_udata2:
474 return 2;
475 case DW_EH_PE_udata4:
476 return 4;
477 case DW_EH_PE_udata8:
478 return 8;
ced3f397
NS
479 default:
480 gcc_unreachable ();
b627d6fe 481 }
b627d6fe
RH
482}
483
e1f9550a
RH
484/* Yield a name for a given pointer encoding. */
485
486const char *
7080f735 487eh_data_format_name (int format)
e1f9550a
RH
488{
489#if HAVE_DESIGNATED_INITIALIZERS
490#define S(p, v) [p] = v,
491#else
492#define S(p, v) case p: return v;
493#endif
494
495#if HAVE_DESIGNATED_INITIALIZERS
496 __extension__ static const char * const format_names[256] = {
497#else
498 switch (format) {
499#endif
500
501 S(DW_EH_PE_absptr, "absolute")
502 S(DW_EH_PE_omit, "omit")
099c8b17 503 S(DW_EH_PE_aligned, "aligned absolute")
e1f9550a
RH
504
505 S(DW_EH_PE_uleb128, "uleb128")
506 S(DW_EH_PE_udata2, "udata2")
507 S(DW_EH_PE_udata4, "udata4")
508 S(DW_EH_PE_udata8, "udata8")
509 S(DW_EH_PE_sleb128, "sleb128")
510 S(DW_EH_PE_sdata2, "sdata2")
511 S(DW_EH_PE_sdata4, "sdata4")
512 S(DW_EH_PE_sdata8, "sdata8")
513
f90811a2 514 S(DW_EH_PE_absptr | DW_EH_PE_pcrel, "pcrel")
e1f9550a
RH
515 S(DW_EH_PE_uleb128 | DW_EH_PE_pcrel, "pcrel uleb128")
516 S(DW_EH_PE_udata2 | DW_EH_PE_pcrel, "pcrel udata2")
517 S(DW_EH_PE_udata4 | DW_EH_PE_pcrel, "pcrel udata4")
518 S(DW_EH_PE_udata8 | DW_EH_PE_pcrel, "pcrel udata8")
519 S(DW_EH_PE_sleb128 | DW_EH_PE_pcrel, "pcrel sleb128")
520 S(DW_EH_PE_sdata2 | DW_EH_PE_pcrel, "pcrel sdata2")
521 S(DW_EH_PE_sdata4 | DW_EH_PE_pcrel, "pcrel sdata4")
522 S(DW_EH_PE_sdata8 | DW_EH_PE_pcrel, "pcrel sdata8")
523
f90811a2 524 S(DW_EH_PE_absptr | DW_EH_PE_textrel, "textrel")
e1f9550a
RH
525 S(DW_EH_PE_uleb128 | DW_EH_PE_textrel, "textrel uleb128")
526 S(DW_EH_PE_udata2 | DW_EH_PE_textrel, "textrel udata2")
527 S(DW_EH_PE_udata4 | DW_EH_PE_textrel, "textrel udata4")
528 S(DW_EH_PE_udata8 | DW_EH_PE_textrel, "textrel udata8")
529 S(DW_EH_PE_sleb128 | DW_EH_PE_textrel, "textrel sleb128")
530 S(DW_EH_PE_sdata2 | DW_EH_PE_textrel, "textrel sdata2")
531 S(DW_EH_PE_sdata4 | DW_EH_PE_textrel, "textrel sdata4")
532 S(DW_EH_PE_sdata8 | DW_EH_PE_textrel, "textrel sdata8")
533
f90811a2 534 S(DW_EH_PE_absptr | DW_EH_PE_datarel, "datarel")
e1f9550a
RH
535 S(DW_EH_PE_uleb128 | DW_EH_PE_datarel, "datarel uleb128")
536 S(DW_EH_PE_udata2 | DW_EH_PE_datarel, "datarel udata2")
537 S(DW_EH_PE_udata4 | DW_EH_PE_datarel, "datarel udata4")
538 S(DW_EH_PE_udata8 | DW_EH_PE_datarel, "datarel udata8")
539 S(DW_EH_PE_sleb128 | DW_EH_PE_datarel, "datarel sleb128")
540 S(DW_EH_PE_sdata2 | DW_EH_PE_datarel, "datarel sdata2")
541 S(DW_EH_PE_sdata4 | DW_EH_PE_datarel, "datarel sdata4")
542 S(DW_EH_PE_sdata8 | DW_EH_PE_datarel, "datarel sdata8")
543
f90811a2 544 S(DW_EH_PE_absptr | DW_EH_PE_funcrel, "funcrel")
e1f9550a
RH
545 S(DW_EH_PE_uleb128 | DW_EH_PE_funcrel, "funcrel uleb128")
546 S(DW_EH_PE_udata2 | DW_EH_PE_funcrel, "funcrel udata2")
547 S(DW_EH_PE_udata4 | DW_EH_PE_funcrel, "funcrel udata4")
548 S(DW_EH_PE_udata8 | DW_EH_PE_funcrel, "funcrel udata8")
549 S(DW_EH_PE_sleb128 | DW_EH_PE_funcrel, "funcrel sleb128")
550 S(DW_EH_PE_sdata2 | DW_EH_PE_funcrel, "funcrel sdata2")
551 S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4")
552 S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8")
553
49576e25
RS
554 S(DW_EH_PE_indirect | DW_EH_PE_absptr, "indirect absolute")
555
f90811a2
RH
556 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel,
557 "indirect pcrel")
e1f9550a
RH
558 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel,
559 "indirect pcrel uleb128")
560 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_pcrel,
561 "indirect pcrel udata2")
562 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_pcrel,
563 "indirect pcrel udata4")
564 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_pcrel,
565 "indirect pcrel udata8")
566 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_pcrel,
567 "indirect pcrel sleb128")
568 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_pcrel,
569 "indirect pcrel sdata2")
570 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_pcrel,
571 "indirect pcrel sdata4")
572 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_pcrel,
573 "indirect pcrel sdata8")
574
f90811a2
RH
575 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_textrel,
576 "indirect textrel")
e1f9550a
RH
577 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_textrel,
578 "indirect textrel uleb128")
579 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_textrel,
580 "indirect textrel udata2")
581 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_textrel,
582 "indirect textrel udata4")
583 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_textrel,
584 "indirect textrel udata8")
585 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_textrel,
586 "indirect textrel sleb128")
587 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_textrel,
588 "indirect textrel sdata2")
589 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_textrel,
590 "indirect textrel sdata4")
591 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_textrel,
592 "indirect textrel sdata8")
593
f90811a2
RH
594 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_datarel,
595 "indirect datarel")
e1f9550a
RH
596 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_datarel,
597 "indirect datarel uleb128")
598 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_datarel,
599 "indirect datarel udata2")
600 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_datarel,
601 "indirect datarel udata4")
602 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_datarel,
603 "indirect datarel udata8")
604 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_datarel,
605 "indirect datarel sleb128")
606 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_datarel,
607 "indirect datarel sdata2")
608 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_datarel,
609 "indirect datarel sdata4")
610 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_datarel,
611 "indirect datarel sdata8")
612
f90811a2
RH
613 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_funcrel,
614 "indirect funcrel")
e1f9550a
RH
615 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_funcrel,
616 "indirect funcrel uleb128")
617 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_funcrel,
618 "indirect funcrel udata2")
619 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_funcrel,
620 "indirect funcrel udata4")
621 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_funcrel,
622 "indirect funcrel udata8")
623 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_funcrel,
624 "indirect funcrel sleb128")
625 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_funcrel,
626 "indirect funcrel sdata2")
627 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_funcrel,
628 "indirect funcrel sdata4")
629 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_funcrel,
630 "indirect funcrel sdata8")
631
632#if HAVE_DESIGNATED_INITIALIZERS
633 };
634
ced3f397 635 gcc_assert (format >= 0 && format < 0x100 && format_names[format]);
b8698a0f 636
e1f9550a
RH
637 return format_names[format];
638#else
639 }
ced3f397 640 gcc_unreachable ();
e1f9550a
RH
641#endif
642}
643
d4ea4622
RH
644/* Output an unsigned LEB128 quantity, but only the byte values. */
645
646void
647dw2_asm_output_data_uleb128_raw (unsigned HOST_WIDE_INT value)
648{
649 while (1)
650 {
651 int byte = (value & 0x7f);
652 value >>= 7;
653 if (value != 0)
654 /* More bytes to follow. */
655 byte |= 0x80;
656
a3f1cee4 657 fprintf (asm_out_file, "%#x", byte);
d4ea4622
RH
658 if (value == 0)
659 break;
660 fputc (',', asm_out_file);
661 }
662}
663
2e4b9b8c
RH
664/* Output an unsigned LEB128 quantity. */
665
666void
e34d07f2
KG
667dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value,
668 const char *comment, ...)
2e4b9b8c 669{
e34d07f2 670 va_list ap;
7080f735 671
e34d07f2 672 va_start (ap, comment);
2e4b9b8c 673
61214be1 674 if (HAVE_AS_LEB128)
2e4b9b8c 675 {
61214be1
TS
676 fputs ("\t.uleb128 ", asm_out_file);
677 fprint_whex (asm_out_file, value);
678
679 if (flag_debug_asm && comment)
680 {
681 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
682 vfprintf (asm_out_file, comment, ap);
683 }
2e4b9b8c 684 }
61214be1 685 else
2e4b9b8c 686 {
61214be1
TS
687 unsigned HOST_WIDE_INT work = value;
688 const char *byte_op = targetm.asm_out.byte_op;
689
690 if (byte_op)
691 fputs (byte_op, asm_out_file);
692 do
2e4b9b8c 693 {
61214be1
TS
694 int byte = (work & 0x7f);
695 work >>= 7;
696 if (work != 0)
697 /* More bytes to follow. */
698 byte |= 0x80;
699
700 if (byte_op)
701 {
702 fprintf (asm_out_file, "%#x", byte);
703 if (work != 0)
704 fputc (',', asm_out_file);
705 }
706 else
707 assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
708 }
709 while (work != 0);
710
711 if (flag_debug_asm)
712 {
713 fprintf (asm_out_file, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX,
714 ASM_COMMENT_START, value);
715 if (comment)
716 {
717 fputs ("; ", asm_out_file);
718 vfprintf (asm_out_file, comment, ap);
719 }
2e4b9b8c
RH
720 }
721 }
61214be1 722
5e3929ed 723 putc ('\n', asm_out_file);
2e4b9b8c 724
e34d07f2 725 va_end (ap);
2e4b9b8c
RH
726}
727
d4ea4622
RH
728/* Output an signed LEB128 quantity, but only the byte values. */
729
730void
731dw2_asm_output_data_sleb128_raw (HOST_WIDE_INT value)
732{
733 int byte, more;
734
735 while (1)
736 {
737 byte = (value & 0x7f);
738 value >>= 7;
739 more = !((value == 0 && (byte & 0x40) == 0)
740 || (value == -1 && (byte & 0x40) != 0));
741 if (more)
742 byte |= 0x80;
743
a3f1cee4 744 fprintf (asm_out_file, "%#x", byte);
d4ea4622
RH
745 if (!more)
746 break;
747 fputc (',', asm_out_file);
748 }
749}
750
09da1532 751/* Output a signed LEB128 quantity. */
2e4b9b8c
RH
752
753void
e34d07f2
KG
754dw2_asm_output_data_sleb128 (HOST_WIDE_INT value,
755 const char *comment, ...)
2e4b9b8c 756{
e34d07f2 757 va_list ap;
7080f735 758
e34d07f2 759 va_start (ap, comment);
2e4b9b8c 760
61214be1 761 if (HAVE_AS_LEB128)
2e4b9b8c 762 {
61214be1
TS
763 fprintf (asm_out_file, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC, value);
764
765 if (flag_debug_asm && comment)
766 {
767 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
768 vfprintf (asm_out_file, comment, ap);
769 }
2e4b9b8c 770 }
61214be1 771 else
2e4b9b8c 772 {
61214be1
TS
773 HOST_WIDE_INT work = value;
774 int more, byte;
775 const char *byte_op = targetm.asm_out.byte_op;
776
777 if (byte_op)
778 fputs (byte_op, asm_out_file);
779 do
2e4b9b8c 780 {
61214be1
TS
781 byte = (work & 0x7f);
782 /* arithmetic shift */
783 work >>= 7;
784 more = !((work == 0 && (byte & 0x40) == 0)
785 || (work == -1 && (byte & 0x40) != 0));
786 if (more)
787 byte |= 0x80;
788
789 if (byte_op)
790 {
791 fprintf (asm_out_file, "%#x", byte);
792 if (more)
793 fputc (',', asm_out_file);
794 }
795 else
796 assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
797 }
798 while (more);
799
800 if (flag_debug_asm)
801 {
802 fprintf (asm_out_file, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC,
803 ASM_COMMENT_START, value);
804 if (comment)
805 {
806 fputs ("; ", asm_out_file);
807 vfprintf (asm_out_file, comment, ap);
808 }
2e4b9b8c
RH
809 }
810 }
61214be1 811
2e4b9b8c
RH
812 fputc ('\n', asm_out_file);
813
e34d07f2 814 va_end (ap);
2e4b9b8c
RH
815}
816
bd2b9f1e
AO
817/* Output symbol LAB1 as an unsigned LEB128 quantity. LAB1 should be
818 an assembler-computed constant, e.g. a view number, because we
819 can't have relocations in LEB128 quantities. */
820
821void
822dw2_asm_output_symname_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
823 const char *comment, ...)
824{
825 va_list ap;
826
827 va_start (ap, comment);
828
829#ifdef HAVE_AS_LEB128
830 fputs ("\t.uleb128 ", asm_out_file);
831 assemble_name (asm_out_file, lab1);
832#else
833 gcc_unreachable ();
834#endif
835
836 if (flag_debug_asm && comment)
837 {
838 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
839 vfprintf (asm_out_file, comment, ap);
840 }
841 fputc ('\n', asm_out_file);
842
843 va_end (ap);
844}
845
2e4b9b8c 846void
e34d07f2
KG
847dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
848 const char *lab2 ATTRIBUTE_UNUSED,
849 const char *comment, ...)
2e4b9b8c 850{
e34d07f2
KG
851 va_list ap;
852
853 va_start (ap, comment);
2e4b9b8c 854
61214be1
TS
855 gcc_assert (HAVE_AS_LEB128);
856
da6af203 857 fputs ("\t.uleb128 ", asm_out_file);
2e4b9b8c 858 assemble_name (asm_out_file, lab1);
5e3929ed 859 putc ('-', asm_out_file);
e53b6e56 860 /* dwarf2out.cc might give us a label expression (e.g. .LVL548-1)
7728669d
MW
861 as second argument. If so, make it a subexpression, to make
862 sure the substraction is done in the right order. */
863 if (strchr (lab2, '-') != NULL)
864 {
865 putc ('(', asm_out_file);
866 assemble_name (asm_out_file, lab2);
867 putc (')', asm_out_file);
868 }
869 else
870 assemble_name (asm_out_file, lab2);
2e4b9b8c
RH
871
872 if (flag_debug_asm && comment)
873 {
874 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
875 vfprintf (asm_out_file, comment, ap);
876 }
877 fputc ('\n', asm_out_file);
878
e34d07f2 879 va_end (ap);
2e4b9b8c
RH
880}
881
c8f4fe99
BE
882#if 0
883
2e4b9b8c 884void
e34d07f2
KG
885dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED,
886 const char *lab2 ATTRIBUTE_UNUSED,
887 const char *comment, ...)
2e4b9b8c 888{
e34d07f2 889 va_list ap;
7080f735 890
e34d07f2 891 va_start (ap, comment);
2e4b9b8c 892
61214be1
TS
893 gcc_assert (HAVE_AS_LEB128);
894
da6af203 895 fputs ("\t.sleb128 ", asm_out_file);
2e4b9b8c 896 assemble_name (asm_out_file, lab1);
5e3929ed 897 putc ('-', asm_out_file);
2e4b9b8c 898 assemble_name (asm_out_file, lab2);
2e4b9b8c
RH
899
900 if (flag_debug_asm && comment)
901 {
902 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
903 vfprintf (asm_out_file, comment, ap);
904 }
905 fputc ('\n', asm_out_file);
906
e34d07f2 907 va_end (ap);
2e4b9b8c 908}
c8f4fe99 909#endif /* 0 */
2a1ee410 910\f
de144fb2 911static GTY(()) hash_map<const char *, tree> *indirect_pool;
17211ab5
GK
912
913static GTY(()) int dw2_const_labelno;
2a1ee410 914
f31d9224 915#if defined(HAVE_GAS_HIDDEN)
7abcdb06 916# define USE_LINKONCE_INDIRECT (SUPPORTS_ONE_ONLY && !XCOFF_DEBUGGING_INFO)
d6d26764
JJ
917#else
918# define USE_LINKONCE_INDIRECT 0
919#endif
920
de144fb2
TS
921/* Compare two std::pair<const char *, tree> by their first element.
922 Returns <0, 0, or
dc1327cd
AO
923 >0 to indicate whether K1 is less than, equal to, or greater than
924 K2, respectively. */
925
926static int
de144fb2 927compare_strings (const void *a, const void *b)
dc1327cd 928{
de144fb2
TS
929 const char *s1 = ((const std::pair<const char *, tree> *) a)->first;
930 const char *s2 = ((const std::pair<const char *, tree> *) b)->first;
dc1327cd
AO
931 int ret;
932
933 if (s1 == s2)
934 return 0;
935
936 ret = strcmp (s1, s2);
937
938 /* The strings are always those from IDENTIFIER_NODEs, and,
939 therefore, we should never have two copies of the same
940 string. */
941 gcc_assert (ret);
942
943 return ret;
944}
945
e1f9550a
RH
946/* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
947 memory. Differs from force_const_mem in that a single pool is used for
948 the entire unit of translation, and the memory is not guaranteed to be
d858f359 949 "near" the function in any interesting sense. IS_PUBLIC controls whether
b03e9863 950 the symbol can be shared across the entire application (or DSO). */
e1f9550a 951
d4ea4622 952rtx
d858f359 953dw2_force_const_mem (rtx x, bool is_public)
2a1ee410 954{
a2649528 955 const char *key;
78bd9046 956 tree decl_id;
2a1ee410
RH
957
958 if (! indirect_pool)
de144fb2 959 indirect_pool = hash_map<const char *, tree>::create_ggc (64);
2a1ee410 960
ced3f397 961 gcc_assert (GET_CODE (x) == SYMBOL_REF);
1ee9fb20 962
a2649528 963 key = XSTR (x, 0);
de144fb2
TS
964 tree *slot = indirect_pool->get (key);
965 if (slot)
966 decl_id = *slot;
2a1ee410
RH
967 else
968 {
2a1ee410 969 tree id;
a2649528 970 const char *str = targetm.strip_name_encoding (key);
2a1ee410 971
d858f359 972 if (is_public && USE_LINKONCE_INDIRECT)
d6d26764 973 {
f883e0a7 974 char *ref_name = XALLOCAVEC (char, strlen (str) + sizeof "DW.ref.");
d6d26764 975
1ee9fb20 976 sprintf (ref_name, "DW.ref.%s", str);
78bd9046
AO
977 gcc_assert (!maybe_get_identifier (ref_name));
978 decl_id = get_identifier (ref_name);
979 TREE_PUBLIC (decl_id) = 1;
d6d26764
JJ
980 }
981 else
982 {
d6d26764
JJ
983 char label[32];
984
17211ab5
GK
985 ASM_GENERATE_INTERNAL_LABEL (label, "LDFCM", dw2_const_labelno);
986 ++dw2_const_labelno;
78bd9046
AO
987 gcc_assert (!maybe_get_identifier (label));
988 decl_id = get_identifier (label);
d6d26764 989 }
2a1ee410 990
1ee9fb20 991 id = maybe_get_identifier (str);
2a1ee410
RH
992 if (id)
993 TREE_SYMBOL_REFERENCED (id) = 1;
994
de144fb2 995 indirect_pool->put (key, decl_id);
2a1ee410
RH
996 }
997
78bd9046 998 return gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (decl_id));
2a1ee410
RH
999}
1000
de144fb2
TS
1001/* A helper function for dw2_output_indirect_constants. Emit one queued
1002 constant to memory. */
e1f9550a 1003
2a1ee410 1004static int
de144fb2 1005dw2_output_indirect_constant_1 (const char *sym, tree id)
2a1ee410 1006{
2a1ee410 1007 rtx sym_ref;
de144fb2 1008 tree decl;
78bd9046 1009
c2255bc4 1010 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id, ptr_type_node);
9937ab02 1011 SET_DECL_ASSEMBLER_NAME (decl, id);
78bd9046
AO
1012 DECL_ARTIFICIAL (decl) = 1;
1013 DECL_IGNORED_P (decl) = 1;
90841d43 1014 DECL_INITIAL (decl) = build_fold_addr_expr (decl);
3895ec53 1015 TREE_READONLY (decl) = 1;
56f3e9ac 1016 TREE_STATIC (decl) = 1;
78bd9046
AO
1017
1018 if (TREE_PUBLIC (id))
1019 {
1020 TREE_PUBLIC (decl) = 1;
fc26fae3 1021 make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
ee610fcd
RO
1022 if (USE_LINKONCE_INDIRECT)
1023 DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
78bd9046 1024 }
78bd9046 1025
2a1ee410 1026 sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
058494f9
MO
1027 /* Disable ASan for decl because redzones cause ABI breakage between GCC and
1028 libstdc++ for `.LDFCM*' variables. See PR 78651 for details. */
1029 unsigned int save_flag_sanitize = flag_sanitize;
1030 flag_sanitize &= ~(SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS
1031 | SANITIZE_KERNEL_ADDRESS);
d64257a4
JJ
1032 /* And also temporarily disable -fsection-anchors. These indirect constants
1033 are never referenced from code, so it doesn't make any sense to aggregate
1034 them in blocks. */
1035 int save_flag_section_anchors = flag_section_anchors;
1036 flag_section_anchors = 0;
b03e9863 1037 assemble_variable (decl, 1, 1, 1);
d64257a4 1038 flag_section_anchors = save_flag_section_anchors;
058494f9 1039 flag_sanitize = save_flag_sanitize;
50b6ee8b 1040 assemble_integer (sym_ref, POINTER_SIZE_UNITS, POINTER_SIZE, 1);
f13ed3ed
JJ
1041 /* The following is a hack recognized by use_blocks_for_decl_p to disable
1042 section anchor handling of the decl. */
1043 DECL_INITIAL (decl) = decl;
2a1ee410
RH
1044
1045 return 0;
1046}
1047
e1f9550a
RH
1048/* Emit the constants queued through dw2_force_const_mem. */
1049
2a1ee410 1050void
7080f735 1051dw2_output_indirect_constants (void)
2a1ee410 1052{
de144fb2
TS
1053 if (!indirect_pool)
1054 return;
1055
1056 auto_vec<std::pair<const char *, tree> > temp (indirect_pool->elements ());
1057 for (hash_map<const char *, tree>::iterator iter = indirect_pool->begin ();
1058 iter != indirect_pool->end (); ++iter)
1059 temp.quick_push (*iter);
1060
21c0a521 1061 temp.qsort (compare_strings);
de144fb2 1062
21c0a521 1063 for (unsigned int i = 0; i < temp.length (); i++)
de144fb2 1064 dw2_output_indirect_constant_1 (temp[i].first, temp[i].second);
2a1ee410
RH
1065}
1066
b03e9863
EB
1067/* Like dw2_asm_output_addr_rtx, but encode the pointer as directed.
1068 If PUBLIC is set and the encoding is DW_EH_PE_indirect, the indirect
1069 reference is shared across the entire application (or DSO). */
e1f9550a 1070
2a1ee410 1071void
d858f359 1072dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr, bool is_public,
e34d07f2 1073 const char *comment, ...)
2a1ee410
RH
1074{
1075 int size;
e34d07f2 1076 va_list ap;
7080f735 1077
e34d07f2 1078 va_start (ap, comment);
e1f9550a
RH
1079
1080 size = size_of_encoded_value (encoding);
2a1ee410 1081
099c8b17
RH
1082 if (encoding == DW_EH_PE_aligned)
1083 {
1084 assemble_align (POINTER_SIZE);
9f5cd0c5 1085 assemble_integer (addr, size, POINTER_SIZE, 1);
0edf1bb2 1086 va_end (ap);
9f5cd0c5 1087 return;
099c8b17
RH
1088 }
1089
3248917b
RK
1090 /* NULL is _always_ represented as a plain zero, as is 1 for Ada's
1091 "all others". */
1092 if (addr == const0_rtx || addr == const1_rtx)
c8af3574 1093 assemble_integer (addr, size, BITS_PER_UNIT, 1);
e1f9550a 1094 else
2a1ee410 1095 {
e1f9550a
RH
1096 restart:
1097 /* Allow the target first crack at emitting this. Some of the
3a538a66 1098 special relocations require special directives instead of
e1f9550a 1099 just ".4byte" or whatever. */
2a1ee410 1100#ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
e1f9550a
RH
1101 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file, encoding, size,
1102 addr, done);
2a1ee410
RH
1103#endif
1104
e1f9550a
RH
1105 /* Indirection is used to get dynamic relocations out of a
1106 read-only section. */
1107 if (encoding & DW_EH_PE_indirect)
1108 {
1109 /* It is very tempting to use force_const_mem so that we share data
1110 with the normal constant pool. However, we've already emitted
1111 the constant pool for this function. Moreover, we'd like to
b03e9863
EB
1112 share these constants across the entire unit of translation and
1113 even, if possible, across the entire application (or DSO). */
d858f359 1114 addr = dw2_force_const_mem (addr, is_public);
e1f9550a
RH
1115 encoding &= ~DW_EH_PE_indirect;
1116 goto restart;
1117 }
2a1ee410 1118
e1f9550a
RH
1119 switch (encoding & 0xF0)
1120 {
1121 case DW_EH_PE_absptr:
301d03af 1122 dw2_assemble_integer (size, addr);
e1f9550a 1123 break;
2a1ee410 1124
04218b35
AD
1125#ifdef ASM_OUTPUT_DWARF_DATAREL
1126 case DW_EH_PE_datarel:
1127 gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1128 ASM_OUTPUT_DWARF_DATAREL (asm_out_file, size, XSTR (addr, 0));
1129 break;
1130#endif
1131
e1f9550a 1132 case DW_EH_PE_pcrel:
ced3f397 1133 gcc_assert (GET_CODE (addr) == SYMBOL_REF);
2a1ee410 1134#ifdef ASM_OUTPUT_DWARF_PCREL
e1f9550a 1135 ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, XSTR (addr, 0));
2a1ee410 1136#else
301d03af 1137 dw2_assemble_integer (size, gen_rtx_MINUS (Pmode, addr, pc_rtx));
2a1ee410 1138#endif
e1f9550a 1139 break;
2a1ee410 1140
e1f9550a 1141 default:
3a538a66 1142 /* Other encodings should have been handled by
e1f9550a 1143 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */
ced3f397 1144 gcc_unreachable ();
e1f9550a 1145 }
2a1ee410
RH
1146
1147#ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
e1f9550a 1148 done:;
2a1ee410 1149#endif
e1f9550a
RH
1150 }
1151
1152 if (flag_debug_asm && comment)
1153 {
1154 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
1155 vfprintf (asm_out_file, comment, ap);
1156 }
2a1ee410 1157 fputc ('\n', asm_out_file);
e1f9550a 1158
e34d07f2 1159 va_end (ap);
2a1ee410 1160}
17211ab5
GK
1161
1162#include "gt-dwarf2asm.h"