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