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