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