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