]> gcc.gnu.org Git - gcc.git/blame - gcc/dwarf2asm.c
Merge basic-improvements-branch to trunk
[gcc.git] / gcc / dwarf2asm.c
CommitLineData
2e4b9b8c 1/* Dwarf2 assembler output helper routines.
c4f2c499 2 Copyright (C) 2001, 2002 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
8Software Foundation; either version 2, or (at your option) any later
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
1322177d
LB
17along with GCC; see the file COPYING. If not, write to the Free
18Software Foundation, 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
2e4b9b8c
RH
20
21
22#include "config.h"
23#include "system.h"
4977bab6
ZW
24#include "coretypes.h"
25#include "tm.h"
2e4b9b8c 26#include "flags.h"
2a1ee410 27#include "tree.h"
2e4b9b8c
RH
28#include "rtl.h"
29#include "output.h"
301d03af 30#include "target.h"
2e4b9b8c 31#include "dwarf2asm.h"
2a1ee410
RH
32#include "dwarf2.h"
33#include "splay-tree.h"
34#include "ggc.h"
2e4b9b8c
RH
35#include "tm_p.h"
36
37
38/* How to start an assembler comment. */
39#ifndef ASM_COMMENT_START
40#define ASM_COMMENT_START ";#"
41#endif
42
2e4b9b8c 43\f
301d03af
RS
44/* Output an unaligned integer with the given value and size. Prefer not
45 to print a newline, since the caller may want to add a comment. */
46
47void
48dw2_assemble_integer (size, x)
2e4b9b8c 49 int size;
301d03af 50 rtx x;
2e4b9b8c 51{
301d03af
RS
52 const char *op = integer_asm_op (size, FALSE);
53
54 if (op)
2e4b9b8c 55 {
301d03af
RS
56 fputs (op, asm_out_file);
57 if (GET_CODE (x) == CONST_INT)
58 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
59 else
60 output_addr_const (asm_out_file, x);
2e4b9b8c 61 }
301d03af
RS
62 else
63 assemble_integer (x, size, BITS_PER_UNIT, 1);
2e4b9b8c 64}
3a538a66 65
2e4b9b8c 66
8e7fa2c8
RH
67/* Output an immediate constant in a given size. */
68
2e4b9b8c
RH
69void
70dw2_asm_output_data VPARAMS ((int size, unsigned HOST_WIDE_INT value,
71 const char *comment, ...))
72{
7a75edb7
AJ
73 VA_OPEN (ap, comment);
74 VA_FIXEDARG (ap, int, size);
75 VA_FIXEDARG (ap, unsigned HOST_WIDE_INT, value);
76 VA_FIXEDARG (ap, const char *, comment);
2e4b9b8c 77
da6af203 78 if (size * 8 < HOST_BITS_PER_WIDE_INT)
c4f2c499 79 value &= ~(~(unsigned HOST_WIDE_INT) 0 << (size * 8));
da6af203 80
301d03af 81 dw2_assemble_integer (size, GEN_INT (value));
2e4b9b8c
RH
82
83 if (flag_debug_asm && comment)
84 {
85 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
86 vfprintf (asm_out_file, comment, ap);
87 }
88 fputc ('\n', asm_out_file);
89
7a75edb7 90 VA_CLOSE (ap);
2e4b9b8c
RH
91}
92
8e7fa2c8
RH
93/* Output the difference between two symbols in a given size. */
94/* ??? There appear to be assemblers that do not like such
95 subtraction, but do support ASM_SET_OP. It's unfortunately
96 impossible to do here, since the ASM_SET_OP for the difference
97 symbol must appear after both symbols are defined. */
98
2e4b9b8c
RH
99void
100dw2_asm_output_delta VPARAMS ((int size, const char *lab1, const char *lab2,
101 const char *comment, ...))
102{
7a75edb7
AJ
103 VA_OPEN (ap, comment);
104 VA_FIXEDARG (ap, int, size);
105 VA_FIXEDARG (ap, const char *, lab1);
106 VA_FIXEDARG (ap, const char *, lab2);
107 VA_FIXEDARG (ap, const char *, comment);
2e4b9b8c 108
7606e68f
SS
109#ifdef ASM_OUTPUT_DWARF_DELTA
110 ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2);
111#else
301d03af
RS
112 dw2_assemble_integer (size,
113 gen_rtx_MINUS (Pmode,
114 gen_rtx_SYMBOL_REF (Pmode, lab1),
115 gen_rtx_SYMBOL_REF (Pmode, lab2)));
7606e68f 116#endif
2e4b9b8c
RH
117 if (flag_debug_asm && comment)
118 {
119 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
120 vfprintf (asm_out_file, comment, ap);
121 }
122 fputc ('\n', asm_out_file);
123
7a75edb7 124 VA_CLOSE (ap);
2e4b9b8c
RH
125}
126
8e7fa2c8
RH
127/* Output a section-relative reference to a label. In general this
128 can only be done for debugging symbols. E.g. on most targets with
129 the GNU linker, this is accomplished with a direct reference and
130 the knowledge that the debugging section will be placed at VMA 0.
131 Some targets have special relocations for this that we must use. */
132
2e4b9b8c
RH
133void
134dw2_asm_output_offset VPARAMS ((int size, const char *label,
135 const char *comment, ...))
136{
7a75edb7
AJ
137 VA_OPEN (ap, comment);
138 VA_FIXEDARG (ap, int, size);
139 VA_FIXEDARG (ap, const char *, label);
140 VA_FIXEDARG (ap, const char *, comment);
2e4b9b8c 141
8e7fa2c8
RH
142#ifdef ASM_OUTPUT_DWARF_OFFSET
143 ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label);
144#else
301d03af 145 dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
2e4b9b8c
RH
146#endif
147
148 if (flag_debug_asm && comment)
149 {
150 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
151 vfprintf (asm_out_file, comment, ap);
152 }
153 fputc ('\n', asm_out_file);
154
7a75edb7 155 VA_CLOSE (ap);
2e4b9b8c
RH
156}
157
8e7fa2c8
RH
158/* Output a self-relative reference to a label, possibly in a
159 different section or object file. */
160
2e4b9b8c 161void
40cdfca6
KG
162dw2_asm_output_pcrel VPARAMS ((int size ATTRIBUTE_UNUSED,
163 const char *label ATTRIBUTE_UNUSED,
2e4b9b8c
RH
164 const char *comment, ...))
165{
7a75edb7
AJ
166 VA_OPEN (ap, comment);
167 VA_FIXEDARG (ap, int, size);
168 VA_FIXEDARG (ap, const char *, label);
169 VA_FIXEDARG (ap, const char *, comment);
2e4b9b8c 170
8e7fa2c8
RH
171#ifdef ASM_OUTPUT_DWARF_PCREL
172 ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label);
173#else
301d03af
RS
174 dw2_assemble_integer (size,
175 gen_rtx_MINUS (Pmode,
176 gen_rtx_SYMBOL_REF (Pmode, label),
177 pc_rtx));
8e7fa2c8
RH
178#endif
179
180 if (flag_debug_asm && comment)
181 {
182 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
183 vfprintf (asm_out_file, comment, ap);
184 }
185 fputc ('\n', asm_out_file);
186
7a75edb7 187 VA_CLOSE (ap);
8e7fa2c8
RH
188}
189
190/* Output an absolute reference to a label. */
191
192void
193dw2_asm_output_addr VPARAMS ((int size, const char *label,
194 const char *comment, ...))
195{
7a75edb7
AJ
196 VA_OPEN (ap, comment);
197 VA_FIXEDARG (ap, int, size);
198 VA_FIXEDARG (ap, const char *, label);
199 VA_FIXEDARG (ap, const char *, comment);
8e7fa2c8 200
301d03af 201 dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
2e4b9b8c
RH
202
203 if (flag_debug_asm && comment)
204 {
205 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
206 vfprintf (asm_out_file, comment, ap);
207 }
208 fputc ('\n', asm_out_file);
209
7a75edb7 210 VA_CLOSE (ap);
2e4b9b8c
RH
211}
212
8e7fa2c8
RH
213/* Similar, but use an RTX expression instead of a text label. */
214
2e4b9b8c
RH
215void
216dw2_asm_output_addr_rtx VPARAMS ((int size, rtx addr,
217 const char *comment, ...))
218{
7a75edb7
AJ
219 VA_OPEN (ap, comment);
220 VA_FIXEDARG (ap, int, size);
221 VA_FIXEDARG (ap, rtx, addr);
222 VA_FIXEDARG (ap, const char *, comment);
2e4b9b8c 223
301d03af 224 dw2_assemble_integer (size, addr);
2e4b9b8c
RH
225
226 if (flag_debug_asm && comment)
227 {
228 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
229 vfprintf (asm_out_file, comment, ap);
230 }
231 fputc ('\n', asm_out_file);
232
7a75edb7 233 VA_CLOSE (ap);
2e4b9b8c
RH
234}
235
236void
237dw2_asm_output_nstring VPARAMS ((const char *str, size_t orig_len,
238 const char *comment, ...))
239{
7a75edb7 240 size_t i, len;
2e4b9b8c 241
7a75edb7
AJ
242 VA_OPEN (ap, comment);
243 VA_FIXEDARG (ap, const char *, str);
c43f84d7 244 VA_FIXEDARG (ap, size_t, orig_len);
7a75edb7 245 VA_FIXEDARG (ap, const char *, comment);
2e4b9b8c 246
7a75edb7 247 len = orig_len;
2e4b9b8c
RH
248
249 if (len == (size_t) -1)
250 len = strlen (str);
251
252 if (flag_debug_asm && comment)
253 {
254 fputs ("\t.ascii \"", asm_out_file);
255 for (i = 0; i < len; i++)
256 {
257 int c = str[i];
258 if (c == '\"' || c == '\\')
259 fputc ('\\', asm_out_file);
260 if (ISPRINT(c))
261 fputc (c, asm_out_file);
262 else
263 fprintf (asm_out_file, "\\%o", c);
264 }
265 fprintf (asm_out_file, "\\0\"\t%s ", ASM_COMMENT_START);
266 vfprintf (asm_out_file, comment, ap);
267 fputc ('\n', asm_out_file);
268 }
269 else
270 {
271 /* If an explicit length was given, we can't assume there
272 is a null termination in the string buffer. */
273 if (orig_len == (size_t) -1)
274 len += 1;
275 ASM_OUTPUT_ASCII (asm_out_file, str, len);
276 if (orig_len != (size_t) -1)
301d03af 277 assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1);
2e4b9b8c
RH
278 }
279
7a75edb7 280 VA_CLOSE (ap);
2e4b9b8c
RH
281}
282\f
283
284/* Return the size of an unsigned LEB128 quantity. */
285
286int
287size_of_uleb128 (value)
288 unsigned HOST_WIDE_INT value;
289{
4977bab6 290 int size = 0;
2e4b9b8c
RH
291
292 do
293 {
2e4b9b8c
RH
294 value >>= 7;
295 size += 1;
296 }
297 while (value != 0);
298
299 return size;
300}
301
302/* Return the size of a signed LEB128 quantity. */
303
304int
305size_of_sleb128 (value)
306 HOST_WIDE_INT value;
307{
308 int size = 0, byte;
309
310 do
311 {
312 byte = (value & 0x7f);
313 value >>= 7;
314 size += 1;
315 }
316 while (!((value == 0 && (byte & 0x40) == 0)
317 || (value == -1 && (byte & 0x40) != 0)));
318
319 return size;
320}
321
b627d6fe 322/* Given an encoding, return the number of bytes the format occupies.
3a538a66 323 This is only defined for fixed-size encodings, and so does not
b627d6fe
RH
324 include leb128. */
325
326int
327size_of_encoded_value (encoding)
328 int encoding;
329{
330 if (encoding == DW_EH_PE_omit)
331 return 0;
332
333 switch (encoding & 0x07)
334 {
335 case DW_EH_PE_absptr:
336 return POINTER_SIZE / BITS_PER_UNIT;
337 case DW_EH_PE_udata2:
338 return 2;
339 case DW_EH_PE_udata4:
340 return 4;
341 case DW_EH_PE_udata8:
342 return 8;
343 }
344 abort ();
345}
346
e1f9550a
RH
347/* Yield a name for a given pointer encoding. */
348
349const char *
350eh_data_format_name (format)
351 int format;
352{
353#if HAVE_DESIGNATED_INITIALIZERS
354#define S(p, v) [p] = v,
355#else
356#define S(p, v) case p: return v;
357#endif
358
359#if HAVE_DESIGNATED_INITIALIZERS
360 __extension__ static const char * const format_names[256] = {
361#else
362 switch (format) {
363#endif
364
365 S(DW_EH_PE_absptr, "absolute")
366 S(DW_EH_PE_omit, "omit")
099c8b17 367 S(DW_EH_PE_aligned, "aligned absolute")
e1f9550a
RH
368
369 S(DW_EH_PE_uleb128, "uleb128")
370 S(DW_EH_PE_udata2, "udata2")
371 S(DW_EH_PE_udata4, "udata4")
372 S(DW_EH_PE_udata8, "udata8")
373 S(DW_EH_PE_sleb128, "sleb128")
374 S(DW_EH_PE_sdata2, "sdata2")
375 S(DW_EH_PE_sdata4, "sdata4")
376 S(DW_EH_PE_sdata8, "sdata8")
377
f90811a2 378 S(DW_EH_PE_absptr | DW_EH_PE_pcrel, "pcrel")
e1f9550a
RH
379 S(DW_EH_PE_uleb128 | DW_EH_PE_pcrel, "pcrel uleb128")
380 S(DW_EH_PE_udata2 | DW_EH_PE_pcrel, "pcrel udata2")
381 S(DW_EH_PE_udata4 | DW_EH_PE_pcrel, "pcrel udata4")
382 S(DW_EH_PE_udata8 | DW_EH_PE_pcrel, "pcrel udata8")
383 S(DW_EH_PE_sleb128 | DW_EH_PE_pcrel, "pcrel sleb128")
384 S(DW_EH_PE_sdata2 | DW_EH_PE_pcrel, "pcrel sdata2")
385 S(DW_EH_PE_sdata4 | DW_EH_PE_pcrel, "pcrel sdata4")
386 S(DW_EH_PE_sdata8 | DW_EH_PE_pcrel, "pcrel sdata8")
387
f90811a2 388 S(DW_EH_PE_absptr | DW_EH_PE_textrel, "textrel")
e1f9550a
RH
389 S(DW_EH_PE_uleb128 | DW_EH_PE_textrel, "textrel uleb128")
390 S(DW_EH_PE_udata2 | DW_EH_PE_textrel, "textrel udata2")
391 S(DW_EH_PE_udata4 | DW_EH_PE_textrel, "textrel udata4")
392 S(DW_EH_PE_udata8 | DW_EH_PE_textrel, "textrel udata8")
393 S(DW_EH_PE_sleb128 | DW_EH_PE_textrel, "textrel sleb128")
394 S(DW_EH_PE_sdata2 | DW_EH_PE_textrel, "textrel sdata2")
395 S(DW_EH_PE_sdata4 | DW_EH_PE_textrel, "textrel sdata4")
396 S(DW_EH_PE_sdata8 | DW_EH_PE_textrel, "textrel sdata8")
397
f90811a2 398 S(DW_EH_PE_absptr | DW_EH_PE_datarel, "datarel")
e1f9550a
RH
399 S(DW_EH_PE_uleb128 | DW_EH_PE_datarel, "datarel uleb128")
400 S(DW_EH_PE_udata2 | DW_EH_PE_datarel, "datarel udata2")
401 S(DW_EH_PE_udata4 | DW_EH_PE_datarel, "datarel udata4")
402 S(DW_EH_PE_udata8 | DW_EH_PE_datarel, "datarel udata8")
403 S(DW_EH_PE_sleb128 | DW_EH_PE_datarel, "datarel sleb128")
404 S(DW_EH_PE_sdata2 | DW_EH_PE_datarel, "datarel sdata2")
405 S(DW_EH_PE_sdata4 | DW_EH_PE_datarel, "datarel sdata4")
406 S(DW_EH_PE_sdata8 | DW_EH_PE_datarel, "datarel sdata8")
407
f90811a2 408 S(DW_EH_PE_absptr | DW_EH_PE_funcrel, "funcrel")
e1f9550a
RH
409 S(DW_EH_PE_uleb128 | DW_EH_PE_funcrel, "funcrel uleb128")
410 S(DW_EH_PE_udata2 | DW_EH_PE_funcrel, "funcrel udata2")
411 S(DW_EH_PE_udata4 | DW_EH_PE_funcrel, "funcrel udata4")
412 S(DW_EH_PE_udata8 | DW_EH_PE_funcrel, "funcrel udata8")
413 S(DW_EH_PE_sleb128 | DW_EH_PE_funcrel, "funcrel sleb128")
414 S(DW_EH_PE_sdata2 | DW_EH_PE_funcrel, "funcrel sdata2")
415 S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4")
416 S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8")
417
f90811a2
RH
418 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel,
419 "indirect pcrel")
e1f9550a
RH
420 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel,
421 "indirect pcrel uleb128")
422 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_pcrel,
423 "indirect pcrel udata2")
424 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_pcrel,
425 "indirect pcrel udata4")
426 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_pcrel,
427 "indirect pcrel udata8")
428 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_pcrel,
429 "indirect pcrel sleb128")
430 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_pcrel,
431 "indirect pcrel sdata2")
432 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_pcrel,
433 "indirect pcrel sdata4")
434 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_pcrel,
435 "indirect pcrel sdata8")
436
f90811a2
RH
437 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_textrel,
438 "indirect textrel")
e1f9550a
RH
439 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_textrel,
440 "indirect textrel uleb128")
441 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_textrel,
442 "indirect textrel udata2")
443 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_textrel,
444 "indirect textrel udata4")
445 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_textrel,
446 "indirect textrel udata8")
447 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_textrel,
448 "indirect textrel sleb128")
449 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_textrel,
450 "indirect textrel sdata2")
451 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_textrel,
452 "indirect textrel sdata4")
453 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_textrel,
454 "indirect textrel sdata8")
455
f90811a2
RH
456 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_datarel,
457 "indirect datarel")
e1f9550a
RH
458 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_datarel,
459 "indirect datarel uleb128")
460 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_datarel,
461 "indirect datarel udata2")
462 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_datarel,
463 "indirect datarel udata4")
464 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_datarel,
465 "indirect datarel udata8")
466 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_datarel,
467 "indirect datarel sleb128")
468 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_datarel,
469 "indirect datarel sdata2")
470 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_datarel,
471 "indirect datarel sdata4")
472 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_datarel,
473 "indirect datarel sdata8")
474
f90811a2
RH
475 S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_funcrel,
476 "indirect funcrel")
e1f9550a
RH
477 S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_funcrel,
478 "indirect funcrel uleb128")
479 S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_funcrel,
480 "indirect funcrel udata2")
481 S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_funcrel,
482 "indirect funcrel udata4")
483 S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_funcrel,
484 "indirect funcrel udata8")
485 S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_funcrel,
486 "indirect funcrel sleb128")
487 S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_funcrel,
488 "indirect funcrel sdata2")
489 S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_funcrel,
490 "indirect funcrel sdata4")
491 S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_funcrel,
492 "indirect funcrel sdata8")
493
494#if HAVE_DESIGNATED_INITIALIZERS
495 };
496
497 if (format < 0 || format > 0xff || format_names[format] == NULL)
498 abort ();
499 return format_names[format];
500#else
501 }
502 abort ();
503#endif
504}
505
2e4b9b8c
RH
506/* Output an unsigned LEB128 quantity. */
507
508void
509dw2_asm_output_data_uleb128 VPARAMS ((unsigned HOST_WIDE_INT value,
510 const char *comment, ...))
511{
7a75edb7
AJ
512 VA_OPEN (ap, comment);
513 VA_FIXEDARG (ap, unsigned HOST_WIDE_INT, value);
514 VA_FIXEDARG (ap, const char *, comment);
2e4b9b8c
RH
515
516#ifdef HAVE_AS_LEB128
da6af203 517 fputs ("\t.uleb128 ", asm_out_file);
2e4b9b8c
RH
518 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
519
520 if (flag_debug_asm && comment)
521 {
522 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
523 vfprintf (asm_out_file, comment, ap);
524 }
525#else
526 {
527 unsigned HOST_WIDE_INT work = value;
301d03af 528 const char *byte_op = targetm.asm_out.byte_op;
2e4b9b8c 529
301d03af
RS
530 if (byte_op)
531 fputs (byte_op, asm_out_file);
2e4b9b8c
RH
532 do
533 {
534 int byte = (work & 0x7f);
535 work >>= 7;
536 if (work != 0)
537 /* More bytes to follow. */
538 byte |= 0x80;
539
301d03af
RS
540 if (byte_op)
541 {
542 fprintf (asm_out_file, "0x%x", byte);
543 if (work != 0)
544 fputc (',', asm_out_file);
545 }
546 else
547 assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
2e4b9b8c
RH
548 }
549 while (work != 0);
550
551 if (flag_debug_asm)
552 {
553 fprintf (asm_out_file, "\t%s uleb128 ", ASM_COMMENT_START);
554 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
555 if (comment)
556 {
557 fputs ("; ", asm_out_file);
558 vfprintf (asm_out_file, comment, ap);
559 }
560 }
561 }
562#endif
563 fputc ('\n', asm_out_file);
564
7a75edb7 565 VA_CLOSE (ap);
2e4b9b8c
RH
566}
567
09da1532 568/* Output a signed LEB128 quantity. */
2e4b9b8c
RH
569
570void
571dw2_asm_output_data_sleb128 VPARAMS ((HOST_WIDE_INT value,
572 const char *comment, ...))
573{
7a75edb7
AJ
574 VA_OPEN (ap, comment);
575 VA_FIXEDARG (ap, HOST_WIDE_INT, value);
576 VA_FIXEDARG (ap, const char *, comment);
2e4b9b8c
RH
577
578#ifdef HAVE_AS_LEB128
da6af203
RH
579 fputs ("\t.sleb128 ", asm_out_file);
580 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, value);
2e4b9b8c
RH
581
582 if (flag_debug_asm && comment)
583 {
584 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
585 vfprintf (asm_out_file, comment, ap);
586 }
587#else
588 {
589 HOST_WIDE_INT work = value;
590 int more, byte;
301d03af 591 const char *byte_op = targetm.asm_out.byte_op;
2e4b9b8c 592
301d03af
RS
593 if (byte_op)
594 fputs (byte_op, asm_out_file);
2e4b9b8c
RH
595 do
596 {
597 byte = (work & 0x7f);
598 /* arithmetic shift */
599 work >>= 7;
600 more = !((work == 0 && (byte & 0x40) == 0)
601 || (work == -1 && (byte & 0x40) != 0));
602 if (more)
603 byte |= 0x80;
604
301d03af
RS
605 if (byte_op)
606 {
607 fprintf (asm_out_file, "0x%x", byte);
608 if (more)
609 fputc (',', asm_out_file);
610 }
611 else
612 assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
2e4b9b8c
RH
613 }
614 while (more);
615
616 if (flag_debug_asm)
617 {
618 fprintf (asm_out_file, "\t%s sleb128 ", ASM_COMMENT_START);
619 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, value);
620 if (comment)
621 {
622 fputs ("; ", asm_out_file);
623 vfprintf (asm_out_file, comment, ap);
624 }
625 }
626 }
627#endif
628 fputc ('\n', asm_out_file);
629
7a75edb7 630 VA_CLOSE (ap);
2e4b9b8c
RH
631}
632
633void
634dw2_asm_output_delta_uleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
635 const char *lab2 ATTRIBUTE_UNUSED,
636 const char *comment, ...))
637{
7a75edb7
AJ
638 VA_OPEN (ap, comment);
639 VA_FIXEDARG (ap, const char *, lab1);
640 VA_FIXEDARG (ap, const char *, lab2);
641 VA_FIXEDARG (ap, const char *, comment);
2e4b9b8c
RH
642
643#ifdef HAVE_AS_LEB128
da6af203 644 fputs ("\t.uleb128 ", asm_out_file);
2e4b9b8c
RH
645 assemble_name (asm_out_file, lab1);
646 fputc ('-', asm_out_file);
647 assemble_name (asm_out_file, lab2);
648#else
649 abort ();
650#endif
651
652 if (flag_debug_asm && comment)
653 {
654 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
655 vfprintf (asm_out_file, comment, ap);
656 }
657 fputc ('\n', asm_out_file);
658
7a75edb7 659 VA_CLOSE (ap);
2e4b9b8c
RH
660}
661
662void
663dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
664 const char *lab2 ATTRIBUTE_UNUSED,
665 const char *comment, ...))
666{
7a75edb7
AJ
667 VA_OPEN (ap, comment);
668 VA_FIXEDARG (ap, const char *, lab1);
669 VA_FIXEDARG (ap, const char *, lab2);
670 VA_FIXEDARG (ap, const char *, comment);
2e4b9b8c
RH
671
672#ifdef HAVE_AS_LEB128
da6af203 673 fputs ("\t.sleb128 ", asm_out_file);
2e4b9b8c
RH
674 assemble_name (asm_out_file, lab1);
675 fputc ('-', asm_out_file);
676 assemble_name (asm_out_file, lab2);
677#else
678 abort ();
679#endif
680
681 if (flag_debug_asm && comment)
682 {
683 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
684 vfprintf (asm_out_file, comment, ap);
685 }
686 fputc ('\n', asm_out_file);
687
7a75edb7 688 VA_CLOSE (ap);
2e4b9b8c 689}
2a1ee410 690\f
d6d26764
JJ
691static int mark_indirect_pool_entry PARAMS ((splay_tree_node, void *));
692static void mark_indirect_pool PARAMS ((PTR arg));
2a1ee410
RH
693static rtx dw2_force_const_mem PARAMS ((rtx));
694static int dw2_output_indirect_constant_1 PARAMS ((splay_tree_node, void *));
695
696static splay_tree indirect_pool;
697
d6d26764
JJ
698#if defined(HAVE_GAS_HIDDEN) && defined(SUPPORTS_ONE_ONLY)
699# define USE_LINKONCE_INDIRECT 1
700#else
701# define USE_LINKONCE_INDIRECT 0
702#endif
703
704/* Mark all indirect constants for GC. */
705
706static int
707mark_indirect_pool_entry (node, data)
708 splay_tree_node node;
709 void* data ATTRIBUTE_UNUSED;
710{
e2500fed 711 ggc_mark_tree ((tree) node->value);
d6d26764
JJ
712 return 0;
713}
714
715/* Mark all indirect constants for GC. */
716
717static void
718mark_indirect_pool (arg)
719 PTR arg ATTRIBUTE_UNUSED;
720{
721 splay_tree_foreach (indirect_pool, mark_indirect_pool_entry, NULL);
722}
723
e1f9550a
RH
724/* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
725 memory. Differs from force_const_mem in that a single pool is used for
726 the entire unit of translation, and the memory is not guaranteed to be
727 "near" the function in any interesting sense. */
728
2a1ee410
RH
729static rtx
730dw2_force_const_mem (x)
731 rtx x;
732{
733 splay_tree_node node;
1ee9fb20 734 const char *str;
d6d26764 735 tree decl;
2a1ee410
RH
736
737 if (! indirect_pool)
d6d26764
JJ
738 {
739 indirect_pool = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
740 ggc_add_root (&indirect_pool, 1, sizeof indirect_pool, mark_indirect_pool);
741 }
2a1ee410
RH
742
743 if (GET_CODE (x) != SYMBOL_REF)
744 abort ();
1ee9fb20 745
772c5265 746 str = (* targetm.strip_name_encoding) (XSTR (x, 0));
1ee9fb20 747 node = splay_tree_lookup (indirect_pool, (splay_tree_key) str);
2a1ee410 748 if (node)
d6d26764 749 decl = (tree) node->value;
2a1ee410
RH
750 else
751 {
2a1ee410
RH
752 tree id;
753
d6d26764
JJ
754 if (USE_LINKONCE_INDIRECT)
755 {
1ee9fb20 756 char *ref_name = alloca (strlen (str) + sizeof "DW.ref.");
d6d26764 757
1ee9fb20 758 sprintf (ref_name, "DW.ref.%s", str);
d6d26764
JJ
759 id = get_identifier (ref_name);
760 decl = build_decl (VAR_DECL, id, ptr_type_node);
761 DECL_ARTIFICIAL (decl) = 1;
a8988448 762 TREE_PUBLIC (decl) = 1;
d6d26764
JJ
763 DECL_INITIAL (decl) = decl;
764 make_decl_one_only (decl);
765 }
766 else
767 {
768 extern int const_labelno;
769 char label[32];
770
771 ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
772 ++const_labelno;
773 id = get_identifier (label);
774 decl = build_decl (VAR_DECL, id, ptr_type_node);
775 DECL_ARTIFICIAL (decl) = 1;
a8988448 776 TREE_STATIC (decl) = 1;
d6d26764
JJ
777 DECL_INITIAL (decl) = decl;
778 }
2a1ee410 779
1ee9fb20 780 id = maybe_get_identifier (str);
2a1ee410
RH
781 if (id)
782 TREE_SYMBOL_REFERENCED (id) = 1;
783
1ee9fb20 784 splay_tree_insert (indirect_pool, (splay_tree_key) str,
d6d26764 785 (splay_tree_value) decl);
2a1ee410
RH
786 }
787
d6d26764 788 return XEXP (DECL_RTL (decl), 0);
2a1ee410
RH
789}
790
e1f9550a
RH
791/* A helper function for dw2_output_indirect_constants called through
792 splay_tree_foreach. Emit one queued constant to memory. */
793
2a1ee410
RH
794static int
795dw2_output_indirect_constant_1 (node, data)
796 splay_tree_node node;
797 void* data ATTRIBUTE_UNUSED;
798{
d6d26764 799 const char *sym;
2a1ee410
RH
800 rtx sym_ref;
801
2a1ee410
RH
802 sym = (const char *) node->key;
803 sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
d6d26764
JJ
804 if (USE_LINKONCE_INDIRECT)
805 fprintf (asm_out_file, "\t.hidden DW.ref.%s\n", sym);
806 assemble_variable ((tree) node->value, 1, 1, 1);
2919600a 807 assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
2a1ee410
RH
808
809 return 0;
810}
811
e1f9550a
RH
812/* Emit the constants queued through dw2_force_const_mem. */
813
2a1ee410
RH
814void
815dw2_output_indirect_constants ()
816{
d6d26764
JJ
817 if (indirect_pool)
818 splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL);
2a1ee410
RH
819}
820
e1f9550a
RH
821/* Like dw2_asm_output_addr_rtx, but encode the pointer as directed. */
822
2a1ee410 823void
e1f9550a
RH
824dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding,
825 rtx addr,
826 const char *comment, ...))
2a1ee410
RH
827{
828 int size;
829
7a75edb7
AJ
830 VA_OPEN (ap, comment);
831 VA_FIXEDARG (ap, int, encoding);
832 VA_FIXEDARG (ap, rtx, addr);
833 VA_FIXEDARG (ap, const char *, comment);
e1f9550a
RH
834
835 size = size_of_encoded_value (encoding);
2a1ee410 836
099c8b17
RH
837 if (encoding == DW_EH_PE_aligned)
838 {
839 assemble_align (POINTER_SIZE);
9f5cd0c5
RH
840 assemble_integer (addr, size, POINTER_SIZE, 1);
841 return;
099c8b17
RH
842 }
843
3248917b
RK
844 /* NULL is _always_ represented as a plain zero, as is 1 for Ada's
845 "all others". */
846 if (addr == const0_rtx || addr == const1_rtx)
c8af3574 847 assemble_integer (addr, size, BITS_PER_UNIT, 1);
e1f9550a 848 else
2a1ee410 849 {
e1f9550a
RH
850 restart:
851 /* Allow the target first crack at emitting this. Some of the
3a538a66 852 special relocations require special directives instead of
e1f9550a 853 just ".4byte" or whatever. */
2a1ee410 854#ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
e1f9550a
RH
855 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file, encoding, size,
856 addr, done);
2a1ee410
RH
857#endif
858
e1f9550a
RH
859 /* Indirection is used to get dynamic relocations out of a
860 read-only section. */
861 if (encoding & DW_EH_PE_indirect)
862 {
863 /* It is very tempting to use force_const_mem so that we share data
864 with the normal constant pool. However, we've already emitted
865 the constant pool for this function. Moreover, we'd like to
866 share these constants across the entire unit of translation,
867 or better, across the entire application (or DSO). */
868 addr = dw2_force_const_mem (addr);
869 encoding &= ~DW_EH_PE_indirect;
870 goto restart;
871 }
2a1ee410 872
e1f9550a
RH
873 switch (encoding & 0xF0)
874 {
875 case DW_EH_PE_absptr:
301d03af 876 dw2_assemble_integer (size, addr);
e1f9550a 877 break;
2a1ee410 878
e1f9550a
RH
879 case DW_EH_PE_pcrel:
880 if (GET_CODE (addr) != SYMBOL_REF)
881 abort ();
2a1ee410 882#ifdef ASM_OUTPUT_DWARF_PCREL
e1f9550a 883 ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, XSTR (addr, 0));
2a1ee410 884#else
301d03af 885 dw2_assemble_integer (size, gen_rtx_MINUS (Pmode, addr, pc_rtx));
2a1ee410 886#endif
e1f9550a 887 break;
2a1ee410 888
e1f9550a 889 default:
3a538a66 890 /* Other encodings should have been handled by
e1f9550a
RH
891 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */
892 abort ();
893 }
2a1ee410
RH
894
895#ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
e1f9550a 896 done:;
2a1ee410 897#endif
e1f9550a
RH
898 }
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 }
2a1ee410 905 fputc ('\n', asm_out_file);
e1f9550a 906
7a75edb7 907 VA_CLOSE (ap);
2a1ee410 908}
This page took 0.593302 seconds and 5 git commands to generate.