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