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
),
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
);