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