|
|
1.1 root 1: /* Output variables, constants and external declarations, for GNU compiler.
1.1.1.8 root 2: Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
1.1 root 3:
4: This file is part of GNU CC.
5:
6: GNU CC is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 2, or (at your option)
9: any later version.
10:
11: GNU CC is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU CC; see the file COPYING. If not, write to
1.1.1.8 root 18: the Free Software Foundation, 59 Temple Place - Suite 330,
19: Boston, MA 02111-1307, USA. */
1.1 root 20:
21:
22: /* This file handles generation of all the assembler code
23: *except* the instructions of a function.
24: This includes declarations of variables and their initial values.
25:
26: We also output the assembler code for constants stored in memory
27: and are responsible for combining constants with the same value. */
28:
29: #include <stdio.h>
30: #include <setjmp.h>
31: /* #include <stab.h> */
32: #include "config.h"
33: #include "rtl.h"
34: #include "tree.h"
35: #include "flags.h"
1.1.1.4 root 36: #include "function.h"
1.1 root 37: #include "expr.h"
1.1.1.8 root 38: #include "output.h"
1.1 root 39: #include "hard-reg-set.h"
40: #include "regs.h"
1.1.1.3 root 41: #include "defaults.h"
1.1.1.4 root 42: #include "real.h"
1.1.1.6 root 43: #include "bytecode.h"
1.1 root 44:
45: #include "obstack.h"
1.1.1.8 root 46: #include "c-pragma.h"
1.1 root 47:
1.1.1.2 root 48: #ifdef XCOFF_DEBUGGING_INFO
49: #include "xcoffout.h"
50: #endif
51:
1.1.1.6 root 52: #include <ctype.h>
53:
1.1 root 54: #ifndef ASM_STABS_OP
55: #define ASM_STABS_OP ".stabs"
56: #endif
57:
1.1.1.4 root 58: /* This macro gets just the user-specified name
59: out of the string in a SYMBOL_REF. On most machines,
60: we discard the * if any and that's all. */
61: #ifndef STRIP_NAME_ENCODING
62: #define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
63: (VAR) = ((SYMBOL_NAME) + ((SYMBOL_NAME)[0] == '*'))
64: #endif
65:
1.1 root 66: /* File in which assembler code is being written. */
67:
68: extern FILE *asm_out_file;
69:
70: /* The (assembler) name of the first globally-visible object output. */
71: char *first_global_object_name;
72:
73: extern struct obstack *current_obstack;
74: extern struct obstack *saveable_obstack;
1.1.1.7 root 75: extern struct obstack *rtl_obstack;
1.1 root 76: extern struct obstack permanent_obstack;
77: #define obstack_chunk_alloc xmalloc
78:
79: /* Number for making the label on the next
80: constant that is stored in memory. */
81:
82: int const_labelno;
83:
84: /* Number for making the label on the next
85: static variable internal to a function. */
86:
87: int var_labelno;
88:
1.1.1.6 root 89: /* Carry information from ASM_DECLARE_OBJECT_NAME
90: to ASM_FINISH_DECLARE_OBJECT. */
91:
92: int size_directive_output;
93:
94: /* The last decl for which assemble_variable was called,
95: if it did ASM_DECLARE_OBJECT_NAME.
96: If the last call to assemble_variable didn't do that,
97: this holds 0. */
98:
99: tree last_assemble_variable_decl;
100:
1.1.1.8 root 101:
102: #ifdef HANDLE_PRAGMA_WEAK
103: /* Any weak symbol declarations waiting to be emitted. */
104:
105: struct weak_syms
106: {
107: struct weak_syms *next;
108: char *name;
109: char *value;
110: };
111:
112: static struct weak_syms *weak_decls;
113: #endif
114:
1.1 root 115: /* Nonzero if at least one function definition has been seen. */
116:
1.1.1.8 root 117: static int function_defined;
1.1 root 118:
1.1.1.8 root 119: struct addr_const;
120: struct constant_descriptor;
121: struct rtx_const;
122: struct pool_constant;
123:
124: static void bc_make_decl_rtl PROTO((tree, char *, int));
125: static char *strip_reg_name PROTO((char *));
126: static void bc_output_ascii PROTO((FILE *, char *, int));
127: static int contains_pointers_p PROTO((tree));
128: static void decode_addr_const PROTO((tree, struct addr_const *));
129: static int const_hash PROTO((tree));
130: static int compare_constant PROTO((tree,
131: struct constant_descriptor *));
132: static char *compare_constant_1 PROTO((tree, char *));
133: static struct constant_descriptor *record_constant PROTO((tree));
134: static void record_constant_1 PROTO((tree));
135: static tree copy_constant PROTO((tree));
136: static void output_constant_def_contents PROTO((tree, int, int));
137: static void decode_rtx_const PROTO((enum machine_mode, rtx,
138: struct rtx_const *));
139: static int const_hash_rtx PROTO((enum machine_mode, rtx));
140: static int compare_constant_rtx PROTO((enum machine_mode, rtx,
141: struct constant_descriptor *));
142: static struct constant_descriptor *record_constant_rtx PROTO((enum machine_mode,
143: rtx));
144: static struct pool_constant *find_pool_constant PROTO((rtx));
145: static int output_addressed_constants PROTO((tree));
146: static void bc_assemble_integer PROTO((tree, int));
147: static void output_constructor PROTO((tree, int));
1.1 root 148:
149: #ifdef EXTRA_SECTIONS
1.1.1.7 root 150: static enum in_section {no_section, in_text, in_data, in_named, EXTRA_SECTIONS} in_section
1.1 root 151: = no_section;
152: #else
1.1.1.7 root 153: static enum in_section {no_section, in_text, in_data, in_named} in_section
1.1 root 154: = no_section;
155: #endif
156:
1.1.1.7 root 157: /* Return a non-zero value if DECL has a section attribute. */
158: #define IN_NAMED_SECTION(DECL) \
159: ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
160: && DECL_SECTION_NAME (DECL) != NULL_TREE)
161:
162: /* Text of section name when in_section == in_named. */
163: static char *in_named_name;
164:
1.1 root 165: /* Define functions like text_section for any extra sections. */
166: #ifdef EXTRA_SECTION_FUNCTIONS
167: EXTRA_SECTION_FUNCTIONS
168: #endif
169:
170: /* Tell assembler to switch to text section. */
171:
172: void
173: text_section ()
174: {
175: if (in_section != in_text)
176: {
1.1.1.6 root 177: if (output_bytecode)
178: bc_text ();
179: else
180: fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
181:
1.1 root 182: in_section = in_text;
183: }
184: }
185:
186: /* Tell assembler to switch to data section. */
187:
188: void
189: data_section ()
190: {
191: if (in_section != in_data)
192: {
1.1.1.6 root 193: if (output_bytecode)
194: bc_data ();
195: else
1.1 root 196: {
1.1.1.6 root 197: if (flag_shared_data)
198: {
1.1 root 199: #ifdef SHARED_SECTION_ASM_OP
1.1.1.6 root 200: fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
1.1 root 201: #else
1.1.1.6 root 202: fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
1.1 root 203: #endif
1.1.1.6 root 204: }
205: else
206: fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
1.1 root 207: }
208:
209: in_section = in_data;
210: }
211: }
212:
1.1.1.3 root 213: /* Tell assembler to switch to read-only data section. This is normally
214: the text section. */
215:
216: void
217: readonly_data_section ()
218: {
219: #ifdef READONLY_DATA_SECTION
220: READONLY_DATA_SECTION (); /* Note this can call data_section. */
221: #else
222: text_section ();
223: #endif
224: }
225:
1.1 root 226: /* Determine if we're in the text section. */
227:
228: int
229: in_text_section ()
230: {
231: return in_section == in_text;
232: }
1.1.1.7 root 233:
1.1.1.8 root 234: /* Tell assembler to change to section NAME for DECL.
235: If DECL is NULL, just switch to section NAME.
236: If NAME is NULL, get the name from DECL. */
1.1.1.7 root 237:
238: void
1.1.1.8 root 239: named_section (decl, name)
240: tree decl;
1.1.1.7 root 241: char *name;
242: {
1.1.1.8 root 243: if (decl != NULL_TREE
244: && (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL))
245: abort ();
246: if (name == NULL)
247: name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
248:
1.1.1.7 root 249: if (in_section != in_named || strcmp (name, in_named_name))
250: {
251: in_named_name = name;
252: in_section = in_named;
253:
254: #ifdef ASM_OUTPUT_SECTION_NAME
1.1.1.8 root 255: ASM_OUTPUT_SECTION_NAME (asm_out_file, decl, name);
1.1.1.7 root 256: #else
257: /* Section attributes are not supported if this macro isn't provided -
258: some host formats don't support them at all. The front-end should
259: already have flagged this as an error. */
260: abort ();
261: #endif
262: }
263: }
1.1.1.8 root 264:
265: /* Switch to the section for function DECL.
266:
267: If DECL is NULL_TREE, switch to the text section.
268: ??? It's not clear that we will ever be passed NULL_TREE, but it's
269: safer to handle it. */
270:
271: void
272: function_section (decl)
273: tree decl;
274: {
275: if (decl != NULL_TREE
276: && DECL_SECTION_NAME (decl) != NULL_TREE)
277: named_section (decl, (char *) 0);
278: else
279: text_section ();
280: }
1.1 root 281:
282: /* Create the rtl to represent a function, for a function definition.
283: DECL is a FUNCTION_DECL node which describes which function.
284: The rtl is stored into DECL. */
285:
286: void
287: make_function_rtl (decl)
288: tree decl;
289: {
290: char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
291:
1.1.1.6 root 292: if (output_bytecode)
293: {
294: if (DECL_RTL (decl) == 0)
295: DECL_RTL (decl) = bc_gen_rtx (name, 0, (struct bc_label *) 0);
296:
297: /* Record that at least one function has been defined. */
298: function_defined = 1;
299: return;
300: }
301:
1.1 root 302: /* Rename a nested function to avoid conflicts. */
303: if (decl_function_context (decl) != 0
304: && DECL_INITIAL (decl) != 0
305: && DECL_RTL (decl) == 0)
306: {
307: char *label;
308:
309: name = IDENTIFIER_POINTER (DECL_NAME (decl));
310: ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
311: name = obstack_copy0 (saveable_obstack, label, strlen (label));
312: var_labelno++;
313: }
314:
315: if (DECL_RTL (decl) == 0)
316: {
317: DECL_RTL (decl)
318: = gen_rtx (MEM, DECL_MODE (decl),
319: gen_rtx (SYMBOL_REF, Pmode, name));
320:
321: /* Optionally set flags or add text to the name to record information
322: such as that it is a function name. If the name is changed, the macro
1.1.1.7 root 323: ASM_OUTPUT_LABELREF will have to know how to strip this information. */
1.1 root 324: #ifdef ENCODE_SECTION_INFO
325: ENCODE_SECTION_INFO (decl);
326: #endif
327: }
328:
329: /* Record at least one function has been defined. */
330: function_defined = 1;
331: }
332:
1.1.1.6 root 333: /* Create the DECL_RTL for a declaration for a static or external
334: variable or static or external function.
335: ASMSPEC, if not 0, is the string which the user specified
336: as the assembler symbol name.
337: TOP_LEVEL is nonzero if this is a file-scope variable.
338: This is never called for PARM_DECLs. */
1.1.1.8 root 339:
340: static void
1.1.1.6 root 341: bc_make_decl_rtl (decl, asmspec, top_level)
342: tree decl;
343: char *asmspec;
344: int top_level;
345: {
346: register char *name = TREE_STRING_POINTER (DECL_ASSEMBLER_NAME (decl));
347:
348: if (DECL_RTL (decl) == 0)
349: {
350: /* Print an error message for register variables. */
351: if (DECL_REGISTER (decl) && TREE_CODE (decl) == FUNCTION_DECL)
352: error ("function declared `register'");
353: else if (DECL_REGISTER (decl))
354: error ("global register variables not supported in the interpreter");
355:
356: /* Handle ordinary static variables and functions. */
357: if (DECL_RTL (decl) == 0)
358: {
359: /* Can't use just the variable's own name for a variable
360: whose scope is less than the whole file.
361: Concatenate a distinguishing number. */
362: if (!top_level && !DECL_EXTERNAL (decl) && asmspec == 0)
363: {
364: char *label;
365:
366: ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
367: name = obstack_copy0 (saveable_obstack, label, strlen (label));
368: var_labelno++;
369: }
370:
371: DECL_RTL (decl) = bc_gen_rtx (name, 0, (struct bc_label *) 0);
372: }
373: }
374: }
375:
1.1.1.2 root 376: /* Given NAME, a putative register name, discard any customary prefixes. */
377:
378: static char *
379: strip_reg_name (name)
380: char *name;
381: {
382: #ifdef REGISTER_PREFIX
383: if (!strncmp (name, REGISTER_PREFIX, strlen (REGISTER_PREFIX)))
384: name += strlen (REGISTER_PREFIX);
385: #endif
386: if (name[0] == '%' || name[0] == '#')
387: name++;
388: return name;
389: }
1.1.1.3 root 390:
1.1 root 391: /* Decode an `asm' spec for a declaration as a register name.
392: Return the register number, or -1 if nothing specified,
1.1.1.4 root 393: or -2 if the ASMSPEC is not `cc' or `memory' and is not recognized,
394: or -3 if ASMSPEC is `cc' and is not recognized,
395: or -4 if ASMSPEC is `memory' and is not recognized.
1.1.1.3 root 396: Accept an exact spelling or a decimal number.
397: Prefixes such as % are optional. */
1.1 root 398:
399: int
400: decode_reg_name (asmspec)
401: char *asmspec;
402: {
403: if (asmspec != 0)
404: {
405: int i;
406:
1.1.1.2 root 407: /* Get rid of confusing prefixes. */
408: asmspec = strip_reg_name (asmspec);
409:
1.1 root 410: /* Allow a decimal number as a "register name". */
411: for (i = strlen (asmspec) - 1; i >= 0; i--)
412: if (! (asmspec[i] >= '0' && asmspec[i] <= '9'))
413: break;
414: if (asmspec[0] != 0 && i < 0)
415: {
416: i = atoi (asmspec);
417: if (i < FIRST_PSEUDO_REGISTER && i >= 0)
418: return i;
419: else
420: return -2;
421: }
422:
423: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1.1.1.2 root 424: if (reg_names[i][0]
425: && ! strcmp (asmspec, strip_reg_name (reg_names[i])))
1.1 root 426: return i;
427:
428: #ifdef ADDITIONAL_REGISTER_NAMES
429: {
430: static struct { char *name; int number; } table[]
431: = ADDITIONAL_REGISTER_NAMES;
432:
433: for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
434: if (! strcmp (asmspec, table[i].name))
435: return table[i].number;
436: }
437: #endif /* ADDITIONAL_REGISTER_NAMES */
438:
1.1.1.4 root 439: if (!strcmp (asmspec, "memory"))
440: return -4;
441:
1.1.1.3 root 442: if (!strcmp (asmspec, "cc"))
443: return -3;
444:
1.1 root 445: return -2;
446: }
447:
448: return -1;
449: }
450:
451: /* Create the DECL_RTL for a declaration for a static or external variable
452: or static or external function.
453: ASMSPEC, if not 0, is the string which the user specified
454: as the assembler symbol name.
455: TOP_LEVEL is nonzero if this is a file-scope variable.
456:
457: This is never called for PARM_DECL nodes. */
458:
459: void
460: make_decl_rtl (decl, asmspec, top_level)
461: tree decl;
462: char *asmspec;
463: int top_level;
464: {
1.1.1.7 root 465: register char *name = 0;
1.1.1.6 root 466: int reg_number;
467:
468: if (output_bytecode)
469: {
470: bc_make_decl_rtl (decl, asmspec, top_level);
471: return;
472: }
473:
474: reg_number = decode_reg_name (asmspec);
1.1 root 475:
476: if (DECL_ASSEMBLER_NAME (decl) != NULL_TREE)
477: name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
478:
479: if (reg_number == -2)
480: {
481: /* ASMSPEC is given, and not the name of a register. */
482: name = (char *) obstack_alloc (saveable_obstack,
483: strlen (asmspec) + 2);
484: name[0] = '*';
485: strcpy (&name[1], asmspec);
486: }
487:
488: /* For a duplicate declaration, we can be called twice on the
1.1.1.6 root 489: same DECL node. Don't discard the RTL already made. */
490: if (DECL_RTL (decl) == 0)
1.1 root 491: {
492: DECL_RTL (decl) = 0;
493:
494: /* First detect errors in declaring global registers. */
1.1.1.4 root 495: if (DECL_REGISTER (decl) && reg_number == -1)
1.1 root 496: error_with_decl (decl,
497: "register name not specified for `%s'");
1.1.1.4 root 498: else if (DECL_REGISTER (decl) && reg_number < 0)
1.1 root 499: error_with_decl (decl,
500: "invalid register name for `%s'");
1.1.1.4 root 501: else if ((reg_number >= 0 || reg_number == -3) && ! DECL_REGISTER (decl))
1.1 root 502: error_with_decl (decl,
503: "register name given for non-register variable `%s'");
1.1.1.4 root 504: else if (DECL_REGISTER (decl) && TREE_CODE (decl) == FUNCTION_DECL)
1.1 root 505: error ("function declared `register'");
1.1.1.4 root 506: else if (DECL_REGISTER (decl) && TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
1.1 root 507: error_with_decl (decl, "data type of `%s' isn't suitable for a register");
1.1.1.5 root 508: else if (DECL_REGISTER (decl)
509: && ! HARD_REGNO_MODE_OK (reg_number, TYPE_MODE (TREE_TYPE (decl))))
510: error_with_decl (decl, "register number for `%s' isn't suitable for the data type");
1.1 root 511: /* Now handle properly declared static register variables. */
1.1.1.4 root 512: else if (DECL_REGISTER (decl))
1.1 root 513: {
514: int nregs;
515: #if 0 /* yylex should print the warning for this */
516: if (pedantic)
517: pedwarn ("ANSI C forbids global register variables");
518: #endif
519: if (DECL_INITIAL (decl) != 0 && top_level)
520: {
521: DECL_INITIAL (decl) = 0;
522: error ("global register variable has initial value");
523: }
524: if (fixed_regs[reg_number] == 0
525: && function_defined && top_level)
526: error ("global register variable follows a function definition");
527: if (TREE_THIS_VOLATILE (decl))
528: warning ("volatile register variables don't work as you might wish");
1.1.1.5 root 529:
530: /* If the user specified one of the eliminables registers here,
531: e.g., FRAME_POINTER_REGNUM, we don't want to get this variable
532: confused with that register and be eliminated. Although this
533: usage is somewhat suspect, we nevertheless use the following
534: kludge to avoid setting DECL_RTL to frame_pointer_rtx. */
535:
536: DECL_RTL (decl)
537: = gen_rtx (REG, DECL_MODE (decl), FIRST_PSEUDO_REGISTER);
538: REGNO (DECL_RTL (decl)) = reg_number;
1.1 root 539: REG_USERVAR_P (DECL_RTL (decl)) = 1;
540:
541: if (top_level)
542: {
1.1.1.6 root 543: /* Make this register global, so not usable for anything
544: else. */
1.1 root 545: nregs = HARD_REGNO_NREGS (reg_number, DECL_MODE (decl));
546: while (nregs > 0)
1.1.1.6 root 547: globalize_reg (reg_number + --nregs);
1.1 root 548: }
549: }
1.1.1.7 root 550: /* Specifying a section attribute on an uninitialized variable does not
551: (and cannot) cause it to be put in the given section. The linker
552: can only put initialized objects in specific sections, everything
553: else goes in bss for the linker to sort out later (otherwise the
554: linker would give a duplicate definition error for each compilation
555: unit that behaved thusly). So warn the user. */
556: else if (TREE_CODE (decl) == VAR_DECL
557: && DECL_SECTION_NAME (decl) != NULL_TREE
1.1.1.8 root 558: && DECL_INITIAL (decl) == NULL_TREE
559: && DECL_COMMON (decl)
560: && ! flag_no_common)
1.1.1.7 root 561: {
562: warning_with_decl (decl,
563: "section attribute ignored for uninitialized variable `%s'");
564: /* Remove the section name so subsequent declarations won't see it.
565: We are ignoring it, remember. */
566: DECL_SECTION_NAME (decl) = NULL_TREE;
567: }
1.1 root 568:
569: /* Now handle ordinary static variables and functions (in memory).
570: Also handle vars declared register invalidly. */
571: if (DECL_RTL (decl) == 0)
572: {
573: /* Can't use just the variable's own name for a variable
574: whose scope is less than the whole file.
575: Concatenate a distinguishing number. */
1.1.1.4 root 576: if (!top_level && !DECL_EXTERNAL (decl) && asmspec == 0)
1.1 root 577: {
578: char *label;
579:
580: ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
581: name = obstack_copy0 (saveable_obstack, label, strlen (label));
582: var_labelno++;
583: }
584:
1.1.1.7 root 585: if (name == 0)
586: abort ();
587:
1.1 root 588: DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl),
589: gen_rtx (SYMBOL_REF, Pmode, name));
1.1.1.6 root 590:
591: /* If this variable is to be treated as volatile, show its
592: tree node has side effects. If it has side effects, either
593: because of this test or from TREE_THIS_VOLATILE also
594: being set, show the MEM is volatile. */
595: if (flag_volatile_global && TREE_CODE (decl) == VAR_DECL
596: && TREE_PUBLIC (decl))
597: TREE_SIDE_EFFECTS (decl) = 1;
598: if (TREE_SIDE_EFFECTS (decl))
1.1 root 599: MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
1.1.1.6 root 600:
1.1 root 601: if (TREE_READONLY (decl))
602: RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
603: MEM_IN_STRUCT_P (DECL_RTL (decl))
1.1.1.7 root 604: = AGGREGATE_TYPE_P (TREE_TYPE (decl));
1.1 root 605:
606: /* Optionally set flags or add text to the name to record information
607: such as that it is a function name.
608: If the name is changed, the macro ASM_OUTPUT_LABELREF
1.1.1.7 root 609: will have to know how to strip this information. */
1.1 root 610: #ifdef ENCODE_SECTION_INFO
611: ENCODE_SECTION_INFO (decl);
612: #endif
613: }
614: }
1.1.1.6 root 615: /* If the old RTL had the wrong mode, fix the mode. */
616: else if (GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl))
617: {
618: rtx rtl = DECL_RTL (decl);
619: PUT_MODE (rtl, DECL_MODE (decl));
620: }
1.1 root 621: }
1.1.1.4 root 622:
623: /* Make the rtl for variable VAR be volatile.
624: Use this only for static variables. */
625:
1.1.1.5 root 626: void
1.1.1.4 root 627: make_var_volatile (var)
628: tree var;
629: {
630: if (GET_CODE (DECL_RTL (var)) != MEM)
631: abort ();
632:
633: MEM_VOLATILE_P (DECL_RTL (var)) = 1;
634: }
1.1 root 635:
1.1.1.5 root 636: /* Output alignment directive to align for constant expression EXP. */
637:
638: void
639: assemble_constant_align (exp)
640: tree exp;
641: {
642: int align;
643:
644: /* Align the location counter as required by EXP's data type. */
645: align = TYPE_ALIGN (TREE_TYPE (exp));
646: #ifdef CONSTANT_ALIGNMENT
647: align = CONSTANT_ALIGNMENT (exp, align);
648: #endif
649:
650: if (align > BITS_PER_UNIT)
651: ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
652: }
653:
1.1 root 654: /* Output a string of literal assembler code
655: for an `asm' keyword used between functions. */
656:
657: void
658: assemble_asm (string)
659: tree string;
660: {
1.1.1.6 root 661: if (output_bytecode)
662: {
663: error ("asm statements not allowed in interpreter");
664: return;
665: }
666:
1.1 root 667: app_enable ();
668:
669: if (TREE_CODE (string) == ADDR_EXPR)
670: string = TREE_OPERAND (string, 0);
671:
672: fprintf (asm_out_file, "\t%s\n", TREE_STRING_POINTER (string));
673: }
674:
1.1.1.4 root 675: #if 0 /* This should no longer be needed, because
676: flag_gnu_linker should be 0 on these systems,
677: which should prevent any output
678: if ASM_OUTPUT_CONSTRUCTOR and ASM_OUTPUT_DESTRUCTOR are absent. */
1.1 root 679: #if !(defined(DBX_DEBUGGING_INFO) && !defined(FASCIST_ASSEMBLER))
680: #ifndef ASM_OUTPUT_CONSTRUCTOR
681: #define ASM_OUTPUT_CONSTRUCTOR(file, name)
682: #endif
683: #ifndef ASM_OUTPUT_DESTRUCTOR
684: #define ASM_OUTPUT_DESTRUCTOR(file, name)
685: #endif
686: #endif
1.1.1.4 root 687: #endif /* 0 */
1.1 root 688:
689: /* Record an element in the table of global destructors.
690: How this is done depends on what sort of assembler and linker
691: are in use.
692:
693: NAME should be the name of a global function to be called
694: at exit time. This name is output using assemble_name. */
695:
696: void
697: assemble_destructor (name)
698: char *name;
699: {
700: #ifdef ASM_OUTPUT_DESTRUCTOR
701: ASM_OUTPUT_DESTRUCTOR (asm_out_file, name);
702: #else
703: if (flag_gnu_linker)
704: {
705: /* Now tell GNU LD that this is part of the static destructor set. */
706: /* This code works for any machine provided you use GNU as/ld. */
707: fprintf (asm_out_file, "%s \"___DTOR_LIST__\",22,0,0,", ASM_STABS_OP);
708: assemble_name (asm_out_file, name);
709: fputc ('\n', asm_out_file);
710: }
711: #endif
712: }
713:
714: /* Likewise for global constructors. */
715:
716: void
717: assemble_constructor (name)
718: char *name;
719: {
720: #ifdef ASM_OUTPUT_CONSTRUCTOR
721: ASM_OUTPUT_CONSTRUCTOR (asm_out_file, name);
722: #else
723: if (flag_gnu_linker)
724: {
725: /* Now tell GNU LD that this is part of the static constructor set. */
726: /* This code works for any machine provided you use GNU as/ld. */
727: fprintf (asm_out_file, "%s \"___CTOR_LIST__\",22,0,0,", ASM_STABS_OP);
728: assemble_name (asm_out_file, name);
729: fputc ('\n', asm_out_file);
730: }
731: #endif
732: }
733:
734: /* Likewise for entries we want to record for garbage collection.
735: Garbage collection is still under development. */
736:
737: void
738: assemble_gc_entry (name)
739: char *name;
740: {
741: #ifdef ASM_OUTPUT_GC_ENTRY
742: ASM_OUTPUT_GC_ENTRY (asm_out_file, name);
743: #else
744: if (flag_gnu_linker)
745: {
746: /* Now tell GNU LD that this is part of the static constructor set. */
747: fprintf (asm_out_file, "%s \"___PTR_LIST__\",22,0,0,", ASM_STABS_OP);
748: assemble_name (asm_out_file, name);
749: fputc ('\n', asm_out_file);
750: }
751: #endif
752: }
753:
754: /* Output assembler code for the constant pool of a function and associated
755: with defining the name of the function. DECL describes the function.
756: NAME is the function's name. For the constant pool, we use the current
757: constant pool data. */
758:
759: void
760: assemble_start_function (decl, fnname)
761: tree decl;
762: char *fnname;
763: {
764: int align;
765:
766: /* The following code does not need preprocessing in the assembler. */
767:
768: app_disable ();
769:
770: output_constant_pool (fnname, decl);
771:
1.1.1.8 root 772: function_section (decl);
1.1 root 773:
774: /* Tell assembler to move to target machine's alignment for functions. */
775: align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
776: if (align > 0)
1.1.1.6 root 777: {
778: if (output_bytecode)
779: BC_OUTPUT_ALIGN (asm_out_file, align);
780: else
781: ASM_OUTPUT_ALIGN (asm_out_file, align);
782: }
1.1 root 783:
784: #ifdef ASM_OUTPUT_FUNCTION_PREFIX
785: ASM_OUTPUT_FUNCTION_PREFIX (asm_out_file, fnname);
786: #endif
787:
788: #ifdef SDB_DEBUGGING_INFO
789: /* Output SDB definition of the function. */
790: if (write_symbols == SDB_DEBUG)
791: sdbout_mark_begin_function ();
792: #endif
793:
794: #ifdef DBX_DEBUGGING_INFO
1.1.1.2 root 795: /* Output DBX definition of the function. */
1.1 root 796: if (write_symbols == DBX_DEBUG)
1.1.1.2 root 797: dbxout_begin_function (decl);
1.1 root 798: #endif
799:
800: /* Make function name accessible from other files, if appropriate. */
801:
802: if (TREE_PUBLIC (decl))
803: {
804: if (!first_global_object_name)
1.1.1.8 root 805: {
806: char *p;
807:
808: STRIP_NAME_ENCODING (p, fnname);
809: first_global_object_name = permalloc (strlen (p) + 1);
810: strcpy (first_global_object_name, p);
811: }
812:
813: #ifdef ASM_WEAKEN_LABEL
814: if (DECL_WEAK (decl))
815: ASM_WEAKEN_LABEL (asm_out_file, fnname);
816: else
817: #endif
1.1.1.6 root 818: if (output_bytecode)
819: BC_GLOBALIZE_LABEL (asm_out_file, fnname);
820: else
821: ASM_GLOBALIZE_LABEL (asm_out_file, fnname);
1.1 root 822: }
823:
824: /* Do any machine/system dependent processing of the function name */
825: #ifdef ASM_DECLARE_FUNCTION_NAME
826: ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl);
827: #else
828: /* Standard thing is just output label for the function. */
1.1.1.6 root 829: if (output_bytecode)
830: BC_OUTPUT_LABEL (asm_out_file, fnname);
831: else
832: ASM_OUTPUT_LABEL (asm_out_file, fnname);
1.1 root 833: #endif /* ASM_DECLARE_FUNCTION_NAME */
834: }
835:
836: /* Output assembler code associated with defining the size of the
837: function. DECL describes the function. NAME is the function's name. */
838:
839: void
840: assemble_end_function (decl, fnname)
841: tree decl;
842: char *fnname;
843: {
844: #ifdef ASM_DECLARE_FUNCTION_SIZE
845: ASM_DECLARE_FUNCTION_SIZE (asm_out_file, fnname, decl);
846: #endif
847: }
848:
849: /* Assemble code to leave SIZE bytes of zeros. */
850:
851: void
852: assemble_zeros (size)
853: int size;
854: {
1.1.1.6 root 855: if (output_bytecode)
856: {
857: bc_emit_const_skip (size);
858: return;
859: }
860:
1.1 root 861: #ifdef ASM_NO_SKIP_IN_TEXT
862: /* The `space' pseudo in the text section outputs nop insns rather than 0s,
863: so we must output 0s explicitly in the text section. */
864: if (ASM_NO_SKIP_IN_TEXT && in_text_section ())
865: {
866: int i;
867:
868: for (i = 0; i < size - 20; i += 20)
869: {
870: #ifdef ASM_BYTE_OP
871: fprintf (asm_out_file,
872: "%s 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n", ASM_BYTE_OP);
873: #else
874: fprintf (asm_out_file,
875: "\tbyte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n");
876: #endif
877: }
878: if (i < size)
879: {
880: #ifdef ASM_BYTE_OP
881: fprintf (asm_out_file, "%s 0", ASM_BYTE_OP);
882: #else
883: fprintf (asm_out_file, "\tbyte 0");
884: #endif
885: i++;
886: for (; i < size; i++)
887: fprintf (asm_out_file, ",0");
888: fprintf (asm_out_file, "\n");
889: }
890: }
891: else
892: #endif
1.1.1.5 root 893: if (size > 0)
1.1.1.6 root 894: {
895: if (output_bytecode)
896: BC_OUTPUT_SKIP (asm_out_file, size);
897: else
898: ASM_OUTPUT_SKIP (asm_out_file, size);
899: }
900: }
901:
902: /* Assemble an alignment pseudo op for an ALIGN-bit boundary. */
903:
904: void
905: assemble_align (align)
906: int align;
907: {
908: if (align > BITS_PER_UNIT)
909: ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
1.1 root 910: }
911:
912: /* Assemble a string constant with the specified C string as contents. */
913:
914: void
915: assemble_string (p, size)
1.1.1.5 root 916: char *p;
1.1 root 917: int size;
918: {
919: register int i;
920: int pos = 0;
921: int maximum = 2000;
922:
1.1.1.6 root 923: if (output_bytecode)
924: {
925: bc_emit (p, size);
926: return;
927: }
928:
1.1 root 929: /* If the string is very long, split it up. */
930:
931: while (pos < size)
932: {
933: int thissize = size - pos;
934: if (thissize > maximum)
935: thissize = maximum;
936:
1.1.1.6 root 937: if (output_bytecode)
938: bc_output_ascii (asm_out_file, p, thissize);
939: else
940: {
941: ASM_OUTPUT_ASCII (asm_out_file, p, thissize);
942: }
1.1 root 943:
944: pos += thissize;
945: p += thissize;
946: }
947: }
1.1.1.6 root 948:
949: static void
950: bc_output_ascii (file, p, size)
951: FILE *file;
952: char *p;
953: int size;
954: {
955: BC_OUTPUT_ASCII (file, p, size);
956: }
1.1 root 957:
958: /* Assemble everything that is needed for a variable or function declaration.
959: Not used for automatic variables, and not used for function definitions.
960: Should not be called for variables of incomplete structure type.
961:
962: TOP_LEVEL is nonzero if this variable has file scope.
963: AT_END is nonzero if this is the special handling, at end of compilation,
1.1.1.6 root 964: to define things that have had only tentative definitions.
965: DONT_OUTPUT_DATA if nonzero means don't actually output the
966: initial value (that will be done by the caller). */
1.1 root 967:
968: void
1.1.1.6 root 969: assemble_variable (decl, top_level, at_end, dont_output_data)
1.1 root 970: tree decl;
971: int top_level;
972: int at_end;
1.1.1.8 root 973: int dont_output_data;
1.1 root 974: {
975: register char *name;
976: int align;
977: tree size_tree;
978: int reloc = 0;
1.1.1.6 root 979: enum in_section saved_in_section;
980:
981: last_assemble_variable_decl = 0;
982:
983: if (output_bytecode)
984: return;
1.1 root 985:
986: if (GET_CODE (DECL_RTL (decl)) == REG)
987: {
988: /* Do output symbol info for global register variables, but do nothing
989: else for them. */
990:
991: if (TREE_ASM_WRITTEN (decl))
992: return;
993: TREE_ASM_WRITTEN (decl) = 1;
994:
1.1.1.6 root 995: if (!output_bytecode)
996: {
1.1.1.2 root 997: #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
1.1.1.6 root 998: /* File-scope global variables are output here. */
999: if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
1000: && top_level)
1001: dbxout_symbol (decl, 0);
1.1 root 1002: #endif
1003: #ifdef SDB_DEBUGGING_INFO
1.1.1.6 root 1004: if (write_symbols == SDB_DEBUG && top_level
1005: /* Leave initialized global vars for end of compilation;
1006: see comment in compile_file. */
1007: && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0))
1008: sdbout_symbol (decl, 0);
1.1 root 1009: #endif
1.1.1.6 root 1010: }
1.1 root 1011:
1012: /* Don't output any DWARF debugging information for variables here.
1013: In the case of local variables, the information for them is output
1014: when we do our recursive traversal of the tree representation for
1015: the entire containing function. In the case of file-scope variables,
1016: we output information for all of them at the very end of compilation
1017: while we are doing our final traversal of the chain of file-scope
1018: declarations. */
1019:
1020: return;
1021: }
1022:
1.1.1.5 root 1023: /* Normally no need to say anything here for external references,
1.1.1.8 root 1024: since assemble_external is called by the language-specific code
1.1.1.5 root 1025: when a declaration is first seen. */
1.1 root 1026:
1.1.1.4 root 1027: if (DECL_EXTERNAL (decl))
1.1 root 1028: return;
1029:
1030: /* Output no assembler code for a function declaration.
1031: Only definitions of functions output anything. */
1032:
1033: if (TREE_CODE (decl) == FUNCTION_DECL)
1034: return;
1035:
1036: /* If type was incomplete when the variable was declared,
1037: see if it is complete now. */
1038:
1039: if (DECL_SIZE (decl) == 0)
1040: layout_decl (decl, 0);
1041:
1042: /* Still incomplete => don't allocate it; treat the tentative defn
1043: (which is what it must have been) as an `extern' reference. */
1044:
1.1.1.6 root 1045: if (!dont_output_data && DECL_SIZE (decl) == 0)
1.1 root 1046: {
1047: error_with_file_and_line (DECL_SOURCE_FILE (decl),
1048: DECL_SOURCE_LINE (decl),
1.1.1.4 root 1049: "storage size of `%s' isn't known",
1.1 root 1050: IDENTIFIER_POINTER (DECL_NAME (decl)));
1.1.1.7 root 1051: TREE_ASM_WRITTEN (decl) = 1;
1.1 root 1052: return;
1053: }
1054:
1055: /* The first declaration of a variable that comes through this function
1056: decides whether it is global (in C, has external linkage)
1057: or local (in C, has internal linkage). So do nothing more
1058: if this function has already run. */
1059:
1060: if (TREE_ASM_WRITTEN (decl))
1061: return;
1062:
1063: TREE_ASM_WRITTEN (decl) = 1;
1064:
1.1.1.8 root 1065: app_disable ();
1.1 root 1066:
1.1.1.8 root 1067: if (! dont_output_data)
1.1.1.6 root 1068: {
1069: if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
1070: goto finish;
1.1 root 1071:
1.1.1.6 root 1072: /* This is better than explicit arithmetic, since it avoids overflow. */
1073: size_tree = size_binop (CEIL_DIV_EXPR,
1.1.1.8 root 1074: DECL_SIZE (decl), size_int (BITS_PER_UNIT));
1.1 root 1075:
1.1.1.6 root 1076: if (TREE_INT_CST_HIGH (size_tree) != 0)
1077: {
1078: error_with_decl (decl, "size of variable `%s' is too large");
1079: goto finish;
1080: }
1.1 root 1081: }
1082:
1083: name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
1084:
1085: /* Handle uninitialized definitions. */
1086:
1087: /* ANSI specifies that a tentative definition which is not merged with
1088: a non-tentative definition behaves exactly like a definition with an
1089: initializer equal to zero. (Section 3.7.2)
1.1.1.6 root 1090: -fno-common gives strict ANSI behavior. Usually you don't want it.
1091: This matters only for variables with external linkage. */
1092: if ((! flag_no_common || ! TREE_PUBLIC (decl))
1.1.1.7 root 1093: && DECL_COMMON (decl)
1.1.1.6 root 1094: && ! dont_output_data
1.1 root 1095: && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
1096: {
1097: int size = TREE_INT_CST_LOW (size_tree);
1098: int rounded = size;
1099:
1100: if (TREE_INT_CST_HIGH (size_tree) != 0)
1101: error_with_decl (decl, "size of variable `%s' is too large");
1102: /* Don't allocate zero bytes of common,
1103: since that means "undefined external" in the linker. */
1104: if (size == 0) rounded = 1;
1105: /* Round size up to multiple of BIGGEST_ALIGNMENT bits
1106: so that each uninitialized object starts on such a boundary. */
1107: rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
1108: rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1109: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
1.1.1.6 root 1110:
1111: #ifdef DBX_DEBUGGING_INFO
1112: /* File-scope global variables are output here. */
1113: if (write_symbols == DBX_DEBUG && top_level)
1114: dbxout_symbol (decl, 0);
1115: #endif
1116: #ifdef SDB_DEBUGGING_INFO
1117: if (write_symbols == SDB_DEBUG && top_level
1118: /* Leave initialized global vars for end of compilation;
1119: see comment in compile_file. */
1120: && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0))
1121: sdbout_symbol (decl, 0);
1122: #endif
1123:
1124: /* Don't output any DWARF debugging information for variables here.
1125: In the case of local variables, the information for them is output
1126: when we do our recursive traversal of the tree representation for
1127: the entire containing function. In the case of file-scope variables,
1128: we output information for all of them at the very end of compilation
1129: while we are doing our final traversal of the chain of file-scope
1130: declarations. */
1131:
1.1 root 1132: #if 0
1133: if (flag_shared_data)
1134: data_section ();
1135: #endif
1136: if (TREE_PUBLIC (decl))
1137: {
1138: #ifdef ASM_OUTPUT_SHARED_COMMON
1139: if (flag_shared_data)
1140: ASM_OUTPUT_SHARED_COMMON (asm_out_file, name, size, rounded);
1141: else
1142: #endif
1.1.1.6 root 1143: if (output_bytecode)
1144: {
1145: BC_OUTPUT_COMMON (asm_out_file, name, size, rounded);
1146: }
1147: else
1148: {
1.1 root 1149: #ifdef ASM_OUTPUT_ALIGNED_COMMON
1.1.1.6 root 1150: ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size,
1151: DECL_ALIGN (decl));
1.1 root 1152: #else
1.1.1.6 root 1153: ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
1.1 root 1154: #endif
1.1.1.6 root 1155: }
1.1 root 1156: }
1157: else
1158: {
1159: #ifdef ASM_OUTPUT_SHARED_LOCAL
1160: if (flag_shared_data)
1161: ASM_OUTPUT_SHARED_LOCAL (asm_out_file, name, size, rounded);
1162: else
1163: #endif
1.1.1.6 root 1164: if (output_bytecode)
1165: {
1166: BC_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
1167: }
1168: else
1169: {
1.1 root 1170: #ifdef ASM_OUTPUT_ALIGNED_LOCAL
1.1.1.6 root 1171: ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,
1172: DECL_ALIGN (decl));
1.1 root 1173: #else
1.1.1.6 root 1174: ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
1.1 root 1175: #endif
1.1.1.6 root 1176: }
1.1 root 1177: }
1.1.1.2 root 1178: goto finish;
1.1 root 1179: }
1180:
1181: /* Handle initialized definitions. */
1182:
1183: /* First make the assembler name(s) global if appropriate. */
1184: if (TREE_PUBLIC (decl) && DECL_NAME (decl))
1185: {
1186: if (!first_global_object_name)
1.1.1.8 root 1187: {
1188: char *p;
1189:
1190: STRIP_NAME_ENCODING (p, name);
1191: first_global_object_name = permalloc (strlen (p) + 1);
1192: strcpy (first_global_object_name, p);
1193: }
1194:
1195: #ifdef ASM_WEAKEN_LABEL
1196: if (DECL_WEAK (decl))
1197: ASM_WEAKEN_LABEL (asm_out_file, name);
1198: else
1199: #endif
1.1 root 1200: ASM_GLOBALIZE_LABEL (asm_out_file, name);
1201: }
1202: #if 0
1203: for (d = equivalents; d; d = TREE_CHAIN (d))
1204: {
1205: tree e = TREE_VALUE (d);
1206: if (TREE_PUBLIC (e) && DECL_NAME (e))
1207: ASM_GLOBALIZE_LABEL (asm_out_file,
1208: XSTR (XEXP (DECL_RTL (e), 0), 0));
1209: }
1210: #endif
1211:
1212: /* Output any data that we will need to use the address of. */
1.1.1.6 root 1213: if (DECL_INITIAL (decl) == error_mark_node)
1214: reloc = contains_pointers_p (TREE_TYPE (decl));
1215: else if (DECL_INITIAL (decl))
1.1 root 1216: reloc = output_addressed_constants (DECL_INITIAL (decl));
1217:
1218: /* Switch to the proper section for this data. */
1.1.1.7 root 1219: if (IN_NAMED_SECTION (decl))
1.1.1.8 root 1220: named_section (decl, NULL);
1.1.1.7 root 1221: else
1222: {
1223: /* C++ can have const variables that get initialized from constructors,
1224: and thus can not be in a readonly section. We prevent this by
1225: verifying that the initial value is constant for objects put in a
1226: readonly section.
1227:
1228: error_mark_node is used by the C front end to indicate that the
1229: initializer has not been seen yet. In this case, we assume that
1230: the initializer must be constant. */
1.1 root 1231: #ifdef SELECT_SECTION
1.1.1.7 root 1232: SELECT_SECTION (decl, reloc);
1.1 root 1233: #else
1.1.1.7 root 1234: if (TREE_READONLY (decl)
1235: && ! TREE_THIS_VOLATILE (decl)
1236: && DECL_INITIAL (decl)
1237: && (DECL_INITIAL (decl) == error_mark_node
1238: || TREE_CONSTANT (DECL_INITIAL (decl)))
1239: && ! (flag_pic && reloc))
1240: readonly_data_section ();
1241: else
1242: data_section ();
1.1 root 1243: #endif
1.1.1.7 root 1244: }
1.1 root 1245:
1.1.1.6 root 1246: /* dbxout.c needs to know this. */
1247: if (in_text_section ())
1248: DECL_IN_TEXT_SECTION (decl) = 1;
1249:
1250: /* Record current section so we can restore it if dbxout.c clobbers it. */
1251: saved_in_section = in_section;
1252:
1253: /* Output the dbx info now that we have chosen the section. */
1254:
1255: #ifdef DBX_DEBUGGING_INFO
1256: /* File-scope global variables are output here. */
1257: if (write_symbols == DBX_DEBUG && top_level)
1258: dbxout_symbol (decl, 0);
1259: #endif
1260: #ifdef SDB_DEBUGGING_INFO
1261: if (write_symbols == SDB_DEBUG && top_level
1262: /* Leave initialized global vars for end of compilation;
1263: see comment in compile_file. */
1264: && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0))
1265: sdbout_symbol (decl, 0);
1266: #endif
1267:
1268: /* Don't output any DWARF debugging information for variables here.
1269: In the case of local variables, the information for them is output
1270: when we do our recursive traversal of the tree representation for
1271: the entire containing function. In the case of file-scope variables,
1272: we output information for all of them at the very end of compilation
1273: while we are doing our final traversal of the chain of file-scope
1274: declarations. */
1275:
1276: /* If the debugging output changed sections, reselect the section
1277: that's supposed to be selected. */
1278: if (in_section != saved_in_section)
1279: {
1280: /* Switch to the proper section for this data. */
1281: #ifdef SELECT_SECTION
1282: SELECT_SECTION (decl, reloc);
1283: #else
1284: if (TREE_READONLY (decl)
1285: && ! TREE_THIS_VOLATILE (decl)
1.1.1.7 root 1286: && DECL_INITIAL (decl)
1287: && (DECL_INITIAL (decl) == error_mark_node
1288: || TREE_CONSTANT (DECL_INITIAL (decl)))
1.1.1.6 root 1289: && ! (flag_pic && reloc))
1290: readonly_data_section ();
1291: else
1292: data_section ();
1293: #endif
1294: }
1295:
1.1 root 1296: /* Compute and output the alignment of this data. */
1297:
1298: align = DECL_ALIGN (decl);
1.1.1.6 root 1299: /* In the case for initialing an array whose length isn't specified,
1300: where we have not yet been able to do the layout,
1301: figure out the proper alignment now. */
1302: if (dont_output_data && DECL_SIZE (decl) == 0
1303: && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1304: align = MAX (align, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl))));
1305:
1.1 root 1306: /* Some object file formats have a maximum alignment which they support.
1307: In particular, a.out format supports a maximum alignment of 4. */
1308: #ifndef MAX_OFILE_ALIGNMENT
1309: #define MAX_OFILE_ALIGNMENT BIGGEST_ALIGNMENT
1310: #endif
1311: if (align > MAX_OFILE_ALIGNMENT)
1312: {
1313: warning_with_decl (decl,
1314: "alignment of `%s' is greater than maximum object file alignment");
1315: align = MAX_OFILE_ALIGNMENT;
1316: }
1317: #ifdef DATA_ALIGNMENT
1318: /* On some machines, it is good to increase alignment sometimes. */
1319: align = DATA_ALIGNMENT (TREE_TYPE (decl), align);
1320: #endif
1321: #ifdef CONSTANT_ALIGNMENT
1322: if (DECL_INITIAL (decl))
1323: align = CONSTANT_ALIGNMENT (DECL_INITIAL (decl), align);
1324: #endif
1325:
1326: /* Reset the alignment in case we have made it tighter, so we can benefit
1327: from it in get_pointer_alignment. */
1328: DECL_ALIGN (decl) = align;
1329:
1330: if (align > BITS_PER_UNIT)
1.1.1.6 root 1331: {
1332: if (output_bytecode)
1333: BC_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
1334: else
1335: ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
1336: }
1.1 root 1337:
1338: /* Do any machine/system dependent processing of the object. */
1339: #ifdef ASM_DECLARE_OBJECT_NAME
1.1.1.6 root 1340: last_assemble_variable_decl = decl;
1.1 root 1341: ASM_DECLARE_OBJECT_NAME (asm_out_file, name, decl);
1342: #else
1343: /* Standard thing is just output label for the object. */
1.1.1.6 root 1344: if (output_bytecode)
1345: BC_OUTPUT_LABEL (asm_out_file, name);
1346: else
1347: ASM_OUTPUT_LABEL (asm_out_file, name);
1.1 root 1348: #endif /* ASM_DECLARE_OBJECT_NAME */
1349:
1.1.1.6 root 1350: if (!dont_output_data)
1.1 root 1351: {
1.1.1.6 root 1352: if (DECL_INITIAL (decl))
1353: /* Output the actual data. */
1.1.1.8 root 1354: output_constant (DECL_INITIAL (decl), TREE_INT_CST_LOW (size_tree));
1.1.1.6 root 1355: else
1356: /* Leave space for it. */
1.1.1.8 root 1357: assemble_zeros (TREE_INT_CST_LOW (size_tree));
1.1 root 1358: }
1.1.1.2 root 1359:
1360: finish:
1361: #ifdef XCOFF_DEBUGGING_INFO
1362: /* Unfortunately, the IBM assembler cannot handle stabx before the actual
1363: declaration. When something like ".stabx "aa:S-2",aa,133,0" is emitted
1364: and `aa' hasn't been output yet, the assembler generates a stab entry with
1365: a value of zero, in addition to creating an unnecessary external entry
1.1.1.3 root 1366: for `aa'. Hence, we must postpone dbxout_symbol to here at the end. */
1.1.1.2 root 1367:
1368: /* File-scope global variables are output here. */
1369: if (write_symbols == XCOFF_DEBUG && top_level)
1.1.1.6 root 1370: {
1371: saved_in_section = in_section;
1372:
1373: dbxout_symbol (decl, 0);
1374:
1375: if (in_section != saved_in_section)
1376: {
1377: /* Switch to the proper section for this data. */
1378: #ifdef SELECT_SECTION
1379: SELECT_SECTION (decl, reloc);
1380: #else
1381: if (TREE_READONLY (decl)
1382: && ! TREE_THIS_VOLATILE (decl)
1.1.1.7 root 1383: && DECL_INITIAL (decl)
1384: && (DECL_INITIAL (decl) == error_mark_node
1385: || TREE_CONSTANT (DECL_INITIAL (decl)))
1.1.1.6 root 1386: && ! (flag_pic && reloc))
1387: readonly_data_section ();
1388: else
1389: data_section ();
1390: #endif
1391: }
1392: }
1.1.1.2 root 1393: #else
1394: /* There must be a statement after a label. */
1395: ;
1396: #endif
1.1 root 1397: }
1398:
1.1.1.6 root 1399: /* Return 1 if type TYPE contains any pointers. */
1400:
1401: static int
1402: contains_pointers_p (type)
1403: tree type;
1404: {
1405: switch (TREE_CODE (type))
1406: {
1407: case POINTER_TYPE:
1408: case REFERENCE_TYPE:
1409: /* I'm not sure whether OFFSET_TYPE needs this treatment,
1410: so I'll play safe and return 1. */
1411: case OFFSET_TYPE:
1412: return 1;
1413:
1414: case RECORD_TYPE:
1415: case UNION_TYPE:
1416: case QUAL_UNION_TYPE:
1417: {
1418: tree fields;
1419: /* For a type that has fields, see if the fields have pointers. */
1420: for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
1.1.1.7 root 1421: if (TREE_CODE (fields) == FIELD_DECL
1422: && contains_pointers_p (TREE_TYPE (fields)))
1.1.1.6 root 1423: return 1;
1424: return 0;
1425: }
1426:
1427: case ARRAY_TYPE:
1428: /* An array type contains pointers if its element type does. */
1429: return contains_pointers_p (TREE_TYPE (type));
1430:
1431: default:
1432: return 0;
1433: }
1434: }
1435:
1.1.1.7 root 1436: /* Output text storage for constructor CONSTR. */
1.1.1.6 root 1437:
1.1.1.7 root 1438: void
1.1.1.8 root 1439: bc_output_constructor (constr, size)
1440: tree constr;
1441: int size;
1.1.1.6 root 1442: {
1443: int i;
1444:
1445: /* Must always be a literal; non-literal constructors are handled
1446: differently. */
1447:
1448: if (!TREE_CONSTANT (constr))
1449: abort ();
1450:
1451: /* Always const */
1452: text_section ();
1453:
1454: /* Align */
1.1.1.8 root 1455: for (i = 0; TYPE_ALIGN (constr) >= BITS_PER_UNIT << (i + 1); i++)
1456: ;
1457:
1.1.1.6 root 1458: if (i > 0)
1459: BC_OUTPUT_ALIGN (asm_out_file, i);
1460:
1461: /* Output data */
1.1.1.8 root 1462: output_constant (constr, size);
1.1.1.6 root 1463: }
1464:
1465: /* Create storage for constructor CONSTR. */
1466:
1467: void
1468: bc_output_data_constructor (constr)
1469: tree constr;
1470: {
1471: int i;
1472:
1473: /* Put in data section */
1474: data_section ();
1475:
1476: /* Align */
1477: for (i = 0; TYPE_ALIGN (constr) >= BITS_PER_UNIT << (i + 1); i++);
1478: if (i > 0)
1479: BC_OUTPUT_ALIGN (asm_out_file, i);
1480:
1481: /* The constructor is filled in at runtime. */
1482: BC_OUTPUT_SKIP (asm_out_file, int_size_in_bytes (TREE_TYPE (constr)));
1483: }
1484:
1.1 root 1485: /* Output something to declare an external symbol to the assembler.
1486: (Most assemblers don't need this, so we normally output nothing.)
1487: Do nothing if DECL is not external. */
1488:
1489: void
1490: assemble_external (decl)
1491: tree decl;
1492: {
1.1.1.6 root 1493: if (output_bytecode)
1494: return;
1495:
1.1 root 1496: #ifdef ASM_OUTPUT_EXTERNAL
1497: if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd'
1.1.1.4 root 1498: && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
1.1 root 1499: {
1500: rtx rtl = DECL_RTL (decl);
1501:
1502: if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
1503: && ! SYMBOL_REF_USED (XEXP (rtl, 0)))
1504: {
1505: /* Some systems do require some output. */
1506: SYMBOL_REF_USED (XEXP (rtl, 0)) = 1;
1507: ASM_OUTPUT_EXTERNAL (asm_out_file, decl, XSTR (XEXP (rtl, 0), 0));
1508: }
1509: }
1510: #endif
1511: }
1512:
1513: /* Similar, for calling a library function FUN. */
1514:
1515: void
1516: assemble_external_libcall (fun)
1517: rtx fun;
1518: {
1519: #ifdef ASM_OUTPUT_EXTERNAL_LIBCALL
1.1.1.6 root 1520: if (!output_bytecode)
1.1 root 1521: {
1.1.1.6 root 1522: /* Declare library function name external when first used, if nec. */
1523: if (! SYMBOL_REF_USED (fun))
1524: {
1525: SYMBOL_REF_USED (fun) = 1;
1526: ASM_OUTPUT_EXTERNAL_LIBCALL (asm_out_file, fun);
1527: }
1.1 root 1528: }
1529: #endif
1530: }
1531:
1532: /* Declare the label NAME global. */
1533:
1534: void
1535: assemble_global (name)
1536: char *name;
1537: {
1538: ASM_GLOBALIZE_LABEL (asm_out_file, name);
1539: }
1540:
1541: /* Assemble a label named NAME. */
1542:
1543: void
1544: assemble_label (name)
1545: char *name;
1546: {
1.1.1.6 root 1547: if (output_bytecode)
1548: BC_OUTPUT_LABEL (asm_out_file, name);
1549: else
1550: ASM_OUTPUT_LABEL (asm_out_file, name);
1.1 root 1551: }
1552:
1553: /* Output to FILE a reference to the assembler name of a C-level name NAME.
1554: If NAME starts with a *, the rest of NAME is output verbatim.
1555: Otherwise NAME is transformed in an implementation-defined way
1556: (usually by the addition of an underscore).
1557: Many macros in the tm file are defined to call this function. */
1558:
1559: void
1560: assemble_name (file, name)
1561: FILE *file;
1562: char *name;
1563: {
1.1.1.7 root 1564: char *real_name;
1.1.1.8 root 1565: int save_warn_id_clash = warn_id_clash;
1.1.1.7 root 1566:
1567: STRIP_NAME_ENCODING (real_name, name);
1.1.1.8 root 1568:
1569: /* Don't warn about an identifier name length clash on this name, since
1570: it can be a user symbol suffixed by a number. */
1571: warn_id_clash = 0;
1.1.1.7 root 1572: TREE_SYMBOL_REFERENCED (get_identifier (real_name)) = 1;
1.1.1.8 root 1573: warn_id_clash = save_warn_id_clash;
1.1.1.7 root 1574:
1.1 root 1575: if (name[0] == '*')
1.1.1.6 root 1576: {
1577: if (output_bytecode)
1.1.1.8 root 1578: bc_emit_labelref (name, 0);
1.1.1.6 root 1579: else
1580: fputs (&name[1], file);
1581: }
1.1 root 1582: else
1.1.1.6 root 1583: {
1584: if (output_bytecode)
1585: BC_OUTPUT_LABELREF (file, name);
1586: else
1587: ASM_OUTPUT_LABELREF (file, name);
1588: }
1.1 root 1589: }
1590:
1591: /* Allocate SIZE bytes writable static space with a gensym name
1592: and return an RTX to refer to its address. */
1593:
1594: rtx
1595: assemble_static_space (size)
1596: int size;
1597: {
1598: char name[12];
1599: char *namestring;
1600: rtx x;
1601: /* Round size up to multiple of BIGGEST_ALIGNMENT bits
1602: so that each uninitialized object starts on such a boundary. */
1603: int rounded = ((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
1604: / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1605: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
1606:
1607: #if 0
1608: if (flag_shared_data)
1609: data_section ();
1610: #endif
1611:
1612: ASM_GENERATE_INTERNAL_LABEL (name, "LF", const_labelno);
1613: ++const_labelno;
1614:
1615: namestring = (char *) obstack_alloc (saveable_obstack,
1616: strlen (name) + 2);
1617: strcpy (namestring, name);
1618:
1.1.1.6 root 1619: if (output_bytecode)
1620: x = bc_gen_rtx (namestring, 0, (struct bc_label *) 0);
1621: else
1622: x = gen_rtx (SYMBOL_REF, Pmode, namestring);
1623:
1624: if (output_bytecode)
1625: {
1626: BC_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
1627: }
1628: else
1629: {
1.1 root 1630: #ifdef ASM_OUTPUT_ALIGNED_LOCAL
1.1.1.6 root 1631: ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, BIGGEST_ALIGNMENT);
1.1 root 1632: #else
1.1.1.6 root 1633: ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
1.1 root 1634: #endif
1.1.1.6 root 1635: }
1.1 root 1636: return x;
1637: }
1638:
1639: /* Assemble the static constant template for function entry trampolines.
1640: This is done at most once per compilation.
1641: Returns an RTX for the address of the template. */
1642:
1.1.1.9 ! root 1643: #ifdef TRAMPOLINE_TEMPLATE
1.1 root 1644: rtx
1645: assemble_trampoline_template ()
1646: {
1647: char label[256];
1648: char *name;
1649: int align;
1650:
1.1.1.6 root 1651: /* Shouldn't get here */
1652: if (output_bytecode)
1653: abort ();
1654:
1.1.1.4 root 1655: /* By default, put trampoline templates in read-only data section. */
1656:
1657: #ifdef TRAMPOLINE_SECTION
1658: TRAMPOLINE_SECTION ();
1659: #else
1660: readonly_data_section ();
1661: #endif
1662:
1.1 root 1663: /* Write the assembler code to define one. */
1664: align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
1665: if (align > 0)
1666: ASM_OUTPUT_ALIGN (asm_out_file, align);
1667:
1668: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LTRAMP", 0);
1669: TRAMPOLINE_TEMPLATE (asm_out_file);
1670:
1671: /* Record the rtl to refer to it. */
1672: ASM_GENERATE_INTERNAL_LABEL (label, "LTRAMP", 0);
1673: name
1674: = (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));
1675: return gen_rtx (SYMBOL_REF, Pmode, name);
1676: }
1.1.1.9 ! root 1677: #endif
1.1 root 1678:
1679: /* Assemble the integer constant X into an object of SIZE bytes.
1680: X must be either a CONST_INT or CONST_DOUBLE.
1681:
1682: Return 1 if we were able to output the constant, otherwise 0. If FORCE is
1683: non-zero, abort if we can't output the constant. */
1684:
1685: int
1686: assemble_integer (x, size, force)
1687: rtx x;
1688: int size;
1689: int force;
1690: {
1691: /* First try to use the standard 1, 2, 4, 8, and 16 byte
1692: ASM_OUTPUT... macros. */
1693:
1694: switch (size)
1695: {
1696: #ifdef ASM_OUTPUT_CHAR
1697: case 1:
1698: ASM_OUTPUT_CHAR (asm_out_file, x);
1699: return 1;
1700: #endif
1701:
1702: #ifdef ASM_OUTPUT_SHORT
1703: case 2:
1704: ASM_OUTPUT_SHORT (asm_out_file, x);
1705: return 1;
1706: #endif
1707:
1708: #ifdef ASM_OUTPUT_INT
1709: case 4:
1710: ASM_OUTPUT_INT (asm_out_file, x);
1711: return 1;
1712: #endif
1713:
1714: #ifdef ASM_OUTPUT_DOUBLE_INT
1715: case 8:
1716: ASM_OUTPUT_DOUBLE_INT (asm_out_file, x);
1717: return 1;
1718: #endif
1719:
1720: #ifdef ASM_OUTPUT_QUADRUPLE_INT
1721: case 16:
1722: ASM_OUTPUT_QUADRUPLE_INT (asm_out_file, x);
1723: return 1;
1724: #endif
1725: }
1726:
1727: /* If we couldn't do it that way, there are two other possibilities: First,
1728: if the machine can output an explicit byte and this is a 1 byte constant,
1729: we can use ASM_OUTPUT_BYTE. */
1730:
1731: #ifdef ASM_OUTPUT_BYTE
1732: if (size == 1 && GET_CODE (x) == CONST_INT)
1733: {
1734: ASM_OUTPUT_BYTE (asm_out_file, INTVAL (x));
1735: return 1;
1736: }
1737: #endif
1738:
1739: /* Finally, if SIZE is larger than a single word, try to output the constant
1740: one word at a time. */
1741:
1742: if (size > UNITS_PER_WORD)
1743: {
1744: int i;
1745: enum machine_mode mode
1746: = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
1747: rtx word;
1748:
1749: for (i = 0; i < size / UNITS_PER_WORD; i++)
1750: {
1751: word = operand_subword (x, i, 0, mode);
1752:
1753: if (word == 0)
1754: break;
1755:
1756: if (! assemble_integer (word, UNITS_PER_WORD, 0))
1757: break;
1758: }
1759:
1760: if (i == size / UNITS_PER_WORD)
1761: return 1;
1762: /* If we output at least one word and then could not finish,
1763: there is no valid way to continue. */
1764: if (i > 0)
1765: abort ();
1766: }
1767:
1768: if (force)
1769: abort ();
1770:
1771: return 0;
1772: }
1773:
1774: /* Assemble the floating-point constant D into an object of size MODE. */
1775:
1776: void
1777: assemble_real (d, mode)
1778: REAL_VALUE_TYPE d;
1779: enum machine_mode mode;
1780: {
1781: jmp_buf output_constant_handler;
1782:
1783: if (setjmp (output_constant_handler))
1784: {
1785: error ("floating point trap outputting a constant");
1786: #ifdef REAL_IS_NOT_DOUBLE
1.1.1.7 root 1787: bzero ((char *) &d, sizeof d);
1.1 root 1788: d = dconst0;
1789: #else
1790: d = 0;
1791: #endif
1792: }
1793:
1794: set_float_handler (output_constant_handler);
1795:
1796: switch (mode)
1797: {
1.1.1.5 root 1798: #ifdef ASM_OUTPUT_BYTE_FLOAT
1799: case QFmode:
1800: ASM_OUTPUT_BYTE_FLOAT (asm_out_file, d);
1801: break;
1802: #endif
1803: #ifdef ASM_OUTPUT_SHORT_FLOAT
1804: case HFmode:
1805: ASM_OUTPUT_SHORT_FLOAT (asm_out_file, d);
1806: break;
1807: #endif
1.1.1.7 root 1808: #ifdef ASM_OUTPUT_THREE_QUARTER_FLOAT
1809: case TQFmode:
1810: ASM_OUTPUT_THREE_QUARTER_FLOAT (asm_out_file, d);
1811: break;
1812: #endif
1.1 root 1813: #ifdef ASM_OUTPUT_FLOAT
1814: case SFmode:
1815: ASM_OUTPUT_FLOAT (asm_out_file, d);
1816: break;
1817: #endif
1818:
1819: #ifdef ASM_OUTPUT_DOUBLE
1820: case DFmode:
1821: ASM_OUTPUT_DOUBLE (asm_out_file, d);
1822: break;
1823: #endif
1824:
1825: #ifdef ASM_OUTPUT_LONG_DOUBLE
1.1.1.5 root 1826: case XFmode:
1.1 root 1827: case TFmode:
1828: ASM_OUTPUT_LONG_DOUBLE (asm_out_file, d);
1829: break;
1830: #endif
1831:
1832: default:
1833: abort ();
1834: }
1835:
1.1.1.4 root 1836: set_float_handler (NULL_PTR);
1.1 root 1837: }
1838:
1839: /* Here we combine duplicate floating constants to make
1840: CONST_DOUBLE rtx's, and force those out to memory when necessary. */
1841:
1842: /* Chain of all CONST_DOUBLE rtx's constructed for the current function.
1843: They are chained through the CONST_DOUBLE_CHAIN.
1844: A CONST_DOUBLE rtx has CONST_DOUBLE_MEM != cc0_rtx iff it is on this chain.
1845: In that case, CONST_DOUBLE_MEM is either a MEM,
1.1.1.4 root 1846: or const0_rtx if no MEM has been made for this CONST_DOUBLE yet.
1847:
1848: (CONST_DOUBLE_MEM is used only for top-level functions.
1849: See force_const_mem for explanation.) */
1.1 root 1850:
1851: static rtx const_double_chain;
1852:
1.1.1.6 root 1853: /* Return a CONST_DOUBLE or CONST_INT for a value specified as a pair of ints.
1.1 root 1854: For an integer, I0 is the low-order word and I1 is the high-order word.
1855: For a real number, I0 is the word with the low address
1856: and I1 is the word with the high address. */
1857:
1858: rtx
1859: immed_double_const (i0, i1, mode)
1.1.1.4 root 1860: HOST_WIDE_INT i0, i1;
1.1 root 1861: enum machine_mode mode;
1862: {
1863: register rtx r;
1864: int in_current_obstack;
1865:
1.1.1.5 root 1866: if (GET_MODE_CLASS (mode) == MODE_INT
1867: || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1.1 root 1868: {
1869: /* We clear out all bits that don't belong in MODE, unless they and our
1870: sign bit are all one. So we get either a reasonable negative value
1871: or a reasonable unsigned value for this mode. */
1872: int width = GET_MODE_BITSIZE (mode);
1.1.1.4 root 1873: if (width < HOST_BITS_PER_WIDE_INT
1874: && ((i0 & ((HOST_WIDE_INT) (-1) << (width - 1)))
1875: != ((HOST_WIDE_INT) (-1) << (width - 1))))
1876: i0 &= ((HOST_WIDE_INT) 1 << width) - 1, i1 = 0;
1877: else if (width == HOST_BITS_PER_WIDE_INT
1.1 root 1878: && ! (i1 == ~0 && i0 < 0))
1879: i1 = 0;
1.1.1.4 root 1880: else if (width > 2 * HOST_BITS_PER_WIDE_INT)
1.1 root 1881: /* We cannot represent this value as a constant. */
1882: abort ();
1883:
1.1.1.7 root 1884: /* If this would be an entire word for the target, but is not for
1885: the host, then sign-extend on the host so that the number will look
1886: the same way on the host that it would on the target.
1887:
1888: For example, when building a 64 bit alpha hosted 32 bit sparc
1889: targeted compiler, then we want the 32 bit unsigned value -1 to be
1890: represented as a 64 bit value -1, and not as 0x00000000ffffffff.
1891: The later confuses the sparc backend. */
1892:
1893: if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
1894: && (i0 & ((HOST_WIDE_INT) 1 << (width - 1))))
1895: i0 |= ((HOST_WIDE_INT) (-1) << width);
1896:
1.1.1.4 root 1897: /* If MODE fits within HOST_BITS_PER_WIDE_INT, always use a CONST_INT.
1.1 root 1898:
1899: ??? Strictly speaking, this is wrong if we create a CONST_INT
1900: for a large unsigned constant with the size of MODE being
1.1.1.4 root 1901: HOST_BITS_PER_WIDE_INT and later try to interpret that constant in a
1902: wider mode. In that case we will mis-interpret it as a negative
1903: number.
1.1 root 1904:
1905: Unfortunately, the only alternative is to make a CONST_DOUBLE
1906: for any constant in any mode if it is an unsigned constant larger
1907: than the maximum signed integer in an int on the host. However,
1908: doing this will break everyone that always expects to see a CONST_INT
1909: for SImode and smaller.
1910:
1911: We have always been making CONST_INTs in this case, so nothing new
1912: is being broken. */
1913:
1.1.1.4 root 1914: if (width <= HOST_BITS_PER_WIDE_INT)
1.1 root 1915: i1 = (i0 < 0) ? ~0 : 0;
1916:
1917: /* If this integer fits in one word, return a CONST_INT. */
1918: if ((i1 == 0 && i0 >= 0)
1919: || (i1 == ~0 && i0 < 0))
1.1.1.4 root 1920: return GEN_INT (i0);
1.1 root 1921:
1922: /* We use VOIDmode for integers. */
1923: mode = VOIDmode;
1924: }
1925:
1926: /* Search the chain for an existing CONST_DOUBLE with the right value.
1927: If one is found, return it. */
1928:
1929: for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))
1930: if (CONST_DOUBLE_LOW (r) == i0 && CONST_DOUBLE_HIGH (r) == i1
1931: && GET_MODE (r) == mode)
1932: return r;
1933:
1934: /* No; make a new one and add it to the chain.
1935:
1936: We may be called by an optimizer which may be discarding any memory
1937: allocated during its processing (such as combine and loop). However,
1938: we will be leaving this constant on the chain, so we cannot tolerate
1939: freed memory. So switch to saveable_obstack for this allocation
1940: and then switch back if we were in current_obstack. */
1941:
1.1.1.5 root 1942: push_obstacks_nochange ();
1943: rtl_in_saveable_obstack ();
1.1 root 1944: r = gen_rtx (CONST_DOUBLE, mode, 0, i0, i1);
1.1.1.5 root 1945: pop_obstacks ();
1.1 root 1946:
1.1.1.6 root 1947: /* Don't touch const_double_chain in nested function; see force_const_mem.
1948: Also, don't touch it if not inside any function. */
1949: if (outer_function_chain == 0 && current_function_decl != 0)
1.1.1.4 root 1950: {
1951: CONST_DOUBLE_CHAIN (r) = const_double_chain;
1952: const_double_chain = r;
1953: }
1.1 root 1954:
1955: /* Store const0_rtx in mem-slot since this CONST_DOUBLE is on the chain.
1956: Actual use of mem-slot is only through force_const_mem. */
1957:
1958: CONST_DOUBLE_MEM (r) = const0_rtx;
1959:
1960: return r;
1961: }
1962:
1963: /* Return a CONST_DOUBLE for a specified `double' value
1964: and machine mode. */
1965:
1966: rtx
1967: immed_real_const_1 (d, mode)
1968: REAL_VALUE_TYPE d;
1969: enum machine_mode mode;
1970: {
1971: union real_extract u;
1972: register rtx r;
1973: int in_current_obstack;
1974:
1975: /* Get the desired `double' value as a sequence of ints
1976: since that is how they are stored in a CONST_DOUBLE. */
1977:
1978: u.d = d;
1979:
1980: /* Detect special cases. */
1981:
1.1.1.2 root 1982: /* Avoid REAL_VALUES_EQUAL here in order to distinguish minus zero. */
1.1.1.7 root 1983: if (!bcmp ((char *) &dconst0, (char *) &d, sizeof d))
1.1 root 1984: return CONST0_RTX (mode);
1.1.1.5 root 1985: /* Check for NaN first, because some ports (specifically the i386) do not
1986: emit correct ieee-fp code by default, and thus will generate a core
1987: dump here if we pass a NaN to REAL_VALUES_EQUAL and if REAL_VALUES_EQUAL
1988: does a floating point comparison. */
1989: else if (! REAL_VALUE_ISNAN (d) && REAL_VALUES_EQUAL (dconst1, d))
1.1 root 1990: return CONST1_RTX (mode);
1991:
1.1.1.4 root 1992: if (sizeof u == 2 * sizeof (HOST_WIDE_INT))
1.1 root 1993: return immed_double_const (u.i[0], u.i[1], mode);
1994:
1995: /* The rest of this function handles the case where
1996: a float value requires more than 2 ints of space.
1997: It will be deleted as dead code on machines that don't need it. */
1998:
1999: /* Search the chain for an existing CONST_DOUBLE with the right value.
2000: If one is found, return it. */
2001:
2002: for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))
1.1.1.7 root 2003: if (! bcmp ((char *) &CONST_DOUBLE_LOW (r), (char *) &u, sizeof u)
1.1 root 2004: && GET_MODE (r) == mode)
2005: return r;
2006:
2007: /* No; make a new one and add it to the chain.
2008:
2009: We may be called by an optimizer which may be discarding any memory
2010: allocated during its processing (such as combine and loop). However,
2011: we will be leaving this constant on the chain, so we cannot tolerate
2012: freed memory. So switch to saveable_obstack for this allocation
2013: and then switch back if we were in current_obstack. */
2014:
1.1.1.5 root 2015: push_obstacks_nochange ();
2016: rtl_in_saveable_obstack ();
1.1 root 2017: r = rtx_alloc (CONST_DOUBLE);
2018: PUT_MODE (r, mode);
1.1.1.7 root 2019: bcopy ((char *) &u, (char *) &CONST_DOUBLE_LOW (r), sizeof u);
1.1.1.5 root 2020: pop_obstacks ();
1.1 root 2021:
1.1.1.6 root 2022: /* Don't touch const_double_chain in nested function; see force_const_mem.
2023: Also, don't touch it if not inside any function. */
2024: if (outer_function_chain == 0 && current_function_decl != 0)
1.1.1.4 root 2025: {
2026: CONST_DOUBLE_CHAIN (r) = const_double_chain;
2027: const_double_chain = r;
2028: }
1.1 root 2029:
2030: /* Store const0_rtx in CONST_DOUBLE_MEM since this CONST_DOUBLE is on the
2031: chain, but has not been allocated memory. Actual use of CONST_DOUBLE_MEM
2032: is only through force_const_mem. */
2033:
2034: CONST_DOUBLE_MEM (r) = const0_rtx;
2035:
2036: return r;
2037: }
2038:
2039: /* Return a CONST_DOUBLE rtx for a value specified by EXP,
2040: which must be a REAL_CST tree node. */
2041:
2042: rtx
2043: immed_real_const (exp)
2044: tree exp;
2045: {
2046: return immed_real_const_1 (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)));
2047: }
2048:
2049: /* At the end of a function, forget the memory-constants
2050: previously made for CONST_DOUBLEs. Mark them as not on real_constant_chain.
2051: Also clear out real_constant_chain and clear out all the chain-pointers. */
2052:
2053: void
2054: clear_const_double_mem ()
2055: {
2056: register rtx r, next;
2057:
1.1.1.4 root 2058: /* Don't touch CONST_DOUBLE_MEM for nested functions.
2059: See force_const_mem for explanation. */
2060: if (outer_function_chain != 0)
2061: return;
2062:
1.1 root 2063: for (r = const_double_chain; r; r = next)
2064: {
2065: next = CONST_DOUBLE_CHAIN (r);
2066: CONST_DOUBLE_CHAIN (r) = 0;
2067: CONST_DOUBLE_MEM (r) = cc0_rtx;
2068: }
2069: const_double_chain = 0;
2070: }
2071:
2072: /* Given an expression EXP with a constant value,
2073: reduce it to the sum of an assembler symbol and an integer.
2074: Store them both in the structure *VALUE.
2075: Abort if EXP does not reduce. */
2076:
2077: struct addr_const
2078: {
2079: rtx base;
1.1.1.4 root 2080: HOST_WIDE_INT offset;
1.1 root 2081: };
2082:
2083: static void
2084: decode_addr_const (exp, value)
2085: tree exp;
2086: struct addr_const *value;
2087: {
2088: register tree target = TREE_OPERAND (exp, 0);
2089: register int offset = 0;
2090: register rtx x;
2091:
2092: while (1)
2093: {
2094: if (TREE_CODE (target) == COMPONENT_REF
2095: && (TREE_CODE (DECL_FIELD_BITPOS (TREE_OPERAND (target, 1)))
2096: == INTEGER_CST))
2097: {
2098: offset += TREE_INT_CST_LOW (DECL_FIELD_BITPOS (TREE_OPERAND (target, 1))) / BITS_PER_UNIT;
2099: target = TREE_OPERAND (target, 0);
2100: }
2101: else if (TREE_CODE (target) == ARRAY_REF)
2102: {
2103: if (TREE_CODE (TREE_OPERAND (target, 1)) != INTEGER_CST
2104: || TREE_CODE (TYPE_SIZE (TREE_TYPE (target))) != INTEGER_CST)
2105: abort ();
2106: offset += ((TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (target)))
2107: * TREE_INT_CST_LOW (TREE_OPERAND (target, 1)))
2108: / BITS_PER_UNIT);
2109: target = TREE_OPERAND (target, 0);
2110: }
2111: else
2112: break;
2113: }
2114:
2115: switch (TREE_CODE (target))
2116: {
2117: case VAR_DECL:
2118: case FUNCTION_DECL:
2119: x = DECL_RTL (target);
2120: break;
2121:
2122: case LABEL_DECL:
1.1.1.6 root 2123: if (output_bytecode)
2124: /* FIXME: this may not be correct, check it */
2125: x = bc_gen_rtx (TREE_STRING_POINTER (target), 0, (struct bc_label *) 0);
2126: else
2127: x = gen_rtx (MEM, FUNCTION_MODE,
2128: gen_rtx (LABEL_REF, VOIDmode,
2129: label_rtx (TREE_OPERAND (exp, 0))));
1.1 root 2130: break;
2131:
2132: case REAL_CST:
2133: case STRING_CST:
2134: case COMPLEX_CST:
2135: case CONSTRUCTOR:
2136: x = TREE_CST_RTL (target);
2137: break;
2138:
2139: default:
2140: abort ();
2141: }
2142:
1.1.1.6 root 2143: if (!output_bytecode)
2144: {
2145: if (GET_CODE (x) != MEM)
2146: abort ();
2147: x = XEXP (x, 0);
2148: }
1.1 root 2149:
2150: value->base = x;
2151: value->offset = offset;
2152: }
2153:
2154: /* Uniquize all constants that appear in memory.
2155: Each constant in memory thus far output is recorded
2156: in `const_hash_table' with a `struct constant_descriptor'
2157: that contains a polish representation of the value of
2158: the constant.
2159:
2160: We cannot store the trees in the hash table
2161: because the trees may be temporary. */
2162:
2163: struct constant_descriptor
2164: {
2165: struct constant_descriptor *next;
2166: char *label;
2167: char contents[1];
2168: };
2169:
2170: #define HASHBITS 30
2171: #define MAX_HASH_TABLE 1009
2172: static struct constant_descriptor *const_hash_table[MAX_HASH_TABLE];
2173:
2174: /* Compute a hash code for a constant expression. */
2175:
1.1.1.8 root 2176: static int
1.1 root 2177: const_hash (exp)
2178: tree exp;
2179: {
2180: register char *p;
2181: register int len, hi, i;
2182: register enum tree_code code = TREE_CODE (exp);
2183:
2184: if (code == INTEGER_CST)
2185: {
2186: p = (char *) &TREE_INT_CST_LOW (exp);
2187: len = 2 * sizeof TREE_INT_CST_LOW (exp);
2188: }
2189: else if (code == REAL_CST)
2190: {
2191: p = (char *) &TREE_REAL_CST (exp);
2192: len = sizeof TREE_REAL_CST (exp);
2193: }
2194: else if (code == STRING_CST)
2195: p = TREE_STRING_POINTER (exp), len = TREE_STRING_LENGTH (exp);
2196: else if (code == COMPLEX_CST)
2197: return const_hash (TREE_REALPART (exp)) * 5
2198: + const_hash (TREE_IMAGPART (exp));
1.1.1.8 root 2199: else if (code == CONSTRUCTOR && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
2200: {
2201: len = int_size_in_bytes (TREE_TYPE (exp));
2202: p = (char*) alloca (len);
2203: get_set_constructor_bytes (exp, (unsigned char *) p, len);
2204: }
1.1 root 2205: else if (code == CONSTRUCTOR)
2206: {
2207: register tree link;
2208:
2209: /* For record type, include the type in the hashing.
2210: We do not do so for array types
2211: because (1) the sizes of the elements are sufficient
1.1.1.3 root 2212: and (2) distinct array types can have the same constructor.
2213: Instead, we include the array size because the constructor could
2214: be shorter. */
1.1 root 2215: if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
1.1.1.4 root 2216: hi = ((HOST_WIDE_INT) TREE_TYPE (exp) & ((1 << HASHBITS) - 1))
2217: % MAX_HASH_TABLE;
1.1 root 2218: else
1.1.1.3 root 2219: hi = ((5 + int_size_in_bytes (TREE_TYPE (exp)))
2220: & ((1 << HASHBITS) - 1)) % MAX_HASH_TABLE;
1.1 root 2221:
2222: for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
1.1.1.4 root 2223: if (TREE_VALUE (link))
2224: hi = (hi * 603 + const_hash (TREE_VALUE (link))) % MAX_HASH_TABLE;
1.1 root 2225:
2226: return hi;
2227: }
2228: else if (code == ADDR_EXPR)
2229: {
2230: struct addr_const value;
2231: decode_addr_const (exp, &value);
2232: if (GET_CODE (value.base) == SYMBOL_REF)
2233: {
2234: /* Don't hash the address of the SYMBOL_REF;
2235: only use the offset and the symbol name. */
2236: hi = value.offset;
2237: p = XSTR (value.base, 0);
2238: for (i = 0; p[i] != 0; i++)
2239: hi = ((hi * 613) + (unsigned)(p[i]));
2240: }
2241: else if (GET_CODE (value.base) == LABEL_REF)
2242: hi = value.offset + CODE_LABEL_NUMBER (XEXP (value.base, 0)) * 13;
2243:
2244: hi &= (1 << HASHBITS) - 1;
2245: hi %= MAX_HASH_TABLE;
2246: return hi;
2247: }
2248: else if (code == PLUS_EXPR || code == MINUS_EXPR)
2249: return const_hash (TREE_OPERAND (exp, 0)) * 9
2250: + const_hash (TREE_OPERAND (exp, 1));
2251: else if (code == NOP_EXPR || code == CONVERT_EXPR)
2252: return const_hash (TREE_OPERAND (exp, 0)) * 7 + 2;
2253:
2254: /* Compute hashing function */
2255: hi = len;
2256: for (i = 0; i < len; i++)
2257: hi = ((hi * 613) + (unsigned)(p[i]));
2258:
2259: hi &= (1 << HASHBITS) - 1;
2260: hi %= MAX_HASH_TABLE;
2261: return hi;
2262: }
2263:
2264: /* Compare a constant expression EXP with a constant-descriptor DESC.
2265: Return 1 if DESC describes a constant with the same value as EXP. */
2266:
2267: static int
2268: compare_constant (exp, desc)
2269: tree exp;
2270: struct constant_descriptor *desc;
2271: {
2272: return 0 != compare_constant_1 (exp, desc->contents);
2273: }
2274:
2275: /* Compare constant expression EXP with a substring P of a constant descriptor.
2276: If they match, return a pointer to the end of the substring matched.
2277: If they do not match, return 0.
2278:
2279: Since descriptors are written in polish prefix notation,
2280: this function can be used recursively to test one operand of EXP
2281: against a subdescriptor, and if it succeeds it returns the
2282: address of the subdescriptor for the next operand. */
2283:
2284: static char *
2285: compare_constant_1 (exp, p)
2286: tree exp;
2287: char *p;
2288: {
2289: register char *strp;
2290: register int len;
2291: register enum tree_code code = TREE_CODE (exp);
2292:
2293: if (code != (enum tree_code) *p++)
2294: return 0;
2295:
2296: if (code == INTEGER_CST)
2297: {
2298: /* Integer constants are the same only if the same width of type. */
2299: if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
2300: return 0;
2301: strp = (char *) &TREE_INT_CST_LOW (exp);
2302: len = 2 * sizeof TREE_INT_CST_LOW (exp);
2303: }
2304: else if (code == REAL_CST)
2305: {
2306: /* Real constants are the same only if the same width of type. */
2307: if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
2308: return 0;
2309: strp = (char *) &TREE_REAL_CST (exp);
2310: len = sizeof TREE_REAL_CST (exp);
2311: }
2312: else if (code == STRING_CST)
2313: {
2314: if (flag_writable_strings)
2315: return 0;
2316: strp = TREE_STRING_POINTER (exp);
2317: len = TREE_STRING_LENGTH (exp);
1.1.1.7 root 2318: if (bcmp ((char *) &TREE_STRING_LENGTH (exp), p,
1.1 root 2319: sizeof TREE_STRING_LENGTH (exp)))
2320: return 0;
2321: p += sizeof TREE_STRING_LENGTH (exp);
2322: }
2323: else if (code == COMPLEX_CST)
2324: {
2325: p = compare_constant_1 (TREE_REALPART (exp), p);
2326: if (p == 0) return 0;
2327: p = compare_constant_1 (TREE_IMAGPART (exp), p);
2328: return p;
2329: }
1.1.1.8 root 2330: else if (code == CONSTRUCTOR && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
2331: {
2332: len = int_size_in_bytes (TREE_TYPE (exp));
2333: strp = (char*) alloca (len);
2334: get_set_constructor_bytes (exp, (unsigned char *) strp, len);
2335: }
1.1 root 2336: else if (code == CONSTRUCTOR)
2337: {
2338: register tree link;
2339: int length = list_length (CONSTRUCTOR_ELTS (exp));
2340: tree type;
2341:
1.1.1.7 root 2342: if (bcmp ((char *) &length, p, sizeof length))
1.1 root 2343: return 0;
2344: p += sizeof length;
2345:
2346: /* For record constructors, insist that the types match.
2347: For arrays, just verify both constructors are for arrays. */
2348: if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
2349: type = TREE_TYPE (exp);
2350: else
2351: type = 0;
1.1.1.7 root 2352: if (bcmp ((char *) &type, p, sizeof type))
1.1 root 2353: return 0;
2354: p += sizeof type;
2355:
1.1.1.3 root 2356: /* For arrays, insist that the size in bytes match. */
2357: if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
2358: {
2359: int size = int_size_in_bytes (TREE_TYPE (exp));
1.1.1.7 root 2360: if (bcmp ((char *) &size, p, sizeof size))
1.1.1.3 root 2361: return 0;
2362: p += sizeof size;
2363: }
2364:
1.1 root 2365: for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
1.1.1.4 root 2366: {
2367: if (TREE_VALUE (link))
2368: {
2369: if ((p = compare_constant_1 (TREE_VALUE (link), p)) == 0)
2370: return 0;
2371: }
2372: else
2373: {
2374: tree zero = 0;
2375:
1.1.1.7 root 2376: if (bcmp ((char *) &zero, p, sizeof zero))
1.1.1.4 root 2377: return 0;
2378: p += sizeof zero;
2379: }
2380: }
2381:
1.1 root 2382: return p;
2383: }
2384: else if (code == ADDR_EXPR)
2385: {
2386: struct addr_const value;
2387: decode_addr_const (exp, &value);
2388: strp = (char *) &value.offset;
2389: len = sizeof value.offset;
2390: /* Compare the offset. */
2391: while (--len >= 0)
2392: if (*p++ != *strp++)
2393: return 0;
2394: /* Compare symbol name. */
2395: strp = XSTR (value.base, 0);
2396: len = strlen (strp) + 1;
2397: }
2398: else if (code == PLUS_EXPR || code == MINUS_EXPR)
2399: {
2400: p = compare_constant_1 (TREE_OPERAND (exp, 0), p);
2401: if (p == 0) return 0;
2402: p = compare_constant_1 (TREE_OPERAND (exp, 1), p);
2403: return p;
2404: }
2405: else if (code == NOP_EXPR || code == CONVERT_EXPR)
2406: {
2407: p = compare_constant_1 (TREE_OPERAND (exp, 0), p);
2408: return p;
2409: }
2410:
2411: /* Compare constant contents. */
2412: while (--len >= 0)
2413: if (*p++ != *strp++)
2414: return 0;
2415:
2416: return p;
2417: }
2418:
2419: /* Construct a constant descriptor for the expression EXP.
2420: It is up to the caller to enter the descriptor in the hash table. */
2421:
2422: static struct constant_descriptor *
2423: record_constant (exp)
2424: tree exp;
2425: {
1.1.1.5 root 2426: struct constant_descriptor *next = 0;
2427: char *label = 0;
2428:
2429: /* Make a struct constant_descriptor. The first two pointers will
2430: be filled in later. Here we just leave space for them. */
1.1 root 2431:
1.1.1.5 root 2432: obstack_grow (&permanent_obstack, (char *) &next, sizeof next);
2433: obstack_grow (&permanent_obstack, (char *) &label, sizeof label);
1.1 root 2434: record_constant_1 (exp);
2435: return (struct constant_descriptor *) obstack_finish (&permanent_obstack);
2436: }
2437:
2438: /* Add a description of constant expression EXP
2439: to the object growing in `permanent_obstack'.
2440: No need to return its address; the caller will get that
2441: from the obstack when the object is complete. */
2442:
2443: static void
2444: record_constant_1 (exp)
2445: tree exp;
2446: {
2447: register char *strp;
2448: register int len;
2449: register enum tree_code code = TREE_CODE (exp);
2450:
2451: obstack_1grow (&permanent_obstack, (unsigned int) code);
2452:
1.1.1.8 root 2453: switch (code)
1.1 root 2454: {
1.1.1.8 root 2455: case INTEGER_CST:
1.1 root 2456: obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
2457: strp = (char *) &TREE_INT_CST_LOW (exp);
2458: len = 2 * sizeof TREE_INT_CST_LOW (exp);
1.1.1.8 root 2459: break;
2460:
2461: case REAL_CST:
1.1 root 2462: obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
2463: strp = (char *) &TREE_REAL_CST (exp);
2464: len = sizeof TREE_REAL_CST (exp);
1.1.1.8 root 2465: break;
2466:
2467: case STRING_CST:
1.1 root 2468: if (flag_writable_strings)
2469: return;
1.1.1.8 root 2470:
1.1 root 2471: strp = TREE_STRING_POINTER (exp);
2472: len = TREE_STRING_LENGTH (exp);
2473: obstack_grow (&permanent_obstack, (char *) &TREE_STRING_LENGTH (exp),
2474: sizeof TREE_STRING_LENGTH (exp));
1.1.1.8 root 2475: break;
2476:
2477: case COMPLEX_CST:
1.1 root 2478: record_constant_1 (TREE_REALPART (exp));
2479: record_constant_1 (TREE_IMAGPART (exp));
2480: return;
2481:
1.1.1.8 root 2482: case CONSTRUCTOR:
2483: if (TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
1.1.1.3 root 2484: {
1.1.1.8 root 2485: int nbytes = int_size_in_bytes (TREE_TYPE (exp));
2486: obstack_grow (&permanent_obstack, &nbytes, sizeof (nbytes));
2487: obstack_blank (&permanent_obstack, nbytes);
2488: get_set_constructor_bytes
2489: (exp, (unsigned char *) permanent_obstack.next_free, nbytes);
2490: return;
1.1.1.3 root 2491: }
1.1.1.8 root 2492: else
1.1.1.4 root 2493: {
1.1.1.8 root 2494: register tree link;
2495: int length = list_length (CONSTRUCTOR_ELTS (exp));
2496: tree type;
2497:
2498: obstack_grow (&permanent_obstack, (char *) &length, sizeof length);
2499:
2500: /* For record constructors, insist that the types match.
2501: For arrays, just verify both constructors are for arrays. */
2502: if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
2503: type = TREE_TYPE (exp);
1.1.1.4 root 2504: else
1.1.1.8 root 2505: type = 0;
2506: obstack_grow (&permanent_obstack, (char *) &type, sizeof type);
2507:
2508: /* For arrays, insist that the size in bytes match. */
2509: if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
1.1.1.4 root 2510: {
1.1.1.8 root 2511: int size = int_size_in_bytes (TREE_TYPE (exp));
2512: obstack_grow (&permanent_obstack, (char *) &size, sizeof size);
2513: }
1.1.1.4 root 2514:
1.1.1.8 root 2515: for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
2516: {
2517: if (TREE_VALUE (link))
2518: record_constant_1 (TREE_VALUE (link));
2519: else
2520: {
2521: tree zero = 0;
2522:
2523: obstack_grow (&permanent_obstack,
2524: (char *) &zero, sizeof zero);
2525: }
1.1.1.4 root 2526: }
2527: }
1.1 root 2528: return;
1.1.1.8 root 2529:
2530: case ADDR_EXPR:
2531: {
2532: struct addr_const value;
2533:
2534: decode_addr_const (exp, &value);
2535: /* Record the offset. */
2536: obstack_grow (&permanent_obstack,
2537: (char *) &value.offset, sizeof value.offset);
2538: /* Record the symbol name. */
2539: obstack_grow (&permanent_obstack, XSTR (value.base, 0),
2540: strlen (XSTR (value.base, 0)) + 1);
2541: }
1.1 root 2542: return;
1.1.1.8 root 2543:
2544: case PLUS_EXPR:
2545: case MINUS_EXPR:
1.1 root 2546: record_constant_1 (TREE_OPERAND (exp, 0));
2547: record_constant_1 (TREE_OPERAND (exp, 1));
2548: return;
1.1.1.8 root 2549:
2550: case NOP_EXPR:
2551: case CONVERT_EXPR:
2552: case NON_LVALUE_EXPR:
1.1 root 2553: record_constant_1 (TREE_OPERAND (exp, 0));
2554: return;
1.1.1.8 root 2555:
2556: default:
2557: abort ();
1.1 root 2558: }
2559:
2560: /* Record constant contents. */
2561: obstack_grow (&permanent_obstack, strp, len);
2562: }
2563:
1.1.1.6 root 2564: /* Record a list of constant expressions that were passed to
2565: output_constant_def but that could not be output right away. */
2566:
2567: struct deferred_constant
2568: {
2569: struct deferred_constant *next;
2570: tree exp;
2571: int reloc;
2572: int labelno;
2573: };
2574:
2575: static struct deferred_constant *deferred_constants;
2576:
2577: /* Nonzero means defer output of addressed subconstants
2578: (i.e., those for which output_constant_def is called.) */
2579: static int defer_addressed_constants_flag;
2580:
2581: /* Start deferring output of subconstants. */
2582:
2583: void
2584: defer_addressed_constants ()
2585: {
2586: defer_addressed_constants_flag++;
2587: }
2588:
2589: /* Stop deferring output of subconstants,
2590: and output now all those that have been deferred. */
2591:
2592: void
2593: output_deferred_addressed_constants ()
2594: {
2595: struct deferred_constant *p, *next;
2596:
2597: defer_addressed_constants_flag--;
2598:
2599: if (defer_addressed_constants_flag > 0)
2600: return;
2601:
2602: for (p = deferred_constants; p; p = next)
2603: {
2604: output_constant_def_contents (p->exp, p->reloc, p->labelno);
2605: next = p->next;
2606: free (p);
2607: }
2608:
2609: deferred_constants = 0;
2610: }
2611:
2612: /* Make a copy of the whole tree structure for a constant.
2613: This handles the same types of nodes that compare_constant
2614: and record_constant handle. */
2615:
2616: static tree
2617: copy_constant (exp)
2618: tree exp;
2619: {
2620: switch (TREE_CODE (exp))
2621: {
1.1.1.8 root 2622: case ADDR_EXPR:
2623: /* For ADDR_EXPR, we do not want to copy the decl whose address
2624: is requested. We do want to copy constants though. */
2625: if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == 'c')
2626: return build1 (TREE_CODE (exp), TREE_TYPE (exp),
2627: copy_constant (TREE_OPERAND (exp, 0)));
2628: else
2629: return copy_node (exp);
2630:
1.1.1.6 root 2631: case INTEGER_CST:
2632: case REAL_CST:
2633: case STRING_CST:
2634: return copy_node (exp);
2635:
2636: case COMPLEX_CST:
2637: return build_complex (copy_constant (TREE_REALPART (exp)),
2638: copy_constant (TREE_IMAGPART (exp)));
2639:
2640: case PLUS_EXPR:
2641: case MINUS_EXPR:
2642: return build (TREE_CODE (exp), TREE_TYPE (exp),
2643: copy_constant (TREE_OPERAND (exp, 0)),
2644: copy_constant (TREE_OPERAND (exp, 1)));
2645:
2646: case NOP_EXPR:
2647: case CONVERT_EXPR:
2648: return build1 (TREE_CODE (exp), TREE_TYPE (exp),
2649: copy_constant (TREE_OPERAND (exp, 0)));
2650:
2651: case CONSTRUCTOR:
2652: {
2653: tree copy = copy_node (exp);
2654: tree list = copy_list (CONSTRUCTOR_ELTS (exp));
2655: tree tail;
2656:
1.1.1.7 root 2657: CONSTRUCTOR_ELTS (copy) = list;
1.1.1.6 root 2658: for (tail = list; tail; tail = TREE_CHAIN (tail))
2659: TREE_VALUE (tail) = copy_constant (TREE_VALUE (tail));
1.1.1.8 root 2660: if (TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
2661: for (tail = list; tail; tail = TREE_CHAIN (tail))
2662: TREE_PURPOSE (tail) = copy_constant (TREE_PURPOSE (tail));
1.1.1.6 root 2663:
2664: return copy;
2665: }
2666:
2667: default:
2668: abort ();
2669: }
2670: }
2671:
1.1 root 2672: /* Return an rtx representing a reference to constant data in memory
2673: for the constant expression EXP.
1.1.1.6 root 2674:
1.1 root 2675: If assembler code for such a constant has already been output,
2676: return an rtx to refer to it.
1.1.1.6 root 2677: Otherwise, output such a constant in memory (or defer it for later)
2678: and generate an rtx for it.
2679:
2680: The TREE_CST_RTL of EXP is set up to point to that rtx.
1.1 root 2681: The const_hash_table records which constants already have label strings. */
2682:
2683: rtx
2684: output_constant_def (exp)
2685: tree exp;
2686: {
1.1.1.6 root 2687: register int hash;
1.1 root 2688: register struct constant_descriptor *desc;
2689: char label[256];
2690: char *found = 0;
2691: int reloc;
2692: register rtx def;
2693:
2694: if (TREE_CODE (exp) == INTEGER_CST)
2695: abort (); /* No TREE_CST_RTL slot in these. */
2696:
2697: if (TREE_CST_RTL (exp))
2698: return TREE_CST_RTL (exp);
2699:
2700: /* Make sure any other constants whose addresses appear in EXP
2701: are assigned label numbers. */
2702:
2703: reloc = output_addressed_constants (exp);
2704:
2705: /* Compute hash code of EXP. Search the descriptors for that hash code
2706: to see if any of them describes EXP. If yes, the descriptor records
2707: the label number already assigned. */
2708:
1.1.1.7 root 2709: hash = const_hash (exp) % MAX_HASH_TABLE;
1.1.1.6 root 2710:
1.1.1.7 root 2711: for (desc = const_hash_table[hash]; desc; desc = desc->next)
2712: if (compare_constant (exp, desc))
2713: {
2714: found = desc->label;
2715: break;
2716: }
1.1.1.6 root 2717:
1.1.1.7 root 2718: if (found == 0)
2719: {
2720: /* No constant equal to EXP is known to have been output.
2721: Make a constant descriptor to enter EXP in the hash table.
2722: Assign the label number and record it in the descriptor for
2723: future calls to this function to find. */
1.1.1.6 root 2724:
1.1.1.7 root 2725: /* Create a string containing the label name, in LABEL. */
2726: ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
2727:
2728: desc = record_constant (exp);
2729: desc->next = const_hash_table[hash];
2730: desc->label
2731: = (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));
2732: const_hash_table[hash] = desc;
2733: }
2734: else
2735: {
2736: /* Create a string containing the label name, in LABEL. */
2737: ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
1.1 root 2738: }
1.1.1.6 root 2739:
1.1 root 2740: /* We have a symbol name; construct the SYMBOL_REF and the MEM. */
2741:
2742: push_obstacks_nochange ();
2743: if (TREE_PERMANENT (exp))
2744: end_temporary_allocation ();
2745:
1.1.1.7 root 2746: def = gen_rtx (SYMBOL_REF, Pmode, desc->label);
1.1.1.6 root 2747:
1.1.1.7 root 2748: TREE_CST_RTL (exp)
2749: = gen_rtx (MEM, TYPE_MODE (TREE_TYPE (exp)), def);
2750: RTX_UNCHANGING_P (TREE_CST_RTL (exp)) = 1;
2751: if (AGGREGATE_TYPE_P (TREE_TYPE (exp)))
2752: MEM_IN_STRUCT_P (TREE_CST_RTL (exp)) = 1;
2753:
1.1 root 2754: pop_obstacks ();
2755:
2756: /* Optionally set flags or add text to the name to record information
2757: such as that it is a function name. If the name is changed, the macro
1.1.1.7 root 2758: ASM_OUTPUT_LABELREF will have to know how to strip this information. */
1.1 root 2759: #ifdef ENCODE_SECTION_INFO
2760: ENCODE_SECTION_INFO (exp);
2761: #endif
2762:
1.1.1.6 root 2763: /* If this is the first time we've seen this particular constant,
2764: output it (or defer its output for later). */
1.1 root 2765: if (found == 0)
2766: {
1.1.1.6 root 2767: if (defer_addressed_constants_flag)
2768: {
2769: struct deferred_constant *p;
2770: p = (struct deferred_constant *) xmalloc (sizeof (struct deferred_constant));
2771:
2772: push_obstacks_nochange ();
2773: suspend_momentary ();
2774: p->exp = copy_constant (exp);
2775: pop_obstacks ();
2776: p->reloc = reloc;
2777: p->labelno = const_labelno++;
2778: p->next = deferred_constants;
2779: deferred_constants = p;
2780: }
2781: else
2782: output_constant_def_contents (exp, reloc, const_labelno++);
2783: }
2784:
2785: return TREE_CST_RTL (exp);
2786: }
2787:
2788: /* Now output assembler code to define the label for EXP,
2789: and follow it with the data of EXP. */
1.1 root 2790:
1.1.1.6 root 2791: static void
2792: output_constant_def_contents (exp, reloc, labelno)
2793: tree exp;
2794: int reloc;
2795: int labelno;
2796: {
2797: int align;
2798:
1.1.1.7 root 2799: if (IN_NAMED_SECTION (exp))
1.1.1.8 root 2800: named_section (exp, NULL);
1.1.1.7 root 2801: else
2802: {
2803: /* First switch to text section, except for writable strings. */
1.1 root 2804: #ifdef SELECT_SECTION
1.1.1.7 root 2805: SELECT_SECTION (exp, reloc);
1.1 root 2806: #else
1.1.1.7 root 2807: if (((TREE_CODE (exp) == STRING_CST) && flag_writable_strings)
2808: || (flag_pic && reloc))
2809: data_section ();
2810: else
2811: readonly_data_section ();
1.1 root 2812: #endif
1.1.1.7 root 2813: }
1.1 root 2814:
1.1.1.6 root 2815: /* Align the location counter as required by EXP's data type. */
2816: align = TYPE_ALIGN (TREE_TYPE (exp));
1.1 root 2817: #ifdef CONSTANT_ALIGNMENT
1.1.1.6 root 2818: align = CONSTANT_ALIGNMENT (exp, align);
1.1 root 2819: #endif
2820:
1.1.1.6 root 2821: if (align > BITS_PER_UNIT)
2822: {
2823: if (!output_bytecode)
2824: {
2825: ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
2826: }
2827: else
2828: {
2829: BC_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
2830: }
2831: }
1.1 root 2832:
1.1.1.6 root 2833: /* Output the label itself. */
2834: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", labelno);
1.1 root 2835:
1.1.1.6 root 2836: /* Output the value of EXP. */
2837: output_constant (exp,
2838: (TREE_CODE (exp) == STRING_CST
2839: ? TREE_STRING_LENGTH (exp)
2840: : int_size_in_bytes (TREE_TYPE (exp))));
1.1 root 2841:
2842: }
2843:
2844: /* Similar hash facility for making memory-constants
2845: from constant rtl-expressions. It is used on RISC machines
2846: where immediate integer arguments and constant addresses are restricted
2847: so that such constants must be stored in memory.
2848:
2849: This pool of constants is reinitialized for each function
2850: so each function gets its own constants-pool that comes right before it.
2851:
2852: All structures allocated here are discarded when functions are saved for
2853: inlining, so they do not need to be allocated permanently. */
2854:
2855: #define MAX_RTX_HASH_TABLE 61
1.1.1.4 root 2856: static struct constant_descriptor **const_rtx_hash_table;
1.1 root 2857:
2858: /* Structure to represent sufficient information about a constant so that
2859: it can be output when the constant pool is output, so that function
2860: integration can be done, and to simplify handling on machines that reference
2861: constant pool as base+displacement. */
2862:
2863: struct pool_constant
2864: {
2865: struct constant_descriptor *desc;
2866: struct pool_constant *next;
2867: enum machine_mode mode;
2868: rtx constant;
2869: int labelno;
2870: int align;
2871: int offset;
2872: };
2873:
2874: /* Pointers to first and last constant in pool. */
2875:
2876: static struct pool_constant *first_pool, *last_pool;
2877:
2878: /* Current offset in constant pool (does not include any machine-specific
2879: header. */
2880:
2881: static int pool_offset;
2882:
2883: /* Structure used to maintain hash table mapping symbols used to their
2884: corresponding constants. */
2885:
2886: struct pool_sym
2887: {
2888: char *label;
2889: struct pool_constant *pool;
2890: struct pool_sym *next;
2891: };
2892:
1.1.1.4 root 2893: static struct pool_sym **const_rtx_sym_hash_table;
1.1 root 2894:
2895: /* Hash code for a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true.
2896: The argument is XSTR (... , 0) */
2897:
2898: #define SYMHASH(LABEL) \
1.1.1.4 root 2899: ((((HOST_WIDE_INT) (LABEL)) & ((1 << HASHBITS) - 1)) % MAX_RTX_HASH_TABLE)
1.1 root 2900:
2901: /* Initialize constant pool hashing for next function. */
2902:
2903: void
2904: init_const_rtx_hash_table ()
2905: {
1.1.1.4 root 2906: const_rtx_hash_table
2907: = ((struct constant_descriptor **)
2908: oballoc (MAX_RTX_HASH_TABLE * sizeof (struct constant_descriptor *)));
2909: const_rtx_sym_hash_table
2910: = ((struct pool_sym **)
2911: oballoc (MAX_RTX_HASH_TABLE * sizeof (struct pool_sym *)));
1.1.1.7 root 2912: bzero ((char *) const_rtx_hash_table,
1.1.1.4 root 2913: MAX_RTX_HASH_TABLE * sizeof (struct constant_descriptor *));
1.1.1.7 root 2914: bzero ((char *) const_rtx_sym_hash_table,
1.1.1.4 root 2915: MAX_RTX_HASH_TABLE * sizeof (struct pool_sym *));
1.1 root 2916:
2917: first_pool = last_pool = 0;
2918: pool_offset = 0;
2919: }
2920:
1.1.1.8 root 2921: /* Save and restore status for a nested function. */
1.1.1.4 root 2922:
2923: void
2924: save_varasm_status (p)
2925: struct function *p;
2926: {
2927: p->const_rtx_hash_table = const_rtx_hash_table;
2928: p->const_rtx_sym_hash_table = const_rtx_sym_hash_table;
2929: p->first_pool = first_pool;
2930: p->last_pool = last_pool;
2931: p->pool_offset = pool_offset;
2932: }
2933:
2934: void
2935: restore_varasm_status (p)
2936: struct function *p;
2937: {
2938: const_rtx_hash_table = p->const_rtx_hash_table;
2939: const_rtx_sym_hash_table = p->const_rtx_sym_hash_table;
2940: first_pool = p->first_pool;
2941: last_pool = p->last_pool;
2942: pool_offset = p->pool_offset;
2943: }
2944:
1.1 root 2945: enum kind { RTX_DOUBLE, RTX_INT };
2946:
2947: struct rtx_const
2948: {
2949: #ifdef ONLY_INT_FIELDS
2950: unsigned int kind : 16;
2951: unsigned int mode : 16;
2952: #else
2953: enum kind kind : 16;
2954: enum machine_mode mode : 16;
2955: #endif
2956: union {
2957: union real_extract du;
2958: struct addr_const addr;
1.1.1.8 root 2959: struct {HOST_WIDE_INT high, low;} di;
1.1 root 2960: } un;
2961: };
2962:
2963: /* Express an rtx for a constant integer (perhaps symbolic)
2964: as the sum of a symbol or label plus an explicit integer.
2965: They are stored into VALUE. */
2966:
2967: static void
2968: decode_rtx_const (mode, x, value)
2969: enum machine_mode mode;
2970: rtx x;
2971: struct rtx_const *value;
2972: {
2973: /* Clear the whole structure, including any gaps. */
2974:
2975: {
2976: int *p = (int *) value;
2977: int *end = (int *) (value + 1);
2978: while (p < end)
2979: *p++ = 0;
2980: }
2981:
2982: value->kind = RTX_INT; /* Most usual kind. */
2983: value->mode = mode;
2984:
2985: switch (GET_CODE (x))
2986: {
2987: case CONST_DOUBLE:
2988: value->kind = RTX_DOUBLE;
1.1.1.6 root 2989: if (GET_MODE (x) != VOIDmode)
1.1.1.8 root 2990: {
2991: value->mode = GET_MODE (x);
2992: bcopy ((char *) &CONST_DOUBLE_LOW (x),
2993: (char *) &value->un.du, sizeof value->un.du);
2994: }
2995: else
2996: {
2997: value->un.di.low = CONST_DOUBLE_LOW (x);
2998: value->un.di.high = CONST_DOUBLE_HIGH (x);
2999: }
1.1 root 3000: break;
3001:
3002: case CONST_INT:
3003: value->un.addr.offset = INTVAL (x);
3004: break;
3005:
3006: case SYMBOL_REF:
3007: case LABEL_REF:
1.1.1.4 root 3008: case PC:
1.1 root 3009: value->un.addr.base = x;
3010: break;
3011:
3012: case CONST:
3013: x = XEXP (x, 0);
3014: if (GET_CODE (x) == PLUS)
3015: {
3016: value->un.addr.base = XEXP (x, 0);
3017: if (GET_CODE (XEXP (x, 1)) != CONST_INT)
3018: abort ();
3019: value->un.addr.offset = INTVAL (XEXP (x, 1));
3020: }
3021: else if (GET_CODE (x) == MINUS)
3022: {
3023: value->un.addr.base = XEXP (x, 0);
3024: if (GET_CODE (XEXP (x, 1)) != CONST_INT)
3025: abort ();
3026: value->un.addr.offset = - INTVAL (XEXP (x, 1));
3027: }
3028: else
3029: abort ();
3030: break;
3031:
3032: default:
3033: abort ();
3034: }
3035:
3036: if (value->kind == RTX_INT && value->un.addr.base != 0)
3037: switch (GET_CODE (value->un.addr.base))
3038: {
3039: case SYMBOL_REF:
3040: case LABEL_REF:
3041: /* Use the string's address, not the SYMBOL_REF's address,
3042: for the sake of addresses of library routines.
3043: For a LABEL_REF, compare labels. */
3044: value->un.addr.base = XEXP (value->un.addr.base, 0);
3045: }
3046: }
3047:
1.1.1.4 root 3048: /* Given a MINUS expression, simplify it if both sides
3049: include the same symbol. */
3050:
3051: rtx
3052: simplify_subtraction (x)
3053: rtx x;
3054: {
3055: struct rtx_const val0, val1;
3056:
3057: decode_rtx_const (GET_MODE (x), XEXP (x, 0), &val0);
3058: decode_rtx_const (GET_MODE (x), XEXP (x, 1), &val1);
3059:
3060: if (val0.un.addr.base == val1.un.addr.base)
3061: return GEN_INT (val0.un.addr.offset - val1.un.addr.offset);
3062: return x;
3063: }
3064:
1.1 root 3065: /* Compute a hash code for a constant RTL expression. */
3066:
1.1.1.8 root 3067: static int
1.1 root 3068: const_hash_rtx (mode, x)
3069: enum machine_mode mode;
3070: rtx x;
3071: {
3072: register int hi, i;
3073:
3074: struct rtx_const value;
3075: decode_rtx_const (mode, x, &value);
3076:
3077: /* Compute hashing function */
3078: hi = 0;
3079: for (i = 0; i < sizeof value / sizeof (int); i++)
3080: hi += ((int *) &value)[i];
3081:
3082: hi &= (1 << HASHBITS) - 1;
3083: hi %= MAX_RTX_HASH_TABLE;
3084: return hi;
3085: }
3086:
3087: /* Compare a constant rtl object X with a constant-descriptor DESC.
3088: Return 1 if DESC describes a constant with the same value as X. */
3089:
3090: static int
3091: compare_constant_rtx (mode, x, desc)
3092: enum machine_mode mode;
3093: rtx x;
3094: struct constant_descriptor *desc;
3095: {
3096: register int *p = (int *) desc->contents;
3097: register int *strp;
3098: register int len;
3099: struct rtx_const value;
3100:
3101: decode_rtx_const (mode, x, &value);
3102: strp = (int *) &value;
3103: len = sizeof value / sizeof (int);
3104:
3105: /* Compare constant contents. */
3106: while (--len >= 0)
3107: if (*p++ != *strp++)
3108: return 0;
3109:
3110: return 1;
3111: }
3112:
3113: /* Construct a constant descriptor for the rtl-expression X.
3114: It is up to the caller to enter the descriptor in the hash table. */
3115:
3116: static struct constant_descriptor *
3117: record_constant_rtx (mode, x)
3118: enum machine_mode mode;
3119: rtx x;
3120: {
3121: struct constant_descriptor *ptr;
3122: char *label;
3123: struct rtx_const value;
3124:
3125: decode_rtx_const (mode, x, &value);
3126:
1.1.1.7 root 3127: /* Put these things in the saveable obstack so we can ensure it won't
3128: be freed if we are called from combine or some other phase that discards
3129: memory allocated from function_obstack (current_obstack). */
3130: obstack_grow (saveable_obstack, &ptr, sizeof ptr);
3131: obstack_grow (saveable_obstack, &label, sizeof label);
1.1 root 3132:
3133: /* Record constant contents. */
1.1.1.7 root 3134: obstack_grow (saveable_obstack, &value, sizeof value);
1.1 root 3135:
1.1.1.7 root 3136: return (struct constant_descriptor *) obstack_finish (saveable_obstack);
1.1 root 3137: }
3138:
3139: /* Given a constant rtx X, make (or find) a memory constant for its value
3140: and return a MEM rtx to refer to it in memory. */
3141:
3142: rtx
3143: force_const_mem (mode, x)
3144: enum machine_mode mode;
3145: rtx x;
3146: {
3147: register int hash;
3148: register struct constant_descriptor *desc;
3149: char label[256];
3150: char *found = 0;
3151: rtx def;
3152:
3153: /* If we want this CONST_DOUBLE in the same mode as it is in memory
3154: (this will always be true for floating CONST_DOUBLEs that have been
3155: placed in memory, but not for VOIDmode (integer) CONST_DOUBLEs),
3156: use the previous copy. Otherwise, make a new one. Note that in
3157: the unlikely event that this same CONST_DOUBLE is used in two different
3158: modes in an alternating fashion, we will allocate a lot of different
3159: memory locations, but this should be extremely rare. */
3160:
1.1.1.4 root 3161: /* Don't use CONST_DOUBLE_MEM in a nested function.
3162: Nested functions have their own constant pools,
3163: so they can't share the same values in CONST_DOUBLE_MEM
3164: with the containing function. */
3165: if (outer_function_chain == 0)
3166: if (GET_CODE (x) == CONST_DOUBLE
3167: && GET_CODE (CONST_DOUBLE_MEM (x)) == MEM
3168: && GET_MODE (CONST_DOUBLE_MEM (x)) == mode)
3169: return CONST_DOUBLE_MEM (x);
1.1 root 3170:
3171: /* Compute hash code of X. Search the descriptors for that hash code
3172: to see if any of them describes X. If yes, the descriptor records
3173: the label number already assigned. */
3174:
3175: hash = const_hash_rtx (mode, x);
3176:
3177: for (desc = const_rtx_hash_table[hash]; desc; desc = desc->next)
3178: if (compare_constant_rtx (mode, x, desc))
3179: {
3180: found = desc->label;
3181: break;
3182: }
3183:
3184: if (found == 0)
3185: {
3186: register struct pool_constant *pool;
3187: register struct pool_sym *sym;
3188: int align;
3189:
3190: /* No constant equal to X is known to have been output.
3191: Make a constant descriptor to enter X in the hash table.
3192: Assign the label number and record it in the descriptor for
3193: future calls to this function to find. */
3194:
3195: desc = record_constant_rtx (mode, x);
3196: desc->next = const_rtx_hash_table[hash];
3197: const_rtx_hash_table[hash] = desc;
3198:
3199: /* Align the location counter as required by EXP's data type. */
3200: align = (mode == VOIDmode) ? UNITS_PER_WORD : GET_MODE_SIZE (mode);
3201: if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT)
3202: align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
3203:
3204: pool_offset += align - 1;
3205: pool_offset &= ~ (align - 1);
3206:
1.1.1.7 root 3207: /* If RTL is not being placed into the saveable obstack, make a
3208: copy of X that is in the saveable obstack in case we are being
3209: called from combine or some other phase that discards memory
3210: it allocates. We need only do this if it is a CONST, since
3211: no other RTX should be allocated in this situation. */
3212: if (rtl_obstack != saveable_obstack
3213: && GET_CODE (x) == CONST)
3214: {
3215: push_obstacks_nochange ();
3216: rtl_in_saveable_obstack ();
3217:
3218: x = gen_rtx (CONST, GET_MODE (x),
3219: gen_rtx (PLUS, GET_MODE (x),
3220: XEXP (XEXP (x, 0), 0), XEXP (XEXP (x, 0), 1)));
3221: pop_obstacks ();
3222: }
3223:
1.1 root 3224: /* Allocate a pool constant descriptor, fill it in, and chain it in. */
3225:
1.1.1.7 root 3226: pool = (struct pool_constant *) savealloc (sizeof (struct pool_constant));
1.1 root 3227: pool->desc = desc;
3228: pool->constant = x;
3229: pool->mode = mode;
3230: pool->labelno = const_labelno;
3231: pool->align = align;
3232: pool->offset = pool_offset;
3233: pool->next = 0;
3234:
3235: if (last_pool == 0)
3236: first_pool = pool;
3237: else
3238: last_pool->next = pool;
3239:
3240: last_pool = pool;
3241: pool_offset += GET_MODE_SIZE (mode);
3242:
3243: /* Create a string containing the label name, in LABEL. */
3244: ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
3245:
3246: ++const_labelno;
3247:
3248: desc->label = found
3249: = (char *) obstack_copy0 (saveable_obstack, label, strlen (label));
3250:
3251: /* Add label to symbol hash table. */
3252: hash = SYMHASH (found);
1.1.1.7 root 3253: sym = (struct pool_sym *) savealloc (sizeof (struct pool_sym));
1.1 root 3254: sym->label = found;
3255: sym->pool = pool;
3256: sym->next = const_rtx_sym_hash_table[hash];
3257: const_rtx_sym_hash_table[hash] = sym;
3258: }
3259:
3260: /* We have a symbol name; construct the SYMBOL_REF and the MEM. */
3261:
3262: def = gen_rtx (MEM, mode, gen_rtx (SYMBOL_REF, Pmode, found));
3263:
3264: RTX_UNCHANGING_P (def) = 1;
3265: /* Mark the symbol_ref as belonging to this constants pool. */
3266: CONSTANT_POOL_ADDRESS_P (XEXP (def, 0)) = 1;
3267: current_function_uses_const_pool = 1;
3268:
1.1.1.4 root 3269: if (outer_function_chain == 0)
3270: if (GET_CODE (x) == CONST_DOUBLE)
3271: {
3272: if (CONST_DOUBLE_MEM (x) == cc0_rtx)
3273: {
3274: CONST_DOUBLE_CHAIN (x) = const_double_chain;
3275: const_double_chain = x;
3276: }
3277: CONST_DOUBLE_MEM (x) = def;
3278: }
1.1 root 3279:
3280: return def;
3281: }
3282:
3283: /* Given a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true, return a pointer to
3284: the corresponding pool_constant structure. */
3285:
3286: static struct pool_constant *
3287: find_pool_constant (addr)
3288: rtx addr;
3289: {
3290: struct pool_sym *sym;
3291: char *label = XSTR (addr, 0);
3292:
3293: for (sym = const_rtx_sym_hash_table[SYMHASH (label)]; sym; sym = sym->next)
3294: if (sym->label == label)
3295: return sym->pool;
3296:
3297: abort ();
3298: }
3299:
3300: /* Given a constant pool SYMBOL_REF, return the corresponding constant. */
3301:
3302: rtx
3303: get_pool_constant (addr)
3304: rtx addr;
3305: {
3306: return (find_pool_constant (addr))->constant;
3307: }
3308:
3309: /* Similar, return the mode. */
3310:
3311: enum machine_mode
3312: get_pool_mode (addr)
3313: rtx addr;
3314: {
3315: return (find_pool_constant (addr))->mode;
3316: }
3317:
3318: /* Similar, return the offset in the constant pool. */
3319:
3320: int
3321: get_pool_offset (addr)
3322: rtx addr;
3323: {
3324: return (find_pool_constant (addr))->offset;
3325: }
3326:
3327: /* Return the size of the constant pool. */
3328:
3329: int
3330: get_pool_size ()
3331: {
3332: return pool_offset;
3333: }
3334:
3335: /* Write all the constants in the constant pool. */
3336:
3337: void
3338: output_constant_pool (fnname, fndecl)
3339: char *fnname;
3340: tree fndecl;
3341: {
3342: struct pool_constant *pool;
3343: rtx x;
3344: union real_extract u;
3345:
3346: #ifdef ASM_OUTPUT_POOL_PROLOGUE
3347: ASM_OUTPUT_POOL_PROLOGUE (asm_out_file, fnname, fndecl, pool_offset);
3348: #endif
3349:
3350: for (pool = first_pool; pool; pool = pool->next)
3351: {
3352: x = pool->constant;
3353:
3354: /* See if X is a LABEL_REF (or a CONST referring to a LABEL_REF)
3355: whose CODE_LABEL has been deleted. This can occur if a jump table
3356: is eliminated by optimization. If so, write a constant of zero
1.1.1.4 root 3357: instead. Note that this can also happen by turning the
3358: CODE_LABEL into a NOTE. */
3359: if (((GET_CODE (x) == LABEL_REF
3360: && (INSN_DELETED_P (XEXP (x, 0))
3361: || GET_CODE (XEXP (x, 0)) == NOTE)))
1.1 root 3362: || (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
3363: && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
1.1.1.4 root 3364: && (INSN_DELETED_P (XEXP (XEXP (XEXP (x, 0), 0), 0))
3365: || GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == NOTE)))
1.1 root 3366: x = const0_rtx;
3367:
3368: /* First switch to correct section. */
3369: #ifdef SELECT_RTX_SECTION
3370: SELECT_RTX_SECTION (pool->mode, x);
3371: #else
3372: readonly_data_section ();
3373: #endif
3374:
3375: #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY
3376: ASM_OUTPUT_SPECIAL_POOL_ENTRY (asm_out_file, x, pool->mode,
3377: pool->align, pool->labelno, done);
3378: #endif
3379:
3380: if (pool->align > 1)
3381: ASM_OUTPUT_ALIGN (asm_out_file, exact_log2 (pool->align));
3382:
3383: /* Output the label. */
3384: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", pool->labelno);
3385:
3386: /* Output the value of the constant itself. */
3387: switch (GET_MODE_CLASS (pool->mode))
3388: {
3389: case MODE_FLOAT:
3390: if (GET_CODE (x) != CONST_DOUBLE)
3391: abort ();
3392:
1.1.1.7 root 3393: bcopy ((char *) &CONST_DOUBLE_LOW (x), (char *) &u, sizeof u);
1.1 root 3394: assemble_real (u.d, pool->mode);
3395: break;
3396:
3397: case MODE_INT:
1.1.1.5 root 3398: case MODE_PARTIAL_INT:
1.1 root 3399: assemble_integer (x, GET_MODE_SIZE (pool->mode), 1);
3400: break;
3401:
3402: default:
3403: abort ();
3404: }
3405:
3406: done: ;
3407: }
3408:
3409: /* Done with this pool. */
3410: first_pool = last_pool = 0;
3411: }
3412:
3413: /* Find all the constants whose addresses are referenced inside of EXP,
3414: and make sure assembler code with a label has been output for each one.
3415: Indicate whether an ADDR_EXPR has been encountered. */
3416:
1.1.1.8 root 3417: static int
1.1 root 3418: output_addressed_constants (exp)
3419: tree exp;
3420: {
3421: int reloc = 0;
3422:
3423: switch (TREE_CODE (exp))
3424: {
3425: case ADDR_EXPR:
3426: {
3427: register tree constant = TREE_OPERAND (exp, 0);
3428:
3429: while (TREE_CODE (constant) == COMPONENT_REF)
3430: {
3431: constant = TREE_OPERAND (constant, 0);
3432: }
3433:
3434: if (TREE_CODE_CLASS (TREE_CODE (constant)) == 'c'
3435: || TREE_CODE (constant) == CONSTRUCTOR)
3436: /* No need to do anything here
3437: for addresses of variables or functions. */
3438: output_constant_def (constant);
3439: }
3440: reloc = 1;
3441: break;
3442:
3443: case PLUS_EXPR:
3444: case MINUS_EXPR:
3445: reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
3446: reloc |= output_addressed_constants (TREE_OPERAND (exp, 1));
3447: break;
3448:
3449: case NOP_EXPR:
3450: case CONVERT_EXPR:
1.1.1.4 root 3451: case NON_LVALUE_EXPR:
1.1 root 3452: reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
3453: break;
3454:
3455: case CONSTRUCTOR:
3456: {
3457: register tree link;
3458: for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
3459: if (TREE_VALUE (link) != 0)
3460: reloc |= output_addressed_constants (TREE_VALUE (link));
3461: }
3462: break;
3463:
3464: case ERROR_MARK:
3465: break;
3466: }
3467: return reloc;
3468: }
3469:
3470: /* Output assembler code for constant EXP to FILE, with no label.
3471: This includes the pseudo-op such as ".int" or ".byte", and a newline.
3472: Assumes output_addressed_constants has been done on EXP already.
3473:
3474: Generate exactly SIZE bytes of assembler data, padding at the end
3475: with zeros if necessary. SIZE must always be specified.
3476:
3477: SIZE is important for structure constructors,
3478: since trailing members may have been omitted from the constructor.
3479: It is also important for initialization of arrays from string constants
3480: since the full length of the string constant might not be wanted.
3481: It is also needed for initialization of unions, where the initializer's
3482: type is just one member, and that may not be as long as the union.
3483:
3484: There a case in which we would fail to output exactly SIZE bytes:
3485: for a structure constructor that wants to produce more than SIZE bytes.
3486: But such constructors will never be generated for any possible input. */
3487:
3488: void
3489: output_constant (exp, size)
3490: register tree exp;
3491: register int size;
3492: {
3493: register enum tree_code code = TREE_CODE (TREE_TYPE (exp));
3494: rtx x;
3495:
3496: if (size == 0)
3497: return;
3498:
1.1.1.7 root 3499: /* Eliminate the NON_LVALUE_EXPR_EXPR that makes a cast not be an lvalue.
3500: That way we get the constant (we hope) inside it. Also, strip off any
1.1.1.8 root 3501: NOP_EXPR that converts between two record, union, array, or set types. */
1.1.1.7 root 3502: while ((TREE_CODE (exp) == NOP_EXPR
3503: && (TREE_TYPE (exp) == TREE_TYPE (TREE_OPERAND (exp, 0))
1.1.1.8 root 3504: || AGGREGATE_TYPE_P (TREE_TYPE (exp))))
1.1.1.7 root 3505: || TREE_CODE (exp) == NON_LVALUE_EXPR)
3506: exp = TREE_OPERAND (exp, 0);
3507:
1.1 root 3508: /* Allow a constructor with no elements for any data type.
3509: This means to fill the space with zeros. */
1.1.1.4 root 3510: if (TREE_CODE (exp) == CONSTRUCTOR && CONSTRUCTOR_ELTS (exp) == 0)
1.1 root 3511: {
1.1.1.6 root 3512: if (output_bytecode)
3513: bc_emit_const_skip (size);
3514: else
3515: assemble_zeros (size);
1.1 root 3516: return;
3517: }
3518:
3519: switch (code)
3520: {
1.1.1.5 root 3521: case CHAR_TYPE:
3522: case BOOLEAN_TYPE:
1.1 root 3523: case INTEGER_TYPE:
3524: case ENUMERAL_TYPE:
3525: case POINTER_TYPE:
3526: case REFERENCE_TYPE:
3527: /* ??? What about (int)((float)(int)&foo + 4) */
3528: while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
3529: || TREE_CODE (exp) == NON_LVALUE_EXPR)
3530: exp = TREE_OPERAND (exp, 0);
3531:
1.1.1.4 root 3532: if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode,
1.1 root 3533: EXPAND_INITIALIZER),
3534: size, 0))
3535: error ("initializer for integer value is too complicated");
3536: size = 0;
3537: break;
3538:
3539: case REAL_TYPE:
3540: if (TREE_CODE (exp) != REAL_CST)
3541: error ("initializer for floating value is not a floating constant");
3542:
3543: assemble_real (TREE_REAL_CST (exp),
3544: mode_for_size (size * BITS_PER_UNIT, MODE_FLOAT, 0));
3545: size = 0;
3546: break;
3547:
3548: case COMPLEX_TYPE:
3549: output_constant (TREE_REALPART (exp), size / 2);
3550: output_constant (TREE_IMAGPART (exp), size / 2);
3551: size -= (size / 2) * 2;
3552: break;
3553:
3554: case ARRAY_TYPE:
3555: if (TREE_CODE (exp) == CONSTRUCTOR)
3556: {
3557: output_constructor (exp, size);
3558: return;
3559: }
3560: else if (TREE_CODE (exp) == STRING_CST)
3561: {
3562: int excess = 0;
3563:
3564: if (size > TREE_STRING_LENGTH (exp))
3565: {
3566: excess = size - TREE_STRING_LENGTH (exp);
3567: size = TREE_STRING_LENGTH (exp);
3568: }
3569:
3570: assemble_string (TREE_STRING_POINTER (exp), size);
3571: size = excess;
3572: }
3573: else
3574: abort ();
3575: break;
3576:
3577: case RECORD_TYPE:
3578: case UNION_TYPE:
3579: if (TREE_CODE (exp) == CONSTRUCTOR)
3580: output_constructor (exp, size);
3581: else
3582: abort ();
3583: return;
1.1.1.8 root 3584:
3585: case SET_TYPE:
3586: if (TREE_CODE (exp) == INTEGER_CST)
3587: assemble_integer (expand_expr (exp, NULL_RTX,
3588: VOIDmode, EXPAND_INITIALIZER),
3589: size, 1);
3590: else if (TREE_CODE (exp) == CONSTRUCTOR)
3591: {
3592: unsigned char *buffer = (unsigned char *) alloca (size);
3593: if (get_set_constructor_bytes (exp, buffer, size))
3594: abort ();
3595: assemble_string ((char *) buffer, size);
3596: }
3597: else
3598: error ("unknown set constructor type");
3599: return;
1.1 root 3600: }
3601:
3602: if (size > 0)
3603: assemble_zeros (size);
3604: }
1.1.1.6 root 3605:
3606: /* Bytecode specific code to output assembler for integer. */
1.1.1.8 root 3607:
1.1.1.6 root 3608: static void
3609: bc_assemble_integer (exp, size)
3610: tree exp;
3611: int size;
3612: {
3613: tree const_part;
3614: tree addr_part;
3615: tree tmp;
3616:
3617: /* FIXME: is this fold() business going to be as good as the
3618: expand_expr() using EXPAND_SUM above in the RTL case? I
3619: hate RMS.
3620: FIXME: Copied as is from BC-GCC1; may need work. Don't hate. -bson */
3621:
3622: exp = fold (exp);
3623:
3624: while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR)
3625: exp = TREE_OPERAND (exp, 0);
3626: if (TREE_CODE (exp) == INTEGER_CST)
3627: {
3628: const_part = exp;
3629: addr_part = 0;
3630: }
3631: else if (TREE_CODE (exp) == PLUS_EXPR)
3632: {
3633: const_part = TREE_OPERAND (exp, 0);
3634: while (TREE_CODE (const_part) == NOP_EXPR
3635: || TREE_CODE (const_part) == CONVERT_EXPR)
3636: const_part = TREE_OPERAND (const_part, 0);
3637: addr_part = TREE_OPERAND (exp, 1);
3638: while (TREE_CODE (addr_part) == NOP_EXPR
3639: || TREE_CODE (addr_part) == CONVERT_EXPR)
3640: addr_part = TREE_OPERAND (addr_part, 0);
3641: if (TREE_CODE (const_part) != INTEGER_CST)
3642: tmp = const_part, const_part = addr_part, addr_part = tmp;
3643: if (TREE_CODE (const_part) != INTEGER_CST
3644: || TREE_CODE (addr_part) != ADDR_EXPR)
3645: abort (); /* FIXME: we really haven't considered
3646: all the possible cases here. */
3647: }
3648: else if (TREE_CODE (exp) == ADDR_EXPR)
3649: {
3650: const_part = integer_zero_node;
3651: addr_part = exp;
3652: }
3653: else
3654: abort (); /* FIXME: ditto previous. */
3655:
3656: if (addr_part == 0)
3657: {
3658: if (size == 1)
3659: {
3660: char c = TREE_INT_CST_LOW (const_part);
3661: bc_emit (&c, 1);
3662: size -= 1;
3663: }
3664: else if (size == 2)
3665: {
3666: short s = TREE_INT_CST_LOW (const_part);
3667: bc_emit ((char *) &s, 2);
3668: size -= 2;
3669: }
3670: else if (size == 4)
3671: {
3672: int i = TREE_INT_CST_LOW (const_part);
3673: bc_emit ((char *) &i, 4);
3674: size -= 4;
3675: }
3676: else if (size == 8)
3677: {
1.1.1.8 root 3678: if (WORDS_BIG_ENDIAN)
3679: {
3680: int i = TREE_INT_CST_HIGH (const_part);
3681: bc_emit ((char *) &i, 4);
3682: i = TREE_INT_CST_LOW (const_part);
3683: bc_emit ((char *) &i, 4);
3684: }
3685: else
3686: {
3687: int i = TREE_INT_CST_LOW (const_part);
3688: bc_emit ((char *) &i, 4);
3689: i = TREE_INT_CST_HIGH (const_part);
3690: bc_emit ((char *) &i, 4);
3691: }
1.1.1.6 root 3692: size -= 8;
3693: }
3694: }
3695: else
3696: if (size == 4
3697: && TREE_CODE (TREE_OPERAND (addr_part, 0)) == VAR_DECL)
1.1.1.8 root 3698: bc_emit_labelref (IDENTIFIER_POINTER
3699: (DECL_ASSEMBLER_NAME (TREE_OPERAND (addr_part, 0))),
1.1.1.6 root 3700: TREE_INT_CST_LOW (const_part));
3701: else
3702: abort (); /* FIXME: there may be more cases. */
3703: }
1.1 root 3704:
3705: /* Subroutine of output_constant, used for CONSTRUCTORs
3706: (aggregate constants).
3707: Generate at least SIZE bytes, padding if necessary. */
3708:
1.1.1.8 root 3709: static void
1.1 root 3710: output_constructor (exp, size)
3711: tree exp;
3712: int size;
3713: {
3714: register tree link, field = 0;
1.1.1.6 root 3715: HOST_WIDE_INT min_index = 0;
1.1 root 3716: /* Number of bytes output or skipped so far.
3717: In other words, current position within the constructor. */
3718: int total_bytes = 0;
3719: /* Non-zero means BYTE contains part of a byte, to be output. */
3720: int byte_buffer_in_use = 0;
3721: register int byte;
3722:
1.1.1.4 root 3723: if (HOST_BITS_PER_WIDE_INT < BITS_PER_UNIT)
1.1 root 3724: abort ();
3725:
3726: if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
3727: field = TYPE_FIELDS (TREE_TYPE (exp));
3728:
1.1.1.6 root 3729: if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
3730: && TYPE_DOMAIN (TREE_TYPE (exp)) != 0)
3731: min_index
3732: = TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (exp))));
3733:
1.1 root 3734: /* As LINK goes through the elements of the constant,
3735: FIELD goes through the structure fields, if the constant is a structure.
3736: if the constant is a union, then we override this,
3737: by getting the field from the TREE_LIST element.
3738: But the constant could also be an array. Then FIELD is zero. */
3739: for (link = CONSTRUCTOR_ELTS (exp);
3740: link;
3741: link = TREE_CHAIN (link),
3742: field = field ? TREE_CHAIN (field) : 0)
3743: {
3744: tree val = TREE_VALUE (link);
1.1.1.6 root 3745: tree index = 0;
3746:
1.1 root 3747: /* the element in a union constructor specifies the proper field. */
1.1.1.6 root 3748:
3749: if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
3750: || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE)
3751: {
3752: /* if available, use the type given by link */
3753: if (TREE_PURPOSE (link) != 0)
3754: field = TREE_PURPOSE (link);
3755: }
3756:
3757: if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
3758: index = TREE_PURPOSE (link);
1.1 root 3759:
3760: /* Eliminate the marker that makes a cast not be an lvalue. */
1.1.1.4 root 3761: if (val != 0)
3762: STRIP_NOPS (val);
1.1 root 3763:
3764: if (field == 0 || !DECL_BIT_FIELD (field))
3765: {
1.1.1.6 root 3766: /* An element that is not a bit-field. */
3767:
1.1 root 3768: register int fieldsize;
3769: /* Since this structure is static,
3770: we know the positions are constant. */
3771: int bitpos = (field ? (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
3772: / BITS_PER_UNIT)
3773: : 0);
1.1.1.6 root 3774: if (index != 0)
3775: bitpos = (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (val)))
3776: / BITS_PER_UNIT
3777: * (TREE_INT_CST_LOW (index) - min_index));
1.1 root 3778:
1.1.1.6 root 3779: /* Output any buffered-up bit-fields preceding this element. */
1.1 root 3780: if (byte_buffer_in_use)
3781: {
3782: ASM_OUTPUT_BYTE (asm_out_file, byte);
3783: total_bytes++;
3784: byte_buffer_in_use = 0;
3785: }
3786:
3787: /* Advance to offset of this element.
3788: Note no alignment needed in an array, since that is guaranteed
3789: if each element has the proper size. */
1.1.1.6 root 3790: if ((field != 0 || index != 0) && bitpos != total_bytes)
1.1 root 3791: {
1.1.1.6 root 3792: if (!output_bytecode)
3793: assemble_zeros (bitpos - total_bytes);
3794: else
3795: bc_emit_const_skip (bitpos - total_bytes);
1.1 root 3796: total_bytes = bitpos;
3797: }
3798:
3799: /* Determine size this element should occupy. */
3800: if (field)
3801: {
3802: if (TREE_CODE (DECL_SIZE (field)) != INTEGER_CST)
3803: abort ();
3804: if (TREE_INT_CST_LOW (DECL_SIZE (field)) > 100000)
3805: {
3806: /* This avoids overflow trouble. */
3807: tree size_tree = size_binop (CEIL_DIV_EXPR,
3808: DECL_SIZE (field),
3809: size_int (BITS_PER_UNIT));
3810: fieldsize = TREE_INT_CST_LOW (size_tree);
3811: }
3812: else
3813: {
3814: fieldsize = TREE_INT_CST_LOW (DECL_SIZE (field));
3815: fieldsize = (fieldsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
3816: }
3817: }
3818: else
3819: fieldsize = int_size_in_bytes (TREE_TYPE (TREE_TYPE (exp)));
3820:
3821: /* Output the element's initial value. */
3822: if (val == 0)
3823: assemble_zeros (fieldsize);
3824: else
3825: output_constant (val, fieldsize);
3826:
3827: /* Count its size. */
3828: total_bytes += fieldsize;
3829: }
3830: else if (val != 0 && TREE_CODE (val) != INTEGER_CST)
3831: error ("invalid initial value for member `%s'",
3832: IDENTIFIER_POINTER (DECL_NAME (field)));
3833: else
3834: {
3835: /* Element that is a bit-field. */
3836:
3837: int next_offset = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field));
3838: int end_offset
3839: = (next_offset + TREE_INT_CST_LOW (DECL_SIZE (field)));
3840:
3841: if (val == 0)
3842: val = integer_zero_node;
3843:
3844: /* If this field does not start in this (or, next) byte,
3845: skip some bytes. */
3846: if (next_offset / BITS_PER_UNIT != total_bytes)
3847: {
3848: /* Output remnant of any bit field in previous bytes. */
3849: if (byte_buffer_in_use)
3850: {
3851: ASM_OUTPUT_BYTE (asm_out_file, byte);
3852: total_bytes++;
3853: byte_buffer_in_use = 0;
3854: }
3855:
3856: /* If still not at proper byte, advance to there. */
3857: if (next_offset / BITS_PER_UNIT != total_bytes)
3858: {
3859: assemble_zeros (next_offset / BITS_PER_UNIT - total_bytes);
3860: total_bytes = next_offset / BITS_PER_UNIT;
3861: }
3862: }
3863:
3864: if (! byte_buffer_in_use)
3865: byte = 0;
3866:
3867: /* We must split the element into pieces that fall within
3868: separate bytes, and combine each byte with previous or
3869: following bit-fields. */
3870:
1.1.1.2 root 3871: /* next_offset is the offset n fbits from the beginning of
1.1 root 3872: the structure to the next bit of this element to be processed.
3873: end_offset is the offset of the first bit past the end of
3874: this element. */
3875: while (next_offset < end_offset)
3876: {
3877: int this_time;
1.1.1.8 root 3878: int shift;
3879: HOST_WIDE_INT value;
1.1 root 3880: int next_byte = next_offset / BITS_PER_UNIT;
3881: int next_bit = next_offset % BITS_PER_UNIT;
3882:
3883: /* Advance from byte to byte
3884: within this element when necessary. */
3885: while (next_byte != total_bytes)
3886: {
3887: ASM_OUTPUT_BYTE (asm_out_file, byte);
3888: total_bytes++;
3889: byte = 0;
3890: }
3891:
3892: /* Number of bits we can process at once
3893: (all part of the same byte). */
3894: this_time = MIN (end_offset - next_offset,
3895: BITS_PER_UNIT - next_bit);
1.1.1.8 root 3896: if (BYTES_BIG_ENDIAN)
1.1 root 3897: {
1.1.1.8 root 3898: /* On big-endian machine, take the most significant bits
3899: first (of the bits that are significant)
3900: and put them into bytes from the most significant end. */
3901: shift = end_offset - next_offset - this_time;
3902: /* Don't try to take a bunch of bits that cross
3903: the word boundary in the INTEGER_CST. */
3904: if (shift < HOST_BITS_PER_WIDE_INT
3905: && shift + this_time > HOST_BITS_PER_WIDE_INT)
3906: {
3907: this_time -= (HOST_BITS_PER_WIDE_INT - shift);
3908: shift = HOST_BITS_PER_WIDE_INT;
3909: }
3910:
3911: /* Now get the bits from the appropriate constant word. */
3912: if (shift < HOST_BITS_PER_WIDE_INT)
3913: {
3914: value = TREE_INT_CST_LOW (val);
3915: }
3916: else if (shift < 2 * HOST_BITS_PER_WIDE_INT)
3917: {
3918: value = TREE_INT_CST_HIGH (val);
3919: shift -= HOST_BITS_PER_WIDE_INT;
3920: }
3921: else
3922: abort ();
3923: byte |= (((value >> shift)
3924: & (((HOST_WIDE_INT) 1 << this_time) - 1))
3925: << (BITS_PER_UNIT - this_time - next_bit));
1.1 root 3926: }
3927: else
3928: {
1.1.1.8 root 3929: /* On little-endian machines,
3930: take first the least significant bits of the value
3931: and pack them starting at the least significant
3932: bits of the bytes. */
3933: shift = (next_offset
3934: - TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)));
3935: /* Don't try to take a bunch of bits that cross
3936: the word boundary in the INTEGER_CST. */
3937: if (shift < HOST_BITS_PER_WIDE_INT
3938: && shift + this_time > HOST_BITS_PER_WIDE_INT)
3939: {
3940: this_time -= (HOST_BITS_PER_WIDE_INT - shift);
3941: shift = HOST_BITS_PER_WIDE_INT;
3942: }
3943:
3944: /* Now get the bits from the appropriate constant word. */
3945: if (shift < HOST_BITS_PER_INT)
3946: value = TREE_INT_CST_LOW (val);
3947: else if (shift < 2 * HOST_BITS_PER_WIDE_INT)
3948: {
3949: value = TREE_INT_CST_HIGH (val);
3950: shift -= HOST_BITS_PER_WIDE_INT;
3951: }
3952: else
3953: abort ();
3954: byte |= (((value >> shift)
3955: & (((HOST_WIDE_INT) 1 << this_time) - 1))
3956: << next_bit);
1.1 root 3957: }
3958: next_offset += this_time;
3959: byte_buffer_in_use = 1;
3960: }
3961: }
3962: }
3963: if (byte_buffer_in_use)
3964: {
3965: ASM_OUTPUT_BYTE (asm_out_file, byte);
3966: total_bytes++;
3967: }
3968: if (total_bytes < size)
3969: assemble_zeros (size - total_bytes);
3970: }
1.1.1.6 root 3971:
3972: /* Output asm to handle ``#pragma weak'' */
3973: void
1.1.1.8 root 3974: handle_pragma_weak (what, name, value)
1.1.1.6 root 3975: enum pragma_state what;
3976: char *name, *value;
3977: {
1.1.1.8 root 3978: #ifdef HANDLE_PRAGMA_WEAK
1.1.1.6 root 3979: if (what == ps_name || what == ps_value)
3980: {
1.1.1.8 root 3981: struct weak_syms *weak =
3982: (struct weak_syms *)permalloc (sizeof (struct weak_syms));
3983: weak->next = weak_decls;
3984: weak->name = permalloc (strlen (name) + 1);
3985: strcpy (weak->name, name);
3986:
3987: if (what != ps_value)
3988: weak->value = NULL_PTR;
1.1.1.6 root 3989:
3990: else
1.1.1.8 root 3991: {
3992: weak->value = permalloc (strlen (value) + 1);
3993: strcpy (weak->value, value);
3994: }
1.1.1.6 root 3995:
1.1.1.8 root 3996: weak_decls = weak;
1.1.1.6 root 3997: }
3998: else if (! (what == ps_done || what == ps_start))
3999: warning ("malformed `#pragma weak'");
1.1.1.8 root 4000: #endif /* HANDLE_PRAGMA_WEAK */
4001: }
4002:
4003: /* Declare DECL to be a weak symbol. */
4004:
4005: void
4006: declare_weak (decl)
4007: tree decl;
4008: {
4009: if (! TREE_PUBLIC (decl))
4010: error_with_decl (decl, "weak declaration of `%s' must be public");
4011: else if (TREE_ASM_WRITTEN (decl))
4012: error_with_decl (decl, "weak declaration of `%s' must precede definition");
4013: else if (SUPPORTS_WEAK)
4014: DECL_WEAK (decl) = 1;
1.1.1.6 root 4015: }
4016:
1.1.1.8 root 4017: /* Emit any pending weak declarations. */
1.1.1.6 root 4018:
1.1.1.8 root 4019: void
4020: weak_finish ()
4021: {
4022: #ifdef HANDLE_PRAGMA_WEAK
4023: if (HANDLE_PRAGMA_WEAK)
4024: {
4025: struct weak_syms *t;
4026: for (t = weak_decls; t; t = t->next)
4027: {
4028: ASM_WEAKEN_LABEL (asm_out_file, t->name);
4029: if (t->value)
4030: ASM_OUTPUT_DEF (asm_out_file, t->name, t->value);
4031: }
4032: }
4033: #endif
4034: }
4035:
4036: void
4037: assemble_alias (decl, target)
4038: tree decl, target;
4039: {
4040: #ifdef ASM_OUTPUT_DEF
4041: char *name;
4042:
4043: make_decl_rtl (decl, (char*)0, 1);
4044: name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
4045:
4046: /* Make name accessible from other files, if appropriate. */
4047:
4048: if (TREE_PUBLIC (decl))
4049: {
4050: #ifdef ASM_WEAKEN_LABEL
4051: if (DECL_WEAK (decl))
4052: ASM_WEAKEN_LABEL (asm_out_file, name);
4053: else
4054: #endif
4055: if (output_bytecode)
4056: BC_GLOBALIZE_LABEL (asm_out_file, name);
4057: else
4058: ASM_GLOBALIZE_LABEL (asm_out_file, name);
4059: }
4060:
4061: ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
4062: TREE_ASM_WRITTEN (decl) = 1;
4063: #else
4064: warning ("alias definitions not supported in this configuration");
4065: #endif
4066: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.