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