|
|
1.1 root 1: /* Output variables, constants and external declarations, for GNU compiler.
2: Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 2, or (at your option)
9: any later version.
10:
11: GNU CC is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU CC; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
20:
21: /* This file handles generation of all the assembler code
22: *except* the instructions of a function.
23: This includes declarations of variables and their initial values.
24:
25: We also output the assembler code for constants stored in memory
26: and are responsible for combining constants with the same value. */
27:
28: #include <stdio.h>
29: #include <setjmp.h>
30: /* #include <stab.h> */
31: #include "config.h"
32: #include "rtl.h"
33: #include "tree.h"
34: #include "flags.h"
35: #include "expr.h"
36: #include "hard-reg-set.h"
37: #include "regs.h"
1.1.1.3 ! root 38: #include "defaults.h"
1.1 root 39:
40: #include "obstack.h"
41:
1.1.1.2 root 42: #ifdef XCOFF_DEBUGGING_INFO
43: #include "xcoffout.h"
44: #endif
45:
1.1 root 46: #ifndef ASM_STABS_OP
47: #define ASM_STABS_OP ".stabs"
48: #endif
49:
50: /* File in which assembler code is being written. */
51:
52: extern FILE *asm_out_file;
53:
54: /* The (assembler) name of the first globally-visible object output. */
55: char *first_global_object_name;
56:
57: extern struct obstack *current_obstack;
58: extern struct obstack *saveable_obstack;
59: extern struct obstack permanent_obstack;
60: #define obstack_chunk_alloc xmalloc
61: extern int xmalloc ();
62:
63: /* Number for making the label on the next
64: constant that is stored in memory. */
65:
66: int const_labelno;
67:
68: /* Number for making the label on the next
69: static variable internal to a function. */
70:
71: int var_labelno;
72:
73: /* Nonzero if at least one function definition has been seen. */
74: static int function_defined;
75:
76: extern FILE *asm_out_file;
77:
78: static char *compare_constant_1 ();
79: static void record_constant_1 ();
80: void output_constant_pool ();
81: void assemble_name ();
82: int output_addressed_constants ();
83: void output_constant ();
84: void output_constructor ();
1.1.1.2 root 85: void data_section ();
1.1 root 86:
87: #ifdef EXTRA_SECTIONS
88: static enum in_section {no_section, in_text, in_data, EXTRA_SECTIONS} in_section
89: = no_section;
90: #else
91: static enum in_section {no_section, in_text, in_data} in_section
92: = no_section;
93: #endif
94:
95: /* Define functions like text_section for any extra sections. */
96: #ifdef EXTRA_SECTION_FUNCTIONS
97: EXTRA_SECTION_FUNCTIONS
98: #endif
99:
100: /* Tell assembler to switch to text section. */
101:
102: void
103: text_section ()
104: {
105: if (in_section != in_text)
106: {
107: fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
108: in_section = in_text;
109: }
110: }
111:
112: /* Tell assembler to switch to data section. */
113:
114: void
115: data_section ()
116: {
117: if (in_section != in_data)
118: {
119: if (flag_shared_data)
120: {
121: #ifdef SHARED_SECTION_ASM_OP
122: fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
123: #else
124: fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
125: #endif
126: }
127: else
128: fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
129:
130: in_section = in_data;
131: }
132: }
133:
1.1.1.3 ! root 134: /* Tell assembler to switch to read-only data section. This is normally
! 135: the text section. */
! 136:
! 137: void
! 138: readonly_data_section ()
! 139: {
! 140: #ifdef READONLY_DATA_SECTION
! 141: READONLY_DATA_SECTION (); /* Note this can call data_section. */
! 142: #else
! 143: text_section ();
! 144: #endif
! 145: }
! 146:
1.1 root 147: /* Determine if we're in the text section. */
148:
149: int
150: in_text_section ()
151: {
152: return in_section == in_text;
153: }
154:
155: /* Create the rtl to represent a function, for a function definition.
156: DECL is a FUNCTION_DECL node which describes which function.
157: The rtl is stored into DECL. */
158:
159: void
160: make_function_rtl (decl)
161: tree decl;
162: {
163: char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
164:
165: /* Rename a nested function to avoid conflicts. */
166: if (decl_function_context (decl) != 0
167: && DECL_INITIAL (decl) != 0
168: && DECL_RTL (decl) == 0)
169: {
170: char *label;
171:
172: name = IDENTIFIER_POINTER (DECL_NAME (decl));
173: ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
174: name = obstack_copy0 (saveable_obstack, label, strlen (label));
175: var_labelno++;
176: }
177:
178: if (DECL_RTL (decl) == 0)
179: {
180: DECL_RTL (decl)
181: = gen_rtx (MEM, DECL_MODE (decl),
182: gen_rtx (SYMBOL_REF, Pmode, name));
183:
184: /* Optionally set flags or add text to the name to record information
185: such as that it is a function name. If the name is changed, the macro
186: ASM_OUTPUT_LABELREF will have to know how to strip this information.
187: And if it finds a * at the beginning after doing so, it must handle
188: that too. */
189: #ifdef ENCODE_SECTION_INFO
190: ENCODE_SECTION_INFO (decl);
191: #endif
192: }
193:
194: /* Record at least one function has been defined. */
195: function_defined = 1;
196: }
197:
1.1.1.2 root 198: /* Given NAME, a putative register name, discard any customary prefixes. */
199:
200: static char *
201: strip_reg_name (name)
202: char *name;
203: {
204: #ifdef REGISTER_PREFIX
205: if (!strncmp (name, REGISTER_PREFIX, strlen (REGISTER_PREFIX)))
206: name += strlen (REGISTER_PREFIX);
207: #endif
208: if (name[0] == '%' || name[0] == '#')
209: name++;
210: return name;
211: }
1.1.1.3 ! root 212:
1.1 root 213: /* Decode an `asm' spec for a declaration as a register name.
214: Return the register number, or -1 if nothing specified,
1.1.1.3 ! root 215: or -2 if the ASMSPEC is not `cc' and is not recognized,
! 216: or -3 if ASMSPEC is `cc' and is not recognized.
! 217: Accept an exact spelling or a decimal number.
! 218: Prefixes such as % are optional. */
1.1 root 219:
220: int
221: decode_reg_name (asmspec)
222: char *asmspec;
223: {
224: if (asmspec != 0)
225: {
226: int i;
227:
1.1.1.2 root 228: /* Get rid of confusing prefixes. */
229: asmspec = strip_reg_name (asmspec);
230:
1.1 root 231: /* Allow a decimal number as a "register name". */
232: for (i = strlen (asmspec) - 1; i >= 0; i--)
233: if (! (asmspec[i] >= '0' && asmspec[i] <= '9'))
234: break;
235: if (asmspec[0] != 0 && i < 0)
236: {
237: i = atoi (asmspec);
238: if (i < FIRST_PSEUDO_REGISTER && i >= 0)
239: return i;
240: else
241: return -2;
242: }
243:
244: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1.1.1.2 root 245: if (reg_names[i][0]
246: && ! strcmp (asmspec, strip_reg_name (reg_names[i])))
1.1 root 247: return i;
248:
249: #ifdef ADDITIONAL_REGISTER_NAMES
250: {
251: static struct { char *name; int number; } table[]
252: = ADDITIONAL_REGISTER_NAMES;
253:
254: for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
255: if (! strcmp (asmspec, table[i].name))
256: return table[i].number;
257: }
258: #endif /* ADDITIONAL_REGISTER_NAMES */
259:
1.1.1.3 ! root 260: if (!strcmp (asmspec, "cc"))
! 261: return -3;
! 262:
1.1 root 263: return -2;
264: }
265:
266: return -1;
267: }
268:
269: /* Create the DECL_RTL for a declaration for a static or external variable
270: or static or external function.
271: ASMSPEC, if not 0, is the string which the user specified
272: as the assembler symbol name.
273: TOP_LEVEL is nonzero if this is a file-scope variable.
274:
275: This is never called for PARM_DECL nodes. */
276:
277: void
278: make_decl_rtl (decl, asmspec, top_level)
279: tree decl;
280: char *asmspec;
281: int top_level;
282: {
283: register char *name;
284: int reg_number = decode_reg_name (asmspec);
285:
286: if (DECL_ASSEMBLER_NAME (decl) != NULL_TREE)
287: name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
288:
289: if (reg_number == -2)
290: {
291: /* ASMSPEC is given, and not the name of a register. */
292: name = (char *) obstack_alloc (saveable_obstack,
293: strlen (asmspec) + 2);
294: name[0] = '*';
295: strcpy (&name[1], asmspec);
296: }
297:
298: /* For a duplicate declaration, we can be called twice on the
299: same DECL node. Don't alter the RTL already made
300: unless the old mode is wrong (which can happen when
301: the previous rtl was made when the type was incomplete). */
302: if (DECL_RTL (decl) == 0
303: || GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl))
304: {
305: DECL_RTL (decl) = 0;
306:
307: /* First detect errors in declaring global registers. */
308: if (TREE_REGDECL (decl) && reg_number == -1)
309: error_with_decl (decl,
310: "register name not specified for `%s'");
1.1.1.3 ! root 311: else if (TREE_REGDECL (decl) && reg_number < 0)
1.1 root 312: error_with_decl (decl,
313: "invalid register name for `%s'");
1.1.1.3 ! root 314: else if ((reg_number >= 0 || reg_number == -3) && ! TREE_REGDECL (decl))
1.1 root 315: error_with_decl (decl,
316: "register name given for non-register variable `%s'");
317: else if (TREE_REGDECL (decl) && TREE_CODE (decl) == FUNCTION_DECL)
318: error ("function declared `register'");
319: else if (TREE_REGDECL (decl) && TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
320: error_with_decl (decl, "data type of `%s' isn't suitable for a register");
321: /* Now handle properly declared static register variables. */
322: else if (TREE_REGDECL (decl))
323: {
324: int nregs;
325: #if 0 /* yylex should print the warning for this */
326: if (pedantic)
327: pedwarn ("ANSI C forbids global register variables");
328: #endif
329: if (DECL_INITIAL (decl) != 0 && top_level)
330: {
331: DECL_INITIAL (decl) = 0;
332: error ("global register variable has initial value");
333: }
334: if (fixed_regs[reg_number] == 0
335: && function_defined && top_level)
336: error ("global register variable follows a function definition");
337: if (TREE_THIS_VOLATILE (decl))
338: warning ("volatile register variables don't work as you might wish");
339: DECL_RTL (decl) = gen_rtx (REG, DECL_MODE (decl), reg_number);
340: REG_USERVAR_P (DECL_RTL (decl)) = 1;
341:
342: if (top_level)
343: {
344: /* Make this register fixed, so not usable for anything else. */
345: nregs = HARD_REGNO_NREGS (reg_number, DECL_MODE (decl));
346: while (nregs > 0)
347: global_regs[reg_number + --nregs] = 1;
348: init_reg_sets_1 ();
349: }
350: }
351:
352: /* Now handle ordinary static variables and functions (in memory).
353: Also handle vars declared register invalidly. */
354: if (DECL_RTL (decl) == 0)
355: {
356: /* Can't use just the variable's own name for a variable
357: whose scope is less than the whole file.
358: Concatenate a distinguishing number. */
359: if (!top_level && !TREE_EXTERNAL (decl) && asmspec == 0)
360: {
361: char *label;
362:
363: ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
364: name = obstack_copy0 (saveable_obstack, label, strlen (label));
365: var_labelno++;
366: }
367:
368: DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl),
369: gen_rtx (SYMBOL_REF, Pmode, name));
370: if (TREE_THIS_VOLATILE (decl))
371: MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
372: if (TREE_READONLY (decl))
373: RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
374: MEM_IN_STRUCT_P (DECL_RTL (decl))
375: = (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
376: || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
377: || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
378:
379: /* Optionally set flags or add text to the name to record information
380: such as that it is a function name.
381: If the name is changed, the macro ASM_OUTPUT_LABELREF
382: will have to know how to strip this information.
383: And if it finds a * at the beginning after doing so,
384: it must handle that too. */
385: #ifdef ENCODE_SECTION_INFO
386: ENCODE_SECTION_INFO (decl);
387: #endif
388: }
389: }
390: }
391:
392: /* Output a string of literal assembler code
393: for an `asm' keyword used between functions. */
394:
395: void
396: assemble_asm (string)
397: tree string;
398: {
399: app_enable ();
400:
401: if (TREE_CODE (string) == ADDR_EXPR)
402: string = TREE_OPERAND (string, 0);
403:
404: fprintf (asm_out_file, "\t%s\n", TREE_STRING_POINTER (string));
405: }
406:
407: /* Tiemann: please get rid of this conditional and put appropriate
408: definitions in each of the files that should have them.
409: The type of debugging format is not the right parameter to
410: control how some other aspect of assembler output is done. */
411:
412: #if !(defined(DBX_DEBUGGING_INFO) && !defined(FASCIST_ASSEMBLER))
413: #ifndef ASM_OUTPUT_CONSTRUCTOR
414: #define ASM_OUTPUT_CONSTRUCTOR(file, name)
415: #endif
416: #ifndef ASM_OUTPUT_DESTRUCTOR
417: #define ASM_OUTPUT_DESTRUCTOR(file, name)
418: #endif
419: #endif
420:
421: /* Record an element in the table of global destructors.
422: How this is done depends on what sort of assembler and linker
423: are in use.
424:
425: NAME should be the name of a global function to be called
426: at exit time. This name is output using assemble_name. */
427:
428: void
429: assemble_destructor (name)
430: char *name;
431: {
432: #ifdef ASM_OUTPUT_DESTRUCTOR
433: ASM_OUTPUT_DESTRUCTOR (asm_out_file, name);
434: #else
435: if (flag_gnu_linker)
436: {
437: /* Now tell GNU LD that this is part of the static destructor set. */
438: /* This code works for any machine provided you use GNU as/ld. */
439: fprintf (asm_out_file, "%s \"___DTOR_LIST__\",22,0,0,", ASM_STABS_OP);
440: assemble_name (asm_out_file, name);
441: fputc ('\n', asm_out_file);
442: }
443: #endif
444: }
445:
446: /* Likewise for global constructors. */
447:
448: void
449: assemble_constructor (name)
450: char *name;
451: {
452: #ifdef ASM_OUTPUT_CONSTRUCTOR
453: ASM_OUTPUT_CONSTRUCTOR (asm_out_file, name);
454: #else
455: if (flag_gnu_linker)
456: {
457: /* Now tell GNU LD that this is part of the static constructor set. */
458: /* This code works for any machine provided you use GNU as/ld. */
459: fprintf (asm_out_file, "%s \"___CTOR_LIST__\",22,0,0,", ASM_STABS_OP);
460: assemble_name (asm_out_file, name);
461: fputc ('\n', asm_out_file);
462: }
463: #endif
464: }
465:
466: /* Likewise for entries we want to record for garbage collection.
467: Garbage collection is still under development. */
468:
469: void
470: assemble_gc_entry (name)
471: char *name;
472: {
473: #ifdef ASM_OUTPUT_GC_ENTRY
474: ASM_OUTPUT_GC_ENTRY (asm_out_file, name);
475: #else
476: if (flag_gnu_linker)
477: {
478: /* Now tell GNU LD that this is part of the static constructor set. */
479: fprintf (asm_out_file, "%s \"___PTR_LIST__\",22,0,0,", ASM_STABS_OP);
480: assemble_name (asm_out_file, name);
481: fputc ('\n', asm_out_file);
482: }
483: #endif
484: }
485:
486: /* Output assembler code for the constant pool of a function and associated
487: with defining the name of the function. DECL describes the function.
488: NAME is the function's name. For the constant pool, we use the current
489: constant pool data. */
490:
491: void
492: assemble_start_function (decl, fnname)
493: tree decl;
494: char *fnname;
495: {
496: int align;
497:
498: /* The following code does not need preprocessing in the assembler. */
499:
500: app_disable ();
501:
502: output_constant_pool (fnname, decl);
503:
504: text_section ();
505:
506:
507: /* Tell assembler to move to target machine's alignment for functions. */
508: align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
509: if (align > 0)
510: ASM_OUTPUT_ALIGN (asm_out_file, align);
511:
512: #ifdef ASM_OUTPUT_FUNCTION_PREFIX
513: ASM_OUTPUT_FUNCTION_PREFIX (asm_out_file, fnname);
514: #endif
515:
516: #ifdef SDB_DEBUGGING_INFO
517: /* Output SDB definition of the function. */
518: if (write_symbols == SDB_DEBUG)
519: sdbout_mark_begin_function ();
520: #endif
521:
522: #ifdef DBX_DEBUGGING_INFO
1.1.1.2 root 523: /* Output DBX definition of the function. */
1.1 root 524: if (write_symbols == DBX_DEBUG)
1.1.1.2 root 525: dbxout_begin_function (decl);
1.1 root 526: #endif
527:
528: /* Make function name accessible from other files, if appropriate. */
529:
530: if (TREE_PUBLIC (decl))
531: {
532: if (!first_global_object_name)
533: first_global_object_name = fnname + (fnname[0] == '*');
534: ASM_GLOBALIZE_LABEL (asm_out_file, fnname);
535: }
536:
537: /* Do any machine/system dependent processing of the function name */
538: #ifdef ASM_DECLARE_FUNCTION_NAME
539: ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl);
540: #else
541: /* Standard thing is just output label for the function. */
542: ASM_OUTPUT_LABEL (asm_out_file, fnname);
543: #endif /* ASM_DECLARE_FUNCTION_NAME */
544: }
545:
546: /* Output assembler code associated with defining the size of the
547: function. DECL describes the function. NAME is the function's name. */
548:
549: void
550: assemble_end_function (decl, fnname)
551: tree decl;
552: char *fnname;
553: {
554: #ifdef ASM_DECLARE_FUNCTION_SIZE
555: ASM_DECLARE_FUNCTION_SIZE (asm_out_file, fnname, decl);
556: #endif
557: }
558:
559: /* Assemble code to leave SIZE bytes of zeros. */
560:
561: void
562: assemble_zeros (size)
563: int size;
564: {
565: #ifdef ASM_NO_SKIP_IN_TEXT
566: /* The `space' pseudo in the text section outputs nop insns rather than 0s,
567: so we must output 0s explicitly in the text section. */
568: if (ASM_NO_SKIP_IN_TEXT && in_text_section ())
569: {
570: int i;
571:
572: for (i = 0; i < size - 20; i += 20)
573: {
574: #ifdef ASM_BYTE_OP
575: fprintf (asm_out_file,
576: "%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);
577: #else
578: fprintf (asm_out_file,
579: "\tbyte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n");
580: #endif
581: }
582: if (i < size)
583: {
584: #ifdef ASM_BYTE_OP
585: fprintf (asm_out_file, "%s 0", ASM_BYTE_OP);
586: #else
587: fprintf (asm_out_file, "\tbyte 0");
588: #endif
589: i++;
590: for (; i < size; i++)
591: fprintf (asm_out_file, ",0");
592: fprintf (asm_out_file, "\n");
593: }
594: }
595: else
596: #endif
597: ASM_OUTPUT_SKIP (asm_out_file, size);
598: }
599:
600: /* Assemble a string constant with the specified C string as contents. */
601:
602: void
603: assemble_string (p, size)
604: unsigned char *p;
605: int size;
606: {
607: register int i;
608: int pos = 0;
609: int maximum = 2000;
610:
611: /* If the string is very long, split it up. */
612:
613: while (pos < size)
614: {
615: int thissize = size - pos;
616: if (thissize > maximum)
617: thissize = maximum;
618:
619: ASM_OUTPUT_ASCII (asm_out_file, p, thissize);
620:
621: pos += thissize;
622: p += thissize;
623: }
624: }
625:
626: /* Assemble everything that is needed for a variable or function declaration.
627: Not used for automatic variables, and not used for function definitions.
628: Should not be called for variables of incomplete structure type.
629:
630: TOP_LEVEL is nonzero if this variable has file scope.
631: AT_END is nonzero if this is the special handling, at end of compilation,
632: to define things that have had only tentative definitions. */
633:
634: void
635: assemble_variable (decl, top_level, at_end)
636: tree decl;
637: int top_level;
638: int at_end;
639: {
640: register char *name;
641: int align;
642: tree size_tree;
643: int reloc = 0;
644:
645: if (GET_CODE (DECL_RTL (decl)) == REG)
646: {
647: /* Do output symbol info for global register variables, but do nothing
648: else for them. */
649:
650: if (TREE_ASM_WRITTEN (decl))
651: return;
652: TREE_ASM_WRITTEN (decl) = 1;
653:
1.1.1.2 root 654: #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
1.1 root 655: /* File-scope global variables are output here. */
1.1.1.2 root 656: if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
657: && top_level)
1.1 root 658: dbxout_symbol (decl, 0);
659: #endif
660: #ifdef SDB_DEBUGGING_INFO
661: if (write_symbols == SDB_DEBUG && top_level
662: /* Leave initialized global vars for end of compilation;
663: see comment in compile_file. */
664: && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0))
665: sdbout_symbol (decl, 0);
666: #endif
667:
668: /* Don't output any DWARF debugging information for variables here.
669: In the case of local variables, the information for them is output
670: when we do our recursive traversal of the tree representation for
671: the entire containing function. In the case of file-scope variables,
672: we output information for all of them at the very end of compilation
673: while we are doing our final traversal of the chain of file-scope
674: declarations. */
675:
676: return;
677: }
678:
679: /* Normally no need to say anything for external references,
680: since assembler considers all undefined symbols external. */
681:
682: if (TREE_EXTERNAL (decl))
683: return;
684:
685: /* Output no assembler code for a function declaration.
686: Only definitions of functions output anything. */
687:
688: if (TREE_CODE (decl) == FUNCTION_DECL)
689: return;
690:
691: /* If type was incomplete when the variable was declared,
692: see if it is complete now. */
693:
694: if (DECL_SIZE (decl) == 0)
695: layout_decl (decl, 0);
696:
697: /* Still incomplete => don't allocate it; treat the tentative defn
698: (which is what it must have been) as an `extern' reference. */
699:
700: if (DECL_SIZE (decl) == 0)
701: {
702: error_with_file_and_line (DECL_SOURCE_FILE (decl),
703: DECL_SOURCE_LINE (decl),
704: "storage size of static var `%s' isn't known",
705: IDENTIFIER_POINTER (DECL_NAME (decl)));
706: return;
707: }
708:
709: /* The first declaration of a variable that comes through this function
710: decides whether it is global (in C, has external linkage)
711: or local (in C, has internal linkage). So do nothing more
712: if this function has already run. */
713:
714: if (TREE_ASM_WRITTEN (decl))
715: return;
716:
717: TREE_ASM_WRITTEN (decl) = 1;
718:
719: #ifdef DBX_DEBUGGING_INFO
720: /* File-scope global variables are output here. */
721: if (write_symbols == DBX_DEBUG && top_level)
722: dbxout_symbol (decl, 0);
723: #endif
724: #ifdef SDB_DEBUGGING_INFO
725: if (write_symbols == SDB_DEBUG && top_level
726: /* Leave initialized global vars for end of compilation;
727: see comment in compile_file. */
728: && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0))
729: sdbout_symbol (decl, 0);
730: #endif
731:
732: /* Don't output any DWARF debugging information for variables here.
733: In the case of local variables, the information for them is output
734: when we do our recursive traversal of the tree representation for
735: the entire containing function. In the case of file-scope variables,
736: we output information for all of them at the very end of compilation
737: while we are doing our final traversal of the chain of file-scope
738: declarations. */
739:
740: /* If storage size is erroneously variable, just continue.
741: Error message was already made. */
742:
743: if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
1.1.1.2 root 744: goto finish;
1.1 root 745:
746: app_disable ();
747:
748: /* This is better than explicit arithmetic, since it avoids overflow. */
749: size_tree = size_binop (CEIL_DIV_EXPR,
750: DECL_SIZE (decl), size_int (BITS_PER_UNIT));
751:
752: if (TREE_INT_CST_HIGH (size_tree) != 0)
753: {
754: error_with_decl (decl, "size of variable `%s' is too large");
1.1.1.2 root 755: goto finish;
1.1 root 756: }
757:
758: name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
759:
760: /* Handle uninitialized definitions. */
761:
762: /* ANSI specifies that a tentative definition which is not merged with
763: a non-tentative definition behaves exactly like a definition with an
764: initializer equal to zero. (Section 3.7.2)
765: -fno-common gives strict ANSI behavior. Usually you don't want it. */
766: if (! flag_no_common
767: && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
768: {
769: int size = TREE_INT_CST_LOW (size_tree);
770: int rounded = size;
771:
772: if (TREE_INT_CST_HIGH (size_tree) != 0)
773: error_with_decl (decl, "size of variable `%s' is too large");
774: /* Don't allocate zero bytes of common,
775: since that means "undefined external" in the linker. */
776: if (size == 0) rounded = 1;
777: /* Round size up to multiple of BIGGEST_ALIGNMENT bits
778: so that each uninitialized object starts on such a boundary. */
779: rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
780: rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
781: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
782: #if 0
783: if (flag_shared_data)
784: data_section ();
785: #endif
786: if (TREE_PUBLIC (decl))
787: {
788: #ifdef ASM_OUTPUT_SHARED_COMMON
789: if (flag_shared_data)
790: ASM_OUTPUT_SHARED_COMMON (asm_out_file, name, size, rounded);
791: else
792: #endif
793: #ifdef ASM_OUTPUT_ALIGNED_COMMON
794: ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size,
795: DECL_ALIGN (decl));
796: #else
797: ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
798: #endif
799: }
800: else
801: {
802: #ifdef ASM_OUTPUT_SHARED_LOCAL
803: if (flag_shared_data)
804: ASM_OUTPUT_SHARED_LOCAL (asm_out_file, name, size, rounded);
805: else
806: #endif
807: #ifdef ASM_OUTPUT_ALIGNED_LOCAL
808: ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,
809: DECL_ALIGN (decl));
810: #else
811: ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
812: #endif
813: }
1.1.1.2 root 814: goto finish;
1.1 root 815: }
816:
817: /* Handle initialized definitions. */
818:
819: /* First make the assembler name(s) global if appropriate. */
820: if (TREE_PUBLIC (decl) && DECL_NAME (decl))
821: {
822: if (!first_global_object_name)
823: first_global_object_name = name + (name[0] == '*');
824: ASM_GLOBALIZE_LABEL (asm_out_file, name);
825: }
826: #if 0
827: for (d = equivalents; d; d = TREE_CHAIN (d))
828: {
829: tree e = TREE_VALUE (d);
830: if (TREE_PUBLIC (e) && DECL_NAME (e))
831: ASM_GLOBALIZE_LABEL (asm_out_file,
832: XSTR (XEXP (DECL_RTL (e), 0), 0));
833: }
834: #endif
835:
836: /* Output any data that we will need to use the address of. */
837: if (DECL_INITIAL (decl))
838: reloc = output_addressed_constants (DECL_INITIAL (decl));
839:
840: /* Switch to the proper section for this data. */
841: #ifdef SELECT_SECTION
842: SELECT_SECTION (decl, reloc);
843: #else
844: if (TREE_READONLY (decl)
845: && ! TREE_THIS_VOLATILE (decl)
846: && ! (flag_pic && reloc))
847: readonly_data_section ();
848: else
849: data_section ();
850: #endif
851:
852: /* Compute and output the alignment of this data. */
853:
854: align = DECL_ALIGN (decl);
855: /* Some object file formats have a maximum alignment which they support.
856: In particular, a.out format supports a maximum alignment of 4. */
857: #ifndef MAX_OFILE_ALIGNMENT
858: #define MAX_OFILE_ALIGNMENT BIGGEST_ALIGNMENT
859: #endif
860: if (align > MAX_OFILE_ALIGNMENT)
861: {
862: warning_with_decl (decl,
863: "alignment of `%s' is greater than maximum object file alignment");
864: align = MAX_OFILE_ALIGNMENT;
865: }
866: #ifdef DATA_ALIGNMENT
867: /* On some machines, it is good to increase alignment sometimes. */
868: align = DATA_ALIGNMENT (TREE_TYPE (decl), align);
869: #endif
870: #ifdef CONSTANT_ALIGNMENT
871: if (DECL_INITIAL (decl))
872: align = CONSTANT_ALIGNMENT (DECL_INITIAL (decl), align);
873: #endif
874:
875: /* Reset the alignment in case we have made it tighter, so we can benefit
876: from it in get_pointer_alignment. */
877: DECL_ALIGN (decl) = align;
878:
879: if (align > BITS_PER_UNIT)
880: ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
881:
882: /* Do any machine/system dependent processing of the object. */
883: #ifdef ASM_DECLARE_OBJECT_NAME
884: ASM_DECLARE_OBJECT_NAME (asm_out_file, name, decl);
885: #else
886: /* Standard thing is just output label for the object. */
887: ASM_OUTPUT_LABEL (asm_out_file, name);
888: #endif /* ASM_DECLARE_OBJECT_NAME */
889:
890: #if 0
891: for (d = equivalents; d; d = TREE_CHAIN (d))
892: {
893: tree e = TREE_VALUE (d);
894: ASM_OUTPUT_LABEL (asm_out_file, XSTR (XEXP (DECL_RTL (e), 0), 0));
895: }
896: #endif
897:
898: if (DECL_INITIAL (decl))
899: /* Output the actual data. */
900: output_constant (DECL_INITIAL (decl),
901: int_size_in_bytes (TREE_TYPE (decl)));
902: else
903: /* Leave space for it. */
904: assemble_zeros (int_size_in_bytes (TREE_TYPE (decl)));
1.1.1.2 root 905:
906: finish:
907: #ifdef XCOFF_DEBUGGING_INFO
908: /* Unfortunately, the IBM assembler cannot handle stabx before the actual
909: declaration. When something like ".stabx "aa:S-2",aa,133,0" is emitted
910: and `aa' hasn't been output yet, the assembler generates a stab entry with
911: a value of zero, in addition to creating an unnecessary external entry
1.1.1.3 ! root 912: for `aa'. Hence, we must postpone dbxout_symbol to here at the end. */
1.1.1.2 root 913:
914: /* File-scope global variables are output here. */
915: if (write_symbols == XCOFF_DEBUG && top_level)
916: dbxout_symbol (decl, 0);
917: #else
918: /* There must be a statement after a label. */
919: ;
920: #endif
1.1 root 921: }
922:
923: /* Output something to declare an external symbol to the assembler.
924: (Most assemblers don't need this, so we normally output nothing.)
925: Do nothing if DECL is not external. */
926:
927: void
928: assemble_external (decl)
929: tree decl;
930: {
931: #ifdef ASM_OUTPUT_EXTERNAL
932: if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd'
933: && TREE_EXTERNAL (decl) && TREE_PUBLIC (decl))
934: {
935: rtx rtl = DECL_RTL (decl);
936:
937: if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
938: && ! SYMBOL_REF_USED (XEXP (rtl, 0)))
939: {
940: /* Some systems do require some output. */
941: SYMBOL_REF_USED (XEXP (rtl, 0)) = 1;
942: ASM_OUTPUT_EXTERNAL (asm_out_file, decl, XSTR (XEXP (rtl, 0), 0));
943: }
944: }
945: #endif
946: }
947:
948: /* Similar, for calling a library function FUN. */
949:
950: void
951: assemble_external_libcall (fun)
952: rtx fun;
953: {
954: #ifdef ASM_OUTPUT_EXTERNAL_LIBCALL
955: /* Declare library function name external when first used, if nec. */
956: if (! SYMBOL_REF_USED (fun))
957: {
958: SYMBOL_REF_USED (fun) = 1;
959: ASM_OUTPUT_EXTERNAL_LIBCALL (asm_out_file, fun);
960: }
961: #endif
962: }
963:
964: /* Declare the label NAME global. */
965:
966: void
967: assemble_global (name)
968: char *name;
969: {
970: ASM_GLOBALIZE_LABEL (asm_out_file, name);
971: }
972:
973: /* Assemble a label named NAME. */
974:
975: void
976: assemble_label (name)
977: char *name;
978: {
979: ASM_OUTPUT_LABEL (asm_out_file, name);
980: }
981:
982: /* Output to FILE a reference to the assembler name of a C-level name NAME.
983: If NAME starts with a *, the rest of NAME is output verbatim.
984: Otherwise NAME is transformed in an implementation-defined way
985: (usually by the addition of an underscore).
986: Many macros in the tm file are defined to call this function. */
987:
988: void
989: assemble_name (file, name)
990: FILE *file;
991: char *name;
992: {
993: if (name[0] == '*')
994: fputs (&name[1], file);
995: else
996: ASM_OUTPUT_LABELREF (file, name);
997: }
998:
999: /* Allocate SIZE bytes writable static space with a gensym name
1000: and return an RTX to refer to its address. */
1001:
1002: rtx
1003: assemble_static_space (size)
1004: int size;
1005: {
1006: char name[12];
1007: char *namestring;
1008: rtx x;
1009: /* Round size up to multiple of BIGGEST_ALIGNMENT bits
1010: so that each uninitialized object starts on such a boundary. */
1011: int rounded = ((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
1012: / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1013: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
1014:
1015: #if 0
1016: if (flag_shared_data)
1017: data_section ();
1018: #endif
1019:
1020: ASM_GENERATE_INTERNAL_LABEL (name, "LF", const_labelno);
1021: ++const_labelno;
1022:
1023: namestring = (char *) obstack_alloc (saveable_obstack,
1024: strlen (name) + 2);
1025: strcpy (namestring, name);
1026:
1027: x = gen_rtx (SYMBOL_REF, Pmode, namestring);
1028: #ifdef ASM_OUTPUT_ALIGNED_LOCAL
1029: ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, BIGGEST_ALIGNMENT);
1030: #else
1031: ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
1032: #endif
1033: return x;
1034: }
1035:
1036: /* Assemble the static constant template for function entry trampolines.
1037: This is done at most once per compilation.
1038: Returns an RTX for the address of the template. */
1039:
1040: rtx
1041: assemble_trampoline_template ()
1042: {
1043: char label[256];
1044: char *name;
1045: int align;
1046:
1047: /* Write the assembler code to define one. */
1048: align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
1049: if (align > 0)
1050: ASM_OUTPUT_ALIGN (asm_out_file, align);
1051:
1052: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LTRAMP", 0);
1053: TRAMPOLINE_TEMPLATE (asm_out_file);
1054:
1055: /* Record the rtl to refer to it. */
1056: ASM_GENERATE_INTERNAL_LABEL (label, "LTRAMP", 0);
1057: name
1058: = (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));
1059: return gen_rtx (SYMBOL_REF, Pmode, name);
1060: }
1061:
1062: /* Assemble the integer constant X into an object of SIZE bytes.
1063: X must be either a CONST_INT or CONST_DOUBLE.
1064:
1065: Return 1 if we were able to output the constant, otherwise 0. If FORCE is
1066: non-zero, abort if we can't output the constant. */
1067:
1068: int
1069: assemble_integer (x, size, force)
1070: rtx x;
1071: int size;
1072: int force;
1073: {
1074: /* First try to use the standard 1, 2, 4, 8, and 16 byte
1075: ASM_OUTPUT... macros. */
1076:
1077: switch (size)
1078: {
1079: #ifdef ASM_OUTPUT_CHAR
1080: case 1:
1081: ASM_OUTPUT_CHAR (asm_out_file, x);
1082: return 1;
1083: #endif
1084:
1085: #ifdef ASM_OUTPUT_SHORT
1086: case 2:
1087: ASM_OUTPUT_SHORT (asm_out_file, x);
1088: return 1;
1089: #endif
1090:
1091: #ifdef ASM_OUTPUT_INT
1092: case 4:
1093: ASM_OUTPUT_INT (asm_out_file, x);
1094: return 1;
1095: #endif
1096:
1097: #ifdef ASM_OUTPUT_DOUBLE_INT
1098: case 8:
1099: ASM_OUTPUT_DOUBLE_INT (asm_out_file, x);
1100: return 1;
1101: #endif
1102:
1103: #ifdef ASM_OUTPUT_QUADRUPLE_INT
1104: case 16:
1105: ASM_OUTPUT_QUADRUPLE_INT (asm_out_file, x);
1106: return 1;
1107: #endif
1108: }
1109:
1110: /* If we couldn't do it that way, there are two other possibilities: First,
1111: if the machine can output an explicit byte and this is a 1 byte constant,
1112: we can use ASM_OUTPUT_BYTE. */
1113:
1114: #ifdef ASM_OUTPUT_BYTE
1115: if (size == 1 && GET_CODE (x) == CONST_INT)
1116: {
1117: ASM_OUTPUT_BYTE (asm_out_file, INTVAL (x));
1118: return 1;
1119: }
1120: #endif
1121:
1122: /* Finally, if SIZE is larger than a single word, try to output the constant
1123: one word at a time. */
1124:
1125: if (size > UNITS_PER_WORD)
1126: {
1127: int i;
1128: enum machine_mode mode
1129: = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
1130: rtx word;
1131:
1132: for (i = 0; i < size / UNITS_PER_WORD; i++)
1133: {
1134: word = operand_subword (x, i, 0, mode);
1135:
1136: if (word == 0)
1137: break;
1138:
1139: if (! assemble_integer (word, UNITS_PER_WORD, 0))
1140: break;
1141: }
1142:
1143: if (i == size / UNITS_PER_WORD)
1144: return 1;
1145: /* If we output at least one word and then could not finish,
1146: there is no valid way to continue. */
1147: if (i > 0)
1148: abort ();
1149: }
1150:
1151: if (force)
1152: abort ();
1153:
1154: return 0;
1155: }
1156:
1157: /* Assemble the floating-point constant D into an object of size MODE. */
1158:
1159: void
1160: assemble_real (d, mode)
1161: REAL_VALUE_TYPE d;
1162: enum machine_mode mode;
1163: {
1164: jmp_buf output_constant_handler;
1165:
1166: if (setjmp (output_constant_handler))
1167: {
1168: error ("floating point trap outputting a constant");
1169: #ifdef REAL_IS_NOT_DOUBLE
1170: bzero (&d, sizeof d);
1171: d = dconst0;
1172: #else
1173: d = 0;
1174: #endif
1175: }
1176:
1177: set_float_handler (output_constant_handler);
1178:
1179: switch (mode)
1180: {
1181: #ifdef ASM_OUTPUT_FLOAT
1182: case SFmode:
1183: ASM_OUTPUT_FLOAT (asm_out_file, d);
1184: break;
1185: #endif
1186:
1187: #ifdef ASM_OUTPUT_DOUBLE
1188: case DFmode:
1189: ASM_OUTPUT_DOUBLE (asm_out_file, d);
1190: break;
1191: #endif
1192:
1193: #ifdef ASM_OUTPUT_LONG_DOUBLE
1194: case TFmode:
1195: ASM_OUTPUT_LONG_DOUBLE (asm_out_file, d);
1196: break;
1197: #endif
1198:
1199: default:
1200: abort ();
1201: }
1202:
1203: set_float_handler (0);
1204: }
1205:
1206: /* Here we combine duplicate floating constants to make
1207: CONST_DOUBLE rtx's, and force those out to memory when necessary. */
1208:
1209: /* Chain of all CONST_DOUBLE rtx's constructed for the current function.
1210: They are chained through the CONST_DOUBLE_CHAIN.
1211: A CONST_DOUBLE rtx has CONST_DOUBLE_MEM != cc0_rtx iff it is on this chain.
1212: In that case, CONST_DOUBLE_MEM is either a MEM,
1213: or const0_rtx if no MEM has been made for this CONST_DOUBLE yet. */
1214:
1215: static rtx const_double_chain;
1216:
1217: /* Return a CONST_DOUBLE for a value specified as a pair of ints.
1218: For an integer, I0 is the low-order word and I1 is the high-order word.
1219: For a real number, I0 is the word with the low address
1220: and I1 is the word with the high address. */
1221:
1222: rtx
1223: immed_double_const (i0, i1, mode)
1224: int i0, i1;
1225: enum machine_mode mode;
1226: {
1227: register rtx r;
1228: int in_current_obstack;
1229:
1230: if (GET_MODE_CLASS (mode) == MODE_INT)
1231: {
1232: /* We clear out all bits that don't belong in MODE, unless they and our
1233: sign bit are all one. So we get either a reasonable negative value
1234: or a reasonable unsigned value for this mode. */
1235: int width = GET_MODE_BITSIZE (mode);
1236: if (width < HOST_BITS_PER_INT
1237: && ((i0 & ((-1) << (width - 1))) != ((-1) << (width - 1))))
1238: i0 &= (1 << width) - 1, i1 = 0;
1239: else if (width == HOST_BITS_PER_INT
1240: && ! (i1 == ~0 && i0 < 0))
1241: i1 = 0;
1242: else if (width > 2 * HOST_BITS_PER_INT)
1243: /* We cannot represent this value as a constant. */
1244: abort ();
1245:
1246: /* If MODE fits within HOST_BITS_PER_INT, always use a CONST_INT.
1247:
1248: ??? Strictly speaking, this is wrong if we create a CONST_INT
1249: for a large unsigned constant with the size of MODE being
1250: HOST_BITS_PER_INT and later try to interpret that constant in a wider
1251: mode. In that case we will mis-interpret it as a negative number.
1252:
1253: Unfortunately, the only alternative is to make a CONST_DOUBLE
1254: for any constant in any mode if it is an unsigned constant larger
1255: than the maximum signed integer in an int on the host. However,
1256: doing this will break everyone that always expects to see a CONST_INT
1257: for SImode and smaller.
1258:
1259: We have always been making CONST_INTs in this case, so nothing new
1260: is being broken. */
1261:
1262: if (width <= HOST_BITS_PER_INT)
1263: i1 = (i0 < 0) ? ~0 : 0;
1264:
1265: /* If this integer fits in one word, return a CONST_INT. */
1266: if ((i1 == 0 && i0 >= 0)
1267: || (i1 == ~0 && i0 < 0))
1268: return gen_rtx (CONST_INT, VOIDmode, i0);
1269:
1270: /* We use VOIDmode for integers. */
1271: mode = VOIDmode;
1272: }
1273:
1274: /* Search the chain for an existing CONST_DOUBLE with the right value.
1275: If one is found, return it. */
1276:
1277: for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))
1278: if (CONST_DOUBLE_LOW (r) == i0 && CONST_DOUBLE_HIGH (r) == i1
1279: && GET_MODE (r) == mode)
1280: return r;
1281:
1282: /* No; make a new one and add it to the chain.
1283:
1284: We may be called by an optimizer which may be discarding any memory
1285: allocated during its processing (such as combine and loop). However,
1286: we will be leaving this constant on the chain, so we cannot tolerate
1287: freed memory. So switch to saveable_obstack for this allocation
1288: and then switch back if we were in current_obstack. */
1289:
1290: in_current_obstack = rtl_in_saveable_obstack ();
1291: r = gen_rtx (CONST_DOUBLE, mode, 0, i0, i1);
1292: if (in_current_obstack)
1293: rtl_in_current_obstack ();
1294:
1295: CONST_DOUBLE_CHAIN (r) = const_double_chain;
1296: const_double_chain = r;
1297:
1298: /* Store const0_rtx in mem-slot since this CONST_DOUBLE is on the chain.
1299: Actual use of mem-slot is only through force_const_mem. */
1300:
1301: CONST_DOUBLE_MEM (r) = const0_rtx;
1302:
1303: return r;
1304: }
1305:
1306: /* Return a CONST_DOUBLE for a specified `double' value
1307: and machine mode. */
1308:
1309: rtx
1310: immed_real_const_1 (d, mode)
1311: REAL_VALUE_TYPE d;
1312: enum machine_mode mode;
1313: {
1314: union real_extract u;
1315: register rtx r;
1316: int in_current_obstack;
1317:
1318: /* Get the desired `double' value as a sequence of ints
1319: since that is how they are stored in a CONST_DOUBLE. */
1320:
1321: u.d = d;
1322:
1323: /* Detect special cases. */
1324:
1.1.1.2 root 1325: /* Avoid REAL_VALUES_EQUAL here in order to distinguish minus zero. */
1326: if (!bcmp (&dconst0, &d, sizeof d))
1.1 root 1327: return CONST0_RTX (mode);
1328: else if (REAL_VALUES_EQUAL (dconst1, d))
1329: return CONST1_RTX (mode);
1330:
1331: if (sizeof u == 2 * sizeof (int))
1332: return immed_double_const (u.i[0], u.i[1], mode);
1333:
1334: /* The rest of this function handles the case where
1335: a float value requires more than 2 ints of space.
1336: It will be deleted as dead code on machines that don't need it. */
1337:
1338: /* Search the chain for an existing CONST_DOUBLE with the right value.
1339: If one is found, return it. */
1340:
1341: for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))
1342: if (! bcmp (&CONST_DOUBLE_LOW (r), &u, sizeof u)
1343: && GET_MODE (r) == mode)
1344: return r;
1345:
1346: /* No; make a new one and add it to the chain.
1347:
1348: We may be called by an optimizer which may be discarding any memory
1349: allocated during its processing (such as combine and loop). However,
1350: we will be leaving this constant on the chain, so we cannot tolerate
1351: freed memory. So switch to saveable_obstack for this allocation
1352: and then switch back if we were in current_obstack. */
1353:
1354: in_current_obstack = rtl_in_saveable_obstack ();
1355: r = rtx_alloc (CONST_DOUBLE);
1356: PUT_MODE (r, mode);
1357: bcopy (&u, &CONST_DOUBLE_LOW (r), sizeof u);
1358: if (in_current_obstack)
1359: rtl_in_current_obstack ();
1360:
1361: CONST_DOUBLE_CHAIN (r) = const_double_chain;
1362: const_double_chain = r;
1363:
1364: /* Store const0_rtx in CONST_DOUBLE_MEM since this CONST_DOUBLE is on the
1365: chain, but has not been allocated memory. Actual use of CONST_DOUBLE_MEM
1366: is only through force_const_mem. */
1367:
1368: CONST_DOUBLE_MEM (r) = const0_rtx;
1369:
1370: return r;
1371: }
1372:
1373: /* Return a CONST_DOUBLE rtx for a value specified by EXP,
1374: which must be a REAL_CST tree node. */
1375:
1376: rtx
1377: immed_real_const (exp)
1378: tree exp;
1379: {
1380: return immed_real_const_1 (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)));
1381: }
1382:
1383: /* At the end of a function, forget the memory-constants
1384: previously made for CONST_DOUBLEs. Mark them as not on real_constant_chain.
1385: Also clear out real_constant_chain and clear out all the chain-pointers. */
1386:
1387: void
1388: clear_const_double_mem ()
1389: {
1390: register rtx r, next;
1391:
1392: for (r = const_double_chain; r; r = next)
1393: {
1394: next = CONST_DOUBLE_CHAIN (r);
1395: CONST_DOUBLE_CHAIN (r) = 0;
1396: CONST_DOUBLE_MEM (r) = cc0_rtx;
1397: }
1398: const_double_chain = 0;
1399: }
1400:
1401: /* Given an expression EXP with a constant value,
1402: reduce it to the sum of an assembler symbol and an integer.
1403: Store them both in the structure *VALUE.
1404: Abort if EXP does not reduce. */
1405:
1406: struct addr_const
1407: {
1408: rtx base;
1409: int offset;
1410: };
1411:
1412: static void
1413: decode_addr_const (exp, value)
1414: tree exp;
1415: struct addr_const *value;
1416: {
1417: register tree target = TREE_OPERAND (exp, 0);
1418: register int offset = 0;
1419: register rtx x;
1420:
1421: while (1)
1422: {
1423: if (TREE_CODE (target) == COMPONENT_REF
1424: && (TREE_CODE (DECL_FIELD_BITPOS (TREE_OPERAND (target, 1)))
1425: == INTEGER_CST))
1426: {
1427: offset += TREE_INT_CST_LOW (DECL_FIELD_BITPOS (TREE_OPERAND (target, 1))) / BITS_PER_UNIT;
1428: target = TREE_OPERAND (target, 0);
1429: }
1430: else if (TREE_CODE (target) == ARRAY_REF)
1431: {
1432: if (TREE_CODE (TREE_OPERAND (target, 1)) != INTEGER_CST
1433: || TREE_CODE (TYPE_SIZE (TREE_TYPE (target))) != INTEGER_CST)
1434: abort ();
1435: offset += ((TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (target)))
1436: * TREE_INT_CST_LOW (TREE_OPERAND (target, 1)))
1437: / BITS_PER_UNIT);
1438: target = TREE_OPERAND (target, 0);
1439: }
1440: else
1441: break;
1442: }
1443:
1444: switch (TREE_CODE (target))
1445: {
1446: case VAR_DECL:
1447: case FUNCTION_DECL:
1448: x = DECL_RTL (target);
1449: break;
1450:
1451: case LABEL_DECL:
1452: x = gen_rtx (MEM, FUNCTION_MODE,
1453: gen_rtx (LABEL_REF, VOIDmode,
1454: label_rtx (TREE_OPERAND (exp, 0))));
1455: break;
1456:
1457: case REAL_CST:
1458: case STRING_CST:
1459: case COMPLEX_CST:
1460: case CONSTRUCTOR:
1461: x = TREE_CST_RTL (target);
1462: break;
1463:
1464: default:
1465: abort ();
1466: }
1467:
1468: if (GET_CODE (x) != MEM)
1469: abort ();
1470: x = XEXP (x, 0);
1471:
1472: value->base = x;
1473: value->offset = offset;
1474: }
1475:
1476: /* Uniquize all constants that appear in memory.
1477: Each constant in memory thus far output is recorded
1478: in `const_hash_table' with a `struct constant_descriptor'
1479: that contains a polish representation of the value of
1480: the constant.
1481:
1482: We cannot store the trees in the hash table
1483: because the trees may be temporary. */
1484:
1485: struct constant_descriptor
1486: {
1487: struct constant_descriptor *next;
1488: char *label;
1489: char contents[1];
1490: };
1491:
1492: #define HASHBITS 30
1493: #define MAX_HASH_TABLE 1009
1494: static struct constant_descriptor *const_hash_table[MAX_HASH_TABLE];
1495:
1496: /* Compute a hash code for a constant expression. */
1497:
1498: int
1499: const_hash (exp)
1500: tree exp;
1501: {
1502: register char *p;
1503: register int len, hi, i;
1504: register enum tree_code code = TREE_CODE (exp);
1505:
1506: if (code == INTEGER_CST)
1507: {
1508: p = (char *) &TREE_INT_CST_LOW (exp);
1509: len = 2 * sizeof TREE_INT_CST_LOW (exp);
1510: }
1511: else if (code == REAL_CST)
1512: {
1513: p = (char *) &TREE_REAL_CST (exp);
1514: len = sizeof TREE_REAL_CST (exp);
1515: }
1516: else if (code == STRING_CST)
1517: p = TREE_STRING_POINTER (exp), len = TREE_STRING_LENGTH (exp);
1518: else if (code == COMPLEX_CST)
1519: return const_hash (TREE_REALPART (exp)) * 5
1520: + const_hash (TREE_IMAGPART (exp));
1521: else if (code == CONSTRUCTOR)
1522: {
1523: register tree link;
1524:
1525: /* For record type, include the type in the hashing.
1526: We do not do so for array types
1527: because (1) the sizes of the elements are sufficient
1.1.1.3 ! root 1528: and (2) distinct array types can have the same constructor.
! 1529: Instead, we include the array size because the constructor could
! 1530: be shorter. */
1.1 root 1531: if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
1532: hi = ((int) TREE_TYPE (exp) & ((1 << HASHBITS) - 1)) % MAX_HASH_TABLE;
1533: else
1.1.1.3 ! root 1534: hi = ((5 + int_size_in_bytes (TREE_TYPE (exp)))
! 1535: & ((1 << HASHBITS) - 1)) % MAX_HASH_TABLE;
1.1 root 1536:
1537: for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
1538: hi = (hi * 603 + const_hash (TREE_VALUE (link))) % MAX_HASH_TABLE;
1539:
1540: return hi;
1541: }
1542: else if (code == ADDR_EXPR)
1543: {
1544: struct addr_const value;
1545: decode_addr_const (exp, &value);
1546: if (GET_CODE (value.base) == SYMBOL_REF)
1547: {
1548: /* Don't hash the address of the SYMBOL_REF;
1549: only use the offset and the symbol name. */
1550: hi = value.offset;
1551: p = XSTR (value.base, 0);
1552: for (i = 0; p[i] != 0; i++)
1553: hi = ((hi * 613) + (unsigned)(p[i]));
1554: }
1555: else if (GET_CODE (value.base) == LABEL_REF)
1556: hi = value.offset + CODE_LABEL_NUMBER (XEXP (value.base, 0)) * 13;
1557:
1558: hi &= (1 << HASHBITS) - 1;
1559: hi %= MAX_HASH_TABLE;
1560: return hi;
1561: }
1562: else if (code == PLUS_EXPR || code == MINUS_EXPR)
1563: return const_hash (TREE_OPERAND (exp, 0)) * 9
1564: + const_hash (TREE_OPERAND (exp, 1));
1565: else if (code == NOP_EXPR || code == CONVERT_EXPR)
1566: return const_hash (TREE_OPERAND (exp, 0)) * 7 + 2;
1567:
1568: /* Compute hashing function */
1569: hi = len;
1570: for (i = 0; i < len; i++)
1571: hi = ((hi * 613) + (unsigned)(p[i]));
1572:
1573: hi &= (1 << HASHBITS) - 1;
1574: hi %= MAX_HASH_TABLE;
1575: return hi;
1576: }
1577:
1578: /* Compare a constant expression EXP with a constant-descriptor DESC.
1579: Return 1 if DESC describes a constant with the same value as EXP. */
1580:
1581: static int
1582: compare_constant (exp, desc)
1583: tree exp;
1584: struct constant_descriptor *desc;
1585: {
1586: return 0 != compare_constant_1 (exp, desc->contents);
1587: }
1588:
1589: /* Compare constant expression EXP with a substring P of a constant descriptor.
1590: If they match, return a pointer to the end of the substring matched.
1591: If they do not match, return 0.
1592:
1593: Since descriptors are written in polish prefix notation,
1594: this function can be used recursively to test one operand of EXP
1595: against a subdescriptor, and if it succeeds it returns the
1596: address of the subdescriptor for the next operand. */
1597:
1598: static char *
1599: compare_constant_1 (exp, p)
1600: tree exp;
1601: char *p;
1602: {
1603: register char *strp;
1604: register int len;
1605: register enum tree_code code = TREE_CODE (exp);
1606:
1607: if (code != (enum tree_code) *p++)
1608: return 0;
1609:
1610: if (code == INTEGER_CST)
1611: {
1612: /* Integer constants are the same only if the same width of type. */
1613: if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
1614: return 0;
1615: strp = (char *) &TREE_INT_CST_LOW (exp);
1616: len = 2 * sizeof TREE_INT_CST_LOW (exp);
1617: }
1618: else if (code == REAL_CST)
1619: {
1620: /* Real constants are the same only if the same width of type. */
1621: if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
1622: return 0;
1623: strp = (char *) &TREE_REAL_CST (exp);
1624: len = sizeof TREE_REAL_CST (exp);
1625: }
1626: else if (code == STRING_CST)
1627: {
1628: if (flag_writable_strings)
1629: return 0;
1630: strp = TREE_STRING_POINTER (exp);
1631: len = TREE_STRING_LENGTH (exp);
1632: if (bcmp (&TREE_STRING_LENGTH (exp), p,
1633: sizeof TREE_STRING_LENGTH (exp)))
1634: return 0;
1635: p += sizeof TREE_STRING_LENGTH (exp);
1636: }
1637: else if (code == COMPLEX_CST)
1638: {
1639: p = compare_constant_1 (TREE_REALPART (exp), p);
1640: if (p == 0) return 0;
1641: p = compare_constant_1 (TREE_IMAGPART (exp), p);
1642: return p;
1643: }
1644: else if (code == CONSTRUCTOR)
1645: {
1646: register tree link;
1647: int length = list_length (CONSTRUCTOR_ELTS (exp));
1648: tree type;
1649:
1650: if (bcmp (&length, p, sizeof length))
1651: return 0;
1652: p += sizeof length;
1653:
1654: /* For record constructors, insist that the types match.
1655: For arrays, just verify both constructors are for arrays. */
1656: if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
1657: type = TREE_TYPE (exp);
1658: else
1659: type = 0;
1660: if (bcmp (&type, p, sizeof type))
1661: return 0;
1662: p += sizeof type;
1663:
1.1.1.3 ! root 1664: /* For arrays, insist that the size in bytes match. */
! 1665: if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
! 1666: {
! 1667: int size = int_size_in_bytes (TREE_TYPE (exp));
! 1668: if (bcmp (&size, p, sizeof size))
! 1669: return 0;
! 1670: p += sizeof size;
! 1671: }
! 1672:
1.1 root 1673: for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
1674: if ((p = compare_constant_1 (TREE_VALUE (link), p)) == 0)
1675: return 0;
1676: return p;
1677: }
1678: else if (code == ADDR_EXPR)
1679: {
1680: struct addr_const value;
1681: decode_addr_const (exp, &value);
1682: strp = (char *) &value.offset;
1683: len = sizeof value.offset;
1684: /* Compare the offset. */
1685: while (--len >= 0)
1686: if (*p++ != *strp++)
1687: return 0;
1688: /* Compare symbol name. */
1689: strp = XSTR (value.base, 0);
1690: len = strlen (strp) + 1;
1691: }
1692: else if (code == PLUS_EXPR || code == MINUS_EXPR)
1693: {
1694: p = compare_constant_1 (TREE_OPERAND (exp, 0), p);
1695: if (p == 0) return 0;
1696: p = compare_constant_1 (TREE_OPERAND (exp, 1), p);
1697: return p;
1698: }
1699: else if (code == NOP_EXPR || code == CONVERT_EXPR)
1700: {
1701: p = compare_constant_1 (TREE_OPERAND (exp, 0), p);
1702: return p;
1703: }
1704:
1705: /* Compare constant contents. */
1706: while (--len >= 0)
1707: if (*p++ != *strp++)
1708: return 0;
1709:
1710: return p;
1711: }
1712:
1713: /* Construct a constant descriptor for the expression EXP.
1714: It is up to the caller to enter the descriptor in the hash table. */
1715:
1716: static struct constant_descriptor *
1717: record_constant (exp)
1718: tree exp;
1719: {
1720: struct constant_descriptor *ptr = 0;
1721: int buf;
1722:
1723: obstack_grow (&permanent_obstack, &ptr, sizeof ptr);
1724: obstack_grow (&permanent_obstack, &buf, sizeof buf);
1725: record_constant_1 (exp);
1726: return (struct constant_descriptor *) obstack_finish (&permanent_obstack);
1727: }
1728:
1729: /* Add a description of constant expression EXP
1730: to the object growing in `permanent_obstack'.
1731: No need to return its address; the caller will get that
1732: from the obstack when the object is complete. */
1733:
1734: static void
1735: record_constant_1 (exp)
1736: tree exp;
1737: {
1738: register char *strp;
1739: register int len;
1740: register enum tree_code code = TREE_CODE (exp);
1741:
1742: obstack_1grow (&permanent_obstack, (unsigned int) code);
1743:
1744: if (code == INTEGER_CST)
1745: {
1746: obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
1747: strp = (char *) &TREE_INT_CST_LOW (exp);
1748: len = 2 * sizeof TREE_INT_CST_LOW (exp);
1749: }
1750: else if (code == REAL_CST)
1751: {
1752: obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
1753: strp = (char *) &TREE_REAL_CST (exp);
1754: len = sizeof TREE_REAL_CST (exp);
1755: }
1756: else if (code == STRING_CST)
1757: {
1758: if (flag_writable_strings)
1759: return;
1760: strp = TREE_STRING_POINTER (exp);
1761: len = TREE_STRING_LENGTH (exp);
1762: obstack_grow (&permanent_obstack, (char *) &TREE_STRING_LENGTH (exp),
1763: sizeof TREE_STRING_LENGTH (exp));
1764: }
1765: else if (code == COMPLEX_CST)
1766: {
1767: record_constant_1 (TREE_REALPART (exp));
1768: record_constant_1 (TREE_IMAGPART (exp));
1769: return;
1770: }
1771: else if (code == CONSTRUCTOR)
1772: {
1773: register tree link;
1774: int length = list_length (CONSTRUCTOR_ELTS (exp));
1775: tree type;
1776:
1777: obstack_grow (&permanent_obstack, (char *) &length, sizeof length);
1778:
1779: /* For record constructors, insist that the types match.
1780: For arrays, just verify both constructors are for arrays. */
1781: if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
1782: type = TREE_TYPE (exp);
1783: else
1784: type = 0;
1785: obstack_grow (&permanent_obstack, (char *) &type, sizeof type);
1786:
1.1.1.3 ! root 1787: /* For arrays, insist that the size in bytes match. */
! 1788: if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
! 1789: {
! 1790: int size = int_size_in_bytes (TREE_TYPE (exp));
! 1791: obstack_grow (&permanent_obstack, (char *) &size, sizeof size);
! 1792: }
! 1793:
1.1 root 1794: for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
1795: record_constant_1 (TREE_VALUE (link));
1796: return;
1797: }
1798: else if (code == ADDR_EXPR)
1799: {
1800: struct addr_const value;
1801: decode_addr_const (exp, &value);
1802: /* Record the offset. */
1803: obstack_grow (&permanent_obstack,
1804: (char *) &value.offset, sizeof value.offset);
1805: /* Record the symbol name. */
1806: obstack_grow (&permanent_obstack, XSTR (value.base, 0),
1807: strlen (XSTR (value.base, 0)) + 1);
1808: return;
1809: }
1810: else if (code == PLUS_EXPR || code == MINUS_EXPR)
1811: {
1812: record_constant_1 (TREE_OPERAND (exp, 0));
1813: record_constant_1 (TREE_OPERAND (exp, 1));
1814: return;
1815: }
1816: else if (code == NOP_EXPR || code == CONVERT_EXPR)
1817: {
1818: record_constant_1 (TREE_OPERAND (exp, 0));
1819: return;
1820: }
1821:
1822: /* Record constant contents. */
1823: obstack_grow (&permanent_obstack, strp, len);
1824: }
1825:
1826: /* Return an rtx representing a reference to constant data in memory
1827: for the constant expression EXP.
1828: If assembler code for such a constant has already been output,
1829: return an rtx to refer to it.
1830: Otherwise, output such a constant in memory and generate
1831: an rtx for it. The TREE_CST_RTL of EXP is set up to point to that rtx.
1832: The const_hash_table records which constants already have label strings. */
1833:
1834: rtx
1835: output_constant_def (exp)
1836: tree exp;
1837: {
1838: register int hash, align;
1839: register struct constant_descriptor *desc;
1840: char label[256];
1841: char *found = 0;
1842: int reloc;
1843: register rtx def;
1844:
1845: if (TREE_CODE (exp) == INTEGER_CST)
1846: abort (); /* No TREE_CST_RTL slot in these. */
1847:
1848: if (TREE_CST_RTL (exp))
1849: return TREE_CST_RTL (exp);
1850:
1851: /* Make sure any other constants whose addresses appear in EXP
1852: are assigned label numbers. */
1853:
1854: reloc = output_addressed_constants (exp);
1855:
1856: /* Compute hash code of EXP. Search the descriptors for that hash code
1857: to see if any of them describes EXP. If yes, the descriptor records
1858: the label number already assigned. */
1859:
1860: hash = const_hash (exp) % MAX_HASH_TABLE;
1861:
1862: for (desc = const_hash_table[hash]; desc; desc = desc->next)
1863: if (compare_constant (exp, desc))
1864: {
1865: found = desc->label;
1866: break;
1867: }
1868:
1869: if (found == 0)
1870: {
1871: /* No constant equal to EXP is known to have been output.
1872: Make a constant descriptor to enter EXP in the hash table.
1873: Assign the label number and record it in the descriptor for
1874: future calls to this function to find. */
1875:
1876: /* Create a string containing the label name, in LABEL. */
1877: ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
1878:
1879: desc = record_constant (exp);
1880: desc->next = const_hash_table[hash];
1881: desc->label
1882: = (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));
1883: const_hash_table[hash] = desc;
1884: }
1885:
1886: /* We have a symbol name; construct the SYMBOL_REF and the MEM. */
1887:
1888: push_obstacks_nochange ();
1889: if (TREE_PERMANENT (exp))
1890: end_temporary_allocation ();
1891:
1892: def = gen_rtx (SYMBOL_REF, Pmode, desc->label);
1893:
1894: TREE_CST_RTL (exp)
1895: = gen_rtx (MEM, TYPE_MODE (TREE_TYPE (exp)), def);
1896: RTX_UNCHANGING_P (TREE_CST_RTL (exp)) = 1;
1.1.1.3 ! root 1897: if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
! 1898: || TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
! 1899: MEM_IN_STRUCT_P (TREE_CST_RTL (exp)) = 1;
1.1 root 1900:
1901: pop_obstacks ();
1902:
1903: /* Optionally set flags or add text to the name to record information
1904: such as that it is a function name. If the name is changed, the macro
1905: ASM_OUTPUT_LABELREF will have to know how to strip this information.
1906: And if it finds a * at the beginning after doing so, it must handle
1907: that too. */
1908: #ifdef ENCODE_SECTION_INFO
1909: ENCODE_SECTION_INFO (exp);
1910: #endif
1911:
1912: if (found == 0)
1913: {
1914: /* Now output assembler code to define that label
1915: and follow it with the data of EXP. */
1916:
1917: /* First switch to text section, except for writable strings. */
1918: #ifdef SELECT_SECTION
1919: SELECT_SECTION (exp, reloc);
1920: #else
1921: if (((TREE_CODE (exp) == STRING_CST) && flag_writable_strings)
1922: || (flag_pic && reloc))
1923: data_section ();
1924: else
1925: readonly_data_section ();
1926: #endif
1927:
1928: /* Align the location counter as required by EXP's data type. */
1929: align = TYPE_ALIGN (TREE_TYPE (exp));
1930: #ifdef CONSTANT_ALIGNMENT
1931: align = CONSTANT_ALIGNMENT (exp, align);
1932: #endif
1933:
1934: if (align > BITS_PER_UNIT)
1935: ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
1936:
1937: /* Output the label itself. */
1938: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", const_labelno);
1939:
1940: /* Output the value of EXP. */
1941: output_constant (exp,
1942: (TREE_CODE (exp) == STRING_CST
1943: ? TREE_STRING_LENGTH (exp)
1944: : int_size_in_bytes (TREE_TYPE (exp))));
1945:
1946: ++const_labelno;
1947: }
1948:
1949: return TREE_CST_RTL (exp);
1950: }
1951:
1952: /* Similar hash facility for making memory-constants
1953: from constant rtl-expressions. It is used on RISC machines
1954: where immediate integer arguments and constant addresses are restricted
1955: so that such constants must be stored in memory.
1956:
1957: This pool of constants is reinitialized for each function
1958: so each function gets its own constants-pool that comes right before it.
1959:
1960: All structures allocated here are discarded when functions are saved for
1961: inlining, so they do not need to be allocated permanently. */
1962:
1963: #define MAX_RTX_HASH_TABLE 61
1964: static struct constant_descriptor *const_rtx_hash_table[MAX_RTX_HASH_TABLE];
1965:
1966: /* Structure to represent sufficient information about a constant so that
1967: it can be output when the constant pool is output, so that function
1968: integration can be done, and to simplify handling on machines that reference
1969: constant pool as base+displacement. */
1970:
1971: struct pool_constant
1972: {
1973: struct constant_descriptor *desc;
1974: struct pool_constant *next;
1975: enum machine_mode mode;
1976: rtx constant;
1977: int labelno;
1978: int align;
1979: int offset;
1980: };
1981:
1982: /* Pointers to first and last constant in pool. */
1983:
1984: static struct pool_constant *first_pool, *last_pool;
1985:
1986: /* Current offset in constant pool (does not include any machine-specific
1987: header. */
1988:
1989: static int pool_offset;
1990:
1991: /* Structure used to maintain hash table mapping symbols used to their
1992: corresponding constants. */
1993:
1994: struct pool_sym
1995: {
1996: char *label;
1997: struct pool_constant *pool;
1998: struct pool_sym *next;
1999: };
2000:
2001: static struct pool_sym *const_rtx_sym_hash_table[MAX_RTX_HASH_TABLE];
2002:
2003: /* Hash code for a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true.
2004: The argument is XSTR (... , 0) */
2005:
2006: #define SYMHASH(LABEL) \
2007: ((((int) (LABEL)) & ((1 << HASHBITS) - 1)) % MAX_RTX_HASH_TABLE)
2008:
2009: /* Initialize constant pool hashing for next function. */
2010:
2011: void
2012: init_const_rtx_hash_table ()
2013: {
2014: bzero (const_rtx_hash_table, sizeof const_rtx_hash_table);
2015: bzero (const_rtx_sym_hash_table, sizeof const_rtx_sym_hash_table);
2016:
2017: first_pool = last_pool = 0;
2018: pool_offset = 0;
2019: }
2020:
2021: enum kind { RTX_DOUBLE, RTX_INT };
2022:
2023: struct rtx_const
2024: {
2025: #ifdef ONLY_INT_FIELDS
2026: unsigned int kind : 16;
2027: unsigned int mode : 16;
2028: #else
2029: enum kind kind : 16;
2030: enum machine_mode mode : 16;
2031: #endif
2032: union {
2033: union real_extract du;
2034: struct addr_const addr;
2035: } un;
2036: };
2037:
2038: /* Express an rtx for a constant integer (perhaps symbolic)
2039: as the sum of a symbol or label plus an explicit integer.
2040: They are stored into VALUE. */
2041:
2042: static void
2043: decode_rtx_const (mode, x, value)
2044: enum machine_mode mode;
2045: rtx x;
2046: struct rtx_const *value;
2047: {
2048: /* Clear the whole structure, including any gaps. */
2049:
2050: {
2051: int *p = (int *) value;
2052: int *end = (int *) (value + 1);
2053: while (p < end)
2054: *p++ = 0;
2055: }
2056:
2057: value->kind = RTX_INT; /* Most usual kind. */
2058: value->mode = mode;
2059:
2060: switch (GET_CODE (x))
2061: {
2062: case CONST_DOUBLE:
2063: value->kind = RTX_DOUBLE;
2064: value->mode = GET_MODE (x);
2065: bcopy (&CONST_DOUBLE_LOW (x), &value->un.du, sizeof value->un.du);
2066: break;
2067:
2068: case CONST_INT:
2069: value->un.addr.offset = INTVAL (x);
2070: break;
2071:
2072: case SYMBOL_REF:
2073: case LABEL_REF:
2074: value->un.addr.base = x;
2075: break;
2076:
2077: case CONST:
2078: x = XEXP (x, 0);
2079: if (GET_CODE (x) == PLUS)
2080: {
2081: value->un.addr.base = XEXP (x, 0);
2082: if (GET_CODE (XEXP (x, 1)) != CONST_INT)
2083: abort ();
2084: value->un.addr.offset = INTVAL (XEXP (x, 1));
2085: }
2086: else if (GET_CODE (x) == MINUS)
2087: {
2088: value->un.addr.base = XEXP (x, 0);
2089: if (GET_CODE (XEXP (x, 1)) != CONST_INT)
2090: abort ();
2091: value->un.addr.offset = - INTVAL (XEXP (x, 1));
2092: }
2093: else
2094: abort ();
2095: break;
2096:
2097: default:
2098: abort ();
2099: }
2100:
2101: if (value->kind == RTX_INT && value->un.addr.base != 0)
2102: switch (GET_CODE (value->un.addr.base))
2103: {
2104: case SYMBOL_REF:
2105: case LABEL_REF:
2106: /* Use the string's address, not the SYMBOL_REF's address,
2107: for the sake of addresses of library routines.
2108: For a LABEL_REF, compare labels. */
2109: value->un.addr.base = XEXP (value->un.addr.base, 0);
2110: }
2111: }
2112:
2113: /* Compute a hash code for a constant RTL expression. */
2114:
2115: int
2116: const_hash_rtx (mode, x)
2117: enum machine_mode mode;
2118: rtx x;
2119: {
2120: register int hi, i;
2121:
2122: struct rtx_const value;
2123: decode_rtx_const (mode, x, &value);
2124:
2125: /* Compute hashing function */
2126: hi = 0;
2127: for (i = 0; i < sizeof value / sizeof (int); i++)
2128: hi += ((int *) &value)[i];
2129:
2130: hi &= (1 << HASHBITS) - 1;
2131: hi %= MAX_RTX_HASH_TABLE;
2132: return hi;
2133: }
2134:
2135: /* Compare a constant rtl object X with a constant-descriptor DESC.
2136: Return 1 if DESC describes a constant with the same value as X. */
2137:
2138: static int
2139: compare_constant_rtx (mode, x, desc)
2140: enum machine_mode mode;
2141: rtx x;
2142: struct constant_descriptor *desc;
2143: {
2144: register int *p = (int *) desc->contents;
2145: register int *strp;
2146: register int len;
2147: struct rtx_const value;
2148:
2149: decode_rtx_const (mode, x, &value);
2150: strp = (int *) &value;
2151: len = sizeof value / sizeof (int);
2152:
2153: /* Compare constant contents. */
2154: while (--len >= 0)
2155: if (*p++ != *strp++)
2156: return 0;
2157:
2158: return 1;
2159: }
2160:
2161: /* Construct a constant descriptor for the rtl-expression X.
2162: It is up to the caller to enter the descriptor in the hash table. */
2163:
2164: static struct constant_descriptor *
2165: record_constant_rtx (mode, x)
2166: enum machine_mode mode;
2167: rtx x;
2168: {
2169: struct constant_descriptor *ptr;
2170: char *label;
2171: struct rtx_const value;
2172:
2173: decode_rtx_const (mode, x, &value);
2174:
2175: obstack_grow (current_obstack, &ptr, sizeof ptr);
2176: obstack_grow (current_obstack, &label, sizeof label);
2177:
2178: /* Record constant contents. */
2179: obstack_grow (current_obstack, &value, sizeof value);
2180:
2181: return (struct constant_descriptor *) obstack_finish (current_obstack);
2182: }
2183:
2184: /* Given a constant rtx X, make (or find) a memory constant for its value
2185: and return a MEM rtx to refer to it in memory. */
2186:
2187: rtx
2188: force_const_mem (mode, x)
2189: enum machine_mode mode;
2190: rtx x;
2191: {
2192: register int hash;
2193: register struct constant_descriptor *desc;
2194: char label[256];
2195: char *found = 0;
2196: rtx def;
2197:
2198: /* If we want this CONST_DOUBLE in the same mode as it is in memory
2199: (this will always be true for floating CONST_DOUBLEs that have been
2200: placed in memory, but not for VOIDmode (integer) CONST_DOUBLEs),
2201: use the previous copy. Otherwise, make a new one. Note that in
2202: the unlikely event that this same CONST_DOUBLE is used in two different
2203: modes in an alternating fashion, we will allocate a lot of different
2204: memory locations, but this should be extremely rare. */
2205:
2206: if (GET_CODE (x) == CONST_DOUBLE
2207: && GET_CODE (CONST_DOUBLE_MEM (x)) == MEM
2208: && GET_MODE (CONST_DOUBLE_MEM (x)) == mode)
2209: return CONST_DOUBLE_MEM (x);
2210:
2211: /* Compute hash code of X. Search the descriptors for that hash code
2212: to see if any of them describes X. If yes, the descriptor records
2213: the label number already assigned. */
2214:
2215: hash = const_hash_rtx (mode, x);
2216:
2217: for (desc = const_rtx_hash_table[hash]; desc; desc = desc->next)
2218: if (compare_constant_rtx (mode, x, desc))
2219: {
2220: found = desc->label;
2221: break;
2222: }
2223:
2224: if (found == 0)
2225: {
2226: register struct pool_constant *pool;
2227: register struct pool_sym *sym;
2228: int align;
2229:
2230: /* No constant equal to X is known to have been output.
2231: Make a constant descriptor to enter X in the hash table.
2232: Assign the label number and record it in the descriptor for
2233: future calls to this function to find. */
2234:
2235: desc = record_constant_rtx (mode, x);
2236: desc->next = const_rtx_hash_table[hash];
2237: const_rtx_hash_table[hash] = desc;
2238:
2239: /* Align the location counter as required by EXP's data type. */
2240: align = (mode == VOIDmode) ? UNITS_PER_WORD : GET_MODE_SIZE (mode);
2241: if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT)
2242: align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
2243:
2244: pool_offset += align - 1;
2245: pool_offset &= ~ (align - 1);
2246:
2247: /* Allocate a pool constant descriptor, fill it in, and chain it in. */
2248:
2249: pool = (struct pool_constant *) oballoc (sizeof (struct pool_constant));
2250: pool->desc = desc;
2251: pool->constant = x;
2252: pool->mode = mode;
2253: pool->labelno = const_labelno;
2254: pool->align = align;
2255: pool->offset = pool_offset;
2256: pool->next = 0;
2257:
2258: if (last_pool == 0)
2259: first_pool = pool;
2260: else
2261: last_pool->next = pool;
2262:
2263: last_pool = pool;
2264: pool_offset += GET_MODE_SIZE (mode);
2265:
2266: /* Create a string containing the label name, in LABEL. */
2267: ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
2268:
2269: ++const_labelno;
2270:
2271: desc->label = found
2272: = (char *) obstack_copy0 (saveable_obstack, label, strlen (label));
2273:
2274: /* Add label to symbol hash table. */
2275: hash = SYMHASH (found);
2276: sym = (struct pool_sym *) oballoc (sizeof (struct pool_sym));
2277: sym->label = found;
2278: sym->pool = pool;
2279: sym->next = const_rtx_sym_hash_table[hash];
2280: const_rtx_sym_hash_table[hash] = sym;
2281: }
2282:
2283: /* We have a symbol name; construct the SYMBOL_REF and the MEM. */
2284:
2285: def = gen_rtx (MEM, mode, gen_rtx (SYMBOL_REF, Pmode, found));
2286:
2287: RTX_UNCHANGING_P (def) = 1;
2288: /* Mark the symbol_ref as belonging to this constants pool. */
2289: CONSTANT_POOL_ADDRESS_P (XEXP (def, 0)) = 1;
2290: current_function_uses_const_pool = 1;
2291:
2292: if (GET_CODE (x) == CONST_DOUBLE)
2293: {
2294: if (CONST_DOUBLE_MEM (x) == cc0_rtx)
2295: {
2296: CONST_DOUBLE_CHAIN (x) = const_double_chain;
2297: const_double_chain = x;
2298: }
2299: CONST_DOUBLE_MEM (x) = def;
2300: }
2301:
2302: return def;
2303: }
2304:
2305: /* Given a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true, return a pointer to
2306: the corresponding pool_constant structure. */
2307:
2308: static struct pool_constant *
2309: find_pool_constant (addr)
2310: rtx addr;
2311: {
2312: struct pool_sym *sym;
2313: char *label = XSTR (addr, 0);
2314:
2315: for (sym = const_rtx_sym_hash_table[SYMHASH (label)]; sym; sym = sym->next)
2316: if (sym->label == label)
2317: return sym->pool;
2318:
2319: abort ();
2320: }
2321:
2322: /* Given a constant pool SYMBOL_REF, return the corresponding constant. */
2323:
2324: rtx
2325: get_pool_constant (addr)
2326: rtx addr;
2327: {
2328: return (find_pool_constant (addr))->constant;
2329: }
2330:
2331: /* Similar, return the mode. */
2332:
2333: enum machine_mode
2334: get_pool_mode (addr)
2335: rtx addr;
2336: {
2337: return (find_pool_constant (addr))->mode;
2338: }
2339:
2340: /* Similar, return the offset in the constant pool. */
2341:
2342: int
2343: get_pool_offset (addr)
2344: rtx addr;
2345: {
2346: return (find_pool_constant (addr))->offset;
2347: }
2348:
2349: /* Return the size of the constant pool. */
2350:
2351: int
2352: get_pool_size ()
2353: {
2354: return pool_offset;
2355: }
2356:
2357: /* Write all the constants in the constant pool. */
2358:
2359: void
2360: output_constant_pool (fnname, fndecl)
2361: char *fnname;
2362: tree fndecl;
2363: {
2364: struct pool_constant *pool;
2365: rtx x;
2366: union real_extract u;
2367:
2368: #ifdef ASM_OUTPUT_POOL_PROLOGUE
2369: ASM_OUTPUT_POOL_PROLOGUE (asm_out_file, fnname, fndecl, pool_offset);
2370: #endif
2371:
2372: for (pool = first_pool; pool; pool = pool->next)
2373: {
2374: x = pool->constant;
2375:
2376: /* See if X is a LABEL_REF (or a CONST referring to a LABEL_REF)
2377: whose CODE_LABEL has been deleted. This can occur if a jump table
2378: is eliminated by optimization. If so, write a constant of zero
2379: instead. */
2380: if ((GET_CODE (x) == LABEL_REF && INSN_DELETED_P (XEXP (x, 0)))
2381: || (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
2382: && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
2383: && INSN_DELETED_P (XEXP (XEXP (XEXP (x, 0), 0), 0))))
2384: x = const0_rtx;
2385:
2386: /* First switch to correct section. */
2387: #ifdef SELECT_RTX_SECTION
2388: SELECT_RTX_SECTION (pool->mode, x);
2389: #else
2390: readonly_data_section ();
2391: #endif
2392:
2393: #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY
2394: ASM_OUTPUT_SPECIAL_POOL_ENTRY (asm_out_file, x, pool->mode,
2395: pool->align, pool->labelno, done);
2396: #endif
2397:
2398: if (pool->align > 1)
2399: ASM_OUTPUT_ALIGN (asm_out_file, exact_log2 (pool->align));
2400:
2401: /* Output the label. */
2402: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", pool->labelno);
2403:
2404: /* Output the value of the constant itself. */
2405: switch (GET_MODE_CLASS (pool->mode))
2406: {
2407: case MODE_FLOAT:
2408: if (GET_CODE (x) != CONST_DOUBLE)
2409: abort ();
2410:
2411: bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u);
2412: assemble_real (u.d, pool->mode);
2413: break;
2414:
2415: case MODE_INT:
2416: assemble_integer (x, GET_MODE_SIZE (pool->mode), 1);
2417: break;
2418:
2419: default:
2420: abort ();
2421: }
2422:
2423: done: ;
2424: }
2425:
2426: /* Done with this pool. */
2427: first_pool = last_pool = 0;
2428: }
2429:
2430: /* Find all the constants whose addresses are referenced inside of EXP,
2431: and make sure assembler code with a label has been output for each one.
2432: Indicate whether an ADDR_EXPR has been encountered. */
2433:
2434: int
2435: output_addressed_constants (exp)
2436: tree exp;
2437: {
2438: int reloc = 0;
2439:
2440: switch (TREE_CODE (exp))
2441: {
2442: case ADDR_EXPR:
2443: {
2444: register tree constant = TREE_OPERAND (exp, 0);
2445:
2446: while (TREE_CODE (constant) == COMPONENT_REF)
2447: {
2448: constant = TREE_OPERAND (constant, 0);
2449: }
2450:
2451: if (TREE_CODE_CLASS (TREE_CODE (constant)) == 'c'
2452: || TREE_CODE (constant) == CONSTRUCTOR)
2453: /* No need to do anything here
2454: for addresses of variables or functions. */
2455: output_constant_def (constant);
2456: }
2457: reloc = 1;
2458: break;
2459:
2460: case PLUS_EXPR:
2461: case MINUS_EXPR:
2462: reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
2463: reloc |= output_addressed_constants (TREE_OPERAND (exp, 1));
2464: break;
2465:
2466: case NOP_EXPR:
2467: case CONVERT_EXPR:
2468: reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
2469: break;
2470:
2471: case CONSTRUCTOR:
2472: {
2473: register tree link;
2474: for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
2475: if (TREE_VALUE (link) != 0)
2476: reloc |= output_addressed_constants (TREE_VALUE (link));
2477: }
2478: break;
2479:
2480: case ERROR_MARK:
2481: break;
2482: }
2483: return reloc;
2484: }
2485:
2486: /* Output assembler code for constant EXP to FILE, with no label.
2487: This includes the pseudo-op such as ".int" or ".byte", and a newline.
2488: Assumes output_addressed_constants has been done on EXP already.
2489:
2490: Generate exactly SIZE bytes of assembler data, padding at the end
2491: with zeros if necessary. SIZE must always be specified.
2492:
2493: SIZE is important for structure constructors,
2494: since trailing members may have been omitted from the constructor.
2495: It is also important for initialization of arrays from string constants
2496: since the full length of the string constant might not be wanted.
2497: It is also needed for initialization of unions, where the initializer's
2498: type is just one member, and that may not be as long as the union.
2499:
2500: There a case in which we would fail to output exactly SIZE bytes:
2501: for a structure constructor that wants to produce more than SIZE bytes.
2502: But such constructors will never be generated for any possible input. */
2503:
2504: void
2505: output_constant (exp, size)
2506: register tree exp;
2507: register int size;
2508: {
2509: register enum tree_code code = TREE_CODE (TREE_TYPE (exp));
2510: rtx x;
2511:
2512: if (size == 0)
2513: return;
2514:
2515: /* Allow a constructor with no elements for any data type.
2516: This means to fill the space with zeros. */
2517: if (TREE_CODE (exp) == CONSTRUCTOR
2518: && TREE_OPERAND (exp, 1) == 0)
2519: {
2520: assemble_zeros (size);
2521: return;
2522: }
2523:
2524: /* Eliminate the NOP_EXPR that makes a cast not be an lvalue.
2525: That way we get the constant (we hope) inside it. */
2526: if (TREE_CODE (exp) == NOP_EXPR
2527: && TREE_TYPE (exp) == TREE_TYPE (TREE_OPERAND (exp, 0)))
2528: exp = TREE_OPERAND (exp, 0);
2529:
2530: switch (code)
2531: {
2532: case INTEGER_TYPE:
2533: case ENUMERAL_TYPE:
2534: case POINTER_TYPE:
2535: case REFERENCE_TYPE:
2536: /* ??? What about (int)((float)(int)&foo + 4) */
2537: while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
2538: || TREE_CODE (exp) == NON_LVALUE_EXPR)
2539: exp = TREE_OPERAND (exp, 0);
2540:
2541: if (! assemble_integer (expand_expr (exp, 0, VOIDmode,
2542: EXPAND_INITIALIZER),
2543: size, 0))
2544: error ("initializer for integer value is too complicated");
2545: size = 0;
2546: break;
2547:
2548: case REAL_TYPE:
2549: if (TREE_CODE (exp) != REAL_CST)
2550: error ("initializer for floating value is not a floating constant");
2551:
2552: assemble_real (TREE_REAL_CST (exp),
2553: mode_for_size (size * BITS_PER_UNIT, MODE_FLOAT, 0));
2554: size = 0;
2555: break;
2556:
2557: case COMPLEX_TYPE:
2558: output_constant (TREE_REALPART (exp), size / 2);
2559: output_constant (TREE_IMAGPART (exp), size / 2);
2560: size -= (size / 2) * 2;
2561: break;
2562:
2563: case ARRAY_TYPE:
2564: if (TREE_CODE (exp) == CONSTRUCTOR)
2565: {
2566: output_constructor (exp, size);
2567: return;
2568: }
2569: else if (TREE_CODE (exp) == STRING_CST)
2570: {
2571: int excess = 0;
2572:
2573: if (size > TREE_STRING_LENGTH (exp))
2574: {
2575: excess = size - TREE_STRING_LENGTH (exp);
2576: size = TREE_STRING_LENGTH (exp);
2577: }
2578:
2579: assemble_string (TREE_STRING_POINTER (exp), size);
2580: size = excess;
2581: }
2582: else
2583: abort ();
2584: break;
2585:
2586: case RECORD_TYPE:
2587: case UNION_TYPE:
2588: if (TREE_CODE (exp) == CONSTRUCTOR)
2589: output_constructor (exp, size);
2590: else
2591: abort ();
2592: return;
2593: }
2594:
2595: if (size > 0)
2596: assemble_zeros (size);
2597: }
2598:
2599: /* Subroutine of output_constant, used for CONSTRUCTORs
2600: (aggregate constants).
2601: Generate at least SIZE bytes, padding if necessary. */
2602:
2603: void
2604: output_constructor (exp, size)
2605: tree exp;
2606: int size;
2607: {
2608: register tree link, field = 0;
2609: /* Number of bytes output or skipped so far.
2610: In other words, current position within the constructor. */
2611: int total_bytes = 0;
2612: /* Non-zero means BYTE contains part of a byte, to be output. */
2613: int byte_buffer_in_use = 0;
2614: register int byte;
2615:
2616: if (HOST_BITS_PER_INT < BITS_PER_UNIT)
2617: abort ();
2618:
2619: if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
2620: field = TYPE_FIELDS (TREE_TYPE (exp));
2621:
2622: /* As LINK goes through the elements of the constant,
2623: FIELD goes through the structure fields, if the constant is a structure.
2624: if the constant is a union, then we override this,
2625: by getting the field from the TREE_LIST element.
2626: But the constant could also be an array. Then FIELD is zero. */
2627: for (link = CONSTRUCTOR_ELTS (exp);
2628: link;
2629: link = TREE_CHAIN (link),
2630: field = field ? TREE_CHAIN (field) : 0)
2631: {
2632: tree val = TREE_VALUE (link);
2633: /* the element in a union constructor specifies the proper field. */
2634: if (TREE_PURPOSE (link) != 0)
2635: field = TREE_PURPOSE (link);
2636:
2637: /* Eliminate the marker that makes a cast not be an lvalue. */
2638: if (val != 0 && TREE_CODE (val) == NON_LVALUE_EXPR)
2639: val = TREE_OPERAND (val, 0);
2640:
2641: if (field == 0 || !DECL_BIT_FIELD (field))
2642: {
2643: register int fieldsize;
2644: /* Since this structure is static,
2645: we know the positions are constant. */
2646: int bitpos = (field ? (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
2647: / BITS_PER_UNIT)
2648: : 0);
2649:
2650: /* An element that is not a bit-field.
2651: Output any buffered-up bit-fields preceding it. */
2652: if (byte_buffer_in_use)
2653: {
2654: ASM_OUTPUT_BYTE (asm_out_file, byte);
2655: total_bytes++;
2656: byte_buffer_in_use = 0;
2657: }
2658:
2659: /* Advance to offset of this element.
2660: Note no alignment needed in an array, since that is guaranteed
2661: if each element has the proper size. */
2662: if (field != 0 && bitpos != total_bytes)
2663: {
2664: assemble_zeros (bitpos - total_bytes);
2665: total_bytes = bitpos;
2666: }
2667:
2668: /* Determine size this element should occupy. */
2669: if (field)
2670: {
2671: if (TREE_CODE (DECL_SIZE (field)) != INTEGER_CST)
2672: abort ();
2673: if (TREE_INT_CST_LOW (DECL_SIZE (field)) > 100000)
2674: {
2675: /* This avoids overflow trouble. */
2676: tree size_tree = size_binop (CEIL_DIV_EXPR,
2677: DECL_SIZE (field),
2678: size_int (BITS_PER_UNIT));
2679: fieldsize = TREE_INT_CST_LOW (size_tree);
2680: }
2681: else
2682: {
2683: fieldsize = TREE_INT_CST_LOW (DECL_SIZE (field));
2684: fieldsize = (fieldsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
2685: }
2686: }
2687: else
2688: fieldsize = int_size_in_bytes (TREE_TYPE (TREE_TYPE (exp)));
2689:
2690: /* Output the element's initial value. */
2691: if (val == 0)
2692: assemble_zeros (fieldsize);
2693: else
2694: output_constant (val, fieldsize);
2695:
2696: /* Count its size. */
2697: total_bytes += fieldsize;
2698: }
2699: else if (val != 0 && TREE_CODE (val) != INTEGER_CST)
2700: error ("invalid initial value for member `%s'",
2701: IDENTIFIER_POINTER (DECL_NAME (field)));
2702: else
2703: {
2704: /* Element that is a bit-field. */
2705:
2706: int next_offset = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field));
2707: int end_offset
2708: = (next_offset + TREE_INT_CST_LOW (DECL_SIZE (field)));
2709:
2710: if (val == 0)
2711: val = integer_zero_node;
2712:
2713: /* If this field does not start in this (or, next) byte,
2714: skip some bytes. */
2715: if (next_offset / BITS_PER_UNIT != total_bytes)
2716: {
2717: /* Output remnant of any bit field in previous bytes. */
2718: if (byte_buffer_in_use)
2719: {
2720: ASM_OUTPUT_BYTE (asm_out_file, byte);
2721: total_bytes++;
2722: byte_buffer_in_use = 0;
2723: }
2724:
2725: /* If still not at proper byte, advance to there. */
2726: if (next_offset / BITS_PER_UNIT != total_bytes)
2727: {
2728: assemble_zeros (next_offset / BITS_PER_UNIT - total_bytes);
2729: total_bytes = next_offset / BITS_PER_UNIT;
2730: }
2731: }
2732:
2733: if (! byte_buffer_in_use)
2734: byte = 0;
2735:
2736: /* We must split the element into pieces that fall within
2737: separate bytes, and combine each byte with previous or
2738: following bit-fields. */
2739:
1.1.1.2 root 2740: /* next_offset is the offset n fbits from the beginning of
1.1 root 2741: the structure to the next bit of this element to be processed.
2742: end_offset is the offset of the first bit past the end of
2743: this element. */
2744: while (next_offset < end_offset)
2745: {
2746: int this_time;
2747: int shift, value;
2748: int next_byte = next_offset / BITS_PER_UNIT;
2749: int next_bit = next_offset % BITS_PER_UNIT;
2750:
2751: /* Advance from byte to byte
2752: within this element when necessary. */
2753: while (next_byte != total_bytes)
2754: {
2755: ASM_OUTPUT_BYTE (asm_out_file, byte);
2756: total_bytes++;
2757: byte = 0;
2758: }
2759:
2760: /* Number of bits we can process at once
2761: (all part of the same byte). */
2762: this_time = MIN (end_offset - next_offset,
2763: BITS_PER_UNIT - next_bit);
2764: #if BYTES_BIG_ENDIAN
2765: /* On big-endian machine, take the most significant bits
2766: first (of the bits that are significant)
2767: and put them into bytes from the most significant end. */
2768: shift = end_offset - next_offset - this_time;
2769: /* Don't try to take a bunch of bits that cross
2770: the word boundary in the INTEGER_CST. */
2771: if (shift < HOST_BITS_PER_INT
2772: && shift + this_time > HOST_BITS_PER_INT)
2773: {
2774: this_time -= (HOST_BITS_PER_INT - shift);
2775: shift = HOST_BITS_PER_INT;
2776: }
2777:
2778: /* Now get the bits from the appropriate constant word. */
2779: if (shift < HOST_BITS_PER_INT)
2780: {
2781: value = TREE_INT_CST_LOW (val);
2782: }
2783: else if (shift < 2 * HOST_BITS_PER_INT)
2784: {
2785: value = TREE_INT_CST_HIGH (val);
2786: shift -= HOST_BITS_PER_INT;
2787: }
2788: else
2789: abort ();
2790: byte |= (((value >> shift) & ((1 << this_time) - 1))
2791: << (BITS_PER_UNIT - this_time - next_bit));
2792: #else
2793: /* On little-endian machines,
2794: take first the least significant bits of the value
2795: and pack them starting at the least significant
2796: bits of the bytes. */
2797: shift = (next_offset
2798: - TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)));
2799: /* Don't try to take a bunch of bits that cross
2800: the word boundary in the INTEGER_CST. */
2801: if (shift < HOST_BITS_PER_INT
2802: && shift + this_time > HOST_BITS_PER_INT)
2803: {
2804: this_time -= (HOST_BITS_PER_INT - shift);
2805: shift = HOST_BITS_PER_INT;
2806: }
2807:
2808: /* Now get the bits from the appropriate constant word. */
2809: if (shift < HOST_BITS_PER_INT)
2810: value = TREE_INT_CST_LOW (val);
2811: else if (shift < 2 * HOST_BITS_PER_INT)
2812: {
2813: value = TREE_INT_CST_HIGH (val);
2814: shift -= HOST_BITS_PER_INT;
2815: }
2816: else
2817: abort ();
2818: byte |= ((value >> shift) & ((1 << this_time) - 1)) << next_bit;
2819: #endif
2820: next_offset += this_time;
2821: byte_buffer_in_use = 1;
2822: }
2823: }
2824: }
2825: if (byte_buffer_in_use)
2826: {
2827: ASM_OUTPUT_BYTE (asm_out_file, byte);
2828: total_bytes++;
2829: }
2830: if (total_bytes < size)
2831: assemble_zeros (size - total_bytes);
2832: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.