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