]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/dwarf2asm.c
dwarf2out.c: Revert most of 2000-11-25 and 2001-01-24 changes.
[thirdparty/gcc.git] / gcc / dwarf2asm.c
CommitLineData
2e4b9b8c
RH
1/* Dwarf2 assembler output helper routines.
2 Copyright (C) 2001 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21
22#include "config.h"
23#include "system.h"
24#include "flags.h"
25#include "rtl.h"
26#include "output.h"
27#include "dwarf2asm.h"
28#include "tm_p.h"
29
30
31/* How to start an assembler comment. */
32#ifndef ASM_COMMENT_START
33#define ASM_COMMENT_START ";#"
34#endif
35
36/* Definitions of defaults for assembler-dependent names of various
37 pseudo-ops and section names. These may be overridden in the tm.h
38 file (if necessary) for a particular assembler. */
39
40#ifdef OBJECT_FORMAT_ELF
41#ifndef UNALIGNED_SHORT_ASM_OP
42#define UNALIGNED_SHORT_ASM_OP "\t.2byte\t"
43#endif
44#ifndef UNALIGNED_INT_ASM_OP
45#define UNALIGNED_INT_ASM_OP "\t.4byte\t"
46#endif
47#ifndef UNALIGNED_DOUBLE_INT_ASM_OP
48#define UNALIGNED_DOUBLE_INT_ASM_OP "\t.8byte\t"
49#endif
50#endif /* OBJECT_FORMAT_ELF */
51
52#ifndef ASM_BYTE_OP
53#define ASM_BYTE_OP "\t.byte\t"
54#endif
55
56/* We don't have unaligned support, let's hope the normal output works for
57 .debug_frame. But we know it won't work for .debug_info. */
58#if !defined(UNALIGNED_INT_ASM_OP) && defined(DWARF2_DEBUGGING_INFO)
59 #error DWARF2_DEBUGGING_INFO requires UNALIGNED_INT_ASM_OP.
60#endif
61
62\f
63#ifdef UNALIGNED_INT_ASM_OP
64static const char * unaligned_integer_asm_op PARAMS ((int));
65
66static inline const char *
67unaligned_integer_asm_op (size)
68 int size;
69{
70 const char *op;
71 switch (size)
72 {
73 case 1:
74 op = ASM_BYTE_OP;
75 break;
76 case 2:
77 op = UNALIGNED_SHORT_ASM_OP;
78 break;
79 case 4:
80 op = UNALIGNED_INT_ASM_OP;
81 break;
82 case 8:
83#ifdef UNALIGNED_DOUBLE_INT_ASM_OP
84 op = UNALIGNED_DOUBLE_INT_ASM_OP;
85 break;
86#endif
87 default:
88 abort ();
89 }
90 return op;
91}
92#endif /* UNALIGNED_INT_ASM_OP */
93
8e7fa2c8
RH
94/* Output an immediate constant in a given size. */
95
2e4b9b8c
RH
96void
97dw2_asm_output_data VPARAMS ((int size, unsigned HOST_WIDE_INT value,
98 const char *comment, ...))
99{
100#ifndef ANSI_PROTOTYPES
101 int size;
102 unsigned HOST_WIDE_INT value;
103 const char *comment;
104#endif
105 va_list ap;
106
107 VA_START (ap, comment);
108
109#ifndef ANSI_PROTOTYPES
110 size = va_arg (ap, int);
111 value = va_arg (ap, unsigned HOST_WIDE_INT);
112 comment = va_arg (ap, const char *);
113#endif
114
115#ifdef UNALIGNED_INT_ASM_OP
116 fputs (unaligned_integer_asm_op (size), asm_out_file);
117 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
118#else
119 assemble_integer (GEN_INT (value), size, 1);
120#endif
121
122 if (flag_debug_asm && comment)
123 {
124 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
125 vfprintf (asm_out_file, comment, ap);
126 }
127 fputc ('\n', asm_out_file);
128
129 va_end (ap);
130}
131
8e7fa2c8
RH
132/* Output the difference between two symbols in a given size. */
133/* ??? There appear to be assemblers that do not like such
134 subtraction, but do support ASM_SET_OP. It's unfortunately
135 impossible to do here, since the ASM_SET_OP for the difference
136 symbol must appear after both symbols are defined. */
137
2e4b9b8c
RH
138void
139dw2_asm_output_delta VPARAMS ((int size, const char *lab1, const char *lab2,
140 const char *comment, ...))
141{
142#ifndef ANSI_PROTOTYPES
143 int size;
144 const char *lab1, *lab2;
145 const char *comment;
146#endif
147 va_list ap;
148
149 VA_START (ap, comment);
150
151#ifndef ANSI_PROTOTYPES
152 size = va_arg (ap, int);
153 lab1 = va_arg (ap, const char *);
154 lab2 = va_arg (ap, const char *);
155 comment = va_arg (ap, const char *);
156#endif
157
158#ifdef UNALIGNED_INT_ASM_OP
159 fputs (unaligned_integer_asm_op (size), asm_out_file);
160 assemble_name (asm_out_file, lab1);
161 fputc ('-', asm_out_file);
162 assemble_name (asm_out_file, lab2);
163#else
d2f65b7b 164 assemble_integer (gen_rtx_MINUS (smallest_mode_for_size (size, MODE_INT),
2e4b9b8c
RH
165 gen_rtx_SYMBOL_REF (Pmode, lab1),
166 gen_rtx_SYMBOL_REF (Pmode, lab2)),
167 size, 1);
168#endif
169
170 if (flag_debug_asm && comment)
171 {
172 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
173 vfprintf (asm_out_file, comment, ap);
174 }
175 fputc ('\n', asm_out_file);
176
177 va_end (ap);
178}
179
8e7fa2c8
RH
180/* Output a section-relative reference to a label. In general this
181 can only be done for debugging symbols. E.g. on most targets with
182 the GNU linker, this is accomplished with a direct reference and
183 the knowledge that the debugging section will be placed at VMA 0.
184 Some targets have special relocations for this that we must use. */
185
2e4b9b8c
RH
186void
187dw2_asm_output_offset VPARAMS ((int size, const char *label,
188 const char *comment, ...))
189{
190#ifndef ANSI_PROTOTYPES
191 int size;
192 const char *label;
193 const char *comment;
194#endif
195 va_list ap;
196
197 VA_START (ap, comment);
198
199#ifndef ANSI_PROTOTYPES
200 size = va_arg (ap, int);
201 label = va_arg (ap, const char *);
202 comment = va_arg (ap, const char *);
203#endif
204
8e7fa2c8
RH
205#ifdef ASM_OUTPUT_DWARF_OFFSET
206 ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label);
207#else
2e4b9b8c
RH
208#ifdef UNALIGNED_INT_ASM_OP
209 fputs (unaligned_integer_asm_op (size), asm_out_file);
210 assemble_name (asm_out_file, label);
211#else
212 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, label), size, 1);
8e7fa2c8 213#endif
2e4b9b8c
RH
214#endif
215
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);
222
223 va_end (ap);
224}
225
8e7fa2c8
RH
226/* Output a self-relative reference to a label, possibly in a
227 different section or object file. */
228
2e4b9b8c
RH
229void
230dw2_asm_output_pcrel VPARAMS ((int size, const char *label,
231 const char *comment, ...))
232{
233#ifndef ANSI_PROTOTYPES
234 int size;
235 const char *label;
236 const char *comment;
237#endif
238 va_list ap;
239
240 VA_START (ap, comment);
241
242#ifndef ANSI_PROTOTYPES
243 size = va_arg (ap, int);
244 label = va_arg (ap, const char *);
245 comment = va_arg (ap, const char *);
246#endif
247
8e7fa2c8
RH
248#ifdef ASM_OUTPUT_DWARF_PCREL
249 ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label);
250#else
2e4b9b8c
RH
251#ifdef UNALIGNED_INT_ASM_OP
252 fputs (unaligned_integer_asm_op (size), asm_out_file);
2e4b9b8c
RH
253 assemble_name (asm_out_file, label);
254 fputc ('-', asm_out_file);
255 fputc ('.', asm_out_file);
256#else
257 abort ();
258#endif
8e7fa2c8
RH
259#endif
260
261 if (flag_debug_asm && comment)
262 {
263 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
264 vfprintf (asm_out_file, comment, ap);
265 }
266 fputc ('\n', asm_out_file);
267
268 va_end (ap);
269}
270
271/* Output an absolute reference to a label. */
272
273void
274dw2_asm_output_addr VPARAMS ((int size, const char *label,
275 const char *comment, ...))
276{
277#ifndef ANSI_PROTOTYPES
278 int size;
279 const char *label;
280 const char *comment;
281#endif
282 va_list ap;
283
284 VA_START (ap, comment);
285
286#ifndef ANSI_PROTOTYPES
287 size = va_arg (ap, int);
288 label = va_arg (ap, const char *);
289 comment = va_arg (ap, const char *);
290#endif
291
292#ifdef UNALIGNED_INT_ASM_OP
293 fputs (unaligned_integer_asm_op (size), asm_out_file);
294 assemble_name (asm_out_file, label);
295#else
296 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, label), size, 1);
297#endif
2e4b9b8c
RH
298
299 if (flag_debug_asm && comment)
300 {
301 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
302 vfprintf (asm_out_file, comment, ap);
303 }
304 fputc ('\n', asm_out_file);
305
306 va_end (ap);
307}
308
8e7fa2c8
RH
309/* Similar, but use an RTX expression instead of a text label. */
310
2e4b9b8c
RH
311void
312dw2_asm_output_addr_rtx VPARAMS ((int size, rtx addr,
313 const char *comment, ...))
314{
315#ifndef ANSI_PROTOTYPES
316 int size;
317 rtx addr;
318 const char *comment;
319#endif
320 va_list ap;
321
322 VA_START (ap, comment);
323
324#ifndef ANSI_PROTOTYPES
325 size = va_arg (ap, int);
326 addr = va_arg (ap, rtx);
327 comment = va_arg (ap, const char *);
328#endif
329
330#ifdef UNALIGNED_INT_ASM_OP
331 fputs (unaligned_integer_asm_op (size), asm_out_file);
332 output_addr_const (asm_out_file, addr);
333#else
334 assemble_integer (addr, size, 1);
335#endif
336
337 if (flag_debug_asm && comment)
338 {
339 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
340 vfprintf (asm_out_file, comment, ap);
341 }
342 fputc ('\n', asm_out_file);
343
344 va_end (ap);
345}
346
347void
348dw2_asm_output_nstring VPARAMS ((const char *str, size_t orig_len,
349 const char *comment, ...))
350{
351#ifndef ANSI_PROTOTYPES
352 const char *str;
353 size_t orig_len;
354 const char *comment;
355#endif
356 va_list ap;
357 size_t i, len = orig_len;
358
359 VA_START (ap, comment);
360
361#ifndef ANSI_PROTOTYPES
362 str = va_arg (ap, const char *);
363 len = va_arg (ap, size_t);
364 comment = va_arg (ap, const char *);
365#endif
366
367 if (len == (size_t) -1)
368 len = strlen (str);
369
370 if (flag_debug_asm && comment)
371 {
372 fputs ("\t.ascii \"", asm_out_file);
373 for (i = 0; i < len; i++)
374 {
375 int c = str[i];
376 if (c == '\"' || c == '\\')
377 fputc ('\\', asm_out_file);
378 if (ISPRINT(c))
379 fputc (c, asm_out_file);
380 else
381 fprintf (asm_out_file, "\\%o", c);
382 }
383 fprintf (asm_out_file, "\\0\"\t%s ", ASM_COMMENT_START);
384 vfprintf (asm_out_file, comment, ap);
385 fputc ('\n', asm_out_file);
386 }
387 else
388 {
389 /* If an explicit length was given, we can't assume there
390 is a null termination in the string buffer. */
391 if (orig_len == (size_t) -1)
392 len += 1;
393 ASM_OUTPUT_ASCII (asm_out_file, str, len);
394 if (orig_len != (size_t) -1)
395 fprintf (asm_out_file, "%s0\n", ASM_BYTE_OP);
396 }
397
398 va_end (ap);
399}
400\f
401
402/* Return the size of an unsigned LEB128 quantity. */
403
404int
405size_of_uleb128 (value)
406 unsigned HOST_WIDE_INT value;
407{
408 int size = 0, byte;
409
410 do
411 {
412 byte = (value & 0x7f);
413 value >>= 7;
414 size += 1;
415 }
416 while (value != 0);
417
418 return size;
419}
420
421/* Return the size of a signed LEB128 quantity. */
422
423int
424size_of_sleb128 (value)
425 HOST_WIDE_INT value;
426{
427 int size = 0, byte;
428
429 do
430 {
431 byte = (value & 0x7f);
432 value >>= 7;
433 size += 1;
434 }
435 while (!((value == 0 && (byte & 0x40) == 0)
436 || (value == -1 && (byte & 0x40) != 0)));
437
438 return size;
439}
440
441/* Output an unsigned LEB128 quantity. */
442
443void
444dw2_asm_output_data_uleb128 VPARAMS ((unsigned HOST_WIDE_INT value,
445 const char *comment, ...))
446{
447#ifndef ANSI_PROTOTYPES
448 unsigned HOST_WIDE_INT value;
449 const char *comment;
450#endif
451 va_list ap;
452
453 VA_START (ap, comment);
454
455#ifndef ANSI_PROTOTYPES
456 value = va_arg (ap, unsigned HOST_WIDE_INT);
457 comment = va_arg (ap, const char *);
458#endif
459
460#ifdef HAVE_AS_LEB128
461 fputs ("\t.uleb128\t", asm_out_file);
462 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
463
464 if (flag_debug_asm && comment)
465 {
466 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
467 vfprintf (asm_out_file, comment, ap);
468 }
469#else
470 {
471 unsigned HOST_WIDE_INT work = value;
472
473 fputs (ASM_BYTE_OP, asm_out_file);
474 do
475 {
476 int byte = (work & 0x7f);
477 work >>= 7;
478 if (work != 0)
479 /* More bytes to follow. */
480 byte |= 0x80;
481
482 fprintf (asm_out_file, "0x%x", byte);
483 if (work != 0)
484 fputc (',', asm_out_file);
485 }
486 while (work != 0);
487
488 if (flag_debug_asm)
489 {
490 fprintf (asm_out_file, "\t%s uleb128 ", ASM_COMMENT_START);
491 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
492 if (comment)
493 {
494 fputs ("; ", asm_out_file);
495 vfprintf (asm_out_file, comment, ap);
496 }
497 }
498 }
499#endif
500 fputc ('\n', asm_out_file);
501
502 va_end (ap);
503}
504
505/* Output an signed LEB128 quantity. */
506
507void
508dw2_asm_output_data_sleb128 VPARAMS ((HOST_WIDE_INT value,
509 const char *comment, ...))
510{
511#ifndef ANSI_PROTOTYPES
512 HOST_WIDE_INT value;
513 const char *comment;
514#endif
515 va_list ap;
516
517 VA_START (ap, comment);
518
519#ifndef ANSI_PROTOTYPES
520 value = va_arg (ap, HOST_WIDE_INT);
521 comment = va_arg (ap, const char *);
522#endif
523
524#ifdef HAVE_AS_LEB128
525 fputs ("\t.sleb128\t", asm_out_file);
526 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
527
528 if (flag_debug_asm && comment)
529 {
530 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
531 vfprintf (asm_out_file, comment, ap);
532 }
533#else
534 {
535 HOST_WIDE_INT work = value;
536 int more, byte;
537
538 fputs (ASM_BYTE_OP, asm_out_file);
539 do
540 {
541 byte = (work & 0x7f);
542 /* arithmetic shift */
543 work >>= 7;
544 more = !((work == 0 && (byte & 0x40) == 0)
545 || (work == -1 && (byte & 0x40) != 0));
546 if (more)
547 byte |= 0x80;
548
549 fprintf (asm_out_file, "0x%x", byte);
550 if (more)
551 fputc (',', asm_out_file);
552 }
553 while (more);
554
555 if (flag_debug_asm)
556 {
557 fprintf (asm_out_file, "\t%s sleb128 ", ASM_COMMENT_START);
558 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, value);
559 if (comment)
560 {
561 fputs ("; ", asm_out_file);
562 vfprintf (asm_out_file, comment, ap);
563 }
564 }
565 }
566#endif
567 fputc ('\n', asm_out_file);
568
569 va_end (ap);
570}
571
572void
573dw2_asm_output_delta_uleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
574 const char *lab2 ATTRIBUTE_UNUSED,
575 const char *comment, ...))
576{
577#ifndef ANSI_PROTOTYPES
578 const char *lab1, *lab2;
579 const char *comment;
580#endif
581 va_list ap;
582
583 VA_START (ap, comment);
584
585#ifndef ANSI_PROTOTYPES
586 lab1 = va_arg (ap, const char *);
587 lab2 = va_arg (ap, const char *);
588 comment = va_arg (ap, const char *);
589#endif
590
591#ifdef HAVE_AS_LEB128
592 fputs ("\t.uleb128\t", asm_out_file);
593 assemble_name (asm_out_file, lab1);
594 fputc ('-', asm_out_file);
595 assemble_name (asm_out_file, lab2);
596#else
597 abort ();
598#endif
599
600 if (flag_debug_asm && comment)
601 {
602 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
603 vfprintf (asm_out_file, comment, ap);
604 }
605 fputc ('\n', asm_out_file);
606
607 va_end (ap);
608}
609
610void
611dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
612 const char *lab2 ATTRIBUTE_UNUSED,
613 const char *comment, ...))
614{
615#ifndef ANSI_PROTOTYPES
616 const char *lab1, *lab2;
617 const char *comment;
618#endif
619 va_list ap;
620
621 VA_START (ap, comment);
622
623#ifndef ANSI_PROTOTYPES
624 lab1 = va_arg (ap, const char *);
625 lab2 = va_arg (ap, const char *);
626 comment = va_arg (ap, const char *);
627#endif
628
629#ifdef HAVE_AS_LEB128
630 fputs ("\t.sleb128\t", asm_out_file);
631 assemble_name (asm_out_file, lab1);
632 fputc ('-', asm_out_file);
633 assemble_name (asm_out_file, lab2);
634#else
635 abort ();
636#endif
637
638 if (flag_debug_asm && comment)
639 {
640 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
641 vfprintf (asm_out_file, comment, ap);
642 }
643 fputc ('\n', asm_out_file);
644
645 va_end (ap);
646}