Sync usage with man page.
[netbsd-mini2440.git] / gnu / usr.bin / g++ / cc1plus / varasm.c
blob7650ab817344c17468a26fc5f44bd993fb3f9378
1 /* Output variables, constants and external declarations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
4 This file is part of GNU CC.
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 1, or (at your option)
9 any later version.
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.
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. */
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.
25 We also output the assembler code for constants stored in memory
26 and are responsible for combining constants with the same value. */
28 #include <stdio.h>
29 #include <setjmp.h>
30 /* #include <stab.h> */
31 #include "config.h"
32 #include "rtl.h"
33 #include "tree.h"
34 #include "flags.h"
35 #include "expr.h"
36 #include "hard-reg-set.h"
38 #include "obstack.h"
40 #define MIN(a, b) ((a) < (b) ? (a) : (b))
42 /* File in which assembler code is being written. */
44 extern FILE *asm_out_file;
46 /* The (assembler) name of the first globally-visible object output. */
47 char *first_global_object_name = 0;
49 extern struct obstack *current_obstack;
50 extern struct obstack *saveable_obstack;
51 extern struct obstack permanent_obstack;
52 #define obstack_chunk_alloc xmalloc
53 extern int xmalloc ();
55 /* Number for making the label on the next
56 constant that is stored in memory. */
58 int const_labelno;
60 /* Number for making the label on the next
61 static variable internal to a function. */
63 int var_labelno;
65 /* Nonzero if at least one function definition has been seen. */
66 static int function_defined;
68 extern FILE *asm_out_file;
70 static char *compare_constant_1 ();
71 static void record_constant_1 ();
72 void output_constant_pool ();
73 void assemble_name ();
74 void output_addressed_constants ();
75 void output_constant ();
76 void output_constructor ();
78 #ifdef EXTRA_SECTIONS
79 static enum in_section {no_section, in_text, in_data, EXTRA_SECTIONS} in_section
80 = no_section;
81 #else
82 static enum in_section {no_section, in_text, in_data} in_section
83 = no_section;
84 #endif
86 /* Define functions like text_section for any extra sections. */
87 #ifdef EXTRA_SECTION_FUNCTIONS
88 EXTRA_SECTION_FUNCTIONS
89 #endif
91 /* Tell assembler to switch to text section. */
93 void
94 text_section ()
96 if (in_section != in_text)
98 fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
99 in_section = in_text;
103 /* Tell assembler to switch to data section. */
105 void
106 data_section ()
108 if (in_section != in_data)
110 if (flag_shared_data)
112 #ifdef SHARED_SECTION_ASM_OP
113 fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
114 #else
115 fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
116 #endif
118 else
119 fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
121 in_section = in_data;
125 /* Determine if we're in the text section. */
128 in_text_section ()
130 return in_section == in_text;
133 /* Create the rtl to represent a function, for a function definition.
134 DECL is a FUNCTION_DECL node which describes which function.
135 The rtl is stored into DECL. */
137 void
138 make_function_rtl (decl)
139 tree decl;
141 /* Rename a nested function to avoid conflicts. */
142 if (DECL_CONTEXT (decl) != 0 && DECL_INITIAL (decl) != 0
143 && DECL_RTL (decl) == 0)
145 char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
146 char *label;
148 ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
149 DECL_ASSEMBLER_NAME (decl)
150 = obstack_copy0 (saveable_obstack, label, strlen (label));
151 var_labelno++;
154 if (DECL_RTL (decl) == 0)
155 DECL_RTL (decl)
156 = gen_rtx (MEM, DECL_MODE (decl),
157 gen_rtx (SYMBOL_REF, Pmode, DECL_ASSEMBLER_NAME (decl)));
159 /* Record at least one function has been defined. */
160 function_defined = 1;
163 /* Decode an `asm' spec for a declaration as a register name.
164 Return the register number, or -1 if nothing specified,
165 or -2 if the name is not a register. */
168 decode_reg_name (asmspec)
169 char *asmspec;
171 if (asmspec != 0)
173 int i;
174 extern char *reg_names[];
176 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
177 if (!strcmp (asmspec, reg_names[i]))
178 break;
180 if (i < FIRST_PSEUDO_REGISTER)
181 return i;
182 else
183 return -2;
186 return -1;
189 /* Create the DECL_RTL for a declaration for a static or external variable
190 or static or external function.
191 ASMSPEC, if not 0, is the string which the user specified
192 as the assembler symbol name.
193 TOP_LEVEL is nonzero if this is a file-scope variable.
195 This is never called for PARM_DECL nodes. */
197 void
198 make_decl_rtl (decl, asmspec, top_level)
199 tree decl;
200 char *asmspec;
201 int top_level;
203 register char *name = DECL_ASSEMBLER_NAME (decl);
204 int reg_number = decode_reg_name (asmspec);
206 if (reg_number == -2)
208 name = (char *) obstack_alloc (saveable_obstack,
209 strlen (asmspec) + 2);
210 name[0] = '*';
211 strcpy (&name[1], asmspec);
214 /* For a duplicate declaration, we can be called twice on the
215 same DECL node. Don't alter the RTL already made
216 unless the old mode is wrong (which can happen when
217 the previous rtl was made when the type was incomplete). */
218 if (DECL_RTL (decl) == 0
219 || GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl))
221 DECL_RTL (decl) = 0;
223 /* First detect errors in declaring global registers. */
224 if (TREE_REGDECL (decl) && reg_number == -1)
225 error_with_decl (decl,
226 "register name not specified for `%s'");
227 else if (TREE_REGDECL (decl) && reg_number == -2)
228 error_with_decl (decl,
229 "invalid register name for `%s'");
230 else if (reg_number >= 0 && ! TREE_REGDECL (decl))
231 error_with_decl (decl,
232 "register name given for non-register variable `%s'");
233 else if (TREE_REGDECL (decl) && TREE_CODE (decl) == FUNCTION_DECL)
234 error ("function declared `register'");
235 else if (TREE_REGDECL (decl) && TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
236 error_with_decl (decl, "data type of `%s' isn't suitable for a register");
237 /* Now handle properly declared static register variables. */
238 else if (TREE_REGDECL (decl))
240 int nregs;
241 if (pedantic)
242 warning ("ANSI C forbids global register variables");
243 if (DECL_INITIAL (decl) != 0)
245 DECL_INITIAL (decl) = 0;
246 error ("global register variable has initial value");
248 if (fixed_regs[reg_number] == 0
249 && function_defined && top_level)
250 error ("global register variable follows a function definition");
251 if (TREE_THIS_VOLATILE (decl))
252 warning ("volatile register variables don't work as you might wish");
253 DECL_RTL (decl) = gen_rtx (REG, DECL_MODE (decl), reg_number);
254 if (top_level)
256 /* Make this register fixed, so not usable for anything else. */
257 nregs = HARD_REGNO_NREGS (reg_number, DECL_MODE (decl));
258 while (nregs > 0)
259 global_regs[reg_number + --nregs] = 1;
260 init_reg_sets_1 ();
264 /* Now handle ordinary static variables and functions (in memory).
265 Also handle vars declared register invalidly. */
266 if (DECL_RTL (decl) == 0)
268 /* Can't use just the variable's own name for a variable
269 whose scope is less than the whole file.
270 Concatenate a distinguishing number. */
271 if (!top_level && !TREE_EXTERNAL (decl) && asmspec == 0)
273 char *label;
275 ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
276 name = obstack_copy0 (saveable_obstack, label, strlen (label));
277 var_labelno++;
280 DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl),
281 gen_rtx (SYMBOL_REF, Pmode, name));
282 if (TREE_VOLATILE (decl))
283 MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
284 if (TREE_READONLY (decl))
285 RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
286 MEM_IN_STRUCT_P (DECL_RTL (decl))
287 = (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
288 || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
289 || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
294 /* Output a string of literal assembler code
295 for an `asm' keyword used between functions. */
297 void
298 assemble_asm (string)
299 tree string;
301 app_enable ();
303 fprintf (asm_out_file, "\t%s\n", TREE_STRING_POINTER (string));
306 /* Output assembler code for the constant pool of a function and associated
307 with defining the name of the function. DECL describes the function.
308 For the constant pool, we use the current constant pool data. */
310 void
311 assemble_function (decl)
312 tree decl;
314 rtx x, n;
315 char *fnname;
316 int align;
318 /* Get the function's name, as described by its RTL.
319 This may be different from the DECL_NAME name used in the source file. */
321 x = DECL_RTL (decl);
322 if (GET_CODE (x) != MEM)
323 abort ();
324 n = XEXP (x, 0);
325 if (GET_CODE (n) != SYMBOL_REF)
326 abort ();
327 fnname = XSTR (n, 0);
329 /* The following code does not need preprocessing in the assembler. */
331 app_disable ();
333 output_constant_pool (fnname, decl);
335 text_section ();
337 #ifdef SDB_DEBUGGING_INFO
338 /* Make sure types are defined for debugger before fcn name is defined. */
339 if (write_symbols == SDB_DEBUG)
340 sdbout_tags (gettags ());
341 #endif
343 /* Tell assembler to move to target machine's alignment for functions. */
345 align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
346 if (align > 0)
347 ASM_OUTPUT_ALIGN (asm_out_file, align);
349 #ifdef SDB_DEBUGGING_INFO
350 /* Output SDB definition of the function. */
351 if (write_symbols == SDB_DEBUG)
352 sdbout_mark_begin_function ();
353 #endif
355 /* Make function name accessible from other files, if appropriate. */
357 if (TREE_PUBLIC (decl))
359 if (!first_global_object_name)
360 first_global_object_name = fnname;
361 ASM_GLOBALIZE_LABEL (asm_out_file, fnname);
364 /* Do any machine/system dependent processing of the function name */
365 #ifdef ASM_DECLARE_FUNCTION_NAME
366 ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl);
367 #else
368 /* Standard thing is just output label for the function. */
369 ASM_OUTPUT_LABEL (asm_out_file, fnname);
370 #endif /* ASM_DECLARE_FUNCTION_NAME */
373 /* Assemble " .int 0\n" or whatever this assembler wants. */
375 void
376 assemble_integer_zero ()
378 ASM_OUTPUT_INT (asm_out_file, const0_rtx);
381 /* Assemble a string constant with the specified C string as contents. */
383 void
384 assemble_string (p, size)
385 unsigned char *p;
386 int size;
388 register int i;
389 int pos = 0;
390 int maximum = 2000;
392 /* If the string is very long, split it up. */
394 while (pos < size)
396 int thissize = size - pos;
397 if (thissize > maximum)
398 thissize = maximum;
400 #ifdef ASM_OUTPUT_ASCII
401 ASM_OUTPUT_ASCII (asm_out_file, p, thissize);
402 #else
403 fprintf (asm_out_file, "\t.ascii \"");
405 for (i = 0; i < thissize; i++)
407 register int c = p[i];
408 if (c == '\"' || c == '\\')
409 putc ('\\', asm_out_file);
410 if (c >= ' ' && c < 0177)
411 putc (c, asm_out_file);
412 else
414 fprintf (asm_out_file, "\\%o", c);
415 /* After an octal-escape, if a digit follows,
416 terminate one string constant and start another.
417 The Vax assembler fails to stop reading the escape
418 after three digits, so this is the only way we
419 can get it to parse the data properly. */
420 if (i < thissize - 1
421 && p[i + 1] >= '0' && p[i + 1] <= '9')
422 fprintf (asm_out_file, "\"\n\t.ascii \"");
425 fprintf (asm_out_file, "\"\n");
426 #endif /* no ASM_OUTPUT_ASCII */
428 pos += thissize;
429 p += thissize;
433 /* Assemble everything that is needed for a variable or function declaration.
434 Not used for automatic variables, and not used for function definitions.
435 Should not be called for variables of incomplete structure type.
437 TOP_LEVEL is nonzero if this variable has file scope.
438 WRITE_SYMBOLS is DBX_DEBUG if writing dbx symbol output.
439 The dbx data for a file-scope variable is written here.
440 AT_END is nonzero if this is the special handling, at end of compilation,
441 to define things that have had only tentative definitions. */
443 void
444 assemble_variable (decl, top_level, write_symbols, at_end)
445 tree decl;
446 int top_level;
447 enum debugger write_symbols;
448 int at_end;
450 register char *name;
451 register int i;
452 int align;
454 /* Do nothing for global register variables. */
456 if (GET_CODE (DECL_RTL (decl)) == REG)
457 return;
459 /* Normally no need to say anything for external references,
460 since assembler considers all undefined symbols external. */
462 if (TREE_EXTERNAL (decl))
463 return;
465 /* Output no assembler code for a function declaration.
466 Only definitions of functions output anything. */
468 if (TREE_CODE (decl) == FUNCTION_DECL)
469 return;
471 /* If type was incomplete when the variable was declared,
472 see if it is complete now. */
474 if (DECL_SIZE (decl) == 0)
475 layout_decl (decl, 0);
477 /* Still incomplete => don't allocate it; treat the tentative defn
478 (which is what it must have been) as an `extern' reference. */
480 if (DECL_SIZE (decl) == 0)
482 error_with_file_and_line (DECL_SOURCE_FILE (decl),
483 DECL_SOURCE_LINE (decl),
484 "storage size of static var `%s' isn't known",
485 IDENTIFIER_POINTER (DECL_NAME (decl)));
486 return;
489 /* The first declaration of a variable that comes through this function
490 decides whether it is global (in C, has external linkage)
491 or local (in C, has internal linkage). So do nothing more
492 if this function has already run. */
494 if (TREE_ASM_WRITTEN (decl))
495 return;
497 TREE_ASM_WRITTEN (decl) = 1;
499 #ifdef DBX_DEBUGGING_INFO
500 /* File-scope global variables are output here. */
501 if (write_symbols == DBX_DEBUG && top_level)
502 dbxout_symbol (decl, 0);
503 #endif
504 #ifdef SDB_DEBUGGING_INFO
505 if (write_symbols == SDB_DEBUG && top_level)
506 sdbout_symbol (decl, 0);
507 #endif
508 if (write_symbols == GDB_DEBUG)
509 /* Make sure the file is known to GDB even if it has no functions. */
510 set_current_gdbfile (DECL_SOURCE_FILE (decl));
512 /* If storage size is erroneously variable, just continue.
513 Error message was already made. */
515 if (! TREE_LITERAL (DECL_SIZE (decl)))
516 return;
518 app_disable ();
520 name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
522 /* Handle uninitialized definitions. */
524 if (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node)
526 int size = (TREE_INT_CST_LOW (DECL_SIZE (decl))
527 * DECL_SIZE_UNIT (decl)
528 / BITS_PER_UNIT);
529 int rounded = size;
530 /* Don't allocate zero bytes of common,
531 since that means "undefined external" in the linker. */
532 if (size == 0) rounded = 1;
533 /* Round size up to multiple of BIGGEST_ALIGNMENT bits
534 so that each uninitialized object starts on such a boundary. */
535 rounded = ((rounded + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
536 / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
537 * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
538 if (flag_shared_data)
539 data_section ();
540 if (TREE_PUBLIC (decl))
541 ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
542 else
543 ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
544 return;
547 /* Handle initialized definitions. */
549 /* First make the assembler name(s) global if appropriate. */
550 if (TREE_PUBLIC (decl) && DECL_NAME (decl))
552 if (!first_global_object_name
553 && (DECL_INITIAL (decl) == 0
554 || TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR
555 || CONSTRUCTOR_ELTS (DECL_INITIAL (decl)) != 0))
556 first_global_object_name = name + (name[0] == '*');
557 ASM_GLOBALIZE_LABEL (asm_out_file, name);
559 #if 0
560 for (d = equivalents; d; d = TREE_CHAIN (d))
562 tree e = TREE_VALUE (d);
563 if (TREE_PUBLIC (e) && DECL_NAME (e))
564 ASM_GLOBALIZE_LABEL (asm_out_file,
565 XSTR (XEXP (DECL_RTL (e), 0), 0));
567 #endif
569 /* Output any data that we will need to use the address of. */
570 if (DECL_INITIAL (decl))
571 output_addressed_constants (DECL_INITIAL (decl));
573 /* Switch to the proper section for this data. */
574 #ifdef SELECT_SECTION
575 SELECT_SECTION (decl);
576 #else
577 if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))
578 text_section ();
579 else
580 data_section ();
581 #endif
583 /* Output the alignment of this data. */
584 #ifdef DATA_ALIGNMENT
585 /* On some machines, it is good to increase alignment sometimes. */
586 align = DATA_ALIGNMENT (decl, DECL_ALIGN (decl));
587 #else /* no DATA_ALIGNMENT */
588 align = DECL_ALIGN (decl);
589 #endif /* DATA_ALIGNMENT */
591 for (i = 0; align >= BITS_PER_UNIT << (i + 1); i++);
592 if (i > 0)
593 ASM_OUTPUT_ALIGN (asm_out_file, i);
595 /* Output the name(s) of this data. */
596 ASM_OUTPUT_LABEL (asm_out_file, name);
597 #if 0
598 for (d = equivalents; d; d = TREE_CHAIN (d))
600 tree e = TREE_VALUE (d);
601 ASM_OUTPUT_LABEL (asm_out_file, XSTR (XEXP (DECL_RTL (e), 0), 0));
603 #endif
605 if (DECL_INITIAL (decl))
606 /* Output the actual data. */
607 output_constant (DECL_INITIAL (decl), int_size_in_bytes (TREE_TYPE (decl)));
608 else
609 /* Leave space for it. */
610 ASM_OUTPUT_SKIP (asm_out_file, int_size_in_bytes (TREE_TYPE (decl)));
613 /* Output something to declare an external symbol to the assembler.
614 (Most assemblers don't need this, so we normally output nothing.) */
616 void
617 assemble_external (decl)
618 tree decl;
620 rtx rtl = DECL_RTL (decl);
622 if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF)
624 #ifdef ASM_OUTPUT_EXTERNAL
625 /* Some systems do require some output. */
626 ASM_OUTPUT_EXTERNAL (asm_out_file, decl, XSTR (XEXP (rtl, 0), 0));
627 #endif
631 /* Output to FILE a reference to the assembler name of a C-level name NAME.
632 If NAME starts with a *, the rest of NAME is output verbatim.
633 Otherwise NAME is transformed in an implementation-defined way
634 (usually by the addition of an underscore).
635 Many macros in the tm file are defined to call this function. */
637 void
638 assemble_name (file, name)
639 FILE *file;
640 char *name;
642 if (name[0] == '*')
643 fputs (&name[1], file);
644 else
645 ASM_OUTPUT_LABELREF (file, name);
648 /* Allocate SIZE bytes writable static space with a gensym name
649 and return an RTX to refer to its address. */
652 assemble_static_space (size)
653 int size;
655 char name[12];
656 char *namestring;
657 rtx x;
658 /* Round size up to multiple of BIGGEST_ALIGNMENT bits
659 so that each uninitialized object starts on such a boundary. */
660 int rounded = ((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
661 / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
662 * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
664 if (flag_shared_data)
665 data_section ();
666 ASM_GENERATE_INTERNAL_LABEL (name, "LF", const_labelno);
667 ++const_labelno;
669 namestring = (char *) obstack_alloc (saveable_obstack,
670 strlen (name) + 2);
671 strcpy (namestring, name);
673 x = gen_rtx (SYMBOL_REF, Pmode, namestring);
674 ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
675 return x;
677 #if 0
678 /* Assemble the static constant template for function entry trampolines.
679 This is done at most once per compilation.
680 Returns an RTX for the address of the template. */
683 assemble_trampoline_template ()
685 char label[256];
686 char *name;
687 int align;
689 /* Write the assembler code to define one. */
690 align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
691 if (align > 0)
692 ASM_OUTPUT_ALIGN (asm_out_file, align);
694 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LTRAMP", 0);
695 TRAMPOLINE_TEMPLATE (asm_out_file);
697 /* Record the rtl to refer to it. */
698 ASM_GENERATE_INTERNAL_LABEL (label, "LTRAMP", 0);
699 name
700 = (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));
701 return gen_rtx (SYMBOL_REF, Pmode, name);
703 #endif
705 /* Here we combine duplicate floating constants to make
706 CONST_DOUBLE rtx's, and force those out to memory when necessary. */
708 /* Chain of all CONST_DOUBLE rtx's constructed for the current function.
709 They are chained through the CONST_DOUBLE_CHAIN.
710 A CONST_DOUBLE rtx has CONST_DOUBLE_MEM != cc0_rtx iff it is on this chain.
711 In that case, CONST_DOUBLE_MEM is either a MEM,
712 or const0_rtx if no MEM has been made for this CONST_DOUBLE yet. */
714 static rtx real_constant_chain;
716 /* Return a CONST_DOUBLE for a value specified as a pair of ints.
717 For an integer, I0 is the low-order word and I1 is the high-order word.
718 For a real number, I0 is the word with the low address
719 and I1 is the word with the high address. */
722 immed_double_const (i0, i1, mode)
723 int i0, i1;
724 enum machine_mode mode;
726 register rtx r;
728 if (mode == DImode && i0 == 0 && i1 == 0)
729 return const0_rtx;
731 /* Search the chain for an existing CONST_DOUBLE with the right value.
732 If one is found, return it. */
734 for (r = real_constant_chain; r; r = CONST_DOUBLE_CHAIN (r))
735 if (CONST_DOUBLE_LOW (r) == i0 && CONST_DOUBLE_HIGH (r) == i1
736 && GET_MODE (r) == mode)
737 return r;
739 /* No; make a new one and add it to the chain. */
741 r = gen_rtx (CONST_DOUBLE, mode, 0, i0, i1);
743 CONST_DOUBLE_CHAIN (r) = real_constant_chain;
744 real_constant_chain = r;
746 /* Store const0_rtx in mem-slot since this CONST_DOUBLE is on the chain.
747 Actual use of mem-slot is only through force_const_double_mem. */
749 CONST_DOUBLE_MEM (r) = const0_rtx;
751 return r;
754 /* Return a CONST_DOUBLE for a specified `double' value
755 and machine mode. */
758 immed_real_const_1 (d, mode)
759 REAL_VALUE_TYPE d;
760 enum machine_mode mode;
762 union real_extract u;
763 register rtx r;
764 REAL_VALUE_TYPE negated;
766 /* Get the desired `double' value as a sequence of ints
767 since that is how they are stored in a CONST_DOUBLE. */
769 u.d = d;
771 #if 0
772 /* Detect special cases. */
774 if (REAL_VALUES_EQUAL (dconst0, d))
775 return (mode == DFmode ? dconst0_rtx : fconst0_rtx);
776 else if (REAL_VALUES_EQUAL (dconst1, d))
777 return (mode == DFmode ? dconst1_rtx : fconst1_rtx);
779 if (sizeof u == 2 * sizeof (int))
780 return immed_double_const (u.i[0], u.i[1], mode);
781 #else
782 /* Detect zero. */
784 negated = REAL_VALUE_NEGATE (d);
785 if (REAL_VALUES_EQUAL (negated, d))
786 return (mode == DFmode ? dconst0_rtx : fconst0_rtx);
788 if (sizeof u == 2 * sizeof (int))
789 return immed_double_const (u.i[0], u.i[1], mode);
790 #endif
792 /* The rest of this function handles the case where
793 a float value requires more than 2 ints of space.
794 It will be deleted as dead code on machines that don't need it. */
796 /* Search the chain for an existing CONST_DOUBLE with the right value.
797 If one is found, return it. */
799 for (r = real_constant_chain; r; r = CONST_DOUBLE_CHAIN (r))
800 if (! bcmp (&CONST_DOUBLE_LOW (r), &u, sizeof u)
801 && GET_MODE (r) == mode)
802 return r;
804 /* No; make a new one and add it to the chain. */
806 r = rtx_alloc (CONST_DOUBLE);
807 PUT_MODE (r, mode);
808 bcopy (&u, &CONST_DOUBLE_LOW (r), sizeof u);
810 CONST_DOUBLE_CHAIN (r) = real_constant_chain;
811 real_constant_chain = r;
813 /* Store const0_rtx in slot 2 since this CONST_DOUBLE is on the chain.
814 Actual use of slot 2 is only through force_const_double_mem. */
816 CONST_DOUBLE_MEM (r) = const0_rtx;
818 return r;
821 /* Return a CONST_DOUBLE rtx for a value specified by EXP,
822 which must be a REAL_CST tree node. */
825 immed_real_const (exp)
826 tree exp;
828 return immed_real_const_1 (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)));
831 /* Given a CONST_DOUBLE, cause a constant in memory to be created
832 (unless we already have one for the same value)
833 and return a MEM rtx to refer to it.
834 Put the CONST_DOUBLE on real_constant_chain if it isn't already there. */
837 force_const_double_mem (r)
838 rtx r;
840 if (GET_CODE (CONST_DOUBLE_MEM (r)) != MEM)
841 force_const_mem (GET_MODE (r), r);
843 /* CONST_DOUBLE_MEM (r) is now a MEM with a constant address.
844 If that is legitimate, return it.
845 Othewise it will need reloading, so return a copy of it. */
846 if (memory_address_p (GET_MODE (r), XEXP (CONST_DOUBLE_MEM (r), 0)))
847 return CONST_DOUBLE_MEM (r);
848 return gen_rtx (MEM, GET_MODE (r), XEXP (CONST_DOUBLE_MEM (r), 0));
851 /* At the end of a function, forget the memory-constants
852 previously made for CONST_DOUBLEs. Mark them as not on real_constant_chain.
853 Also clear out real_constant_chain and clear out all the chain-pointers. */
855 void
856 clear_const_double_mem ()
858 register rtx r, next;
860 for (r = real_constant_chain; r; r = next)
862 next = CONST_DOUBLE_CHAIN (r);
863 CONST_DOUBLE_CHAIN (r) = 0;
864 CONST_DOUBLE_MEM (r) = cc0_rtx;
866 real_constant_chain = 0;
869 /* Given an expression EXP with a constant value,
870 reduce it to the sum of an assembler symbol and an integer.
871 Store them both in the structure *VALUE.
872 Abort if EXP does not reduce. */
874 struct addr_const
876 rtx base;
877 int offset;
880 static void
881 decode_addr_const (exp, value)
882 tree exp;
883 struct addr_const *value;
885 register tree target = TREE_OPERAND (exp, 0);
886 register int offset = 0;
887 register rtx x;
889 while (1)
891 if (TREE_CODE (target) == COMPONENT_REF)
893 offset += DECL_OFFSET (TREE_OPERAND (target, 1)) / BITS_PER_UNIT;
894 target = TREE_OPERAND (target, 0);
896 else if (TREE_CODE (target) == ARRAY_REF)
898 if (TREE_CODE (TREE_OPERAND (target, 1)) != INTEGER_CST
899 || TREE_CODE (TYPE_SIZE (TREE_TYPE (target))) != INTEGER_CST)
900 abort ();
901 offset += ((TYPE_SIZE_UNIT (TREE_TYPE (target))
902 * TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (target)))
903 * TREE_INT_CST_LOW (TREE_OPERAND (target, 1)))
904 / BITS_PER_UNIT);
905 target = TREE_OPERAND (target, 0);
907 else break;
910 if (TREE_CODE (target) == VAR_DECL
911 || TREE_CODE (target) == FUNCTION_DECL)
912 x = DECL_RTL (target);
913 else if (TREE_LITERAL (target))
914 x = TREE_CST_RTL (target);
915 else
916 abort ();
918 if (GET_CODE (x) != MEM)
919 abort ();
920 x = XEXP (x, 0);
922 value->base = x;
923 value->offset = offset;
926 /* Uniquize all constants that appear in memory.
927 Each constant in memory thus far output is recorded
928 in `const_hash_table' with a `struct constant_descriptor'
929 that contains a polish representation of the value of
930 the constant.
932 We cannot store the trees in the hash table
933 because the trees may be temporary. */
935 struct constant_descriptor
937 struct constant_descriptor *next;
938 char *label;
939 char contents[1];
942 #define HASHBITS 30
943 #define MAX_HASH_TABLE 1009
944 static struct constant_descriptor *const_hash_table[MAX_HASH_TABLE];
946 /* Compute a hash code for a constant expression. */
949 const_hash (exp)
950 tree exp;
952 register char *p;
953 register int len, hi, i;
954 register enum tree_code code = TREE_CODE (exp);
956 if (code == INTEGER_CST)
958 p = (char *) &TREE_INT_CST_LOW (exp);
959 len = 2 * sizeof TREE_INT_CST_LOW (exp);
961 else if (code == REAL_CST)
963 p = (char *) &TREE_REAL_CST (exp);
964 len = sizeof TREE_REAL_CST (exp);
966 else if (code == STRING_CST)
967 p = TREE_STRING_POINTER (exp), len = TREE_STRING_LENGTH (exp);
968 else if (code == COMPLEX_CST)
969 return const_hash (TREE_REALPART (exp)) * 5
970 + const_hash (TREE_IMAGPART (exp));
971 else if (code == CONSTRUCTOR)
973 register tree link;
975 /* For record type, include the type in the hashing.
976 We do not do so for array types
977 because (1) the sizes of the elements are sufficient
978 and (2) distinct array types can have the same constructor. */
979 if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
980 hi = ((int) TREE_TYPE (exp) & ((1 << HASHBITS) - 1)) % MAX_HASH_TABLE;
981 else
982 hi = 5;
984 for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
985 hi = (hi * 603 + const_hash (TREE_VALUE (link))) % MAX_HASH_TABLE;
987 return hi;
989 else if (code == ADDR_EXPR)
991 struct addr_const value;
992 decode_addr_const (exp, &value);
993 p = (char *) &value;
994 len = sizeof value;
996 else if (code == PLUS_EXPR || code == MINUS_EXPR)
997 return const_hash (TREE_OPERAND (exp, 0)) * 9
998 + const_hash (TREE_OPERAND (exp, 1));
999 else if (code == NOP_EXPR || code == CONVERT_EXPR)
1000 return const_hash (TREE_OPERAND (exp, 0)) * 7 + 2;
1002 /* Compute hashing function */
1003 hi = len;
1004 for (i = 0; i < len; i++)
1005 hi = ((hi * 613) + (unsigned)(p[i]));
1007 hi &= (1 << HASHBITS) - 1;
1008 hi %= MAX_HASH_TABLE;
1009 return hi;
1012 /* Compare a constant expression EXP with a constant-descriptor DESC.
1013 Return 1 if DESC describes a constant with the same value as EXP. */
1015 static int
1016 compare_constant (exp, desc)
1017 tree exp;
1018 struct constant_descriptor *desc;
1020 return 0 != compare_constant_1 (exp, desc->contents);
1023 /* Compare constant expression EXP with a substring P of a constant descriptor.
1024 If they match, return a pointer to the end of the substring matched.
1025 If they do not match, return 0.
1027 Since descriptors are written in polish prefix notation,
1028 this function can be used recursively to test one operand of EXP
1029 against a subdescriptor, and if it succeeds it returns the
1030 address of the subdescriptor for the next operand. */
1032 static char *
1033 compare_constant_1 (exp, p)
1034 tree exp;
1035 char *p;
1037 register char *strp;
1038 register int len;
1039 register enum tree_code code = TREE_CODE (exp);
1041 if (code != (enum tree_code) *p++)
1042 return 0;
1044 if (code == INTEGER_CST)
1046 /* Integer constants are the same only if the same width of type. */
1047 if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
1048 return 0;
1049 strp = (char *) &TREE_INT_CST_LOW (exp);
1050 len = 2 * sizeof TREE_INT_CST_LOW (exp);
1052 else if (code == REAL_CST)
1054 /* Real constants are the same only if the same width of type. */
1055 if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
1056 return 0;
1057 strp = (char *) &TREE_REAL_CST (exp);
1058 len = sizeof TREE_REAL_CST (exp);
1060 else if (code == STRING_CST)
1062 if (flag_writable_strings)
1063 return 0;
1064 strp = TREE_STRING_POINTER (exp);
1065 len = TREE_STRING_LENGTH (exp);
1066 if (bcmp (&TREE_STRING_LENGTH (exp), p,
1067 sizeof TREE_STRING_LENGTH (exp)))
1068 return 0;
1069 p += sizeof TREE_STRING_LENGTH (exp);
1071 else if (code == COMPLEX_CST)
1073 p = compare_constant_1 (TREE_REALPART (exp), p);
1074 if (p == 0) return 0;
1075 p = compare_constant_1 (TREE_IMAGPART (exp), p);
1076 return p;
1078 else if (code == CONSTRUCTOR)
1080 register tree link;
1081 int length = list_length (CONSTRUCTOR_ELTS (exp));
1082 tree type;
1084 if (bcmp (&length, p, sizeof length))
1085 return 0;
1086 p += sizeof length;
1088 /* For record constructors, insist that the types match.
1089 For arrays, just verify both constructors are for arrays. */
1090 if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
1091 type = TREE_TYPE (exp);
1092 else
1093 type = 0;
1094 if (bcmp (&type, p, sizeof type))
1095 return 0;
1096 p += sizeof type;
1098 for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
1099 if ((p = compare_constant_1 (TREE_VALUE (link), p)) == 0)
1100 return 0;
1101 return p;
1103 else if (code == ADDR_EXPR)
1105 struct addr_const value;
1106 decode_addr_const (exp, &value);
1107 strp = (char *) &value;
1108 len = sizeof value;
1109 /* Compare SYMBOL_REF address and offset. */
1110 while (--len >= 0)
1111 if (*p++ != *strp++)
1112 return 0;
1113 /* Compare symbol name. */
1114 strp = XSTR (value.base, 0);
1115 len = strlen (strp) + 1;
1117 else if (code == PLUS_EXPR || code == MINUS_EXPR)
1119 p = compare_constant_1 (TREE_OPERAND (exp, 0), p);
1120 if (p == 0) return 0;
1121 p = compare_constant_1 (TREE_OPERAND (exp, 1), p);
1122 return p;
1124 else if (code == NOP_EXPR || code == CONVERT_EXPR)
1126 p = compare_constant_1 (TREE_OPERAND (exp, 0), p);
1127 return p;
1130 /* Compare constant contents. */
1131 while (--len >= 0)
1132 if (*p++ != *strp++)
1133 return 0;
1135 return p;
1138 /* Construct a constant descriptor for the expression EXP.
1139 It is up to the caller to enter the descriptor in the hash table. */
1141 static struct constant_descriptor *
1142 record_constant (exp)
1143 tree exp;
1145 struct constant_descriptor *ptr = 0;
1146 int buf;
1148 obstack_grow (&permanent_obstack, &ptr, sizeof ptr);
1149 obstack_grow (&permanent_obstack, &buf, sizeof buf);
1150 record_constant_1 (exp);
1151 return (struct constant_descriptor *) obstack_finish (&permanent_obstack);
1154 /* Add a description of constant expression EXP
1155 to the object growing in `permanent_obstack'.
1156 No need to return its address; the caller will get that
1157 from the obstack when the object is complete. */
1159 static void
1160 record_constant_1 (exp)
1161 tree exp;
1163 register char *strp;
1164 register int len;
1165 register enum tree_code code = TREE_CODE (exp);
1167 obstack_1grow (&permanent_obstack, (unsigned int) code);
1169 if (code == INTEGER_CST)
1171 obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
1172 strp = (char *) &TREE_INT_CST_LOW (exp);
1173 len = 2 * sizeof TREE_INT_CST_LOW (exp);
1175 else if (code == REAL_CST)
1177 obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
1178 strp = (char *) &TREE_REAL_CST (exp);
1179 len = sizeof TREE_REAL_CST (exp);
1181 else if (code == STRING_CST)
1183 if (flag_writable_strings)
1184 return;
1185 strp = TREE_STRING_POINTER (exp);
1186 len = TREE_STRING_LENGTH (exp);
1187 obstack_grow (&permanent_obstack, (char *) &TREE_STRING_LENGTH (exp),
1188 sizeof TREE_STRING_LENGTH (exp));
1190 else if (code == COMPLEX_CST)
1192 record_constant_1 (TREE_REALPART (exp));
1193 record_constant_1 (TREE_IMAGPART (exp));
1194 return;
1196 else if (code == CONSTRUCTOR)
1198 register tree link;
1199 int length = list_length (CONSTRUCTOR_ELTS (exp));
1200 tree type;
1202 obstack_grow (&permanent_obstack, (char *) &length, sizeof length);
1204 /* For record constructors, insist that the types match.
1205 For arrays, just verify both constructors are for arrays. */
1206 if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
1207 type = TREE_TYPE (exp);
1208 else
1209 type = 0;
1210 obstack_grow (&permanent_obstack, (char *) &type, sizeof type);
1212 for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
1213 record_constant_1 (TREE_VALUE (link));
1214 return;
1216 else if (code == ADDR_EXPR)
1218 struct addr_const value;
1219 decode_addr_const (exp, &value);
1220 /* Record the SYMBOL_REF address and the offset. */
1221 obstack_grow (&permanent_obstack, (char *) &value, sizeof value);
1222 /* Record the symbol name. */
1223 obstack_grow (&permanent_obstack, XSTR (value.base, 0),
1224 strlen (XSTR (value.base, 0)) + 1);
1225 return;
1227 else if (code == PLUS_EXPR || code == MINUS_EXPR)
1229 record_constant_1 (TREE_OPERAND (exp, 0));
1230 record_constant_1 (TREE_OPERAND (exp, 1));
1231 return;
1233 else if (code == NOP_EXPR || code == CONVERT_EXPR)
1235 record_constant_1 (TREE_OPERAND (exp, 0));
1236 return;
1239 /* Record constant contents. */
1240 obstack_grow (&permanent_obstack, strp, len);
1243 /* Return the constant-label-string for constant value EXP.
1244 If no constant equal to EXP has yet been output,
1245 define a new label and output assembler code for it.
1246 The const_hash_table records which constants already have label strings. */
1248 static char *
1249 get_or_assign_label (exp)
1250 tree exp;
1252 register int hash, i, align;
1253 register struct constant_descriptor *desc;
1254 char label[256];
1256 /* Make sure any other constants whose addresses appear in EXP
1257 are assigned label numbers. */
1259 output_addressed_constants (exp);
1261 /* Compute hash code of EXP. Search the descriptors for that hash code
1262 to see if any of them describes EXP. If yes, the descriptor records
1263 the label number already assigned. */
1265 hash = const_hash (exp) % MAX_HASH_TABLE;
1267 for (desc = const_hash_table[hash]; desc; desc = desc->next)
1268 if (compare_constant (exp, desc))
1269 return desc->label;
1271 /* No constant equal to EXP is known to have been output.
1272 Make a constant descriptor to enter EXP in the hash table.
1273 Assign the label number and record it in the descriptor for
1274 future calls to this function to find. */
1276 desc = record_constant (exp);
1277 desc->next = const_hash_table[hash];
1278 const_hash_table[hash] = desc;
1280 /* Now output assembler code to define that label
1281 and follow it with the data of EXP. */
1283 /* First switch to text section, except for writable strings. */
1284 #ifdef SELECT_SECTION
1285 SELECT_SECTION (exp);
1286 #else
1287 if ((TREE_CODE (exp) == STRING_CST) && flag_writable_strings)
1288 data_section ();
1289 else
1290 text_section ();
1291 #endif
1293 /* Align the location counter as required by EXP's data type. */
1294 #ifdef DATA_ALIGNMENT
1295 align = DATA_ALIGNMENT (exp, TYPE_ALIGN (TREE_TYPE (exp)));
1296 #else
1297 align = TYPE_ALIGN (TREE_TYPE (exp));
1298 #endif
1300 for (i = 0; align >= BITS_PER_UNIT << (i + 1); i++);
1301 if (i > 0)
1302 ASM_OUTPUT_ALIGN (asm_out_file, i);
1304 /* Output the label itself. */
1305 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", const_labelno);
1307 /* Output the value of EXP. */
1308 output_constant (exp,
1309 (TREE_CODE (exp) == STRING_CST
1310 ? TREE_STRING_LENGTH (exp)
1311 : int_size_in_bytes (TREE_TYPE (exp))));
1313 /* Create a string containing the label name, in LABEL. */
1314 ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
1316 ++const_labelno;
1318 desc->label
1319 = (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));
1321 return desc->label;
1324 /* Return an rtx representing a reference to constant data in memory
1325 for the constant expression EXP.
1326 If assembler code for such a constant has already been output,
1327 return an rtx to refer to it.
1328 Otherwise, output such a constant in memory and generate
1329 an rtx for it. The TREE_CST_RTL of EXP is set up to point to that rtx. */
1332 output_constant_def (exp)
1333 tree exp;
1335 register rtx def;
1336 int temp_p = allocation_temporary_p ();
1338 if (TREE_CODE (exp) == INTEGER_CST)
1339 abort (); /* No TREE_CST_RTL slot in these. */
1341 if (TREE_CST_RTL (exp))
1342 return TREE_CST_RTL (exp);
1344 if (TREE_PERMANENT (exp))
1345 end_temporary_allocation ();
1347 def = gen_rtx (SYMBOL_REF, Pmode, get_or_assign_label (exp));
1349 TREE_CST_RTL (exp)
1350 = gen_rtx (MEM, TYPE_MODE (TREE_TYPE (exp)), def);
1351 RTX_UNCHANGING_P (TREE_CST_RTL (exp)) = 1;
1353 if (temp_p && TREE_PERMANENT (exp))
1354 resume_temporary_allocation ();
1356 return TREE_CST_RTL (exp);
1359 /* Similar hash facility for making memory-constants
1360 from constant rtl-expressions. It is used on RISC machines
1361 where immediate integer arguments and constant addresses are restricted
1362 so that such constants must be stored in memory.
1364 This pool of constants is reinitialized for each function
1365 so each function gets its own constants-pool that comes right before it.
1367 All structures allocated here are discarded when functions are saved for
1368 inlining, so they do not need to be allocated permanently. */
1370 #define MAX_RTX_HASH_TABLE 61
1371 static struct constant_descriptor *const_rtx_hash_table[MAX_RTX_HASH_TABLE];
1373 /* Structure to represent sufficient information about a constant so that
1374 it can be output when the constant pool is output, so that function
1375 integration can be done, and to simplify handling on machines that reference
1376 constant pool as base+displacement. */
1378 struct pool_constant
1380 struct constant_descriptor *desc;
1381 struct pool_constant *next;
1382 enum machine_mode mode;
1383 rtx constant;
1384 int labelno;
1385 int align;
1386 int offset;
1389 /* Pointers to first and last constant in pool. */
1391 static struct pool_constant *first_pool, *last_pool;
1393 /* Current offset in constant pool (does not include any machine-specific
1394 header. */
1396 static int pool_offset;
1398 /* Structure used to maintain hash table mapping symbols used to their
1399 corresponding constants. */
1401 struct pool_sym
1403 char *label;
1404 struct pool_constant *pool;
1405 struct pool_sym *next;
1408 static struct pool_sym *const_rtx_sym_hash_table[MAX_RTX_HASH_TABLE];
1410 /* Hash code for a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true.
1411 The argument is XSTR (... , 0) */
1413 #define SYMHASH(LABEL) \
1414 ((((int) (LABEL)) & ((1 << HASHBITS) - 1)) % MAX_RTX_HASH_TABLE)
1416 /* Initialize constant pool hashing for next function. */
1418 void
1419 init_const_rtx_hash_table ()
1421 bzero (const_rtx_hash_table, sizeof const_rtx_hash_table);
1422 bzero (const_rtx_sym_hash_table, sizeof const_rtx_sym_hash_table);
1424 first_pool = last_pool = 0;
1425 pool_offset = 0;
1428 struct rtx_const
1430 enum kind { RTX_DOUBLE, RTX_INT } kind : 16;
1431 enum machine_mode mode : 16;
1432 union {
1433 union real_extract du;
1434 struct addr_const addr;
1435 } un;
1438 /* Express an rtx for a constant integer (perhaps symbolic)
1439 as the sum of a symbol or label plus an explicit integer.
1440 They are stored into VALUE. */
1442 static void
1443 decode_rtx_const (mode, x, value)
1444 enum machine_mode mode;
1445 rtx x;
1446 struct rtx_const *value;
1448 /* Clear the whole structure, including any gaps. */
1451 int *p = (int *) value;
1452 int *end = (int *) (value + 1);
1453 while (p < end)
1454 *p++ = 0;
1457 value->kind = RTX_INT; /* Most usual kind. */
1458 value->mode = mode;
1460 switch (GET_CODE (x))
1462 case CONST_DOUBLE:
1463 value->kind = RTX_DOUBLE;
1464 value->mode = GET_MODE (x);
1465 bcopy (&CONST_DOUBLE_LOW (x), &value->un.du, sizeof value->un.du);
1466 break;
1468 case CONST_INT:
1469 value->un.addr.offset = INTVAL (x);
1470 break;
1472 case SYMBOL_REF:
1473 value->un.addr.base = x;
1474 break;
1476 case LABEL_REF:
1477 value->un.addr.base = x;
1478 break;
1480 case CONST:
1481 x = XEXP (x, 0);
1482 if (GET_CODE (x) == PLUS)
1484 value->un.addr.base = XEXP (XEXP (x, 0), 0);
1485 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
1486 abort ();
1487 value->un.addr.offset = INTVAL (XEXP (x, 1));
1489 else if (GET_CODE (x) == MINUS)
1491 value->un.addr.base = XEXP (x, 0);
1492 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
1493 abort ();
1494 value->un.addr.offset = - INTVAL (XEXP (x, 1));
1496 else
1497 abort ();
1498 break;
1500 default:
1501 abort ();
1504 if (value->kind == RTX_INT && value->un.addr.base != 0)
1505 switch (GET_CODE (value->un.addr.base))
1507 case SYMBOL_REF:
1508 case LABEL_REF:
1509 /* Use the string's address, not the SYMBOL_REF's address,
1510 for the sake of addresses of library routines.
1511 For a LABEL_REF, compare labels. */
1512 value->un.addr.base = XEXP (value->un.addr.base, 0);
1516 /* Compute a hash code for a constant RTL expression. */
1519 const_hash_rtx (mode, x)
1520 enum machine_mode mode;
1521 rtx x;
1523 register int hi, i;
1525 struct rtx_const value;
1526 decode_rtx_const (mode, x, &value);
1528 /* Compute hashing function */
1529 hi = 0;
1530 for (i = 0; i < sizeof value / sizeof (int); i++)
1531 hi += ((int *) &value)[i];
1533 hi &= (1 << HASHBITS) - 1;
1534 hi %= MAX_RTX_HASH_TABLE;
1535 return hi;
1538 /* Compare a constant rtl object X with a constant-descriptor DESC.
1539 Return 1 if DESC describes a constant with the same value as X. */
1541 static int
1542 compare_constant_rtx (mode, x, desc)
1543 enum machine_mode mode;
1544 rtx x;
1545 struct constant_descriptor *desc;
1547 register int *p = (int *) desc->contents;
1548 register int *strp;
1549 register int len;
1550 struct rtx_const value;
1552 decode_rtx_const (mode, x, &value);
1553 strp = (int *) &value;
1554 len = sizeof value / sizeof (int);
1556 /* Compare constant contents. */
1557 while (--len >= 0)
1558 if (*p++ != *strp++)
1559 return 0;
1561 return 1;
1564 /* Construct a constant descriptor for the rtl-expression X.
1565 It is up to the caller to enter the descriptor in the hash table. */
1567 static struct constant_descriptor *
1568 record_constant_rtx (mode, x)
1569 enum machine_mode mode;
1570 rtx x;
1572 struct constant_descriptor *ptr;
1573 char *label;
1574 struct rtx_const value;
1576 decode_rtx_const (mode, x, &value);
1578 obstack_grow (current_obstack, &ptr, sizeof ptr);
1579 obstack_grow (current_obstack, &label, sizeof label);
1581 /* Record constant contents. */
1582 obstack_grow (current_obstack, &value, sizeof value);
1584 return (struct constant_descriptor *) obstack_finish (current_obstack);
1587 /* Given a constant rtx X, make (or find) a memory constant for its value
1588 and return a MEM rtx to refer to it in memory. */
1591 force_const_mem (mode, x)
1592 enum machine_mode mode;
1593 rtx x;
1595 register int hash;
1596 register struct constant_descriptor *desc;
1597 char label[256];
1598 char *found = 0;
1599 rtx def;
1601 if (GET_CODE (x) == CONST_DOUBLE
1602 && GET_CODE (CONST_DOUBLE_MEM (x)) == MEM)
1603 return CONST_DOUBLE_MEM (x);
1605 /* Compute hash code of X. Search the descriptors for that hash code
1606 to see if any of them describes X. If yes, the descriptor records
1607 the label number already assigned. */
1609 hash = const_hash_rtx (mode, x);
1611 for (desc = const_rtx_hash_table[hash]; desc; desc = desc->next)
1612 if (compare_constant_rtx (mode, x, desc))
1614 found = desc->label;
1615 break;
1618 if (found == 0)
1620 register struct pool_constant *pool;
1621 register struct pool_sym *sym;
1622 int align;
1624 /* No constant equal to X is known to have been output.
1625 Make a constant descriptor to enter X in the hash table.
1626 Assign the label number and record it in the descriptor for
1627 future calls to this function to find. */
1629 desc = record_constant_rtx (mode, x);
1630 desc->next = const_rtx_hash_table[hash];
1631 const_rtx_hash_table[hash] = desc;
1633 /* Align the location counter as required by EXP's data type. */
1634 align = (mode == VOIDmode) ? UNITS_PER_WORD : GET_MODE_SIZE (mode);
1635 if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1636 align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
1638 pool_offset += align - 1;
1639 pool_offset &= ~ (align - 1);
1641 /* Allocate a pool constant descriptor, fill it in, and chain it in. */
1643 pool = (struct pool_constant *) oballoc (sizeof (struct pool_constant));
1644 pool->desc = desc;
1645 pool->constant = x;
1646 pool->mode = mode;
1647 pool->labelno = const_labelno;
1648 pool->align = align;
1649 pool->offset = pool_offset;
1650 pool->next = 0;
1652 if (last_pool == 0)
1653 first_pool = pool;
1654 else
1655 last_pool->next = pool;
1657 last_pool = pool;
1658 pool_offset += GET_MODE_SIZE (mode);
1660 /* Create a string containing the label name, in LABEL. */
1661 ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
1663 ++const_labelno;
1665 desc->label = found
1666 = (char *) obstack_copy0 (saveable_obstack, label, strlen (label));
1668 /* Add label to symbol hash table. */
1669 hash = SYMHASH (found);
1670 sym = (struct pool_sym *) oballoc (sizeof (struct pool_sym));
1671 sym->label = found;
1672 sym->pool = pool;
1673 sym->next = const_rtx_sym_hash_table[hash];
1674 const_rtx_sym_hash_table[hash] = sym;
1677 /* We have a symbol name; construct the SYMBOL_REF and the MEM. */
1679 def = gen_rtx (MEM, mode, gen_rtx (SYMBOL_REF, Pmode, found));
1681 RTX_UNCHANGING_P (def) = 1;
1682 /* Mark the symbol_ref as belonging to this constants pool. */
1683 CONSTANT_POOL_ADDRESS_P (XEXP (def, 0)) = 1;
1685 if (GET_CODE (x) == CONST_DOUBLE)
1687 if (CONST_DOUBLE_MEM (x) == cc0_rtx)
1689 CONST_DOUBLE_CHAIN (x) = real_constant_chain;
1690 real_constant_chain = x;
1692 CONST_DOUBLE_MEM (x) = def;
1695 return def;
1698 /* Given a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true, return a pointer to
1699 the corresponding pool_constant structure. */
1701 static struct pool_constant *
1702 find_pool_constant (addr)
1703 rtx addr;
1705 struct pool_sym *sym;
1706 char *label = XSTR (addr, 0);
1708 for (sym = const_rtx_sym_hash_table[SYMHASH (label)]; sym; sym = sym->next)
1709 if (sym->label == label)
1710 return sym->pool;
1712 abort ();
1715 /* Given a constant pool SYMBOL_REF, return the corresponding constant. */
1718 get_pool_constant (addr)
1719 rtx addr;
1721 return (find_pool_constant (addr))->constant;
1724 /* Similar, return the mode. */
1726 enum machine_mode
1727 get_pool_mode (addr)
1728 rtx addr;
1730 return (find_pool_constant (addr))->mode;
1733 /* Similar, return the offset in the constant pool. */
1736 get_pool_offset (addr)
1737 rtx addr;
1739 return (find_pool_constant (addr))->offset;
1742 /* Write all the constants in the constant pool. */
1744 void
1745 output_constant_pool (fnname, fndecl)
1746 char *fnname;
1747 tree fndecl;
1749 struct pool_constant *pool;
1750 rtx x;
1752 #ifdef ASM_OUTPUT_POOL_PROLOGUE
1753 ASM_OUTPUT_POOL_PROLOGUE (asm_out_file, fnname, fndecl, pool_offset);
1754 #endif
1756 for (pool = first_pool; pool; pool = pool->next)
1758 x = pool->constant;
1760 /* First switch to correct section. */
1761 #ifdef SELECT_RTX_SECTION
1762 SELECT_RTX_SECTION (pool->mode, x);
1763 #else
1764 text_section ();
1765 #endif
1767 if (pool->align > 1)
1768 ASM_OUTPUT_ALIGN (asm_out_file, exact_log2 (pool->align));
1770 /* Output the label. */
1771 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", pool->labelno);
1773 /* Output the value of the constant itself. */
1774 if (GET_CODE (x) == CONST_DOUBLE)
1776 union real_extract u;
1778 bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u);
1779 switch (pool->mode)
1781 /* Perhaps change the following to use
1782 CONST_DOUBLE_LOW and CONST_DOUBLE_HIGH, rather than u.i. */
1783 case DImode:
1784 #ifdef ASM_OUTPUT_DOUBLE_INT
1785 ASM_OUTPUT_DOUBLE_INT (asm_out_file, x);
1786 #else /* no ASM_OUTPUT_DOUBLE_INT */
1787 #ifndef WORDS_BIG_ENDIAN
1788 /* Output two ints. */
1789 ASM_OUTPUT_INT (asm_out_file,
1790 gen_rtx (CONST_INT, VOIDmode, u.i[0]));
1791 ASM_OUTPUT_INT (asm_out_file,
1792 gen_rtx (CONST_INT, VOIDmode, u.i[1]));
1793 #else
1794 /* Output two ints. */
1795 ASM_OUTPUT_INT (asm_out_file,
1796 gen_rtx (CONST_INT, VOIDmode, u.i[1]));
1797 ASM_OUTPUT_INT (asm_out_file,
1798 gen_rtx (CONST_INT, VOIDmode, u.i[0]));
1799 #endif /* WORDS_BIG_ENDIAN */
1800 #endif /* no ASM_OUTPUT_DOUBLE_INT */
1801 break;
1803 case DFmode:
1804 ASM_OUTPUT_DOUBLE (asm_out_file, u.d);
1805 break;
1807 case SFmode:
1808 ASM_OUTPUT_FLOAT (asm_out_file, u.d);
1811 else
1812 switch (pool->mode)
1814 case SImode:
1815 ASM_OUTPUT_INT (asm_out_file, x);
1816 break;
1818 case HImode:
1819 ASM_OUTPUT_SHORT (asm_out_file, x);
1820 break;
1822 case QImode:
1823 ASM_OUTPUT_CHAR (asm_out_file, x);
1824 break;
1827 /* Done with this pool. */
1828 first_pool = last_pool = 0;
1831 /* Find all the constants whose addresses are referenced inside of EXP,
1832 and make sure assembler code with a label has been output for each one. */
1834 void
1835 output_addressed_constants (exp)
1836 tree exp;
1838 switch (TREE_CODE (exp))
1840 case ADDR_EXPR:
1842 register tree constant = TREE_OPERAND (exp, 0);
1844 while (TREE_CODE (constant) == COMPONENT_REF)
1846 constant = TREE_OPERAND (constant, 0);
1849 if (TREE_LITERAL (constant))
1850 /* No need to do anything here
1851 for addresses of variables or functions. */
1852 output_constant_def (constant);
1854 break;
1856 case PLUS_EXPR:
1857 case MINUS_EXPR:
1858 output_addressed_constants (TREE_OPERAND (exp, 0));
1859 output_addressed_constants (TREE_OPERAND (exp, 1));
1860 break;
1862 case NOP_EXPR:
1863 case CONVERT_EXPR:
1864 output_addressed_constants (TREE_OPERAND (exp, 0));
1865 break;
1867 case CONSTRUCTOR:
1869 register tree link;
1870 for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
1871 output_addressed_constants (TREE_VALUE (link));
1873 break;
1875 case ERROR_MARK:
1876 break;
1878 default:
1879 if (! TREE_LITERAL (exp))
1880 abort ();
1884 /* Output assembler code for constant EXP to FILE, with no label.
1885 This includes the pseudo-op such as ".int" or ".byte", and a newline.
1886 Assumes output_addressed_constants has been done on EXP already.
1888 Generate exactly SIZE bytes of assembler data, padding at the end
1889 with zeros if necessary. SIZE must always be specified.
1891 SIZE is important for structure constructors,
1892 since trailing members may have been omitted from the constructor.
1893 It is also important for initialization of arrays from string constants
1894 since the full length of the string constant might not be wanted.
1895 It is also needed for initialization of unions, where the initializer's
1896 type is just one member, and that may not be as long as the union.
1898 There a case in which we would fail to output exactly SIZE bytes:
1899 for a structure constructor that wants to produce more than SIZE bytes.
1900 But such constructors will never be generated for any possible input. */
1902 void
1903 output_constant (exp, size)
1904 register tree exp;
1905 register int size;
1907 register enum tree_code code = TREE_CODE (TREE_TYPE (exp));
1908 rtx x;
1910 if (size == 0)
1911 return;
1913 /* Eliminate the NOP_EXPR that makes a cast not be an lvalue.
1914 That way we get the constant (we hope) inside it. */
1915 if (TREE_CODE (exp) == NOP_EXPR
1916 && TREE_TYPE (exp) == TREE_TYPE (TREE_OPERAND (exp, 0)))
1917 exp = TREE_OPERAND (exp, 0);
1919 switch (code)
1921 case INTEGER_TYPE:
1922 case ENUMERAL_TYPE:
1923 case POINTER_TYPE:
1924 case REFERENCE_TYPE:
1925 while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR)
1926 exp = TREE_OPERAND (exp, 0);
1928 #ifndef ASM_OUTPUT_DOUBLE_INT
1929 if (TYPE_MODE (TREE_TYPE (exp)) == DImode)
1931 if (TREE_CODE (exp) == INTEGER_CST)
1933 #ifndef WORDS_BIG_ENDIAN
1934 ASM_OUTPUT_INT (asm_out_file,
1935 gen_rtx (CONST_INT, VOIDmode,
1936 TREE_INT_CST_LOW (exp)));
1937 ASM_OUTPUT_INT (asm_out_file,
1938 gen_rtx (CONST_INT, VOIDmode,
1939 TREE_INT_CST_HIGH (exp)));
1940 #else
1941 ASM_OUTPUT_INT (asm_out_file,
1942 gen_rtx (CONST_INT, VOIDmode,
1943 TREE_INT_CST_HIGH (exp)));
1944 ASM_OUTPUT_INT (asm_out_file,
1945 gen_rtx (CONST_INT, VOIDmode,
1946 TREE_INT_CST_LOW (exp)));
1947 #endif
1948 size -= GET_MODE_SIZE (DImode);
1949 break;
1951 else
1952 error ("8-byte integer constant expression too complicated");
1954 break;
1956 #endif /* no ASM_OUTPUT_DOUBLE_INT */
1958 x = expand_expr (exp, 0, VOIDmode, EXPAND_SUM);
1960 if (size == GET_MODE_SIZE (QImode))
1962 ASM_OUTPUT_CHAR (asm_out_file, x);
1963 size -= GET_MODE_SIZE (QImode);
1965 else if (size == GET_MODE_SIZE (HImode))
1967 ASM_OUTPUT_SHORT (asm_out_file, x);
1968 size -= GET_MODE_SIZE (HImode);
1970 else if (size == GET_MODE_SIZE (SImode))
1972 ASM_OUTPUT_INT (asm_out_file, x);
1973 size -= GET_MODE_SIZE (SImode);
1975 #ifdef ASM_OUTPUT_DOUBLE_INT
1976 else if (size == GET_MODE_SIZE (DImode))
1978 ASM_OUTPUT_DOUBLE_INT (asm_out_file, x);
1979 size -= GET_MODE_SIZE (DImode);
1981 #endif /* ASM_OUTPUT_DOUBLE_INT */
1982 else
1983 abort ();
1985 break;
1987 case REAL_TYPE:
1988 if (TREE_CODE (exp) != REAL_CST)
1989 error ("initializer for floating value is not a floating constant");
1990 else
1992 REAL_VALUE_TYPE d;
1993 jmp_buf output_constant_handler;
1995 d = TREE_REAL_CST (exp);
1996 if (setjmp (output_constant_handler))
1998 error ("floating point trap outputting a constant");
1999 #ifdef REAL_IS_NOT_DOUBLE
2000 bzero (&d, sizeof d);
2001 d = REAL_VALUE_ATOF ("0");
2002 #else
2003 d = 0;
2004 #endif
2006 set_float_handler (output_constant_handler);
2008 if (size < GET_MODE_SIZE (SFmode))
2009 break;
2010 else if (size < GET_MODE_SIZE (DFmode))
2012 ASM_OUTPUT_FLOAT (asm_out_file, d);
2013 size -= GET_MODE_SIZE (SFmode);
2015 else
2017 ASM_OUTPUT_DOUBLE (asm_out_file, d);
2018 size -= GET_MODE_SIZE (DFmode);
2020 set_float_handler (0);
2022 break;
2024 case COMPLEX_TYPE:
2025 output_constant (TREE_REALPART (exp), size / 2);
2026 output_constant (TREE_IMAGPART (exp), size / 2);
2027 size -= (size / 2) * 2;
2028 break;
2030 case ARRAY_TYPE:
2031 if (TREE_CODE (exp) == CONSTRUCTOR)
2033 output_constructor (exp, size);
2034 return;
2036 else if (TREE_CODE (exp) == STRING_CST)
2038 int excess = 0;
2040 if (size > TREE_STRING_LENGTH (exp))
2042 excess = size - TREE_STRING_LENGTH (exp);
2043 size = TREE_STRING_LENGTH (exp);
2046 assemble_string (TREE_STRING_POINTER (exp), size);
2047 size = excess;
2049 else
2050 abort ();
2051 break;
2053 case RECORD_TYPE:
2054 case UNION_TYPE:
2055 if (TREE_CODE (exp) == CONSTRUCTOR)
2056 output_constructor (exp, size);
2057 else
2058 abort ();
2059 return;
2062 if (size > 0)
2063 ASM_OUTPUT_SKIP (asm_out_file, size);
2066 /* Subroutine of output_constant, used for CONSTRUCTORs
2067 (aggregate constants).
2068 Generate at least SIZE bytes, padding if necessary. */
2070 void
2071 output_constructor (exp, size)
2072 tree exp;
2073 int size;
2075 register tree link, field = 0;
2076 /* Number of bytes output or skipped so far.
2077 In other words, current position within the constructor. */
2078 int total_bytes = 0;
2079 /* Non-zero means BYTE contains part of a byte, to be output. */
2080 int byte_buffer_in_use = 0;
2081 register int byte;
2083 if (HOST_BITS_PER_INT < BITS_PER_UNIT)
2084 abort ();
2086 if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
2087 || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE)
2088 field = TYPE_FIELDS (TREE_TYPE (exp));
2090 /* As LINK goes through the elements of the constant,
2091 FIELD goes through the structure fields, if the constant is a structure.
2092 But the constant could also be an array. Then FIELD is zero. */
2093 for (link = CONSTRUCTOR_ELTS (exp);
2094 link;
2095 link = TREE_CHAIN (link),
2096 field = field ? TREE_CHAIN (field) : 0)
2098 tree val = TREE_VALUE (link);
2100 /* Eliminate the NOP_EXPR that makes a cast not be an lvalue. */
2101 if (TREE_CODE (val) == NOP_EXPR
2102 && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0)))
2103 val = TREE_OPERAND (val, 0);
2105 if (field == 0
2106 || (DECL_MODE (field) != BImode))
2108 register int fieldsize;
2110 /* An element that is not a bit-field.
2111 Output any buffered-up bit-fields preceding it. */
2112 if (byte_buffer_in_use)
2114 ASM_OUTPUT_BYTE (asm_out_file, byte);
2115 total_bytes++;
2116 byte_buffer_in_use = 0;
2119 /* Advance to offset of this element.
2120 Note no alignment needed in an array, since that is guaranteed
2121 if each element has the proper size. */
2122 if (field != 0 && DECL_OFFSET (field) / BITS_PER_UNIT != total_bytes)
2124 ASM_OUTPUT_SKIP (asm_out_file,
2125 (DECL_OFFSET (field) / BITS_PER_UNIT
2126 - total_bytes));
2127 total_bytes = DECL_OFFSET (field) / BITS_PER_UNIT;
2130 /* Determine size this element should occupy. */
2131 if (field)
2133 if (! TREE_LITERAL (DECL_SIZE (field)))
2134 abort ();
2135 fieldsize = TREE_INT_CST_LOW (DECL_SIZE (field))
2136 * DECL_SIZE_UNIT (field);
2137 fieldsize = (fieldsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
2139 else
2140 fieldsize = int_size_in_bytes (TREE_TYPE (TREE_TYPE (exp)));
2142 /* Output the element's initial value. */
2143 output_constant (val, fieldsize);
2145 /* Count its size. */
2146 total_bytes += fieldsize;
2148 else if (TREE_CODE (val) != INTEGER_CST)
2149 error ("invalid initial value for member `%s'",
2150 IDENTIFIER_POINTER (DECL_NAME (field)));
2151 else
2153 /* Element that is a bit-field. */
2155 int next_offset = DECL_OFFSET (field);
2156 int end_offset
2157 = (next_offset
2158 + (TREE_INT_CST_LOW (DECL_SIZE (field))
2159 * DECL_SIZE_UNIT (field)));
2161 /* If this field does not start in this (or, next) byte,
2162 skip some bytes. */
2163 if (next_offset / BITS_PER_UNIT != total_bytes)
2165 /* Output remnant of any bit field in previous bytes. */
2166 if (byte_buffer_in_use)
2168 ASM_OUTPUT_BYTE (asm_out_file, byte);
2169 total_bytes++;
2170 byte_buffer_in_use = 0;
2173 /* If still not at proper byte, advance to there. */
2174 if (next_offset / BITS_PER_UNIT != total_bytes)
2176 ASM_OUTPUT_SKIP (asm_out_file,
2177 next_offset / BITS_PER_UNIT - total_bytes);
2178 total_bytes = next_offset / BITS_PER_UNIT;
2182 if (! byte_buffer_in_use)
2183 byte = 0;
2185 /* We must split the element into pieces that fall within
2186 separate bytes, and combine each byte with previous or
2187 following bit-fields. */
2189 /* next_offset is the offset n fbits from the begining of
2190 the structure to the next bit of this element to be processed.
2191 end_offset is the offset of the first bit past the end of
2192 this element. */
2193 while (next_offset < end_offset)
2195 int this_time;
2196 int next_byte = next_offset / BITS_PER_UNIT;
2197 int next_bit = next_offset % BITS_PER_UNIT;
2199 /* Advance from byte to byte
2200 within this element when necessary. */
2201 while (next_byte != total_bytes)
2203 ASM_OUTPUT_BYTE (asm_out_file, byte);
2204 total_bytes++;
2205 byte = 0;
2208 /* Number of bits we can process at once
2209 (all part of the same byte). */
2210 this_time = MIN (end_offset - next_offset,
2211 BITS_PER_UNIT - next_bit);
2212 #ifdef BYTES_BIG_ENDIAN
2213 /* On big-endian machine, take the most significant bits
2214 first (of the bits that are significant)
2215 and put them into bytes from the most significant end. */
2216 byte |= (((TREE_INT_CST_LOW (val)
2217 >> (end_offset - next_offset - this_time))
2218 & ((1 << this_time) - 1))
2219 << (BITS_PER_UNIT - this_time - next_bit));
2220 #else
2221 /* On little-endian machines,
2222 take first the least significant bits of the value
2223 and pack them starting at the least significant
2224 bits of the bytes. */
2225 byte |= ((TREE_INT_CST_LOW (val)
2226 >> (next_offset - DECL_OFFSET (field)))
2227 & ((1 << this_time) - 1)) << next_bit;
2228 #endif
2229 next_offset += this_time;
2230 byte_buffer_in_use = 1;
2234 if (byte_buffer_in_use)
2236 ASM_OUTPUT_BYTE (asm_out_file, byte);
2237 total_bytes++;
2239 if (total_bytes < size)
2240 ASM_OUTPUT_SKIP (asm_out_file, size - total_bytes);