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