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