OSDN Git Service

* crontab, doc_exclude, update_branch_version, update_version,
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2asm.c
1 /* Dwarf2 assembler output helper routines.
2    Copyright (C) 2001 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
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)
9 any later version.
10
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.
15
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.  */
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
64 static const char * unaligned_integer_asm_op  PARAMS ((int));
65
66 static inline const char *
67 unaligned_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
94 void
95 dw2_asm_output_data VPARAMS ((int size, unsigned HOST_WIDE_INT value,
96                               const char *comment, ...))
97 {
98 #ifndef ANSI_PROTOTYPES
99   int size;
100   unsigned HOST_WIDE_INT value;
101   const char *comment;
102 #endif
103   va_list ap;
104
105   VA_START (ap, comment);
106
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 *);
111 #endif
112
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);
116 #else
117   assemble_integer (GEN_INT (value), size, 1);
118 #endif
119
120   if (flag_debug_asm && comment)
121     {
122       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
123       vfprintf (asm_out_file, comment, ap);
124     }
125   fputc ('\n', asm_out_file);
126
127   va_end (ap);
128 }
129
130 void
131 dw2_asm_output_delta VPARAMS ((int size, const char *lab1, const char *lab2,
132                                const char *comment, ...))
133 {
134 #ifndef ANSI_PROTOTYPES
135   int size;
136   const char *lab1, *lab2;
137   const char *comment;
138 #endif
139   va_list ap;
140
141   VA_START (ap, comment);
142
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 *);
148 #endif
149
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);
155 #else
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)),
159                     size, 1);
160 #endif
161
162   if (flag_debug_asm && comment)
163     {
164       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
165       vfprintf (asm_out_file, comment, ap);
166     }
167   fputc ('\n', asm_out_file);
168
169   va_end (ap);
170 }
171
172 void
173 dw2_asm_output_offset VPARAMS ((int size, const char *label,
174                                const char *comment, ...))
175 {
176 #ifndef ANSI_PROTOTYPES
177   int size;
178   const char *label;
179   const char *comment;
180 #endif
181   va_list ap;
182
183   VA_START (ap, comment);
184
185 #ifndef ANSI_PROTOTYPES
186   size = va_arg (ap, int);
187   label = va_arg (ap, const char *);
188   comment = va_arg (ap, const char *);
189 #endif
190
191 #ifdef UNALIGNED_INT_ASM_OP
192   fputs (unaligned_integer_asm_op (size), asm_out_file);
193   assemble_name (asm_out_file, label);
194 #else
195   assemble_integer (gen_rtx_SYMBOL_REF (Pmode, label), size, 1);
196 #endif
197
198   if (flag_debug_asm && comment)
199     {
200       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
201       vfprintf (asm_out_file, comment, ap);
202     }
203   fputc ('\n', asm_out_file);
204
205   va_end (ap);
206 }
207
208 void
209 dw2_asm_output_pcrel VPARAMS ((int size, const char *label,
210                                const char *comment, ...))
211 {
212 #ifndef ANSI_PROTOTYPES
213   int size;
214   const char *label;
215   const char *comment;
216 #endif
217   va_list ap;
218
219   VA_START (ap, comment);
220
221 #ifndef ANSI_PROTOTYPES
222   size = va_arg (ap, int);
223   label = va_arg (ap, const char *);
224   comment = va_arg (ap, const char *);
225 #endif
226
227 #ifdef UNALIGNED_INT_ASM_OP
228   fputs (unaligned_integer_asm_op (size), asm_out_file);
229
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);
236 #else
237   abort ();
238 #endif
239
240   if (flag_debug_asm && comment)
241     {
242       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
243       vfprintf (asm_out_file, comment, ap);
244     }
245   fputc ('\n', asm_out_file);
246
247   va_end (ap);
248 }
249
250 void
251 dw2_asm_output_addr_rtx VPARAMS ((int size, rtx addr,
252                                   const char *comment, ...))
253 {
254 #ifndef ANSI_PROTOTYPES
255   int size;
256   rtx addr;
257   const char *comment;
258 #endif
259   va_list ap;
260
261   VA_START (ap, comment);
262
263 #ifndef ANSI_PROTOTYPES
264   size = va_arg (ap, int);
265   addr = va_arg (ap, rtx);
266   comment = va_arg (ap, const char *);
267 #endif
268
269 #ifdef UNALIGNED_INT_ASM_OP
270   fputs (unaligned_integer_asm_op (size), asm_out_file);
271   output_addr_const (asm_out_file, addr);
272 #else
273   assemble_integer (addr, size, 1);
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
286 void
287 dw2_asm_output_nstring VPARAMS ((const char *str, size_t orig_len,
288                                  const char *comment, ...))
289 {
290 #ifndef ANSI_PROTOTYPES
291   const char *str;
292   size_t orig_len;
293   const char *comment;
294 #endif
295   va_list ap;
296   size_t i, len = orig_len;
297
298   VA_START (ap, comment);
299
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 *);
304 #endif
305
306   if (len == (size_t) -1)
307     len = strlen (str);
308
309   if (flag_debug_asm && comment)
310     {
311       fputs ("\t.ascii \"", asm_out_file);
312       for (i = 0; i < len; i++)
313         {
314           int c = str[i];
315           if (c == '\"' || c == '\\')
316             fputc ('\\', asm_out_file);
317           if (ISPRINT(c))
318             fputc (c, asm_out_file);
319           else
320             fprintf (asm_out_file, "\\%o", c);
321         }
322       fprintf (asm_out_file, "\\0\"\t%s ", ASM_COMMENT_START);
323       vfprintf (asm_out_file, comment, ap);
324       fputc ('\n', asm_out_file);
325     }
326   else
327     {
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)
331         len += 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);
335     }
336
337   va_end (ap);
338 }
339 \f
340
341 /* Return the size of an unsigned LEB128 quantity.  */
342
343 int
344 size_of_uleb128 (value)
345      unsigned HOST_WIDE_INT value;
346 {
347   int size = 0, byte;
348
349   do
350     {
351       byte = (value & 0x7f);
352       value >>= 7;
353       size += 1;
354     }
355   while (value != 0);
356
357   return size;
358 }
359
360 /* Return the size of a signed LEB128 quantity.  */
361
362 int
363 size_of_sleb128 (value)
364      HOST_WIDE_INT value;
365 {
366   int size = 0, byte;
367
368   do
369     {
370       byte = (value & 0x7f);
371       value >>= 7;
372       size += 1;
373     }
374   while (!((value == 0 && (byte & 0x40) == 0)
375            || (value == -1 && (byte & 0x40) != 0)));
376
377   return size;
378 }
379
380 /* Output an unsigned LEB128 quantity.  */
381
382 void
383 dw2_asm_output_data_uleb128 VPARAMS ((unsigned HOST_WIDE_INT value,
384                                       const char *comment, ...))
385 {
386 #ifndef ANSI_PROTOTYPES
387   unsigned HOST_WIDE_INT value;
388   const char *comment;
389 #endif
390   va_list ap;
391
392   VA_START (ap, comment);
393
394 #ifndef ANSI_PROTOTYPES
395   value = va_arg (ap, unsigned HOST_WIDE_INT);
396   comment = va_arg (ap, const char *);
397 #endif
398
399 #ifdef HAVE_AS_LEB128
400   fputs ("\t.uleb128\t", asm_out_file);
401   fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
402
403   if (flag_debug_asm && comment)
404     {
405       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
406       vfprintf (asm_out_file, comment, ap);
407     }
408 #else
409   {
410     unsigned HOST_WIDE_INT work = value;
411
412     fputs (ASM_BYTE_OP, asm_out_file);
413     do
414       {
415         int byte = (work & 0x7f);
416         work >>= 7;
417         if (work != 0)
418           /* More bytes to follow.  */
419           byte |= 0x80;
420
421         fprintf (asm_out_file, "0x%x", byte);
422         if (work != 0)
423           fputc (',', asm_out_file);
424       }
425     while (work != 0);
426
427   if (flag_debug_asm)
428     {
429       fprintf (asm_out_file, "\t%s uleb128 ", ASM_COMMENT_START);
430       fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
431       if (comment)
432         {
433           fputs ("; ", asm_out_file);
434           vfprintf (asm_out_file, comment, ap);
435         }
436     }
437   }
438 #endif
439   fputc ('\n', asm_out_file);
440
441   va_end (ap);
442 }
443
444 /* Output an signed LEB128 quantity.  */
445
446 void
447 dw2_asm_output_data_sleb128 VPARAMS ((HOST_WIDE_INT value,
448                                       const char *comment, ...))
449 {
450 #ifndef ANSI_PROTOTYPES
451   HOST_WIDE_INT value;
452   const char *comment;
453 #endif
454   va_list ap;
455
456   VA_START (ap, comment);
457
458 #ifndef ANSI_PROTOTYPES
459   value = va_arg (ap, HOST_WIDE_INT);
460   comment = va_arg (ap, const char *);
461 #endif
462
463 #ifdef HAVE_AS_LEB128
464   fputs ("\t.sleb128\t", asm_out_file);
465   fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
466
467   if (flag_debug_asm && comment)
468     {
469       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
470       vfprintf (asm_out_file, comment, ap);
471     }
472 #else
473   {
474     HOST_WIDE_INT work = value;
475     int more, byte;
476
477     fputs (ASM_BYTE_OP, asm_out_file);
478     do
479       {
480         byte = (work & 0x7f);
481         /* arithmetic shift */
482         work >>= 7;
483         more = !((work == 0 && (byte & 0x40) == 0)
484                  || (work == -1 && (byte & 0x40) != 0));
485         if (more)
486           byte |= 0x80;
487
488         fprintf (asm_out_file, "0x%x", byte);
489         if (more)
490           fputc (',', asm_out_file);
491       }
492     while (more);
493
494   if (flag_debug_asm)
495     {
496       fprintf (asm_out_file, "\t%s sleb128 ", ASM_COMMENT_START);
497       fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, value);
498       if (comment)
499         {
500           fputs ("; ", asm_out_file);
501           vfprintf (asm_out_file, comment, ap);
502         }
503     }
504   }
505 #endif
506   fputc ('\n', asm_out_file);
507
508   va_end (ap);
509 }
510
511 void
512 dw2_asm_output_delta_uleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
513                                        const char *lab2 ATTRIBUTE_UNUSED,
514                                        const char *comment, ...))
515 {
516 #ifndef ANSI_PROTOTYPES
517   const char *lab1, *lab2;
518   const char *comment;
519 #endif
520   va_list ap;
521
522   VA_START (ap, comment);
523
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 *);
528 #endif
529
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);
535 #else
536   abort ();
537 #endif
538
539   if (flag_debug_asm && comment)
540     {
541       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
542       vfprintf (asm_out_file, comment, ap);
543     }
544   fputc ('\n', asm_out_file);
545
546   va_end (ap);
547 }
548
549 void
550 dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
551                                        const char *lab2 ATTRIBUTE_UNUSED,
552                                        const char *comment, ...))
553 {
554 #ifndef ANSI_PROTOTYPES
555   const char *lab1, *lab2;
556   const char *comment;
557 #endif
558   va_list ap;
559
560   VA_START (ap, comment);
561
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 *);
566 #endif
567
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);
573 #else
574   abort ();
575 #endif
576
577   if (flag_debug_asm && comment)
578     {
579       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
580       vfprintf (asm_out_file, comment, ap);
581     }
582   fputc ('\n', asm_out_file);
583
584   va_end (ap);
585 }