xref: /dflybsd-src/contrib/gcc-4.7/gcc/dwarf2asm.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* Dwarf2 assembler output helper routines.
2*e4b17023SJohn Marino    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino 
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino 
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
8*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
9*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
10*e4b17023SJohn Marino version.
11*e4b17023SJohn Marino 
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15*e4b17023SJohn Marino for more details.
16*e4b17023SJohn Marino 
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
20*e4b17023SJohn Marino 
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino #include "config.h"
23*e4b17023SJohn Marino #include "system.h"
24*e4b17023SJohn Marino #include "coretypes.h"
25*e4b17023SJohn Marino #include "tm.h"
26*e4b17023SJohn Marino #include "flags.h"
27*e4b17023SJohn Marino #include "tree.h"
28*e4b17023SJohn Marino #include "rtl.h"
29*e4b17023SJohn Marino #include "output.h"
30*e4b17023SJohn Marino #include "target.h"
31*e4b17023SJohn Marino #include "dwarf2asm.h"
32*e4b17023SJohn Marino #include "dwarf2.h"
33*e4b17023SJohn Marino #include "splay-tree.h"
34*e4b17023SJohn Marino #include "ggc.h"
35*e4b17023SJohn Marino #include "tm_p.h"
36*e4b17023SJohn Marino 
37*e4b17023SJohn Marino 
38*e4b17023SJohn Marino /* Output an unaligned integer with the given value and size.  Prefer not
39*e4b17023SJohn Marino    to print a newline, since the caller may want to add a comment.  */
40*e4b17023SJohn Marino 
41*e4b17023SJohn Marino void
dw2_assemble_integer(int size,rtx x)42*e4b17023SJohn Marino dw2_assemble_integer (int size, rtx x)
43*e4b17023SJohn Marino {
44*e4b17023SJohn Marino   const char *op = integer_asm_op (size, FALSE);
45*e4b17023SJohn Marino 
46*e4b17023SJohn Marino   if (op)
47*e4b17023SJohn Marino     {
48*e4b17023SJohn Marino       fputs (op, asm_out_file);
49*e4b17023SJohn Marino       if (CONST_INT_P (x))
50*e4b17023SJohn Marino 	fprint_whex (asm_out_file, (unsigned HOST_WIDE_INT) INTVAL (x));
51*e4b17023SJohn Marino       else
52*e4b17023SJohn Marino 	output_addr_const (asm_out_file, x);
53*e4b17023SJohn Marino     }
54*e4b17023SJohn Marino   else
55*e4b17023SJohn Marino     assemble_integer (x, size, BITS_PER_UNIT, 1);
56*e4b17023SJohn Marino }
57*e4b17023SJohn Marino 
58*e4b17023SJohn Marino 
59*e4b17023SJohn Marino /* Output a value of a given size in target byte order.  */
60*e4b17023SJohn Marino 
61*e4b17023SJohn Marino void
dw2_asm_output_data_raw(int size,unsigned HOST_WIDE_INT value)62*e4b17023SJohn Marino dw2_asm_output_data_raw (int size, unsigned HOST_WIDE_INT value)
63*e4b17023SJohn Marino {
64*e4b17023SJohn Marino   unsigned char bytes[8];
65*e4b17023SJohn Marino   int i;
66*e4b17023SJohn Marino 
67*e4b17023SJohn Marino   for (i = 0; i < 8; ++i)
68*e4b17023SJohn Marino     {
69*e4b17023SJohn Marino       bytes[i] = value & 0xff;
70*e4b17023SJohn Marino       value >>= 8;
71*e4b17023SJohn Marino     }
72*e4b17023SJohn Marino 
73*e4b17023SJohn Marino   if (BYTES_BIG_ENDIAN)
74*e4b17023SJohn Marino     {
75*e4b17023SJohn Marino       for (i = size - 1; i > 0; --i)
76*e4b17023SJohn Marino 	fprintf (asm_out_file, "%#x,", bytes[i]);
77*e4b17023SJohn Marino       fprintf (asm_out_file, "%#x", bytes[0]);
78*e4b17023SJohn Marino     }
79*e4b17023SJohn Marino   else
80*e4b17023SJohn Marino     {
81*e4b17023SJohn Marino       for (i = 0; i < size - 1; ++i)
82*e4b17023SJohn Marino 	fprintf (asm_out_file, "%#x,", bytes[i]);
83*e4b17023SJohn Marino       fprintf (asm_out_file, "%#x", bytes[i]);
84*e4b17023SJohn Marino     }
85*e4b17023SJohn Marino }
86*e4b17023SJohn Marino 
87*e4b17023SJohn Marino /* Output an immediate constant in a given SIZE in bytes.  */
88*e4b17023SJohn Marino 
89*e4b17023SJohn Marino void
dw2_asm_output_data(int size,unsigned HOST_WIDE_INT value,const char * comment,...)90*e4b17023SJohn Marino dw2_asm_output_data (int size, unsigned HOST_WIDE_INT value,
91*e4b17023SJohn Marino 		     const char *comment, ...)
92*e4b17023SJohn Marino {
93*e4b17023SJohn Marino   va_list ap;
94*e4b17023SJohn Marino   const char *op = integer_asm_op (size, FALSE);
95*e4b17023SJohn Marino 
96*e4b17023SJohn Marino   va_start (ap, comment);
97*e4b17023SJohn Marino 
98*e4b17023SJohn Marino   if (size * 8 < HOST_BITS_PER_WIDE_INT)
99*e4b17023SJohn Marino     value &= ~(~(unsigned HOST_WIDE_INT) 0 << (size * 8));
100*e4b17023SJohn Marino 
101*e4b17023SJohn Marino   if (op)
102*e4b17023SJohn Marino     {
103*e4b17023SJohn Marino       fputs (op, asm_out_file);
104*e4b17023SJohn Marino       fprint_whex (asm_out_file, value);
105*e4b17023SJohn Marino     }
106*e4b17023SJohn Marino   else
107*e4b17023SJohn Marino     assemble_integer (GEN_INT (value), size, BITS_PER_UNIT, 1);
108*e4b17023SJohn Marino 
109*e4b17023SJohn Marino   if (flag_debug_asm && comment)
110*e4b17023SJohn Marino     {
111*e4b17023SJohn Marino       fputs ("\t" ASM_COMMENT_START " ", asm_out_file);
112*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
113*e4b17023SJohn Marino     }
114*e4b17023SJohn Marino   putc ('\n', asm_out_file);
115*e4b17023SJohn Marino 
116*e4b17023SJohn Marino   va_end (ap);
117*e4b17023SJohn Marino }
118*e4b17023SJohn Marino 
119*e4b17023SJohn Marino /* Output the difference between two symbols in a given size.  */
120*e4b17023SJohn Marino /* ??? There appear to be assemblers that do not like such
121*e4b17023SJohn Marino    subtraction, but do support ASM_SET_OP.  It's unfortunately
122*e4b17023SJohn Marino    impossible to do here, since the ASM_SET_OP for the difference
123*e4b17023SJohn Marino    symbol must appear after both symbols are defined.  */
124*e4b17023SJohn Marino 
125*e4b17023SJohn Marino void
dw2_asm_output_delta(int size,const char * lab1,const char * lab2,const char * comment,...)126*e4b17023SJohn Marino dw2_asm_output_delta (int size, const char *lab1, const char *lab2,
127*e4b17023SJohn Marino 		      const char *comment, ...)
128*e4b17023SJohn Marino {
129*e4b17023SJohn Marino   va_list ap;
130*e4b17023SJohn Marino 
131*e4b17023SJohn Marino   va_start (ap, comment);
132*e4b17023SJohn Marino 
133*e4b17023SJohn Marino #ifdef ASM_OUTPUT_DWARF_DELTA
134*e4b17023SJohn Marino   ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2);
135*e4b17023SJohn Marino #else
136*e4b17023SJohn Marino   dw2_assemble_integer (size,
137*e4b17023SJohn Marino 			gen_rtx_MINUS (Pmode,
138*e4b17023SJohn Marino 				       gen_rtx_SYMBOL_REF (Pmode, lab1),
139*e4b17023SJohn Marino 				       gen_rtx_SYMBOL_REF (Pmode, lab2)));
140*e4b17023SJohn Marino #endif
141*e4b17023SJohn Marino   if (flag_debug_asm && comment)
142*e4b17023SJohn Marino     {
143*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
144*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
145*e4b17023SJohn Marino     }
146*e4b17023SJohn Marino   fputc ('\n', asm_out_file);
147*e4b17023SJohn Marino 
148*e4b17023SJohn Marino   va_end (ap);
149*e4b17023SJohn Marino }
150*e4b17023SJohn Marino 
151*e4b17023SJohn Marino /* Output the difference between two symbols in instruction units
152*e4b17023SJohn Marino    in a given size.  */
153*e4b17023SJohn Marino 
154*e4b17023SJohn Marino void
dw2_asm_output_vms_delta(int size ATTRIBUTE_UNUSED,const char * lab1,const char * lab2,const char * comment,...)155*e4b17023SJohn Marino dw2_asm_output_vms_delta (int size ATTRIBUTE_UNUSED,
156*e4b17023SJohn Marino 			  const char *lab1, const char *lab2,
157*e4b17023SJohn Marino 			  const char *comment, ...)
158*e4b17023SJohn Marino {
159*e4b17023SJohn Marino   va_list ap;
160*e4b17023SJohn Marino 
161*e4b17023SJohn Marino   va_start (ap, comment);
162*e4b17023SJohn Marino 
163*e4b17023SJohn Marino #ifndef ASM_OUTPUT_DWARF_VMS_DELTA
164*e4b17023SJohn Marino   /* VMS Delta is only special on ia64-vms, but this funtion also gets
165*e4b17023SJohn Marino      called on alpha-vms so it has to do something sane.  */
166*e4b17023SJohn Marino   dw2_asm_output_delta (size, lab1, lab2, comment);
167*e4b17023SJohn Marino #else
168*e4b17023SJohn Marino   ASM_OUTPUT_DWARF_VMS_DELTA (asm_out_file, size, lab1, lab2);
169*e4b17023SJohn Marino   if (flag_debug_asm && comment)
170*e4b17023SJohn Marino     {
171*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
172*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
173*e4b17023SJohn Marino     }
174*e4b17023SJohn Marino   fputc ('\n', asm_out_file);
175*e4b17023SJohn Marino #endif
176*e4b17023SJohn Marino 
177*e4b17023SJohn Marino   va_end (ap);
178*e4b17023SJohn Marino }
179*e4b17023SJohn Marino 
180*e4b17023SJohn Marino /* Output a section-relative reference to a LABEL, which was placed in
181*e4b17023SJohn Marino    BASE.  In general this can only be done for debugging symbols.
182*e4b17023SJohn Marino    E.g. on most targets with the GNU linker, this is accomplished with
183*e4b17023SJohn Marino    a direct reference and the knowledge that the debugging section
184*e4b17023SJohn Marino    will be placed at VMA 0.  Some targets have special relocations for
185*e4b17023SJohn Marino    this that we must use.  */
186*e4b17023SJohn Marino 
187*e4b17023SJohn Marino void
dw2_asm_output_offset(int size,const char * label,section * base ATTRIBUTE_UNUSED,const char * comment,...)188*e4b17023SJohn Marino dw2_asm_output_offset (int size, const char *label,
189*e4b17023SJohn Marino 		       section *base ATTRIBUTE_UNUSED,
190*e4b17023SJohn Marino 		       const char *comment, ...)
191*e4b17023SJohn Marino {
192*e4b17023SJohn Marino   va_list ap;
193*e4b17023SJohn Marino 
194*e4b17023SJohn Marino   va_start (ap, comment);
195*e4b17023SJohn Marino 
196*e4b17023SJohn Marino #ifdef ASM_OUTPUT_DWARF_OFFSET
197*e4b17023SJohn Marino   ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label, base);
198*e4b17023SJohn Marino #else
199*e4b17023SJohn Marino   dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
200*e4b17023SJohn Marino #endif
201*e4b17023SJohn Marino 
202*e4b17023SJohn Marino   if (flag_debug_asm && comment)
203*e4b17023SJohn Marino     {
204*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
205*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
206*e4b17023SJohn Marino     }
207*e4b17023SJohn Marino   fputc ('\n', asm_out_file);
208*e4b17023SJohn Marino 
209*e4b17023SJohn Marino   va_end (ap);
210*e4b17023SJohn Marino }
211*e4b17023SJohn Marino 
212*e4b17023SJohn Marino #if 0
213*e4b17023SJohn Marino 
214*e4b17023SJohn Marino /* Output a self-relative reference to a label, possibly in a
215*e4b17023SJohn Marino    different section or object file.  */
216*e4b17023SJohn Marino 
217*e4b17023SJohn Marino void
218*e4b17023SJohn Marino dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED,
219*e4b17023SJohn Marino 		      const char *label ATTRIBUTE_UNUSED,
220*e4b17023SJohn Marino 		      const char *comment, ...)
221*e4b17023SJohn Marino {
222*e4b17023SJohn Marino   va_list ap;
223*e4b17023SJohn Marino 
224*e4b17023SJohn Marino   va_start (ap, comment);
225*e4b17023SJohn Marino 
226*e4b17023SJohn Marino #ifdef ASM_OUTPUT_DWARF_PCREL
227*e4b17023SJohn Marino   ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label);
228*e4b17023SJohn Marino #else
229*e4b17023SJohn Marino   dw2_assemble_integer (size,
230*e4b17023SJohn Marino 			gen_rtx_MINUS (Pmode,
231*e4b17023SJohn Marino 				       gen_rtx_SYMBOL_REF (Pmode, label),
232*e4b17023SJohn Marino 				       pc_rtx));
233*e4b17023SJohn Marino #endif
234*e4b17023SJohn Marino 
235*e4b17023SJohn Marino   if (flag_debug_asm && comment)
236*e4b17023SJohn Marino     {
237*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
238*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
239*e4b17023SJohn Marino     }
240*e4b17023SJohn Marino   fputc ('\n', asm_out_file);
241*e4b17023SJohn Marino 
242*e4b17023SJohn Marino   va_end (ap);
243*e4b17023SJohn Marino }
244*e4b17023SJohn Marino #endif /* 0 */
245*e4b17023SJohn Marino 
246*e4b17023SJohn Marino /* Output an absolute reference to a label.  */
247*e4b17023SJohn Marino 
248*e4b17023SJohn Marino void
dw2_asm_output_addr(int size,const char * label,const char * comment,...)249*e4b17023SJohn Marino dw2_asm_output_addr (int size, const char *label,
250*e4b17023SJohn Marino 		     const char *comment, ...)
251*e4b17023SJohn Marino {
252*e4b17023SJohn Marino   va_list ap;
253*e4b17023SJohn Marino 
254*e4b17023SJohn Marino   va_start (ap, comment);
255*e4b17023SJohn Marino 
256*e4b17023SJohn Marino   dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
257*e4b17023SJohn Marino 
258*e4b17023SJohn Marino   if (flag_debug_asm && comment)
259*e4b17023SJohn Marino     {
260*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
261*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
262*e4b17023SJohn Marino     }
263*e4b17023SJohn Marino   fputc ('\n', asm_out_file);
264*e4b17023SJohn Marino 
265*e4b17023SJohn Marino   va_end (ap);
266*e4b17023SJohn Marino }
267*e4b17023SJohn Marino 
268*e4b17023SJohn Marino /* Similar, but use an RTX expression instead of a text label.  */
269*e4b17023SJohn Marino 
270*e4b17023SJohn Marino void
dw2_asm_output_addr_rtx(int size,rtx addr,const char * comment,...)271*e4b17023SJohn Marino dw2_asm_output_addr_rtx (int size, rtx addr,
272*e4b17023SJohn Marino 			 const char *comment, ...)
273*e4b17023SJohn Marino {
274*e4b17023SJohn Marino   va_list ap;
275*e4b17023SJohn Marino 
276*e4b17023SJohn Marino   va_start (ap, comment);
277*e4b17023SJohn Marino 
278*e4b17023SJohn Marino   dw2_assemble_integer (size, addr);
279*e4b17023SJohn Marino 
280*e4b17023SJohn Marino   if (flag_debug_asm && comment)
281*e4b17023SJohn Marino     {
282*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
283*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
284*e4b17023SJohn Marino     }
285*e4b17023SJohn Marino   fputc ('\n', asm_out_file);
286*e4b17023SJohn Marino 
287*e4b17023SJohn Marino   va_end (ap);
288*e4b17023SJohn Marino }
289*e4b17023SJohn Marino 
290*e4b17023SJohn Marino /* Output the first ORIG_LEN characters of STR as a string.
291*e4b17023SJohn Marino    If ORIG_LEN is equal to -1, ignore this parameter and output
292*e4b17023SJohn Marino    the entire STR instead.
293*e4b17023SJohn Marino    If COMMENT is not NULL and comments in the debug information
294*e4b17023SJohn Marino    have been requested by the user, append the given COMMENT
295*e4b17023SJohn Marino    to the generated output.  */
296*e4b17023SJohn Marino 
297*e4b17023SJohn Marino void
dw2_asm_output_nstring(const char * str,size_t orig_len,const char * comment,...)298*e4b17023SJohn Marino dw2_asm_output_nstring (const char *str, size_t orig_len,
299*e4b17023SJohn Marino 			const char *comment, ...)
300*e4b17023SJohn Marino {
301*e4b17023SJohn Marino   size_t i, len;
302*e4b17023SJohn Marino   va_list ap;
303*e4b17023SJohn Marino 
304*e4b17023SJohn Marino   va_start (ap, comment);
305*e4b17023SJohn Marino 
306*e4b17023SJohn Marino   len = orig_len;
307*e4b17023SJohn Marino 
308*e4b17023SJohn Marino   if (len == (size_t) -1)
309*e4b17023SJohn Marino     len = strlen (str);
310*e4b17023SJohn Marino 
311*e4b17023SJohn Marino   if (flag_debug_asm && comment)
312*e4b17023SJohn Marino     {
313*e4b17023SJohn Marino       fputs ("\t.ascii \"", asm_out_file);
314*e4b17023SJohn Marino       for (i = 0; i < len; i++)
315*e4b17023SJohn Marino 	{
316*e4b17023SJohn Marino 	  int c = str[i];
317*e4b17023SJohn Marino 	  if (c == '\"' || c == '\\')
318*e4b17023SJohn Marino 	    fputc ('\\', asm_out_file);
319*e4b17023SJohn Marino 	  if (ISPRINT(c))
320*e4b17023SJohn Marino 	    fputc (c, asm_out_file);
321*e4b17023SJohn Marino 	  else
322*e4b17023SJohn Marino 	    fprintf (asm_out_file, "\\%o", c);
323*e4b17023SJohn Marino 	}
324*e4b17023SJohn Marino       fprintf (asm_out_file, "\\0\"\t%s ", ASM_COMMENT_START);
325*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
326*e4b17023SJohn Marino       fputc ('\n', asm_out_file);
327*e4b17023SJohn Marino     }
328*e4b17023SJohn Marino   else
329*e4b17023SJohn Marino     {
330*e4b17023SJohn Marino       /* If an explicit length was given, we can't assume there
331*e4b17023SJohn Marino 	 is a null termination in the string buffer.  */
332*e4b17023SJohn Marino       if (orig_len == (size_t) -1)
333*e4b17023SJohn Marino 	len += 1;
334*e4b17023SJohn Marino       ASM_OUTPUT_ASCII (asm_out_file, str, len);
335*e4b17023SJohn Marino       if (orig_len != (size_t) -1)
336*e4b17023SJohn Marino 	assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1);
337*e4b17023SJohn Marino     }
338*e4b17023SJohn Marino 
339*e4b17023SJohn Marino   va_end (ap);
340*e4b17023SJohn Marino }
341*e4b17023SJohn Marino 
342*e4b17023SJohn Marino 
343*e4b17023SJohn Marino /* Return the size of an unsigned LEB128 quantity.  */
344*e4b17023SJohn Marino 
345*e4b17023SJohn Marino int
size_of_uleb128(unsigned HOST_WIDE_INT value)346*e4b17023SJohn Marino size_of_uleb128 (unsigned HOST_WIDE_INT value)
347*e4b17023SJohn Marino {
348*e4b17023SJohn Marino   int size = 0;
349*e4b17023SJohn Marino 
350*e4b17023SJohn Marino   do
351*e4b17023SJohn Marino     {
352*e4b17023SJohn Marino       value >>= 7;
353*e4b17023SJohn Marino       size += 1;
354*e4b17023SJohn Marino     }
355*e4b17023SJohn Marino   while (value != 0);
356*e4b17023SJohn Marino 
357*e4b17023SJohn Marino   return size;
358*e4b17023SJohn Marino }
359*e4b17023SJohn Marino 
360*e4b17023SJohn Marino /* Return the size of a signed LEB128 quantity.  */
361*e4b17023SJohn Marino 
362*e4b17023SJohn Marino int
size_of_sleb128(HOST_WIDE_INT value)363*e4b17023SJohn Marino size_of_sleb128 (HOST_WIDE_INT value)
364*e4b17023SJohn Marino {
365*e4b17023SJohn Marino   int size = 0, byte;
366*e4b17023SJohn Marino 
367*e4b17023SJohn Marino   do
368*e4b17023SJohn Marino     {
369*e4b17023SJohn Marino       byte = (value & 0x7f);
370*e4b17023SJohn Marino       value >>= 7;
371*e4b17023SJohn Marino       size += 1;
372*e4b17023SJohn Marino     }
373*e4b17023SJohn Marino   while (!((value == 0 && (byte & 0x40) == 0)
374*e4b17023SJohn Marino 	   || (value == -1 && (byte & 0x40) != 0)));
375*e4b17023SJohn Marino 
376*e4b17023SJohn Marino   return size;
377*e4b17023SJohn Marino }
378*e4b17023SJohn Marino 
379*e4b17023SJohn Marino /* Given an encoding, return the number of bytes the format occupies.
380*e4b17023SJohn Marino    This is only defined for fixed-size encodings, and so does not
381*e4b17023SJohn Marino    include leb128.  */
382*e4b17023SJohn Marino 
383*e4b17023SJohn Marino int
size_of_encoded_value(int encoding)384*e4b17023SJohn Marino size_of_encoded_value (int encoding)
385*e4b17023SJohn Marino {
386*e4b17023SJohn Marino   if (encoding == DW_EH_PE_omit)
387*e4b17023SJohn Marino     return 0;
388*e4b17023SJohn Marino 
389*e4b17023SJohn Marino   switch (encoding & 0x07)
390*e4b17023SJohn Marino     {
391*e4b17023SJohn Marino     case DW_EH_PE_absptr:
392*e4b17023SJohn Marino       return POINTER_SIZE / BITS_PER_UNIT;
393*e4b17023SJohn Marino     case DW_EH_PE_udata2:
394*e4b17023SJohn Marino       return 2;
395*e4b17023SJohn Marino     case DW_EH_PE_udata4:
396*e4b17023SJohn Marino       return 4;
397*e4b17023SJohn Marino     case DW_EH_PE_udata8:
398*e4b17023SJohn Marino       return 8;
399*e4b17023SJohn Marino     default:
400*e4b17023SJohn Marino       gcc_unreachable ();
401*e4b17023SJohn Marino     }
402*e4b17023SJohn Marino }
403*e4b17023SJohn Marino 
404*e4b17023SJohn Marino /* Yield a name for a given pointer encoding.  */
405*e4b17023SJohn Marino 
406*e4b17023SJohn Marino const char *
eh_data_format_name(int format)407*e4b17023SJohn Marino eh_data_format_name (int format)
408*e4b17023SJohn Marino {
409*e4b17023SJohn Marino #if HAVE_DESIGNATED_INITIALIZERS
410*e4b17023SJohn Marino #define S(p, v)		[p] = v,
411*e4b17023SJohn Marino #else
412*e4b17023SJohn Marino #define S(p, v)		case p: return v;
413*e4b17023SJohn Marino #endif
414*e4b17023SJohn Marino 
415*e4b17023SJohn Marino #if HAVE_DESIGNATED_INITIALIZERS
416*e4b17023SJohn Marino   __extension__ static const char * const format_names[256] = {
417*e4b17023SJohn Marino #else
418*e4b17023SJohn Marino   switch (format) {
419*e4b17023SJohn Marino #endif
420*e4b17023SJohn Marino 
421*e4b17023SJohn Marino   S(DW_EH_PE_absptr, "absolute")
422*e4b17023SJohn Marino   S(DW_EH_PE_omit, "omit")
423*e4b17023SJohn Marino   S(DW_EH_PE_aligned, "aligned absolute")
424*e4b17023SJohn Marino 
425*e4b17023SJohn Marino   S(DW_EH_PE_uleb128, "uleb128")
426*e4b17023SJohn Marino   S(DW_EH_PE_udata2, "udata2")
427*e4b17023SJohn Marino   S(DW_EH_PE_udata4, "udata4")
428*e4b17023SJohn Marino   S(DW_EH_PE_udata8, "udata8")
429*e4b17023SJohn Marino   S(DW_EH_PE_sleb128, "sleb128")
430*e4b17023SJohn Marino   S(DW_EH_PE_sdata2, "sdata2")
431*e4b17023SJohn Marino   S(DW_EH_PE_sdata4, "sdata4")
432*e4b17023SJohn Marino   S(DW_EH_PE_sdata8, "sdata8")
433*e4b17023SJohn Marino 
434*e4b17023SJohn Marino   S(DW_EH_PE_absptr | DW_EH_PE_pcrel, "pcrel")
435*e4b17023SJohn Marino   S(DW_EH_PE_uleb128 | DW_EH_PE_pcrel, "pcrel uleb128")
436*e4b17023SJohn Marino   S(DW_EH_PE_udata2 | DW_EH_PE_pcrel, "pcrel udata2")
437*e4b17023SJohn Marino   S(DW_EH_PE_udata4 | DW_EH_PE_pcrel, "pcrel udata4")
438*e4b17023SJohn Marino   S(DW_EH_PE_udata8 | DW_EH_PE_pcrel, "pcrel udata8")
439*e4b17023SJohn Marino   S(DW_EH_PE_sleb128 | DW_EH_PE_pcrel, "pcrel sleb128")
440*e4b17023SJohn Marino   S(DW_EH_PE_sdata2 | DW_EH_PE_pcrel, "pcrel sdata2")
441*e4b17023SJohn Marino   S(DW_EH_PE_sdata4 | DW_EH_PE_pcrel, "pcrel sdata4")
442*e4b17023SJohn Marino   S(DW_EH_PE_sdata8 | DW_EH_PE_pcrel, "pcrel sdata8")
443*e4b17023SJohn Marino 
444*e4b17023SJohn Marino   S(DW_EH_PE_absptr | DW_EH_PE_textrel, "textrel")
445*e4b17023SJohn Marino   S(DW_EH_PE_uleb128 | DW_EH_PE_textrel, "textrel uleb128")
446*e4b17023SJohn Marino   S(DW_EH_PE_udata2 | DW_EH_PE_textrel, "textrel udata2")
447*e4b17023SJohn Marino   S(DW_EH_PE_udata4 | DW_EH_PE_textrel, "textrel udata4")
448*e4b17023SJohn Marino   S(DW_EH_PE_udata8 | DW_EH_PE_textrel, "textrel udata8")
449*e4b17023SJohn Marino   S(DW_EH_PE_sleb128 | DW_EH_PE_textrel, "textrel sleb128")
450*e4b17023SJohn Marino   S(DW_EH_PE_sdata2 | DW_EH_PE_textrel, "textrel sdata2")
451*e4b17023SJohn Marino   S(DW_EH_PE_sdata4 | DW_EH_PE_textrel, "textrel sdata4")
452*e4b17023SJohn Marino   S(DW_EH_PE_sdata8 | DW_EH_PE_textrel, "textrel sdata8")
453*e4b17023SJohn Marino 
454*e4b17023SJohn Marino   S(DW_EH_PE_absptr | DW_EH_PE_datarel, "datarel")
455*e4b17023SJohn Marino   S(DW_EH_PE_uleb128 | DW_EH_PE_datarel, "datarel uleb128")
456*e4b17023SJohn Marino   S(DW_EH_PE_udata2 | DW_EH_PE_datarel, "datarel udata2")
457*e4b17023SJohn Marino   S(DW_EH_PE_udata4 | DW_EH_PE_datarel, "datarel udata4")
458*e4b17023SJohn Marino   S(DW_EH_PE_udata8 | DW_EH_PE_datarel, "datarel udata8")
459*e4b17023SJohn Marino   S(DW_EH_PE_sleb128 | DW_EH_PE_datarel, "datarel sleb128")
460*e4b17023SJohn Marino   S(DW_EH_PE_sdata2 | DW_EH_PE_datarel, "datarel sdata2")
461*e4b17023SJohn Marino   S(DW_EH_PE_sdata4 | DW_EH_PE_datarel, "datarel sdata4")
462*e4b17023SJohn Marino   S(DW_EH_PE_sdata8 | DW_EH_PE_datarel, "datarel sdata8")
463*e4b17023SJohn Marino 
464*e4b17023SJohn Marino   S(DW_EH_PE_absptr | DW_EH_PE_funcrel, "funcrel")
465*e4b17023SJohn Marino   S(DW_EH_PE_uleb128 | DW_EH_PE_funcrel, "funcrel uleb128")
466*e4b17023SJohn Marino   S(DW_EH_PE_udata2 | DW_EH_PE_funcrel, "funcrel udata2")
467*e4b17023SJohn Marino   S(DW_EH_PE_udata4 | DW_EH_PE_funcrel, "funcrel udata4")
468*e4b17023SJohn Marino   S(DW_EH_PE_udata8 | DW_EH_PE_funcrel, "funcrel udata8")
469*e4b17023SJohn Marino   S(DW_EH_PE_sleb128 | DW_EH_PE_funcrel, "funcrel sleb128")
470*e4b17023SJohn Marino   S(DW_EH_PE_sdata2 | DW_EH_PE_funcrel, "funcrel sdata2")
471*e4b17023SJohn Marino   S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4")
472*e4b17023SJohn Marino   S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8")
473*e4b17023SJohn Marino 
474*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_absptr, "indirect absolute")
475*e4b17023SJohn Marino 
476*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel,
477*e4b17023SJohn Marino     "indirect pcrel")
478*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel,
479*e4b17023SJohn Marino     "indirect pcrel uleb128")
480*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_pcrel,
481*e4b17023SJohn Marino     "indirect pcrel udata2")
482*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_pcrel,
483*e4b17023SJohn Marino     "indirect pcrel udata4")
484*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_pcrel,
485*e4b17023SJohn Marino     "indirect pcrel udata8")
486*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_pcrel,
487*e4b17023SJohn Marino     "indirect pcrel sleb128")
488*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_pcrel,
489*e4b17023SJohn Marino     "indirect pcrel sdata2")
490*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_pcrel,
491*e4b17023SJohn Marino     "indirect pcrel sdata4")
492*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_pcrel,
493*e4b17023SJohn Marino     "indirect pcrel sdata8")
494*e4b17023SJohn Marino 
495*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_textrel,
496*e4b17023SJohn Marino     "indirect textrel")
497*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_textrel,
498*e4b17023SJohn Marino     "indirect textrel uleb128")
499*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_textrel,
500*e4b17023SJohn Marino     "indirect textrel udata2")
501*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_textrel,
502*e4b17023SJohn Marino     "indirect textrel udata4")
503*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_textrel,
504*e4b17023SJohn Marino     "indirect textrel udata8")
505*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_textrel,
506*e4b17023SJohn Marino     "indirect textrel sleb128")
507*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_textrel,
508*e4b17023SJohn Marino     "indirect textrel sdata2")
509*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_textrel,
510*e4b17023SJohn Marino     "indirect textrel sdata4")
511*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_textrel,
512*e4b17023SJohn Marino     "indirect textrel sdata8")
513*e4b17023SJohn Marino 
514*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_datarel,
515*e4b17023SJohn Marino     "indirect datarel")
516*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_datarel,
517*e4b17023SJohn Marino     "indirect datarel uleb128")
518*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_datarel,
519*e4b17023SJohn Marino     "indirect datarel udata2")
520*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_datarel,
521*e4b17023SJohn Marino     "indirect datarel udata4")
522*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_datarel,
523*e4b17023SJohn Marino     "indirect datarel udata8")
524*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_datarel,
525*e4b17023SJohn Marino     "indirect datarel sleb128")
526*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_datarel,
527*e4b17023SJohn Marino     "indirect datarel sdata2")
528*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_datarel,
529*e4b17023SJohn Marino     "indirect datarel sdata4")
530*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_datarel,
531*e4b17023SJohn Marino     "indirect datarel sdata8")
532*e4b17023SJohn Marino 
533*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_funcrel,
534*e4b17023SJohn Marino     "indirect funcrel")
535*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_funcrel,
536*e4b17023SJohn Marino     "indirect funcrel uleb128")
537*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_funcrel,
538*e4b17023SJohn Marino     "indirect funcrel udata2")
539*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_funcrel,
540*e4b17023SJohn Marino     "indirect funcrel udata4")
541*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_funcrel,
542*e4b17023SJohn Marino     "indirect funcrel udata8")
543*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_funcrel,
544*e4b17023SJohn Marino     "indirect funcrel sleb128")
545*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_funcrel,
546*e4b17023SJohn Marino     "indirect funcrel sdata2")
547*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_funcrel,
548*e4b17023SJohn Marino     "indirect funcrel sdata4")
549*e4b17023SJohn Marino   S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_funcrel,
550*e4b17023SJohn Marino     "indirect funcrel sdata8")
551*e4b17023SJohn Marino 
552*e4b17023SJohn Marino #if HAVE_DESIGNATED_INITIALIZERS
553*e4b17023SJohn Marino   };
554*e4b17023SJohn Marino 
555*e4b17023SJohn Marino   gcc_assert (format >= 0 && format < 0x100 && format_names[format]);
556*e4b17023SJohn Marino 
557*e4b17023SJohn Marino   return format_names[format];
558*e4b17023SJohn Marino #else
559*e4b17023SJohn Marino   }
560*e4b17023SJohn Marino   gcc_unreachable ();
561*e4b17023SJohn Marino #endif
562*e4b17023SJohn Marino }
563*e4b17023SJohn Marino 
564*e4b17023SJohn Marino /* Output an unsigned LEB128 quantity, but only the byte values.  */
565*e4b17023SJohn Marino 
566*e4b17023SJohn Marino void
dw2_asm_output_data_uleb128_raw(unsigned HOST_WIDE_INT value)567*e4b17023SJohn Marino dw2_asm_output_data_uleb128_raw (unsigned HOST_WIDE_INT value)
568*e4b17023SJohn Marino {
569*e4b17023SJohn Marino   while (1)
570*e4b17023SJohn Marino     {
571*e4b17023SJohn Marino       int byte = (value & 0x7f);
572*e4b17023SJohn Marino       value >>= 7;
573*e4b17023SJohn Marino       if (value != 0)
574*e4b17023SJohn Marino 	/* More bytes to follow.  */
575*e4b17023SJohn Marino 	byte |= 0x80;
576*e4b17023SJohn Marino 
577*e4b17023SJohn Marino       fprintf (asm_out_file, "%#x", byte);
578*e4b17023SJohn Marino       if (value == 0)
579*e4b17023SJohn Marino 	break;
580*e4b17023SJohn Marino       fputc (',', asm_out_file);
581*e4b17023SJohn Marino     }
582*e4b17023SJohn Marino }
583*e4b17023SJohn Marino 
584*e4b17023SJohn Marino /* Output an unsigned LEB128 quantity.  */
585*e4b17023SJohn Marino 
586*e4b17023SJohn Marino void
dw2_asm_output_data_uleb128(unsigned HOST_WIDE_INT value,const char * comment,...)587*e4b17023SJohn Marino dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value,
588*e4b17023SJohn Marino 			     const char *comment, ...)
589*e4b17023SJohn Marino {
590*e4b17023SJohn Marino   va_list ap;
591*e4b17023SJohn Marino 
592*e4b17023SJohn Marino   va_start (ap, comment);
593*e4b17023SJohn Marino 
594*e4b17023SJohn Marino #ifdef HAVE_AS_LEB128
595*e4b17023SJohn Marino   fputs ("\t.uleb128 ", asm_out_file);
596*e4b17023SJohn Marino   fprint_whex (asm_out_file, value);
597*e4b17023SJohn Marino 
598*e4b17023SJohn Marino   if (flag_debug_asm && comment)
599*e4b17023SJohn Marino     {
600*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
601*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
602*e4b17023SJohn Marino     }
603*e4b17023SJohn Marino #else
604*e4b17023SJohn Marino   {
605*e4b17023SJohn Marino     unsigned HOST_WIDE_INT work = value;
606*e4b17023SJohn Marino     const char *byte_op = targetm.asm_out.byte_op;
607*e4b17023SJohn Marino 
608*e4b17023SJohn Marino     if (byte_op)
609*e4b17023SJohn Marino       fputs (byte_op, asm_out_file);
610*e4b17023SJohn Marino     do
611*e4b17023SJohn Marino       {
612*e4b17023SJohn Marino 	int byte = (work & 0x7f);
613*e4b17023SJohn Marino 	work >>= 7;
614*e4b17023SJohn Marino 	if (work != 0)
615*e4b17023SJohn Marino 	  /* More bytes to follow.  */
616*e4b17023SJohn Marino 	  byte |= 0x80;
617*e4b17023SJohn Marino 
618*e4b17023SJohn Marino 	if (byte_op)
619*e4b17023SJohn Marino 	  {
620*e4b17023SJohn Marino 	    fprintf (asm_out_file, "%#x", byte);
621*e4b17023SJohn Marino 	    if (work != 0)
622*e4b17023SJohn Marino 	      fputc (',', asm_out_file);
623*e4b17023SJohn Marino 	  }
624*e4b17023SJohn Marino 	else
625*e4b17023SJohn Marino 	  assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
626*e4b17023SJohn Marino       }
627*e4b17023SJohn Marino     while (work != 0);
628*e4b17023SJohn Marino 
629*e4b17023SJohn Marino   if (flag_debug_asm)
630*e4b17023SJohn Marino     {
631*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX,
632*e4b17023SJohn Marino 	       ASM_COMMENT_START, value);
633*e4b17023SJohn Marino       if (comment)
634*e4b17023SJohn Marino 	{
635*e4b17023SJohn Marino 	  fputs ("; ", asm_out_file);
636*e4b17023SJohn Marino 	  vfprintf (asm_out_file, comment, ap);
637*e4b17023SJohn Marino 	}
638*e4b17023SJohn Marino     }
639*e4b17023SJohn Marino   }
640*e4b17023SJohn Marino #endif
641*e4b17023SJohn Marino   putc ('\n', asm_out_file);
642*e4b17023SJohn Marino 
643*e4b17023SJohn Marino   va_end (ap);
644*e4b17023SJohn Marino }
645*e4b17023SJohn Marino 
646*e4b17023SJohn Marino /* Output an signed LEB128 quantity, but only the byte values.  */
647*e4b17023SJohn Marino 
648*e4b17023SJohn Marino void
dw2_asm_output_data_sleb128_raw(HOST_WIDE_INT value)649*e4b17023SJohn Marino dw2_asm_output_data_sleb128_raw (HOST_WIDE_INT value)
650*e4b17023SJohn Marino {
651*e4b17023SJohn Marino   int byte, more;
652*e4b17023SJohn Marino 
653*e4b17023SJohn Marino   while (1)
654*e4b17023SJohn Marino     {
655*e4b17023SJohn Marino       byte = (value & 0x7f);
656*e4b17023SJohn Marino       value >>= 7;
657*e4b17023SJohn Marino       more = !((value == 0 && (byte & 0x40) == 0)
658*e4b17023SJohn Marino 		|| (value == -1 && (byte & 0x40) != 0));
659*e4b17023SJohn Marino       if (more)
660*e4b17023SJohn Marino 	byte |= 0x80;
661*e4b17023SJohn Marino 
662*e4b17023SJohn Marino       fprintf (asm_out_file, "%#x", byte);
663*e4b17023SJohn Marino       if (!more)
664*e4b17023SJohn Marino 	break;
665*e4b17023SJohn Marino       fputc (',', asm_out_file);
666*e4b17023SJohn Marino     }
667*e4b17023SJohn Marino }
668*e4b17023SJohn Marino 
669*e4b17023SJohn Marino /* Output a signed LEB128 quantity.  */
670*e4b17023SJohn Marino 
671*e4b17023SJohn Marino void
dw2_asm_output_data_sleb128(HOST_WIDE_INT value,const char * comment,...)672*e4b17023SJohn Marino dw2_asm_output_data_sleb128 (HOST_WIDE_INT value,
673*e4b17023SJohn Marino 			     const char *comment, ...)
674*e4b17023SJohn Marino {
675*e4b17023SJohn Marino   va_list ap;
676*e4b17023SJohn Marino 
677*e4b17023SJohn Marino   va_start (ap, comment);
678*e4b17023SJohn Marino 
679*e4b17023SJohn Marino #ifdef HAVE_AS_LEB128
680*e4b17023SJohn Marino   fprintf (asm_out_file, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC, value);
681*e4b17023SJohn Marino 
682*e4b17023SJohn Marino   if (flag_debug_asm && comment)
683*e4b17023SJohn Marino     {
684*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
685*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
686*e4b17023SJohn Marino     }
687*e4b17023SJohn Marino #else
688*e4b17023SJohn Marino   {
689*e4b17023SJohn Marino     HOST_WIDE_INT work = value;
690*e4b17023SJohn Marino     int more, byte;
691*e4b17023SJohn Marino     const char *byte_op = targetm.asm_out.byte_op;
692*e4b17023SJohn Marino 
693*e4b17023SJohn Marino     if (byte_op)
694*e4b17023SJohn Marino       fputs (byte_op, asm_out_file);
695*e4b17023SJohn Marino     do
696*e4b17023SJohn Marino       {
697*e4b17023SJohn Marino 	byte = (work & 0x7f);
698*e4b17023SJohn Marino 	/* arithmetic shift */
699*e4b17023SJohn Marino 	work >>= 7;
700*e4b17023SJohn Marino 	more = !((work == 0 && (byte & 0x40) == 0)
701*e4b17023SJohn Marino 		 || (work == -1 && (byte & 0x40) != 0));
702*e4b17023SJohn Marino 	if (more)
703*e4b17023SJohn Marino 	  byte |= 0x80;
704*e4b17023SJohn Marino 
705*e4b17023SJohn Marino 	if (byte_op)
706*e4b17023SJohn Marino 	  {
707*e4b17023SJohn Marino 	    fprintf (asm_out_file, "%#x", byte);
708*e4b17023SJohn Marino 	    if (more)
709*e4b17023SJohn Marino 	      fputc (',', asm_out_file);
710*e4b17023SJohn Marino 	  }
711*e4b17023SJohn Marino 	else
712*e4b17023SJohn Marino 	  assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
713*e4b17023SJohn Marino       }
714*e4b17023SJohn Marino     while (more);
715*e4b17023SJohn Marino 
716*e4b17023SJohn Marino   if (flag_debug_asm)
717*e4b17023SJohn Marino     {
718*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC,
719*e4b17023SJohn Marino 	       ASM_COMMENT_START, value);
720*e4b17023SJohn Marino       if (comment)
721*e4b17023SJohn Marino 	{
722*e4b17023SJohn Marino 	  fputs ("; ", asm_out_file);
723*e4b17023SJohn Marino 	  vfprintf (asm_out_file, comment, ap);
724*e4b17023SJohn Marino 	}
725*e4b17023SJohn Marino     }
726*e4b17023SJohn Marino   }
727*e4b17023SJohn Marino #endif
728*e4b17023SJohn Marino   fputc ('\n', asm_out_file);
729*e4b17023SJohn Marino 
730*e4b17023SJohn Marino   va_end (ap);
731*e4b17023SJohn Marino }
732*e4b17023SJohn Marino 
733*e4b17023SJohn Marino void
dw2_asm_output_delta_uleb128(const char * lab1 ATTRIBUTE_UNUSED,const char * lab2 ATTRIBUTE_UNUSED,const char * comment,...)734*e4b17023SJohn Marino dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
735*e4b17023SJohn Marino 			      const char *lab2 ATTRIBUTE_UNUSED,
736*e4b17023SJohn Marino 			      const char *comment, ...)
737*e4b17023SJohn Marino {
738*e4b17023SJohn Marino   va_list ap;
739*e4b17023SJohn Marino 
740*e4b17023SJohn Marino   va_start (ap, comment);
741*e4b17023SJohn Marino 
742*e4b17023SJohn Marino #ifdef HAVE_AS_LEB128
743*e4b17023SJohn Marino   fputs ("\t.uleb128 ", asm_out_file);
744*e4b17023SJohn Marino   assemble_name (asm_out_file, lab1);
745*e4b17023SJohn Marino   putc ('-', asm_out_file);
746*e4b17023SJohn Marino   assemble_name (asm_out_file, lab2);
747*e4b17023SJohn Marino #else
748*e4b17023SJohn Marino   gcc_unreachable ();
749*e4b17023SJohn Marino #endif
750*e4b17023SJohn Marino 
751*e4b17023SJohn Marino   if (flag_debug_asm && comment)
752*e4b17023SJohn Marino     {
753*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
754*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
755*e4b17023SJohn Marino     }
756*e4b17023SJohn Marino   fputc ('\n', asm_out_file);
757*e4b17023SJohn Marino 
758*e4b17023SJohn Marino   va_end (ap);
759*e4b17023SJohn Marino }
760*e4b17023SJohn Marino 
761*e4b17023SJohn Marino #if 0
762*e4b17023SJohn Marino 
763*e4b17023SJohn Marino void
764*e4b17023SJohn Marino dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED,
765*e4b17023SJohn Marino 			      const char *lab2 ATTRIBUTE_UNUSED,
766*e4b17023SJohn Marino 			      const char *comment, ...)
767*e4b17023SJohn Marino {
768*e4b17023SJohn Marino   va_list ap;
769*e4b17023SJohn Marino 
770*e4b17023SJohn Marino   va_start (ap, comment);
771*e4b17023SJohn Marino 
772*e4b17023SJohn Marino #ifdef HAVE_AS_LEB128
773*e4b17023SJohn Marino   fputs ("\t.sleb128 ", asm_out_file);
774*e4b17023SJohn Marino   assemble_name (asm_out_file, lab1);
775*e4b17023SJohn Marino   putc ('-', asm_out_file);
776*e4b17023SJohn Marino   assemble_name (asm_out_file, lab2);
777*e4b17023SJohn Marino #else
778*e4b17023SJohn Marino   gcc_unreachable ();
779*e4b17023SJohn Marino #endif
780*e4b17023SJohn Marino 
781*e4b17023SJohn Marino   if (flag_debug_asm && comment)
782*e4b17023SJohn Marino     {
783*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
784*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
785*e4b17023SJohn Marino     }
786*e4b17023SJohn Marino   fputc ('\n', asm_out_file);
787*e4b17023SJohn Marino 
788*e4b17023SJohn Marino   va_end (ap);
789*e4b17023SJohn Marino }
790*e4b17023SJohn Marino #endif /* 0 */
791*e4b17023SJohn Marino 
792*e4b17023SJohn Marino static int dw2_output_indirect_constant_1 (splay_tree_node, void *);
793*e4b17023SJohn Marino 
794*e4b17023SJohn Marino static GTY((param1_is (char *), param2_is (tree))) splay_tree indirect_pool;
795*e4b17023SJohn Marino 
796*e4b17023SJohn Marino static GTY(()) int dw2_const_labelno;
797*e4b17023SJohn Marino 
798*e4b17023SJohn Marino #if defined(HAVE_GAS_HIDDEN)
799*e4b17023SJohn Marino # define USE_LINKONCE_INDIRECT (SUPPORTS_ONE_ONLY)
800*e4b17023SJohn Marino #else
801*e4b17023SJohn Marino # define USE_LINKONCE_INDIRECT 0
802*e4b17023SJohn Marino #endif
803*e4b17023SJohn Marino 
804*e4b17023SJohn Marino /* Comparison function for a splay tree in which the keys are strings.
805*e4b17023SJohn Marino    K1 and K2 have the dynamic type "const char *".  Returns <0, 0, or
806*e4b17023SJohn Marino    >0 to indicate whether K1 is less than, equal to, or greater than
807*e4b17023SJohn Marino    K2, respectively.  */
808*e4b17023SJohn Marino 
809*e4b17023SJohn Marino static int
splay_tree_compare_strings(splay_tree_key k1,splay_tree_key k2)810*e4b17023SJohn Marino splay_tree_compare_strings (splay_tree_key k1, splay_tree_key k2)
811*e4b17023SJohn Marino {
812*e4b17023SJohn Marino   const char *s1 = (const char *)k1;
813*e4b17023SJohn Marino   const char *s2 = (const char *)k2;
814*e4b17023SJohn Marino   int ret;
815*e4b17023SJohn Marino 
816*e4b17023SJohn Marino   if (s1 == s2)
817*e4b17023SJohn Marino     return 0;
818*e4b17023SJohn Marino 
819*e4b17023SJohn Marino   ret = strcmp (s1, s2);
820*e4b17023SJohn Marino 
821*e4b17023SJohn Marino   /* The strings are always those from IDENTIFIER_NODEs, and,
822*e4b17023SJohn Marino      therefore, we should never have two copies of the same
823*e4b17023SJohn Marino      string.  */
824*e4b17023SJohn Marino   gcc_assert (ret);
825*e4b17023SJohn Marino 
826*e4b17023SJohn Marino   return ret;
827*e4b17023SJohn Marino }
828*e4b17023SJohn Marino 
829*e4b17023SJohn Marino /* Put X, a SYMBOL_REF, in memory.  Return a SYMBOL_REF to the allocated
830*e4b17023SJohn Marino    memory.  Differs from force_const_mem in that a single pool is used for
831*e4b17023SJohn Marino    the entire unit of translation, and the memory is not guaranteed to be
832*e4b17023SJohn Marino    "near" the function in any interesting sense.  IS_PUBLIC controls whether
833*e4b17023SJohn Marino    the symbol can be shared across the entire application (or DSO).  */
834*e4b17023SJohn Marino 
835*e4b17023SJohn Marino rtx
dw2_force_const_mem(rtx x,bool is_public)836*e4b17023SJohn Marino dw2_force_const_mem (rtx x, bool is_public)
837*e4b17023SJohn Marino {
838*e4b17023SJohn Marino   splay_tree_node node;
839*e4b17023SJohn Marino   const char *key;
840*e4b17023SJohn Marino   tree decl_id;
841*e4b17023SJohn Marino 
842*e4b17023SJohn Marino   if (! indirect_pool)
843*e4b17023SJohn Marino     /* We use strcmp, rather than just comparing pointers, so that the
844*e4b17023SJohn Marino        sort order will not depend on the host system.  */
845*e4b17023SJohn Marino     indirect_pool = splay_tree_new_ggc (splay_tree_compare_strings,
846*e4b17023SJohn Marino 					ggc_alloc_splay_tree_str_tree_node_splay_tree_s,
847*e4b17023SJohn Marino 					ggc_alloc_splay_tree_str_tree_node_splay_tree_node_s);
848*e4b17023SJohn Marino 
849*e4b17023SJohn Marino   gcc_assert (GET_CODE (x) == SYMBOL_REF);
850*e4b17023SJohn Marino 
851*e4b17023SJohn Marino   key = XSTR (x, 0);
852*e4b17023SJohn Marino   node = splay_tree_lookup (indirect_pool, (splay_tree_key) key);
853*e4b17023SJohn Marino   if (node)
854*e4b17023SJohn Marino     decl_id = (tree) node->value;
855*e4b17023SJohn Marino   else
856*e4b17023SJohn Marino     {
857*e4b17023SJohn Marino       tree id;
858*e4b17023SJohn Marino       const char *str = targetm.strip_name_encoding (key);
859*e4b17023SJohn Marino 
860*e4b17023SJohn Marino       if (is_public && USE_LINKONCE_INDIRECT)
861*e4b17023SJohn Marino 	{
862*e4b17023SJohn Marino 	  char *ref_name = XALLOCAVEC (char, strlen (str) + sizeof "DW.ref.");
863*e4b17023SJohn Marino 
864*e4b17023SJohn Marino 	  sprintf (ref_name, "DW.ref.%s", str);
865*e4b17023SJohn Marino 	  gcc_assert (!maybe_get_identifier (ref_name));
866*e4b17023SJohn Marino 	  decl_id = get_identifier (ref_name);
867*e4b17023SJohn Marino 	  TREE_PUBLIC (decl_id) = 1;
868*e4b17023SJohn Marino 	}
869*e4b17023SJohn Marino       else
870*e4b17023SJohn Marino 	{
871*e4b17023SJohn Marino 	  char label[32];
872*e4b17023SJohn Marino 
873*e4b17023SJohn Marino 	  ASM_GENERATE_INTERNAL_LABEL (label, "LDFCM", dw2_const_labelno);
874*e4b17023SJohn Marino 	  ++dw2_const_labelno;
875*e4b17023SJohn Marino 	  gcc_assert (!maybe_get_identifier (label));
876*e4b17023SJohn Marino 	  decl_id = get_identifier (label);
877*e4b17023SJohn Marino 	}
878*e4b17023SJohn Marino 
879*e4b17023SJohn Marino       id = maybe_get_identifier (str);
880*e4b17023SJohn Marino       if (id)
881*e4b17023SJohn Marino 	TREE_SYMBOL_REFERENCED (id) = 1;
882*e4b17023SJohn Marino 
883*e4b17023SJohn Marino       splay_tree_insert (indirect_pool, (splay_tree_key) key,
884*e4b17023SJohn Marino 			 (splay_tree_value) decl_id);
885*e4b17023SJohn Marino     }
886*e4b17023SJohn Marino 
887*e4b17023SJohn Marino   return gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (decl_id));
888*e4b17023SJohn Marino }
889*e4b17023SJohn Marino 
890*e4b17023SJohn Marino /* A helper function for dw2_output_indirect_constants called through
891*e4b17023SJohn Marino    splay_tree_foreach.  Emit one queued constant to memory.  */
892*e4b17023SJohn Marino 
893*e4b17023SJohn Marino static int
dw2_output_indirect_constant_1(splay_tree_node node,void * data ATTRIBUTE_UNUSED)894*e4b17023SJohn Marino dw2_output_indirect_constant_1 (splay_tree_node node,
895*e4b17023SJohn Marino 				void *data ATTRIBUTE_UNUSED)
896*e4b17023SJohn Marino {
897*e4b17023SJohn Marino   const char *sym;
898*e4b17023SJohn Marino   rtx sym_ref;
899*e4b17023SJohn Marino   tree id, decl;
900*e4b17023SJohn Marino 
901*e4b17023SJohn Marino   sym = (const char *) node->key;
902*e4b17023SJohn Marino   id = (tree) node->value;
903*e4b17023SJohn Marino 
904*e4b17023SJohn Marino   decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id, ptr_type_node);
905*e4b17023SJohn Marino   SET_DECL_ASSEMBLER_NAME (decl, id);
906*e4b17023SJohn Marino   DECL_ARTIFICIAL (decl) = 1;
907*e4b17023SJohn Marino   DECL_IGNORED_P (decl) = 1;
908*e4b17023SJohn Marino   DECL_INITIAL (decl) = decl;
909*e4b17023SJohn Marino   TREE_READONLY (decl) = 1;
910*e4b17023SJohn Marino 
911*e4b17023SJohn Marino   if (TREE_PUBLIC (id))
912*e4b17023SJohn Marino     {
913*e4b17023SJohn Marino       TREE_PUBLIC (decl) = 1;
914*e4b17023SJohn Marino       make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
915*e4b17023SJohn Marino       if (USE_LINKONCE_INDIRECT)
916*e4b17023SJohn Marino 	DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
917*e4b17023SJohn Marino     }
918*e4b17023SJohn Marino   else
919*e4b17023SJohn Marino     TREE_STATIC (decl) = 1;
920*e4b17023SJohn Marino 
921*e4b17023SJohn Marino   sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
922*e4b17023SJohn Marino   assemble_variable (decl, 1, 1, 1);
923*e4b17023SJohn Marino   assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
924*e4b17023SJohn Marino 
925*e4b17023SJohn Marino   return 0;
926*e4b17023SJohn Marino }
927*e4b17023SJohn Marino 
928*e4b17023SJohn Marino /* Emit the constants queued through dw2_force_const_mem.  */
929*e4b17023SJohn Marino 
930*e4b17023SJohn Marino void
dw2_output_indirect_constants(void)931*e4b17023SJohn Marino dw2_output_indirect_constants (void)
932*e4b17023SJohn Marino {
933*e4b17023SJohn Marino   if (indirect_pool)
934*e4b17023SJohn Marino     splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL);
935*e4b17023SJohn Marino }
936*e4b17023SJohn Marino 
937*e4b17023SJohn Marino /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed.
938*e4b17023SJohn Marino    If PUBLIC is set and the encoding is DW_EH_PE_indirect, the indirect
939*e4b17023SJohn Marino    reference is shared across the entire application (or DSO).  */
940*e4b17023SJohn Marino 
941*e4b17023SJohn Marino void
dw2_asm_output_encoded_addr_rtx(int encoding,rtx addr,bool is_public,const char * comment,...)942*e4b17023SJohn Marino dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr, bool is_public,
943*e4b17023SJohn Marino 				 const char *comment, ...)
944*e4b17023SJohn Marino {
945*e4b17023SJohn Marino   int size;
946*e4b17023SJohn Marino   va_list ap;
947*e4b17023SJohn Marino 
948*e4b17023SJohn Marino   va_start (ap, comment);
949*e4b17023SJohn Marino 
950*e4b17023SJohn Marino   size = size_of_encoded_value (encoding);
951*e4b17023SJohn Marino 
952*e4b17023SJohn Marino   if (encoding == DW_EH_PE_aligned)
953*e4b17023SJohn Marino     {
954*e4b17023SJohn Marino       assemble_align (POINTER_SIZE);
955*e4b17023SJohn Marino       assemble_integer (addr, size, POINTER_SIZE, 1);
956*e4b17023SJohn Marino       va_end (ap);
957*e4b17023SJohn Marino       return;
958*e4b17023SJohn Marino     }
959*e4b17023SJohn Marino 
960*e4b17023SJohn Marino   /* NULL is _always_ represented as a plain zero, as is 1 for Ada's
961*e4b17023SJohn Marino      "all others".  */
962*e4b17023SJohn Marino   if (addr == const0_rtx || addr == const1_rtx)
963*e4b17023SJohn Marino     assemble_integer (addr, size, BITS_PER_UNIT, 1);
964*e4b17023SJohn Marino   else
965*e4b17023SJohn Marino     {
966*e4b17023SJohn Marino     restart:
967*e4b17023SJohn Marino       /* Allow the target first crack at emitting this.  Some of the
968*e4b17023SJohn Marino 	 special relocations require special directives instead of
969*e4b17023SJohn Marino 	 just ".4byte" or whatever.  */
970*e4b17023SJohn Marino #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
971*e4b17023SJohn Marino       ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file, encoding, size,
972*e4b17023SJohn Marino 					 addr, done);
973*e4b17023SJohn Marino #endif
974*e4b17023SJohn Marino 
975*e4b17023SJohn Marino       /* Indirection is used to get dynamic relocations out of a
976*e4b17023SJohn Marino 	 read-only section.  */
977*e4b17023SJohn Marino       if (encoding & DW_EH_PE_indirect)
978*e4b17023SJohn Marino 	{
979*e4b17023SJohn Marino 	  /* It is very tempting to use force_const_mem so that we share data
980*e4b17023SJohn Marino 	     with the normal constant pool.  However, we've already emitted
981*e4b17023SJohn Marino 	     the constant pool for this function.  Moreover, we'd like to
982*e4b17023SJohn Marino 	     share these constants across the entire unit of translation and
983*e4b17023SJohn Marino 	     even, if possible, across the entire application (or DSO).  */
984*e4b17023SJohn Marino 	  addr = dw2_force_const_mem (addr, is_public);
985*e4b17023SJohn Marino 	  encoding &= ~DW_EH_PE_indirect;
986*e4b17023SJohn Marino 	  goto restart;
987*e4b17023SJohn Marino 	}
988*e4b17023SJohn Marino 
989*e4b17023SJohn Marino       switch (encoding & 0xF0)
990*e4b17023SJohn Marino 	{
991*e4b17023SJohn Marino 	case DW_EH_PE_absptr:
992*e4b17023SJohn Marino 	  dw2_assemble_integer (size, addr);
993*e4b17023SJohn Marino 	  break;
994*e4b17023SJohn Marino 
995*e4b17023SJohn Marino 	case DW_EH_PE_pcrel:
996*e4b17023SJohn Marino 	  gcc_assert (GET_CODE (addr) == SYMBOL_REF);
997*e4b17023SJohn Marino #ifdef ASM_OUTPUT_DWARF_PCREL
998*e4b17023SJohn Marino 	  ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, XSTR (addr, 0));
999*e4b17023SJohn Marino #else
1000*e4b17023SJohn Marino 	  dw2_assemble_integer (size, gen_rtx_MINUS (Pmode, addr, pc_rtx));
1001*e4b17023SJohn Marino #endif
1002*e4b17023SJohn Marino 	  break;
1003*e4b17023SJohn Marino 
1004*e4b17023SJohn Marino 	default:
1005*e4b17023SJohn Marino 	  /* Other encodings should have been handled by
1006*e4b17023SJohn Marino 	     ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX.  */
1007*e4b17023SJohn Marino 	  gcc_unreachable ();
1008*e4b17023SJohn Marino 	}
1009*e4b17023SJohn Marino 
1010*e4b17023SJohn Marino #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
1011*e4b17023SJohn Marino     done:;
1012*e4b17023SJohn Marino #endif
1013*e4b17023SJohn Marino     }
1014*e4b17023SJohn Marino 
1015*e4b17023SJohn Marino   if (flag_debug_asm && comment)
1016*e4b17023SJohn Marino     {
1017*e4b17023SJohn Marino       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
1018*e4b17023SJohn Marino       vfprintf (asm_out_file, comment, ap);
1019*e4b17023SJohn Marino     }
1020*e4b17023SJohn Marino   fputc ('\n', asm_out_file);
1021*e4b17023SJohn Marino 
1022*e4b17023SJohn Marino   va_end (ap);
1023*e4b17023SJohn Marino }
1024*e4b17023SJohn Marino 
1025*e4b17023SJohn Marino #include "gt-dwarf2asm.h"
1026