1 /* Dwarf2 assembler output helper routines.
2 Copyright (C) 2001 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
27 #include "dwarf2asm.h"
31 /* How to start an assembler comment. */
32 #ifndef ASM_COMMENT_START
33 #define ASM_COMMENT_START ";#"
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. */
40 #ifdef OBJECT_FORMAT_ELF
41 #ifndef UNALIGNED_SHORT_ASM_OP
42 #define UNALIGNED_SHORT_ASM_OP "\t.2byte\t"
44 #ifndef UNALIGNED_INT_ASM_OP
45 #define UNALIGNED_INT_ASM_OP "\t.4byte\t"
47 #ifndef UNALIGNED_DOUBLE_INT_ASM_OP
48 #define UNALIGNED_DOUBLE_INT_ASM_OP "\t.8byte\t"
50 #endif /* OBJECT_FORMAT_ELF */
53 #define ASM_BYTE_OP "\t.byte\t"
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.
63 #ifdef UNALIGNED_INT_ASM_OP
64 static const char * unaligned_integer_asm_op PARAMS ((int));
66 static inline const char *
67 unaligned_integer_asm_op (size)
77 op = UNALIGNED_SHORT_ASM_OP;
80 op = UNALIGNED_INT_ASM_OP;
83 #ifdef UNALIGNED_DOUBLE_INT_ASM_OP
84 op = UNALIGNED_DOUBLE_INT_ASM_OP;
92 #endif /* UNALIGNED_INT_ASM_OP */
95 dw2_asm_output_data VPARAMS ((int size, unsigned HOST_WIDE_INT value,
96 const char *comment, ...))
98 #ifndef ANSI_PROTOTYPES
100 unsigned HOST_WIDE_INT value;
105 VA_START (ap, comment);
107 #ifndef ANSI_PROTOTYPES
108 size = va_arg (ap, int);
109 value = va_arg (ap, unsigned HOST_WIDE_INT);
110 comment = va_arg (ap, const char *);
113 #ifdef UNALIGNED_INT_ASM_OP
114 fputs (unaligned_integer_asm_op (size), asm_out_file);
115 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
117 assemble_integer (GEN_INT (value), size, 1);
120 if (flag_debug_asm && comment)
122 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
123 vfprintf (asm_out_file, comment, ap);
125 fputc ('\n', asm_out_file);
131 dw2_asm_output_delta VPARAMS ((int size, const char *lab1, const char *lab2,
132 const char *comment, ...))
134 #ifndef ANSI_PROTOTYPES
136 const char *lab1, *lab2;
141 VA_START (ap, comment);
143 #ifndef ANSI_PROTOTYPES
144 size = va_arg (ap, int);
145 lab1 = va_arg (ap, const char *);
146 lab2 = va_arg (ap, const char *);
147 comment = va_arg (ap, const char *);
150 #ifdef UNALIGNED_INT_ASM_OP
151 fputs (unaligned_integer_asm_op (size), asm_out_file);
152 assemble_name (asm_out_file, lab1);
153 fputc ('-', asm_out_file);
154 assemble_name (asm_out_file, lab2);
156 assemble_integer (gen_rtx_MINUS (smallest_mode_for_size (size, MODE_INT, 0),
157 gen_rtx_SYMBOL_REF (Pmode, lab1),
158 gen_rtx_SYMBOL_REF (Pmode, lab2)),
162 if (flag_debug_asm && comment)
164 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
165 vfprintf (asm_out_file, comment, ap);
167 fputc ('\n', asm_out_file);
173 dw2_asm_output_offset VPARAMS ((int size, const char *label,
174 const char *comment, ...))
176 #ifndef ANSI_PROTOTYPES
183 VA_START (ap, comment);
185 #ifndef ANSI_PROTOTYPES
186 size = va_arg (ap, int);
187 label = va_arg (ap, const char *);
188 comment = va_arg (ap, const char *);
191 #ifdef UNALIGNED_INT_ASM_OP
192 fputs (unaligned_integer_asm_op (size), asm_out_file);
193 assemble_name (asm_out_file, label);
195 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, label), size, 1);
198 if (flag_debug_asm && comment)
200 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
201 vfprintf (asm_out_file, comment, ap);
203 fputc ('\n', asm_out_file);
209 dw2_asm_output_pcrel VPARAMS ((int size, const char *label,
210 const char *comment, ...))
212 #ifndef ANSI_PROTOTYPES
219 VA_START (ap, comment);
221 #ifndef ANSI_PROTOTYPES
222 size = va_arg (ap, int);
223 label = va_arg (ap, const char *);
224 comment = va_arg (ap, const char *);
227 #ifdef UNALIGNED_INT_ASM_OP
228 fputs (unaligned_integer_asm_op (size), asm_out_file);
230 /* ??? This needs target conditionalization. E.g. the solaris
231 assembler uses %r_disp32(label). Others don't like "." and
232 we need to generate a temporary label here. */
233 assemble_name (asm_out_file, label);
234 fputc ('-', asm_out_file);
235 fputc ('.', asm_out_file);
240 if (flag_debug_asm && comment)
242 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
243 vfprintf (asm_out_file, comment, ap);
245 fputc ('\n', asm_out_file);
251 dw2_asm_output_addr_rtx VPARAMS ((int size, rtx addr,
252 const char *comment, ...))
254 #ifndef ANSI_PROTOTYPES
261 VA_START (ap, comment);
263 #ifndef ANSI_PROTOTYPES
264 size = va_arg (ap, int);
265 addr = va_arg (ap, rtx);
266 comment = va_arg (ap, const char *);
269 #ifdef UNALIGNED_INT_ASM_OP
270 fputs (unaligned_integer_asm_op (size), asm_out_file);
271 output_addr_const (asm_out_file, addr);
273 assemble_integer (addr, size, 1);
276 if (flag_debug_asm && comment)
278 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
279 vfprintf (asm_out_file, comment, ap);
281 fputc ('\n', asm_out_file);
287 dw2_asm_output_nstring VPARAMS ((const char *str, size_t orig_len,
288 const char *comment, ...))
290 #ifndef ANSI_PROTOTYPES
296 size_t i, len = orig_len;
298 VA_START (ap, comment);
300 #ifndef ANSI_PROTOTYPES
301 str = va_arg (ap, const char *);
302 len = va_arg (ap, size_t);
303 comment = va_arg (ap, const char *);
306 if (len == (size_t) -1)
309 if (flag_debug_asm && comment)
311 fputs ("\t.ascii \"", asm_out_file);
312 for (i = 0; i < len; i++)
315 if (c == '\"' || c == '\\')
316 fputc ('\\', asm_out_file);
318 fputc (c, asm_out_file);
320 fprintf (asm_out_file, "\\%o", c);
322 fprintf (asm_out_file, "\\0\"\t%s ", ASM_COMMENT_START);
323 vfprintf (asm_out_file, comment, ap);
324 fputc ('\n', asm_out_file);
328 /* If an explicit length was given, we can't assume there
329 is a null termination in the string buffer. */
330 if (orig_len == (size_t) -1)
332 ASM_OUTPUT_ASCII (asm_out_file, str, len);
333 if (orig_len != (size_t) -1)
334 fprintf (asm_out_file, "%s0\n", ASM_BYTE_OP);
341 /* Return the size of an unsigned LEB128 quantity. */
344 size_of_uleb128 (value)
345 unsigned HOST_WIDE_INT value;
351 byte = (value & 0x7f);
360 /* Return the size of a signed LEB128 quantity. */
363 size_of_sleb128 (value)
370 byte = (value & 0x7f);
374 while (!((value == 0 && (byte & 0x40) == 0)
375 || (value == -1 && (byte & 0x40) != 0)));
380 /* Output an unsigned LEB128 quantity. */
383 dw2_asm_output_data_uleb128 VPARAMS ((unsigned HOST_WIDE_INT value,
384 const char *comment, ...))
386 #ifndef ANSI_PROTOTYPES
387 unsigned HOST_WIDE_INT value;
392 VA_START (ap, comment);
394 #ifndef ANSI_PROTOTYPES
395 value = va_arg (ap, unsigned HOST_WIDE_INT);
396 comment = va_arg (ap, const char *);
399 #ifdef HAVE_AS_LEB128
400 fputs ("\t.uleb128\t", asm_out_file);
401 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
403 if (flag_debug_asm && comment)
405 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
406 vfprintf (asm_out_file, comment, ap);
410 unsigned HOST_WIDE_INT work = value;
412 fputs (ASM_BYTE_OP, asm_out_file);
415 int byte = (work & 0x7f);
418 /* More bytes to follow. */
421 fprintf (asm_out_file, "0x%x", byte);
423 fputc (',', asm_out_file);
429 fprintf (asm_out_file, "\t%s uleb128 ", ASM_COMMENT_START);
430 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
433 fputs ("; ", asm_out_file);
434 vfprintf (asm_out_file, comment, ap);
439 fputc ('\n', asm_out_file);
444 /* Output an signed LEB128 quantity. */
447 dw2_asm_output_data_sleb128 VPARAMS ((HOST_WIDE_INT value,
448 const char *comment, ...))
450 #ifndef ANSI_PROTOTYPES
456 VA_START (ap, comment);
458 #ifndef ANSI_PROTOTYPES
459 value = va_arg (ap, HOST_WIDE_INT);
460 comment = va_arg (ap, const char *);
463 #ifdef HAVE_AS_LEB128
464 fputs ("\t.sleb128\t", asm_out_file);
465 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
467 if (flag_debug_asm && comment)
469 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
470 vfprintf (asm_out_file, comment, ap);
474 HOST_WIDE_INT work = value;
477 fputs (ASM_BYTE_OP, asm_out_file);
480 byte = (work & 0x7f);
481 /* arithmetic shift */
483 more = !((work == 0 && (byte & 0x40) == 0)
484 || (work == -1 && (byte & 0x40) != 0));
488 fprintf (asm_out_file, "0x%x", byte);
490 fputc (',', asm_out_file);
496 fprintf (asm_out_file, "\t%s sleb128 ", ASM_COMMENT_START);
497 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, value);
500 fputs ("; ", asm_out_file);
501 vfprintf (asm_out_file, comment, ap);
506 fputc ('\n', asm_out_file);
512 dw2_asm_output_delta_uleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
513 const char *lab2 ATTRIBUTE_UNUSED,
514 const char *comment, ...))
516 #ifndef ANSI_PROTOTYPES
517 const char *lab1, *lab2;
522 VA_START (ap, comment);
524 #ifndef ANSI_PROTOTYPES
525 lab1 = va_arg (ap, const char *);
526 lab2 = va_arg (ap, const char *);
527 comment = va_arg (ap, const char *);
530 #ifdef HAVE_AS_LEB128
531 fputs ("\t.uleb128\t", asm_out_file);
532 assemble_name (asm_out_file, lab1);
533 fputc ('-', asm_out_file);
534 assemble_name (asm_out_file, lab2);
539 if (flag_debug_asm && comment)
541 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
542 vfprintf (asm_out_file, comment, ap);
544 fputc ('\n', asm_out_file);
550 dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
551 const char *lab2 ATTRIBUTE_UNUSED,
552 const char *comment, ...))
554 #ifndef ANSI_PROTOTYPES
555 const char *lab1, *lab2;
560 VA_START (ap, comment);
562 #ifndef ANSI_PROTOTYPES
563 lab1 = va_arg (ap, const char *);
564 lab2 = va_arg (ap, const char *);
565 comment = va_arg (ap, const char *);
568 #ifdef HAVE_AS_LEB128
569 fputs ("\t.sleb128\t", asm_out_file);
570 assemble_name (asm_out_file, lab1);
571 fputc ('-', asm_out_file);
572 assemble_name (asm_out_file, lab2);
577 if (flag_debug_asm && comment)
579 fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
580 vfprintf (asm_out_file, comment, ap);
582 fputc ('\n', asm_out_file);